Medical Imaging Interaction Toolkit  2018.4.99-3e3f1a6e
Medical Imaging Interaction Toolkit
mitkClaronTrackingDevice.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
14 #include "mitkClaronTool.h"
15 #include "mitkIGTConfig.h"
16 #include "mitkIGTTimeStamp.h"
17 #include "mitkIGTHardwareException.h"
18 #include <itksys/SystemTools.hxx>
19 #include <iostream>
20 #include <itkMutexLockHolder.h>
21 #include <mitkIOUtil.h>
23 
25 
26 
28 {
29  //set the type of this tracking device
31 
32  this->m_MultiThreader = itk::MultiThreader::New();
33  m_ThreadID = 0;
34 
36  //############################# standard directories ##################################
37  if (m_Device->IsMicronTrackerInstalled())
38  {
40 #ifdef MITK_MICRON_TRACKER_CALIBRATION_DIR
41  m_CalibrationDir = std::string(MITK_MICRON_TRACKER_CALIBRATION_DIR);
42 #endif
43  }
44  else
45  {
46  m_ToolfilesDir = "Error - No Microntracker installed";
47  m_CalibrationDir = "Error - No Microntracker installed";
48  }
49  //##################################################################################################
51 }
52 
54 {
55  mitk::ClaronInterface::Pointer tempInterface = mitk::ClaronInterface::New();
56  return tempInterface->IsMicronTrackerInstalled();
57 }
58 
59 
61 {
62 }
63 
64 
65 mitk::TrackingTool* mitk::ClaronTrackingDevice::AddTool( const char* toolName, const char* fileName )
66 {
67  mitk::ClaronTool::Pointer t = mitk::ClaronTool::New();
68  if (t->LoadFile(fileName) == false)
69  {
70  return nullptr;
71  }
72  t->SetToolName(toolName);
73  if (this->InternalAddTool(t) == false)
74  return nullptr;
75  return t.GetPointer();
76 }
77 
78 
79 bool mitk::ClaronTrackingDevice::InternalAddTool(ClaronTool::Pointer tool)
80 {
81  m_AllTools.push_back(tool);
82  return true;
83 }
84 
85 
86 std::vector<mitk::ClaronTool::Pointer> mitk::ClaronTrackingDevice::DetectTools()
87 {
88  std::vector<mitk::ClaronTool::Pointer> returnValue;
89  std::vector<claronToolHandle> allHandles = m_Device->GetAllActiveTools();
90  for (auto iter = allHandles.begin(); iter != allHandles.end(); ++iter)
91  {
92  ClaronTool::Pointer newTool = ClaronTool::New();
93  newTool->SetToolName(m_Device->GetName(*iter));
94  newTool->SetCalibrationName(m_Device->GetName(*iter));
95  newTool->SetToolHandle(*iter);
96  returnValue.push_back(newTool);
97  }
98  return returnValue;
99 }
100 
101 
103 {
104 
105  //By Alfred: next line because no temp directory is set if MicronTracker is not installed
106  if (!m_Device->IsMicronTrackerInstalled())
107  return false;
108  //##################################################################################
109 
110  //be sure that the temp-directory is empty at start: delete all files in the tool files directory
111  itksys::SystemTools::RemoveADirectory(m_ToolfilesDir.c_str());
112  itksys::SystemTools::MakeDirectory(m_ToolfilesDir.c_str());
113 
114  //copy all toolfiles into the temp directory
115  for (unsigned int i=0; i<m_AllTools.size(); i++)
116  {
117  itksys::SystemTools::CopyAFile(m_AllTools[i]->GetFile().c_str(), m_ToolfilesDir.c_str());
118  }
119  this->SetState(Tracking); // go to mode Tracking
120  this->m_StopTrackingMutex->Lock(); // update the local copy of m_StopTracking
121  this->m_StopTracking = false;
122  this->m_StopTrackingMutex->Unlock();
123 
124  //restart the Microntracker, so it will load the new tool files
125  m_Device->StopTracking();
127 
128  if (m_Device->StartTracking())
129  {
131  m_ThreadID = m_MultiThreader->SpawnThread(this->ThreadStartTracking, this); // start a new thread that executes the TrackTools() method
132  return true;
133  }
134  else
135  {mitkThrowException(mitk::IGTHardwareException) << "Error while trying to start the device!";}
136 }
137 
138 
140 {
141  Superclass::StopTracking();
142  //delete all files in the tool files directory
143  itksys::SystemTools::RemoveADirectory(m_ToolfilesDir.c_str());
144  return true;
145 }
146 
147 
149 {
150  return (unsigned int)this->m_AllTools.size();
151 }
152 
153 
155 {
156  if ( toolNumber >= this->GetToolCount())
157  return nullptr;
158  else
159  return this->m_AllTools[toolNumber];
160 }
161 
162 
164 {
165  bool returnValue;
166  //Create the temp directory
167  itksys::SystemTools::MakeDirectory(m_ToolfilesDir.c_str());
168 
170  returnValue = m_Device->StartTracking();
171 
172  if (returnValue)
173  {
174  this->SetState(Ready);
175  }
176  else
177  {
178  //reset everything
179  if (m_Device.IsNull())
180  {
183  }
184  m_Device->StopTracking();
185  this->SetState(Setup);
186  mitkThrowException(mitk::IGTHardwareException) << "Error while trying to open connection to the MicronTracker.";
187  }
188  return returnValue;
189 }
190 
191 
193 {
194  bool returnValue = true;
195  if (this->GetState() == Setup)
196  return true;
197 
198  returnValue = m_Device->StopTracking();
199 
200  //delete the temporary directory
201  itksys::SystemTools::RemoveADirectory(m_ToolfilesDir.c_str());
202 
203  this->SetState(Setup);
204  return returnValue;
205 }
206 
207 
209 {
210  return m_Device;
211 }
212 
213 
214 std::vector<mitk::ClaronTool::Pointer> mitk::ClaronTrackingDevice::GetAllTools()
215 {
216  return this->m_AllTools;
217 }
218 
219 
221 {
222  try
223  {
224  /* lock the TrackingFinishedMutex to signal that the execution rights are now transfered to the tracking thread */
225  MutexLockHolder trackingFinishedLockHolder(*m_TrackingFinishedMutex); // keep lock until end of scope
226 
227  bool localStopTracking; // Because m_StopTracking is used by two threads, access has to be guarded by a mutex. To minimize thread locking, a local copy is used here
228  this->m_StopTrackingMutex->Lock(); // update the local copy of m_StopTracking
229  localStopTracking = this->m_StopTracking;
230  this->m_StopTrackingMutex->Unlock();
231 
232  while ((this->GetState() == Tracking) && (localStopTracking == false))
233  {
234  this->GetDevice()->GrabFrame();
235 
236  std::vector<mitk::ClaronTool::Pointer> detectedTools = this->DetectTools();
237  std::vector<mitk::ClaronTool::Pointer> allTools = this->GetAllTools();
238  std::vector<mitk::ClaronTool::Pointer>::iterator itAllTools;
239  for(itAllTools = allTools.begin(); itAllTools != allTools.end(); itAllTools++)
240  {
241  mitk::ClaronTool::Pointer currentTool = *itAllTools;
242  //test if current tool was detected
243  std::vector<mitk::ClaronTool::Pointer>::iterator itDetectedTools;
244  bool foundTool = false;
245  for(itDetectedTools = detectedTools.begin(); itDetectedTools != detectedTools.end(); itDetectedTools++)
246  {
247  mitk::ClaronTool::Pointer aktuDet = *itDetectedTools;
248  std::string tempString(currentTool->GetCalibrationName());
249  if (tempString.compare(aktuDet->GetCalibrationName())==0)
250  {
251  currentTool->SetToolHandle(aktuDet->GetToolHandle());
252  foundTool = true;
253  }
254  }
255  if (!foundTool)
256  {
257  currentTool->SetToolHandle(0);
258  }
259 
260  if (currentTool->GetToolHandle() != 0)
261  {
262  currentTool->SetDataValid(true);
263  //get tip position of tool:
264  std::vector<double> pos_vector = this->GetDevice()->GetTipPosition(currentTool->GetToolHandle());
265  //write tip position into tool:
266  mitk::Point3D pos;
267  pos[0] = pos_vector[0];
268  pos[1] = pos_vector[1];
269  pos[2] = pos_vector[2];
270  currentTool->SetPosition(pos);
271  //get tip quaternion of tool
272  std::vector<double> quat = this->GetDevice()->GetTipQuaternions(currentTool->GetToolHandle());
273  //write tip quaternion into tool
274  mitk::Quaternion orientation(quat[1], quat[2], quat[3], quat[0]);
275  currentTool->SetOrientation(orientation);
276 
277  //TODO: read the timestamp data from the tracking device interface
278  currentTool->SetIGTTimeStamp(mitk::IGTTimeStamp::GetInstance()->GetElapsed());
279  }
280  else
281  {
282  mitk::Point3D origin;
283  origin.Fill(0);
284  currentTool->SetPosition(origin);
285  currentTool->SetOrientation(mitk::Quaternion(0,0,0,0));
286  currentTool->SetDataValid(false);
287  }
288  }
289  /* Update the local copy of m_StopTracking */
290  this->m_StopTrackingMutex->Lock();
291  localStopTracking = m_StopTracking;
292  this->m_StopTrackingMutex->Unlock();
293  }
294  }
295  catch(...)
296  {
297  this->StopTracking();
298  mitkThrowException(mitk::IGTHardwareException) << "Error while trying to track tools. Thread stopped.";
299  }
300 }
301 
302 
304 {
305  return this->m_Device->IsMicronTrackerInstalled();
306 }
307 
308 
309 ITK_THREAD_RETURN_TYPE mitk::ClaronTrackingDevice::ThreadStartTracking(void* pInfoStruct)
310 {
311  /* extract this pointer from Thread Info structure */
312  struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct;
313  if (pInfo == nullptr)
314  {
315  return ITK_THREAD_RETURN_VALUE;
316  }
317  if (pInfo->UserData == nullptr)
318  {
319  return ITK_THREAD_RETURN_VALUE;
320  }
321  ClaronTrackingDevice *trackingDevice = (ClaronTrackingDevice*)pInfo->UserData;
322 
323  if (trackingDevice != nullptr)
324  trackingDevice->TrackTools();
325 
326  return ITK_THREAD_RETURN_VALUE;
327 }
itk::MultiThreader::Pointer m_MultiThreader
An object of this class represents an exception of the MITK-IGT module which are releated to the hard...
Interface for all Tracking Tools.
std::string m_ToolfilesDir
The directory where the tool calibration files can be found.
itk::FastMutexLock::Pointer m_TrackingFinishedMutex
mutex to manage control flow of StopTracking()
std::vector< double > GetTipPosition(claronToolHandle c)
std::vector< ClaronTool::Pointer > DetectTools()
Automatically detects tools in field of measurement of the tracking device. Tools can only be detecte...
std::vector< double > GetTipQuaternions(claronToolHandle c)
static Pointer New()
An object of this class represents the interface to the MicronTracker. The methods of this class are ...
DataCollection - Class to facilitate loading/accessing structured data.
std::vector< ClaronTool::Pointer > m_AllTools
vector holding all tools
std::vector< ClaronTool::Pointer > GetAllTools()
bool StartTracking() override
Starts the tracking.
TrackingDeviceState GetState() const
return current object state (Setup, Ready or Tracking)
mitk::TrackingTool * AddTool(const char *toolName, const char *fileName)
Create a new Claron tool with toolName and fileName and add it to the list of tools.
An object of this class represents the MicronTracker device. You can add tools to this device...
unsigned int GetToolCount() const override
bool StopTracking() override
Stops the tracking.
void GrabFrame()
Grabs a frame from the camera.
bool CloseConnection() override
Closes the connection and clears all resources.
bool OpenConnection() override
Opens the connection to the device. This have to be done before the tracking is started.
bool m_StopTracking
signal stop to tracking thread
Interface for all Tracking Devices.
static IGTTimeStamp * GetInstance()
returns a pointer to the current instance of mitkTimeStamp
vnl_quaternion< ScalarType > Quaternion
void Start(itk::Object::Pointer device)
starts the time-acquisition
bool InternalAddTool(ClaronTool::Pointer tool)
Adds a tool to the tracking device.
static ITK_THREAD_RETURN_TYPE ThreadStartTracking(void *data)
std::string m_CalibrationDir
The directory where the camera calibration files can be found.
static std::string CreateTemporaryDirectory(const std::string &templateName="XXXXXX", std::string path=std::string())
Definition: mitkIOUtil.cpp:458
TrackingDeviceData m_Data
current device Data
#define mitkThrowException(classname)
itk::FastMutexLock::Pointer m_StopTrackingMutex
mutex to control access to m_StopTracking
void TrackTools()
This method tracks tools as long as the variable m_Mode is set to "Tracking". Tracking tools means gr...
ClaronInterface::Pointer m_Device
represents the interface to the tracking hardware
void SetState(TrackingDeviceState state)
change object state
TrackingTool * GetTool(unsigned int toolNumber) const override
static Pointer New()
itk::MutexLockHolder< itk::FastMutexLock > MutexLockHolder