Medical Imaging Interaction Toolkit  2016.11.0
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,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
18 #include "mitkClaronTool.h"
19 #include "mitkIGTConfig.h"
20 #include "mitkIGTTimeStamp.h"
21 #include "mitkIGTHardwareException.h"
22 #include <itksys/SystemTools.hxx>
23 #include <iostream>
24 #include <itkMutexLockHolder.h>
26 
28 
29 
31 {
32  //set the type of this tracking device
34 
36  m_ThreadID = 0;
37 
39  //############################# standard directories (from cmake) ##################################
40  if (m_Device->IsMicronTrackerInstalled())
41  {
42 #ifdef MITK_MICRON_TRACKER_TEMP_DIR
43  m_ToolfilesDir = std::string(MITK_MICRON_TRACKER_TEMP_DIR);
44  m_ToolfilesDir.append("/MT-tools");
45 #endif
46 #ifdef MITK_MICRON_TRACKER_CALIBRATION_DIR
47  m_CalibrationDir = std::string(MITK_MICRON_TRACKER_CALIBRATION_DIR);
48 #endif
49  }
50  else
51  {
52  m_ToolfilesDir = "Error - No Microntracker installed";
53  m_CalibrationDir = "Error - No Microntracker installed";
54  }
55  //##################################################################################################
57 }
58 
60 {
62  return tempInterface->IsMicronTrackerInstalled();
63 }
64 
65 
67 {
68 }
69 
70 
71 mitk::TrackingTool* mitk::ClaronTrackingDevice::AddTool( const char* toolName, const char* fileName )
72 {
74  if (t->LoadFile(fileName) == false)
75  {
76  return nullptr;
77  }
78  t->SetToolName(toolName);
79  if (this->InternalAddTool(t) == false)
80  return nullptr;
81  return t.GetPointer();
82 }
83 
84 
86 {
87  m_AllTools.push_back(tool);
88  return true;
89 }
90 
91 
92 std::vector<mitk::ClaronTool::Pointer> mitk::ClaronTrackingDevice::DetectTools()
93 {
94  std::vector<mitk::ClaronTool::Pointer> returnValue;
95  std::vector<claronToolHandle> allHandles = m_Device->GetAllActiveTools();
96  for (auto iter = allHandles.begin(); iter != allHandles.end(); ++iter)
97  {
99  newTool->SetToolName(m_Device->GetName(*iter));
100  newTool->SetCalibrationName(m_Device->GetName(*iter));
101  newTool->SetToolHandle(*iter);
102  returnValue.push_back(newTool);
103  }
104  return returnValue;
105 }
106 
107 
109 {
110 
111  //By Alfred: next line because no temp directory is set if MicronTracker is not installed
112  if (!m_Device->IsMicronTrackerInstalled())
113  return false;
114  //##################################################################################
115 
116  //be sure that the temp-directory is empty at start: delete all files in the tool files directory
117  itksys::SystemTools::RemoveADirectory(m_ToolfilesDir.c_str());
118  itksys::SystemTools::MakeDirectory(m_ToolfilesDir.c_str());
119 
120  //copy all toolfiles into the temp directory
121  for (unsigned int i=0; i<m_AllTools.size(); i++)
122  {
123  itksys::SystemTools::CopyAFile(m_AllTools[i]->GetFile().c_str(), m_ToolfilesDir.c_str());
124  }
125  this->SetState(Tracking); // go to mode Tracking
126  this->m_StopTrackingMutex->Lock(); // update the local copy of m_StopTracking
127  this->m_StopTracking = false;
128  this->m_StopTrackingMutex->Unlock();
129 
130  //restart the Microntracker, so it will load the new tool files
131  m_Device->StopTracking();
132  m_Device->Initialize(m_CalibrationDir,m_ToolfilesDir);
133 
134  if (m_Device->StartTracking())
135  {
137  m_ThreadID = m_MultiThreader->SpawnThread(this->ThreadStartTracking, this); // start a new thread that executes the TrackTools() method
138  return true;
139  }
140  else
141  {mitkThrowException(mitk::IGTHardwareException) << "Error while trying to start the device!";}
142 }
143 
144 
146 {
147  Superclass::StopTracking();
148  //delete all files in the tool files directory
149  itksys::SystemTools::RemoveADirectory(m_ToolfilesDir.c_str());
150  return true;
151 }
152 
153 
155 {
156  return (unsigned int)this->m_AllTools.size();
157 }
158 
159 
161 {
162  if ( toolNumber >= this->GetToolCount())
163  return nullptr;
164  else
165  return this->m_AllTools[toolNumber];
166 }
167 
168 
170 {
171  bool returnValue;
172  //Create the temp directory
173  itksys::SystemTools::MakeDirectory(m_ToolfilesDir.c_str());
174 
175  m_Device->Initialize(m_CalibrationDir,m_ToolfilesDir);
176  returnValue = m_Device->StartTracking();
177 
178  if (returnValue)
179  {
180  this->SetState(Ready);
181  }
182  else
183  {
184  //reset everything
185  if (m_Device.IsNull())
186  {
187  m_Device = mitk::ClaronInterface::New();
188  m_Device->Initialize(m_CalibrationDir, m_ToolfilesDir);
189  }
190  m_Device->StopTracking();
191  this->SetState(Setup);
192  mitkThrowException(mitk::IGTHardwareException) << "Error while trying to open connection to the MicronTracker.";
193  }
194  return returnValue;
195 }
196 
197 
199 {
200  bool returnValue = true;
201  if (this->GetState() == Setup)
202  return true;
203 
204  returnValue = m_Device->StopTracking();
205 
206  //delete the temporary directory
207  itksys::SystemTools::RemoveADirectory(m_ToolfilesDir.c_str());
208 
209  this->SetState(Setup);
210  return returnValue;
211 }
212 
213 
215 {
216  return m_Device;
217 }
218 
219 
220 std::vector<mitk::ClaronTool::Pointer> mitk::ClaronTrackingDevice::GetAllTools()
221 {
222  return this->m_AllTools;
223 }
224 
225 
227 {
228  try
229  {
230  /* lock the TrackingFinishedMutex to signal that the execution rights are now transfered to the tracking thread */
231  MutexLockHolder trackingFinishedLockHolder(*m_TrackingFinishedMutex); // keep lock until end of scope
232 
233  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
234  this->m_StopTrackingMutex->Lock(); // update the local copy of m_StopTracking
235  localStopTracking = this->m_StopTracking;
236  this->m_StopTrackingMutex->Unlock();
237 
238  while ((this->GetState() == Tracking) && (localStopTracking == false))
239  {
240  this->GetDevice()->GrabFrame();
241 
242  std::vector<mitk::ClaronTool::Pointer> detectedTools = this->DetectTools();
243  std::vector<mitk::ClaronTool::Pointer> allTools = this->GetAllTools();
244  std::vector<mitk::ClaronTool::Pointer>::iterator itAllTools;
245  for(itAllTools = allTools.begin(); itAllTools != allTools.end(); itAllTools++)
246  {
247  mitk::ClaronTool::Pointer currentTool = *itAllTools;
248  //test if current tool was detected
249  std::vector<mitk::ClaronTool::Pointer>::iterator itDetectedTools;
250  bool foundTool = false;
251  for(itDetectedTools = detectedTools.begin(); itDetectedTools != detectedTools.end(); itDetectedTools++)
252  {
253  mitk::ClaronTool::Pointer aktuDet = *itDetectedTools;
254  std::string tempString(currentTool->GetCalibrationName());
255  if (tempString.compare(aktuDet->GetCalibrationName())==0)
256  {
257  currentTool->SetToolHandle(aktuDet->GetToolHandle());
258  foundTool = true;
259  }
260  }
261  if (!foundTool)
262  {
263  currentTool->SetToolHandle(0);
264  }
265 
266  if (currentTool->GetToolHandle() != 0)
267  {
268  currentTool->SetDataValid(true);
269  //get tip position of tool:
270  std::vector<double> pos_vector = this->GetDevice()->GetTipPosition(currentTool->GetToolHandle());
271  //write tip position into tool:
272  mitk::Point3D pos;
273  pos[0] = pos_vector[0];
274  pos[1] = pos_vector[1];
275  pos[2] = pos_vector[2];
276  currentTool->SetPosition(pos);
277  //get tip quaternion of tool
278  std::vector<double> quat = this->GetDevice()->GetTipQuaternions(currentTool->GetToolHandle());
279  //write tip quaternion into tool
280  mitk::Quaternion orientation(quat[1], quat[2], quat[3], quat[0]);
281  currentTool->SetOrientation(orientation);
282 
283  //TODO: read the timestamp data from the tracking device interface
284  currentTool->SetIGTTimeStamp(mitk::IGTTimeStamp::GetInstance()->GetElapsed());
285  }
286  else
287  {
288  mitk::Point3D origin;
289  origin.Fill(0);
290  currentTool->SetPosition(origin);
291  currentTool->SetOrientation(mitk::Quaternion(0,0,0,0));
292  currentTool->SetDataValid(false);
293  }
294  }
295  /* Update the local copy of m_StopTracking */
296  this->m_StopTrackingMutex->Lock();
297  localStopTracking = m_StopTracking;
298  this->m_StopTrackingMutex->Unlock();
299  }
300  }
301  catch(...)
302  {
303  this->StopTracking();
304  mitkThrowException(mitk::IGTHardwareException) << "Error while trying to track tools. Thread stopped.";
305  }
306 }
307 
308 
310 {
311  return this->m_Device->IsMicronTrackerInstalled();
312 }
313 
314 
315 ITK_THREAD_RETURN_TYPE mitk::ClaronTrackingDevice::ThreadStartTracking(void* pInfoStruct)
316 {
317  /* extract this pointer from Thread Info structure */
318  struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct;
319  if (pInfo == nullptr)
320  {
321  return ITK_THREAD_RETURN_VALUE;
322  }
323  if (pInfo->UserData == nullptr)
324  {
325  return ITK_THREAD_RETURN_VALUE;
326  }
327  ClaronTrackingDevice *trackingDevice = (ClaronTrackingDevice*)pInfo->UserData;
328 
329  if (trackingDevice != nullptr)
330  trackingDevice->TrackTools();
331 
332  return ITK_THREAD_RETURN_VALUE;
333 }
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.
itk::SmartPointer< Self > Pointer
std::string m_ToolfilesDir
The directory where the tool calibration files can be found.
std::vector< ClaronTool::Pointer > DetectTools()
Automatically detects tools in field of measurement of the tracking device. Tools can only be detecte...
virtual bool IsDeviceInstalled() override
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 > GetAllTools()
virtual bool StartTracking() override
Starts the 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...
virtual unsigned int GetToolCount() const override
virtual bool StopTracking() override
Stops the tracking.
virtual bool CloseConnection() override
Closes the connection and clears all resources.
virtual bool OpenConnection() override
Opens the connection to the device. This have to be done before the tracking is started.
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.
TrackingDeviceData m_Data
current device Data
#define mitkThrowException(classname)
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
static void Setup()
TrackingTool * GetTool(unsigned int toolNumber) const override
static Pointer New()
itk::MutexLockHolder< itk::FastMutexLock > MutexLockHolder
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.