NorMIT-nav  2023.01.05-dev+develop.0da12
An IGT application
cxIgstkTracker.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) SINTEF Department of Medical Technology.
5 All rights reserved.
6 
7 CustusX is released under a BSD 3-Clause license.
8 
9 See Lisence.txt (https://github.com/SINTEFMedtek/CustusX/blob/master/License.txt) for details.
10 =========================================================================*/
11 
12 #include "cxIgstkTracker.h"
13 
14 #include <QStringList>
15 #include "cxLogger.h"
16 #include "cxTypeConversions.h"
17 #include "cxToolUsingIGSTK.h"
18 #include "cxIgstkTool.h"
19 #include <time.h>
20 #include "cxSettings.h"
21 
22 namespace cx
23 {
24 
26  mInternalStructure(internalStructure),
27  mValid(false),
28  mUid(""),
29  mName(""),
30  mTracker(NULL),
31  mCommunication(CommunicationType::New()),
32  mTrackerObserver(ObserverType::New()),
33  mOpen(false),
34  mInitialized(false),
35  mTracking(false)
36 {
37  mCommunication->SetPortNumber(igstk::SerialCommunication::PortNumber0);
38  mCommunication->SetParity(igstk::SerialCommunication::NoParity);
39  mCommunication->SetBaudRate(igstk::SerialCommunication::BaudRate115200);
40  mCommunication->SetDataBits(igstk::SerialCommunication::DataBits8);
41  mCommunication->SetStopBits(igstk::SerialCommunication::StopBits1);
42  mCommunication->SetHardwareHandshake(igstk::SerialCommunication::HandshakeOff);
43 
44  bool logging = settings()->value("IGSTKDebugLogging", true).toBool();
45  if (logging)
46  {
47  QString comLogging = mInternalStructure.mLoggingFolderName + "RecordedStreamByCustusX.txt";
48  mCommunication->SetCaptureFileName(cstring_cast(comLogging));
49  mCommunication->SetCapture(true);
50  }
51 
52  switch (mInternalStructure.mType)
53  {
54  case tsNONE:
55  mUid = mName = "None";
56  reportError("Tracker is of type TRACKER_NONE, this means it's not valid.");
57  mValid = false;
58  return;
59  break;
60  case tsPOLARIS:
61  mUid = mName = "Polaris";
62  mTempPolarisTracker = PolarisTrackerType::New();
63  mTempPolarisTracker->SetCommunication(mCommunication);
64  report("Tracker is set to Polaris");
65  mTracker = mTempPolarisTracker.GetPointer();
66  mValid = true;
67  break;
68  case tsPOLARIS_CLASSIC:
69  mUid = mName = "None";
70  report("Polaris Classic is not supported");
71  mValid = false;
72  break;
73  //There is no special handling of the tracking system if its spectra or vicra, polaris is polaris as we see it
74  case tsAURORA:
75  mUid = mName = "Aurora";
76  mTempAuroraTracker = AuroraTrackerType::New();
77  mTempAuroraTracker->SetCommunication(mCommunication);
78  report("Tracker is set to Aurora");
79  mTracker = mTempAuroraTracker.GetPointer();
80  mValid = true;
81  break;
82  case tsMICRON:
83  mUid = mName = "Micron";
84  report("Tracker is set to Micron, not supported");
85  //TODO: implement support for a micron tracker...
86  mValid = false;
87  break;
88  default:
89  break;
90  }
91  mTrackerObserver->SetCallbackFunction(this, &IgstkTracker::trackerTransformCallback);
92  mTracker->AddObserver(igstk::IGSTKEvent(), mTrackerObserver);
93  mCommunication->AddObserver(igstk::IGSTKEvent(), mTrackerObserver);
94  this->addLogging();
95 }
96 
98 {
99 }
100 
101 TRACKING_SYSTEM IgstkTracker::getType() const
102 {
103  return mInternalStructure.mType;
104 }
105 
106 QString IgstkTracker::getName() const
107 {
108  return mName;
109 }
110 
111 QString IgstkTracker::getUid() const
112 {
113  return mUid;
114 }
115 
117 {
118  return mTracker;
119 }
120 
122 {
123 // igstk::SerialCommunication::ResultType result = igstk::SerialCommunication::FAILURE;
124 // for(int i=0; i<5; ++i)
125 // {
126 // result = mCommunication->OpenCommunication();
127 // if(result == igstk::SerialCommunication::SUCCESS)
128 // break;
129 // else
130 // reportWarning("Could not open communication.");
131 // }
132  if (mCommunication->OpenCommunication() == false)
133  reportWarning("Could not open communication.");
134  mTracker->RequestOpen();
135 }
136 
138 {
139  mTracker->RequestClose();
140  if (mCommunication->CloseCommunication() == false)
141  reportWarning("Could not close communication.");
142 }
143 
144 void IgstkTracker::attachTools(std::map<QString, IgstkToolPtr> tools)
145 {
146  if (!this->isInitialized())
147  return;
148 
149  for (std::map<QString, IgstkToolPtr>::iterator it = tools.begin(); it != tools.end(); ++it)
150  {
151  IgstkToolPtr tool = it->second;
152 
153  if (tool && tool->getPointer())
154  {
155  if (tool->getTrackerType() != mInternalStructure.mType)
157  "Tracker is attaching a tool that is not of the correct type. Trackers type: "
158  + qstring_cast(mInternalStructure.mType) + ", tools tracker type: "
159  + qstring_cast(tool->getTrackerType()));
160 
161  tool->getPointer()->RequestAttachToTracker(mTracker);
162 
163  if (tool->isReference())
164  mTracker->RequestSetReferenceTool(tool->getPointer());
165 // if(tool->getType() == Tool::TOOL_REFERENCE)
166 // mTracker->RequestSetReferenceTool(tool->getPointer());
167  }
168  }
169 }
170 
171 void IgstkTracker::detachTools(std::map<QString, IgstkToolPtr> tools)
172 {
173  if (!this->isInitialized())
174  return;
175 
176  for (std::map<QString, IgstkToolPtr>::iterator it = tools.begin(); it != tools.end(); ++it)
177  {
178  IgstkToolPtr tool = it->second;
179 
180  if (tool && tool->getPointer())
181  {
182  tool->getPointer()->RequestDetachFromTracker();
183  }
184  }
185 }
186 
188 {
189  mTracker->RequestStartTracking();
190 }
191 
193 {
194  mTracker->RequestStopTracking();
195 }
196 
198 {
199  return mValid;
200 }
201 
203 {
204  return mOpen;
205 }
206 
208 {
209  return mInitialized;
210 }
211 
213 {
214  return mTracking;
215 }
216 
217 void IgstkTracker::trackerTransformCallback(const itk::EventObject &event)
218 {
219  //successes
220  if (igstk::TrackerOpenEvent().CheckEvent(&event))
221  {
222  this->internalOpen(true);
223  this->internalInitialized(true);
224  }
225  else if (igstk::TrackerCloseEvent().CheckEvent(&event))
226  {
227  this->internalOpen(false);
228  this->internalInitialized(false);
229  }
230  else if (igstk::TrackerInitializeEvent().CheckEvent(&event))
231  {
232  //Never happens???
233  //this->internalInitialized(true);
234  //report(mUid+" is initialized.");
235  reportWarning("This never happens for some reason... check code");
236  }
237  else if (igstk::TrackerStartTrackingEvent().CheckEvent(&event))
238  {
239  this->internalTracking(true);
240  }
241  else if (igstk::TrackerStopTrackingEvent().CheckEvent(&event))
242  {
243  this->internalTracking(false);
244  }
245  else if (igstk::TrackerUpdateStatusEvent().CheckEvent(&event))
246  {
247  //reportDebug(mUid+" is updated."); //SPAM!
248  }
249  else if (igstk::TrackerToolTransformUpdateEvent().CheckEvent(&event))
250  {
251  //reportDebug(mUid+" has updated a transform."); //SPAM
252  }
253  //communication success
254  else if (igstk::CompletedEvent().CheckEvent(&event))
255  {
256  // this seems to appear after every transmit (several times/second)
257  //report(mUid+" set up communication correctly."); //SPAM
258  }
259  //coordinate system success
260  else if (igstk::CoordinateSystemSetTransformEvent().CheckEvent(&event))
261  {
262  //report();
263  }
264  //failures
265  else if (igstk::InvalidRequestErrorEvent().CheckEvent(&event))
266  {
267  reportWarning(mUid + " received an invalid request. This means that the internal igstk tracker did not accept the request. Do not know which request.");
268  this->shutdown();
269  }
270  else if (igstk::TrackerOpenErrorEvent().CheckEvent(&event))
271  {
272  reportError(mUid + " could not open.");
273  //this->shutdown();
274  }
275  else if (igstk::TrackerCloseErrorEvent().CheckEvent(&event))
276  {
277  reportError(mUid + " could not close.");
278  //this->shutdown();
279  }
280  else if (igstk::TrackerInitializeErrorEvent().CheckEvent(&event))
281  {
282  reportError(mUid + " could not initialize.");
283  //this->shutdown();
284  }
285  else if (igstk::TrackerStartTrackingErrorEvent().CheckEvent(&event))
286  {
287  reportError(mUid + " could not start tracking.");
288  //this->shutdown();
289  }
290  else if (igstk::TrackerStopTrackingErrorEvent().CheckEvent(&event))
291  {
292  reportError(mUid + " could not stop tracking.");
293  //this->shutdown();
294  }
295  else if (igstk::TrackerUpdateStatusErrorEvent().CheckEvent(&event))
296  {
297  reportError(mUid + " could not update.");
298  //this->shutdown();
299  }
300  //communication failure
301  else if (igstk::InputOutputErrorEvent().CheckEvent(&event))
302  {
303  //this happens when you pull out the cable while tracking
304  reportError(mUid + " cannot communicate with input/output.");
305  this->shutdown();
306  }
307  else if (igstk::InputOutputTimeoutEvent().CheckEvent(&event))
308  {
309  reportError(mUid + " input/output communication timed out.");
310  //this->shutdown();
311  }
312  else if (igstk::OpenPortErrorEvent().CheckEvent(&event))
313  {
314  reportError(mUid + " could not open communication with tracker.");
315  this->shutdown();
316  }
317  else if (igstk::ClosePortErrorEvent().CheckEvent(&event))
318  {
319  reportError(mUid + " could not close communication with tracker.");
320  this->shutdown();
321  }
322  else
323  {
324  event.Print(std::cout);
325  }
326 }
327 
329 {
330  bool logging = settings()->value("IGSTKDebugLogging", true).toBool();
331  if (logging)
332  {
333  std::ofstream* loggerFile = new std::ofstream();
334  QString logFile = mInternalStructure.mLoggingFolderName + "Tracker_Logging.txt";
335  loggerFile->open(cstring_cast(logFile));
336  mTrackerLogger = igstk::Logger::New();
337  mTrackerLogOutput = itk::StdStreamLogOutput::New();
338  mTrackerLogOutput->SetStream(*loggerFile);
339  mTrackerLogger->AddLogOutput(mTrackerLogOutput);
340  mTrackerLogger->SetPriorityLevel(itk::Logger::DEBUG);
341 
342  mTracker->SetLogger(mTrackerLogger);
343  mCommunication->SetLogger(mTrackerLogger);
344  }
345 }
346 
348 {
349  if (mOpen == value)
350  return;
351  mOpen = value;
352 
353  report(mUid + " is " + (value ? "open" : "closed") + ".");
354  emit open(mOpen);
355 }
356 
358 {
359  if (mInitialized == value)
360  return;
361  mInitialized = value;
362 
363  report(mUid + " is " + (value ? "" : "un") + "initialized.");
365 }
366 
368 {
369  if (mTracking == value)
370  return;
371  mTracking = value;
372 
373  report(mUid + " is " + (value ? "" : "not ") + "tracking.");
374  emit tracking(mTracking);
375 }
376 
378 {
379  reportWarning(mUid + " experienced a unrecoverable error, reconfiguration is required.");
380  emit error();
381 }
382 
384 {
385  mCommunication->CloseCommunication();
386 
387  //because the tracker now is closed we don't get the callback events so we need to reset the trackers internal
388  //status manually
389  this->internalTracking(false);
390  this->internalInitialized(false);
391  this->internalOpen(false);
392  this->internalError(true);
393 }
394 
395 } //namespace cx
cx::IgstkTracker::mValid
bool mValid
whether this tracker is constructed correctly or not
Definition: cxIgstkTracker.h:137
cx::IgstkTracker::close
void close()
close the
Definition: cxIgstkTracker.cpp:137
cx::IgstkTracker::startTracking
void startTracking()
start tracking
Definition: cxIgstkTracker.cpp:187
cxLogger.h
qstring_cast
QString qstring_cast(const T &val)
Definition: cxTypeConversions.h:46
cx::IgstkTracker::internalOpen
void internalOpen(bool value)
Definition: cxIgstkTracker.cpp:347
cx::Settings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Definition: cxSettings.cpp:66
cx
Namespace for all CustusX production code.
Definition: cx_dev_group_definitions.h:13
cx::IgstkToolPtr
boost::shared_ptr< class IgstkTool > IgstkToolPtr
Definition: cxOpenIGTLinkTool.h:35
cx::ToolFileParser::TrackerInternalStructure::mType
TRACKING_SYSTEM mType
the trackers type
Definition: cxToolFileParser.h:39
cx::IgstkTracker::mCommunication
CommunicationType::Pointer mCommunication
pointer to the serial communication used to communicate with the NDI trackers
Definition: cxIgstkTracker.h:145
cx::report
void report(QString msg)
Definition: cxLogger.cpp:69
cxToolUsingIGSTK.h
cstring_cast
cstring_cast_Placeholder cstring_cast(const T &val)
Definition: cxTypeConversions.h:69
tsPOLARIS
tsPOLARIS
NDIs Polaris tracker.
Definition: cxDefinitions.h:113
cx::IgstkTracker::isTracking
bool isTracking() const
Definition: cxIgstkTracker.cpp:212
cx::IgstkTracker::stopTracking
void stopTracking()
stop tracking
Definition: cxIgstkTracker.cpp:192
cx::IgstkTracker::isOpen
bool isOpen() const
Definition: cxIgstkTracker.cpp:202
cx::IgstkTracker::trackerTransformCallback
void trackerTransformCallback(const itk::EventObject &eventVar)
callback receiving events from the observer
Definition: cxIgstkTracker.cpp:217
cxIgstkTool.h
cx::IgstkTracker::mTempPolarisTracker
PolarisTrackerType::Pointer mTempPolarisTracker
pointer to a temp polaris tracker
Definition: cxIgstkTracker.h:142
cx::IgstkTracker::shutdown
void shutdown()
shuts down the tracker, made to be used when an unrecoverable error occures
Definition: cxIgstkTracker.cpp:383
cx::IgstkTracker::ObserverType
itk::ReceptorMemberCommand< IgstkTracker > ObserverType
Definition: cxIgstkTracker.h:124
tsPOLARIS_CLASSIC
tsPOLARIS_CLASSIC
NDIs Polaris Classic tracker.
Definition: cxDefinitions.h:116
cx::IgstkTracker::mTrackerLogOutput
itk::StdStreamLogOutput::Pointer mTrackerLogOutput
output to write the log to
Definition: cxIgstkTracker.h:148
cx::IgstkTracker::internalTracking
void internalTracking(bool value)
Definition: cxIgstkTracker.cpp:367
cx::IgstkTracker::error
void error()
tsMICRON
tsMICRON
Claron Technologys Micron tracker.
Definition: cxDefinitions.h:118
cx::IgstkTracker::getType
TRACKING_SYSTEM getType() const
returns the trackers type
Definition: cxIgstkTracker.cpp:101
cx::IgstkTracker::isInitialized
bool isInitialized() const
Definition: cxIgstkTracker.cpp:207
cxIgstkTracker.h
cx::IgstkTracker::mName
QString mName
the trackers name
Definition: cxIgstkTracker.h:139
cxTypeConversions.h
cx::IgstkTracker::mInitialized
bool mInitialized
whether or not the tracker is initialized
Definition: cxIgstkTracker.h:151
cx::IgstkTracker::mTracker
TrackerType * mTracker
pointer to the base class of the internal igstk tracker
Definition: cxIgstkTracker.h:140
cxSettings.h
cx::IgstkTracker::mUid
QString mUid
the trackers unique id
Definition: cxIgstkTracker.h:138
cx::IgstkTracker::tracking
void tracking(bool)
cx::IgstkTracker::getName
QString getName() const
get the trackers name
Definition: cxIgstkTracker.cpp:106
cx::ToolFileParser::TrackerInternalStructure
Definition: cxToolFileParser.h:37
cx::IgstkTracker::mInternalStructure
ToolFileParser::TrackerInternalStructure mInternalStructure
the trackers type
Definition: cxIgstkTracker.h:136
cx::IgstkTracker::open
void open()
open the tracker for communication
Definition: cxIgstkTracker.cpp:121
cx::IgstkTracker::internalInitialized
void internalInitialized(bool value)
Definition: cxIgstkTracker.cpp:357
cx::IgstkTracker::getPointer
TrackerType * getPointer() const
return a pointer to the internal tracker base
Definition: cxIgstkTracker.cpp:116
cx::IgstkTracker::CommunicationType
igstk::SerialCommunicationForPosix CommunicationType
Definition: cxIgstkTracker.h:66
cx::IgstkTracker::TrackerType
igstk::Tracker TrackerType
Definition: cxIgstkTracker.h:68
cx::IgstkTracker::mTrackerObserver
ObserverType::Pointer mTrackerObserver
observer listening for igstk events
Definition: cxIgstkTracker.h:146
cx::IgstkTracker::IgstkTracker
IgstkTracker(ToolFileParser::TrackerInternalStructure internalStructure)
Definition: cxIgstkTracker.cpp:25
cx::IgstkTracker::mTempAuroraTracker
AuroraTrackerType::Pointer mTempAuroraTracker
pointer to a temp aurora tracker
Definition: cxIgstkTracker.h:143
tsAURORA
tsAURORA
NDIs Aurora tracker.
Definition: cxDefinitions.h:117
cx::IgstkTracker::addLogging
void addLogging()
adds logging to the internal igstk components
Definition: cxIgstkTracker.cpp:328
cx::IgstkTracker::mOpen
bool mOpen
whether or not the tracker is open
Definition: cxIgstkTracker.h:150
cx::IgstkTracker::~IgstkTracker
~IgstkTracker()
Definition: cxIgstkTracker.cpp:97
cx::IgstkTracker::mTrackerLogger
igstk::Logger::Pointer mTrackerLogger
logging the internal igstk behavior
Definition: cxIgstkTracker.h:147
cx::reportError
void reportError(QString msg)
Definition: cxLogger.cpp:71
cx::IgstkTracker::isValid
bool isValid() const
whether this tracker is constructed correctly or not
Definition: cxIgstkTracker.cpp:197
cx::IgstkTracker::getUid
QString getUid() const
get the tracker unique id
Definition: cxIgstkTracker.cpp:111
tsNONE
tsNONE
Not specified.
Definition: cxDefinitions.h:112
cx::IgstkTracker::internalError
void internalError(bool value)
Definition: cxIgstkTracker.cpp:377
cx::IgstkTracker::initialized
void initialized(bool)
cx::IgstkTracker::attachTools
void attachTools(std::map< QString, IgstkToolPtr > tools)
attach a list of tools to the tracker hw
Definition: cxIgstkTracker.cpp:144
cx::IgstkTracker::detachTools
void detachTools(std::map< QString, IgstkToolPtr > tools)
detach the list of tools from the tracker hw
Definition: cxIgstkTracker.cpp:171
cx::reportWarning
void reportWarning(QString msg)
Definition: cxLogger.cpp:70
cx::settings
Settings * settings()
Shortcut for accessing the settings instance.
Definition: cxSettings.cpp:21
cx::ToolFileParser::TrackerInternalStructure::mLoggingFolderName
QString mLoggingFolderName
path to where log should be saved
Definition: cxToolFileParser.h:40
cx::IgstkTracker::mTracking
bool mTracking
whether or not the tracker is tracking
Definition: cxIgstkTracker.h:152