CustusX  15.8
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxIgstkTool.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 
33 #include "cxIgstkTool.h"
34 
35 #include <QDir>
36 #include <QDateTime>
37 #include <QStringList>
38 #include <QTextStream>
39 #include "cxLogger.h"
40 #include "cxTypeConversions.h"
41 #include "cxSettings.h"
42 #include "cxTransformFile.h"
43 
44 namespace cx
45 {
46 
48 {
49  vtkMatrix4x4Ptr M = vtkMatrix4x4Ptr::New();
50  mCalibration.ExportTransform(*(M.GetPointer()));
51  Transform3D sMt = Transform3D::fromVtkMatrix(M);
52  return sMt;
53 }
54 
56 {
57  mCalibration.ImportTransform(*cal.getVtkMatrix());
58 }
59 
61 {
62  QString filename = mCalibrationFilename;
63 // QFile calibrationFile;
64  if (!filename.isEmpty() && QFile::exists(filename))
65  {
66  //Calibration file exists, overwrite
67 // calibrationFile.setFileName(mCalibrationFilename);
68  }
69  else
70  {
71  //Make a new file, use rom file name as base name
72  filename = mSROMFilename.remove(".rom", Qt::CaseInsensitive);
73  filename.append(".cal");
74 // calibrationFile.setFileName(calibrationFileName);
75  }
76 
77  TransformFile file(filename);
78  file.write(this->getCalibrationAsSSC());
79 //
84 // Transform3D sMt = this->getCalibrationAsSSC();
85 //
86 // if (!calibrationFile.open(QIODevice::WriteOnly | QIODevice::Truncate))
87 // {
88 // reportError("Could not open " + mUid + "s calibrationfile: " + calibrationFile.fileName());
89 // return;
90 // }
91 //
92 // QTextStream streamer(&calibrationFile);
93 // streamer << qstring_cast(sMt);
94 // streamer << endl;
95 //
96 // calibrationFile.close();
97 
98  report("Replaced calibration in " + filename);
99 }
100 
101 
103 {
104  bool retval = true;
105  QString verificationError("Internal verification of tool " + mUid + " failed! REASON: ");
106  if (!mIsPointer && !mIsReference && !mIsProbe)
107  {
108 // reportError(verificationError+" Tag <tool>::<type> is invalid ["+qstring_cast(mType)+"]. Valid types: [pointer, usprobe, reference]");
109  reportError(
110  verificationError
111  + " Tag <tool>::<type> is invalid, must be one one of pointer/probe/reference ");
112  retval = false;
113  }
114  if (mUid.isEmpty())
115  {
116  reportError(verificationError + " Tag <tool>::<uid> is empty. Give tool a unique id.");
117  retval = false;
118  }
119  if (mTrackerType == tsNONE)
120  {
121  reportError(
122  verificationError + " Tag <sensor>::<type> is invalid ["
123  + qstring_cast(mTrackerType)
124  + "]. Valid types: [polaris, spectra, vicra, aurora, micron (NOT SUPPORTED YET)]");
125  retval = false;
126  }
127  if ((mTrackerType == tsAURORA) && (mPortNumber >= 4))
128  {
129  reportError(
130  verificationError + " Tag <sensor>::<portnumber> is invalid ["
131  + qstring_cast(mPortNumber)
132  + "]. Valid numbers: [0, 1, 2, 3]");
133  retval = false;
134  }
135  if ((mTrackerType == tsAURORA) && (mChannelNumber >= 1))
136  {
137  reportError(
138  verificationError + " Tag <sensor>::<channelnumber> is invalid ["
139  + qstring_cast(mChannelNumber) + "]. Valid numbers: [0, 1]");
140  retval = false;
141  }
142  QDir dir;
143  if (!mSROMFilename.isEmpty() && !dir.exists(mSROMFilename))
144  {
145  reportError(
146  verificationError + " Tag <sensor>::<rom_file> is invalid [" + mSROMFilename
147  + "]. Valid path: relative path to existing rom file.");
148  retval = false;
149  }
150  if (!mCalibrationFilename.isEmpty() && !dir.exists(mCalibrationFilename))
151  {
152  reportError(
153  verificationError + " Tag <calibration>::<cal_file> is invalid ["
154  + mCalibrationFilename
155  + "]. Valid path: relative path to existing calibration file.");
156  retval = false;
157  }
158  if (!mTransformSaveFileName.isEmpty() && !dir.exists(mTransformSaveFileName))
159  {
160  reportError(verificationError + " Logging folder is invalid. Contact programmer! :)");
161  retval = false;
162  }
163  if (!mLoggingFolderName.isEmpty() && !dir.exists(mLoggingFolderName))
164  {
165  reportError(verificationError + " Logging folder is invalid. Contact programmer! :)");
166  retval = false;
167  }
168 
169  return retval;
170 }
171 
173 {
174  //apply the calibration
175  mInternalStructure.mCalibration.ImportTransform(*cal.getVtkMatrix());
176  this->setCalibrationTransform(mInternalStructure.mCalibration);
177 
178  Transform3D sMt = mInternalStructure.getCalibrationAsSSC();
179  report("Set " + mInternalStructure.mName + "s calibration to \n" + qstring_cast(sMt));
180 
181  //write to file
182  mInternalStructure.saveCalibrationToFile();
183 }
184 
188 
190  mToolObserver(itk::ReceptorMemberCommand<IgstkTool>::New()), mValid(false), mVisible(false), mAttachedToTracker(
191  false)
192 {
193  qRegisterMetaType<Transform3D>("Transform3D");
194 
195  mInternalStructure = internalStructure;
196 
197  mToolObserver->SetCallbackFunction(this, &IgstkTool::toolTransformCallback);
198 
199  if (mInternalStructure.verify())
200  {
201  mTool = this->buildInternalTool();
202  this->addLogging();
203  mValid = true;
204  }
205  else
206  {
207  reportError(mInternalStructure.mUid + " was created with invalid internal structure.");
208  mValid = false;
209  }
210 }
211 
213 {
214 }
215 
217 {
218  return mInternalStructure;
219 }
220 
222 {
223  return mInternalStructure.mUid;
224 }
225 
226 igstk::TrackerTool::Pointer IgstkTool::getPointer() const
227 {
228  return mTool;
229 }
230 
231 TRACKING_SYSTEM IgstkTool::getTrackerType()
232 {
233  return mInternalStructure.mTrackerType;
234 }
235 
236 //Tool::Type IgstkTool::getType() const
237 //{
238 // return mInternalStructure.mType;
239 //}
240 
241 bool IgstkTool::isValid() const
242 {
243  return mValid;
244 }
245 
247 {
248  return mAttachedToTracker;
249 }
250 
252 {
253  return mTracked;
254 }
255 
257 {
258  return mVisible;
259 }
260 
262 {
263  mReferenceTool = refTool;
264 }
265 
267 {
268  mTracker = tracker;
269 }
270 
271 void IgstkTool::toolTransformCallback(const itk::EventObject &event)
272 {
273  if (igstk::CoordinateSystemTransformToEvent().CheckEvent(&event))
274  {
275  const igstk::CoordinateSystemTransformToEvent *transformEvent;
276  transformEvent = dynamic_cast<const igstk::CoordinateSystemTransformToEvent*>(&event);
277  if (!transformEvent)
278  return;
279 
280  igstk::CoordinateSystemTransformToResult result = transformEvent->Get();
281  igstk::Transform transform = result.GetTransform();
282  if (transform.IsIdentity())
283  return;
284  if (!transform.IsValidNow())
285  {
286  //What to do? this happens alot, dunno why. Ignore? Seems to work ok.
287  //CA20100901: Probable cause: we work on the main (render) thread. This causes several hundred ms lag. Move IGSTK+Toolmanager internals to separate thread.
288  //TODO need to find out why this happens, we get duplicate transforms, it seems, this is not good
289  //return;
290  }
291  if (!mVisible)
292  return; // quickfix replacement for IsValidNow()
293 
294  const igstk::CoordinateSystem* destination = result.GetDestination();
295  IgstkToolPtr strongReference = mReferenceTool.lock();
296 
297  if (strongReference) //if we are tracking with a reftool it must be visible
298  {
299  if (!strongReference->getPointer()->IsCoordinateSystem(destination))
300  return;
301  }
302  else //if we dont have a reftool we use the tracker as patientref
303  {
304  TrackerPtr tracker = mTracker.lock();
305  if (!tracker || !tracker->getPointer()->IsCoordinateSystem(destination))
306  return;
307  }
308 
309  vtkMatrix4x4Ptr vtkMatrix = vtkMatrix4x4Ptr::New();
310  transform.ExportTransform(*vtkMatrix.GetPointer());
311 
312  const Transform3D prMt(vtkMatrix.GetPointer()); //prMt, transform from tool to patientref
313  double timestamp = transform.GetStartTime();
314 
315  emit toolTransformAndTimestamp(prMt, timestamp);
316  }
317  //Successes
318  else if (igstk::TrackerToolConfigurationEvent().CheckEvent(&event))
319  {
320  //this->internalConfigured(true);
321  report(QString("Configured [%1] with the tracking system").arg(mInternalStructure.mUid));
322  }
323  else if (igstk::TrackerToolAttachmentToTrackerEvent().CheckEvent(&event))
324  {
325  this->internalAttachedToTracker(true);
326  }
327  else if (igstk::TrackerToolDetachmentFromTrackerEvent().CheckEvent(&event))
328  {
329  this->internalAttachedToTracker(false);
330  }
331  else if (igstk::TrackerToolMadeTransitionToTrackedStateEvent().CheckEvent(&event))
332  {
333  this->internalVisible(true);
334  //report(mInternalStructure.mUid+" is visible."); //SPAM
335  }
336  else if (igstk::TrackerToolNotAvailableToBeTrackedEvent().CheckEvent(&event))
337  {
338  this->internalVisible(false);
339  //report(mInternalStructure.mUid+" is hidden."); //SPAM
340  }
341  else if (igstk::ToolTrackingStartedEvent().CheckEvent(&event))
342  {
343  this->internalTracked(true);
344  report(mInternalStructure.mUid + " is tracked.");
345  }
346  else if (igstk::ToolTrackingStoppedEvent().CheckEvent(&event))
347  {
348  this->internalTracked(false);
349  report(mInternalStructure.mUid + " is not tracked anymore.");
350  }
351  //Failures
352  else if (igstk::InvalidRequestErrorEvent().CheckEvent(&event))
353  {
355  mInternalStructure.mUid
356  + " received an invalid request. This means that the internal igstk trackertool did not accept the request. Do not know which request.");
357  }
358  else if (igstk::TrackerToolConfigurationErrorEvent().CheckEvent(&event))
359  {
360  reportError(mInternalStructure.mUid + " could not configure with the tracking system.");
361  }
362  else if (igstk::InvalidRequestToAttachTrackerToolErrorEvent().CheckEvent(&event))
363  {
364  reportError(mInternalStructure.mUid + " could not request to attach to tracker.");
365  }
366  else if (igstk::InvalidRequestToDetachTrackerToolErrorEvent().CheckEvent(&event))
367  {
368  reportError(mInternalStructure.mUid + " could not request to detach from tracker.");
369  }
370  else if (igstk::TrackerToolAttachmentToTrackerErrorEvent().CheckEvent(&event))
371  {
372  reportError(mInternalStructure.mUid + " could not attach to tracker.");
373  }
374  else if (igstk::TrackerToolDetachmentFromTrackerErrorEvent().CheckEvent(&event))
375  {
376  reportError(mInternalStructure.mUid + " could not detach from tracker.");
377  }
378  //Polaris specific failures
379  else if (igstk::InvalidPolarisPortNumberErrorEvent().CheckEvent(&event))
380  {
381  reportError(
382  mInternalStructure.mUid + " sendt invalid Polaris port number: "
383  + qstring_cast(mInternalStructure.mPortNumber) + ".");
384  }
385  else if (igstk::InvalidPolarisSROMFilenameErrorEvent().CheckEvent(&event))
386  {
387  reportError(
388  mInternalStructure.mUid + " sendt invalid ROM file: " + mInternalStructure.mSROMFilename);
389  }
390  else if (igstk::InvalidPolarisPartNumberErrorEvent().CheckEvent(&event))
391  {
392  reportError(mInternalStructure.mUid + " has an invalid part number.");
393  }
394  //Aurora specific failures
395  else if (igstk::InvalidAuroraPortNumberErrorEvent().CheckEvent(&event))
396  {
397  reportError(
398  mInternalStructure.mUid + " has an invalid port number: "
399  + qstring_cast(mInternalStructure.mPortNumber) + ".");
400  }
401  else if (igstk::InvalidAuroraSROMFilenameErrorEvent().CheckEvent(&event))
402  {
403  reportError(
404  mInternalStructure.mUid + " sendt invalid ROM file: " + mInternalStructure.mSROMFilename);
405  }
406  else if (igstk::InvalidAuroraPartNumberErrorEvent().CheckEvent(&event))
407  {
408  reportError(mInternalStructure.mUid + " has an invalid part number.");
409  }
410  else if (igstk::InvalidAuroraChannelNumberErrorEvent().CheckEvent(&event))
411  {
412  reportError(
413  mInternalStructure.mUid + " has an invalid channel number:"
414  + qstring_cast(mInternalStructure.mChannelNumber) + ".");
415  }
416 }
417 
418 igstk::TrackerTool::Pointer IgstkTool::buildInternalTool()
419 {
420  igstk::TrackerTool::Pointer tool;
421 
422  igstk::PolarisTrackerTool::Pointer tempPolarisTool;
423  igstk::AuroraTrackerTool::Pointer tempAuroraTool;
424 
425  switch (mInternalStructure.mTrackerType)
426  {
427  case tsNONE:
428  break;
429  case tsPOLARIS_SPECTRA:
430  case tsPOLARIS_VICRA:
431  case tsPOLARIS:
432  tempPolarisTool = igstk::PolarisTrackerTool::New();
433  tempPolarisTool->AddObserver(igstk::IGSTKEvent(), mToolObserver);
434  if (!mInternalStructure.mWireless) //we only support wireless atm
435  return tool = tempPolarisTool.GetPointer();
436  tempPolarisTool->RequestSelectWirelessTrackerTool();
437  tempPolarisTool->RequestSetSROMFileName(string_cast(mInternalStructure.mSROMFilename));
438  tempPolarisTool->RequestConfigure();
439  tempPolarisTool->SetCalibrationTransform(mInternalStructure.mCalibration);
440  tool = tempPolarisTool;
441  break;
442  case tsAURORA:
443  tempAuroraTool = igstk::AuroraTrackerTool::New();
444  tempAuroraTool->AddObserver(igstk::IGSTKEvent(), mToolObserver);
445  if (mInternalStructure.m5DOF)
446  {
447  tempAuroraTool->RequestSelect5DOFTrackerTool();
448  tempAuroraTool->RequestSetPortNumber(mInternalStructure.mPortNumber);
449  tempAuroraTool->RequestSetChannelNumber(mInternalStructure.mChannelNumber);
450  }
451  else
452  {
453  tempAuroraTool->RequestSelect6DOFTrackerTool();
454  tempAuroraTool->RequestSetPortNumber(mInternalStructure.mPortNumber);
455  }
456  tempAuroraTool->RequestConfigure();
457  tempAuroraTool->SetCalibrationTransform(mInternalStructure.mCalibration);
458  tool = tempAuroraTool;
459  break;
460  case tsMICRON:
461  //TODO: implement
462  break;
463  default:
464  break;
465  }
466  return tool;
467 }
468 
469 void IgstkTool::setCalibrationTransform(igstk::Transform calibration)
470 {
471  mInternalStructure.mCalibration = calibration;
472  mTool->SetCalibrationTransform(calibration);
473 }
474 
475 void IgstkTool::internalAttachedToTracker(bool value)
476 {
477  if (mAttachedToTracker == value)
478  return;
479  mAttachedToTracker = value;
480  report(
481  mInternalStructure.mUid + " is " + (value ? "at" : "de") + "tached " + (value ? "to" : "from")
482  + " the tracker.");
483  emit attachedToTracker(mAttachedToTracker);
484 }
485 
486 void IgstkTool::internalTracked(bool value)
487 {
488  if (mTracked == value)
489  return;
490  mTracked = value;
491 
492  if (!mTracked && mVisible)
493  this->internalVisible(false); //Make sure tool is invisible when not tracked
494 
495  emit tracked(mTracked);
496 }
497 
498 void IgstkTool::internalVisible(bool value)
499 {
500  if (mVisible == value)
501  return;
502  mVisible = value;
503  emit toolVisible(mVisible);
504 }
505 
506 void IgstkTool::addLogging()
507 {
508  bool logging = settings()->value("IGSTKDebugLogging", true).toBool();
509  if (logging)
510  {
511  std::ofstream* loggerFile = new std::ofstream();
512  QString logFile = mInternalStructure.mLoggingFolderName + "Tool_" + mInternalStructure.mName + "_Logging.txt";
513  loggerFile->open(cstring_cast(logFile));
514  mLogger = igstk::Logger::New();
515  mLogOutput = itk::StdStreamLogOutput::New();
516  mLogOutput->SetStream(*loggerFile);
517  mLogger->AddLogOutput(mLogOutput);
518  mLogger->SetPriorityLevel(itk::Logger::DEBUG);
519 
520  mTool->SetLogger(mLogger);
521  }
522 }
523 
525 {
526  std::cout << "------------------------------------------------------------------" << std::endl;
527  std::cout << "mIsProbe: " << mInternalStructure.mIsProbe << std::endl;
528  std::cout << "mIsReference: " << mInternalStructure.mIsReference << std::endl;
529  std::cout << "mIsPointer: " << mInternalStructure.mIsPointer << std::endl;
530  std::cout << "mName: " << mInternalStructure.mName << std::endl;
531  std::cout << "mUid: " << mInternalStructure.mUid << std::endl;
532  std::cout << "mTrackerType: " << mInternalStructure.mTrackerType << std::endl;
533  std::cout << "mSROMFilename: " << mInternalStructure.mSROMFilename << std::endl;
534  std::cout << "mPortNumber: " << mInternalStructure.mPortNumber << std::endl;
535  std::cout << "mChannelNumber: " << mInternalStructure.mChannelNumber << std::endl;
536  std::cout << "mReferencePoints: " << string_cast(mInternalStructure.mReferencePoints.size()) << std::endl;
537  std::cout << "mWireless: " << mInternalStructure.mWireless << std::endl;
538  std::cout << "m5DOF: " << mInternalStructure.m5DOF << std::endl;
539  std::cout << "mCalibration: " << std::endl;
540  mInternalStructure.mCalibration.Print(std::cout, itk::Indent());
541  std::cout << "mCalibrationFilename: " << mInternalStructure.mCalibrationFilename << std::endl;
542  std::cout << "mGraphicsFileName: " << mInternalStructure.mGraphicsFileName << std::endl;
543  std::cout << "mTransformSaveFileName: " << mInternalStructure.mTransformSaveFileName << std::endl;
544  std::cout << "mLoggingFolderName: " << mInternalStructure.mLoggingFolderName << std::endl;
545  std::cout << "------------------------------------------------------------------" << std::endl;
546 }
547 
548 } //namespace cx
QString qstring_cast(const T &val)
vtkSmartPointer< class vtkMatrix4x4 > vtkMatrix4x4Ptr
Definition: cxMathBase.h:58
boost::shared_ptr< IgstkTracker > TrackerPtr
TRACKING_SYSTEM getTrackerType()
DoubleBoundingBox3D transform(const Transform3D &m, const DoubleBoundingBox3D &bb)
void reportError(QString msg)
Definition: cxLogger.cpp:92
File format for storing a 4x4 matrix.The read/write methods emit error messages if you dont use the o...
void setCalibrationTransform(igstk::Transform calibration)
QString getUid()
tsNONE
Not specified.
QString mUid
the tools unique id
Definition: cxIgstkTool.h:92
tsPOLARIS
NDIs Polaris tracker.
IgstkTool(InternalStructure internalStructure)
boost::shared_ptr< IgstkTool > IgstkToolPtr
Definition: cxIgstkTool.h:60
void attachedToTracker(bool)
Transform3D Transform3D
Transform3D is a representation of an affine 3D transform.
QString mTransformSaveFileName
path to where transforms should be saved
Definition: cxIgstkTool.h:105
QString mSROMFilename
path to the tools SROM file
Definition: cxIgstkTool.h:95
bool isVisible() const
Thread safe, volatile.
virtual ~IgstkTool()
unsigned int mChannelNumber
the channel the tool is connected to
Definition: cxIgstkTool.h:97
QString mLoggingFolderName
path to where log should be saved
Definition: cxIgstkTool.h:106
cstring_cast_Placeholder cstring_cast(const T &val)
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Definition: cxSettings.cpp:87
void write(const Transform3D &transform)
void toolTransformAndTimestamp(Transform3D matrix, double timestamp)
void toolVisible(bool)
std::string string_cast(const T &val)
QString mName
the tools name
Definition: cxIgstkTool.h:91
bool m5DOF
whether or not the tool have 5 DOF
Definition: cxIgstkTool.h:100
tsPOLARIS_SPECTRA
NDIs Polaris Spectra tracker.
void printInternalStructure()
std::map< int, Vector3D > mReferencePoints
optional point on the frame, specifying a known reference point, 0,0,0 is default, in sensor space
Definition: cxIgstkTool.h:98
igstk::Transform mCalibration
transform read from mCalibrationFilename
Definition: cxIgstkTool.h:101
void setReference(IgstkToolPtr)
void reportWarning(QString msg)
Definition: cxLogger.cpp:91
Transform3D getCalibrationAsSSC() const
Definition: cxIgstkTool.cpp:47
bool isValid() const
Thread safe, volatile.
igstk::TrackerTool::Pointer getPointer() const
return a pointer to the internal tools base object
QString mGraphicsFileName
path to this tools graphics file
Definition: cxIgstkTool.h:103
Class for controlling the igstk tracking (hardware) interface.
Definition: cxIgstkTool.h:72
TRACKING_SYSTEM mTrackerType
what product the tool belongs to
Definition: cxIgstkTool.h:94
A tools internal structure.
Definition: cxIgstkTool.h:80
Settings * settings()
Shortcut for accessing the settings instance.
Definition: cxSettings.cpp:42
bool isInitialized() const
Thread safe, volatile.
unsigned int mPortNumber
the port number the tool is connected to
Definition: cxIgstkTool.h:96
void setCalibration(const Transform3D &cal)
Definition: cxIgstkTool.cpp:55
void updateCalibration(const Transform3D &sMt)
tsAURORA
NDIs Aurora tracker.
void report(QString msg)
Definition: cxLogger.cpp:90
bool mWireless
whether or not the tool is wireless
Definition: cxIgstkTool.h:99
void tracked(bool)
void setTracker(TrackerPtr tracker)
tsMICRON
Claron Technologys Micron tracker.
bool isTracked() const
Thread safe, volatile.
InternalStructure getInternalStructure()
QString mCalibrationFilename
path to the tools calibration file
Definition: cxIgstkTool.h:102
tsPOLARIS_VICRA
NDIs Polaris Vicra tracker.