PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkPlusNDICertusTracker.cxx
Go to the documentation of this file.
1 /*=Plus=header=begin======================================================
2 Program: Plus
3 Copyright (c) Laboratory for Percutaneous Surgery. All rights reserved.
4 See License.txt for details.
5 =========================================================Plus=header=end*/
6 
7 #include "PlusConfigure.h"
8 #include <limits.h>
9 #include <float.h>
10 #include <math.h>
11 #include <ctype.h>
12 
13 // NDI header files require this on Windows
14 #if defined(_WIN32) && !defined(__WINDOWS_H)
15 #define __WINDOWS_H
16 #include "Windows.h"
17 #endif
18 
19 // requires NDIoapi/ndlib
20 #include "ndtypes.h"
21 #include "ndpack.h"
22 #include "ndopto.h"
23 
24 // uses ndicapi for quaternion conversion
25 #include "ndicapi_math.h"
26 
27 #include "vtkTimerLog.h"
28 #include "vtkMatrix4x4.h"
29 #include "vtkTransform.h"
31 #include "vtkPlusDataSource.h"
32 #include "vtkObjectFactory.h"
33 
35 
36 // turn this on to print lots of debug information
37 #define VTK_CERTUS_DEBUG_STATEMENTS 0
38 
39 //----------------------------------------------------------------------------
40 // map values 0, 1, 2 to the proper Certus VLED state constant
41 static VLEDState vtkNDICertusMapVLEDState[] = { VLEDST_OFF, VLEDST_ON, VLEDST_BLINK };
42 
43 //----------------------------------------------------------------------------
45 {
46  this->Version = NULL;
47  this->SendMatrix = vtkMatrix4x4::New();
48  this->NumberOfMarkers = 0;
49  this->NumberOfRigidBodies = 0;
50 
51  for (int i = 0; i < VTK_CERTUS_NTOOLS; i++)
52  {
53  this->PortHandle[i] = 0;
54  this->PortEnabled[i] = 0;
55  }
56 
58 
59  // No callback function provided by the device, so the data capture thread will be used to poll the hardware and add new items to the buffer
60  this->StartThreadForInternalUpdates = true;
61  this->AcquisitionRate = 50;
62 }
63 
64 //----------------------------------------------------------------------------
66 {
67  if (this->Recording)
68  {
69  this->StopRecording();
70  }
71  this->SendMatrix->Delete();
72  if (this->Version)
73  {
74  delete [] this->Version;
75  }
76 }
77 
78 //----------------------------------------------------------------------------
80 {
81  const int BUFSIZE = 200;
82  char version[BUFSIZE + 1];
83  version[BUFSIZE] = 0;
84  OAPIGetVersionString(version, BUFSIZE);
85  return std::string(version);
86 }
87 
88 //----------------------------------------------------------------------------
89 void vtkPlusNDICertusTracker::PrintSelf(ostream& os, vtkIndent indent)
90 {
91  Superclass::PrintSelf(os, indent);
92 
93  os << indent << "SendMatrix: " << this->SendMatrix << "\n";
94  this->SendMatrix->PrintSelf(os, indent.GetNextIndent());
95  os << indent << "NumberOfRigidBodies: " << this->NumberOfRigidBodies << "\n";
96  os << indent << "NumberOfMarkers: " << this->NumberOfMarkers << "\n";
97 }
98 
99 //----------------------------------------------------------------------------
100 static char vtkCertusErrorString[MAX_ERROR_STRING_LENGTH + 1];
101 
102 #define vtkPrintCertusErrorMacro() \
103 { \
104  if (OptotrakGetErrorString(vtkCertusErrorString, MAX_ERROR_STRING_LENGTH+1) == 0) \
105 { \
106  LOG_ERROR(vtkCertusErrorString); \
107 } \
108 }
109 
110 //----------------------------------------------------------------------------
112 {
113  // Set the NIF (Network Information File)
114  if (OptotrakSetProcessingFlags(OPTO_USE_INTERNAL_NIF) != OPTO_NO_ERROR_CODE)
115  {
116  LOG_ERROR("Call to OptotrakSetProcessingFlags() failed.");
118  return PLUS_FAIL;
119  }
120 
121  LOG_DEBUG("TransputerDetermineSystemCfg start...");
122  // Write to the internal NIF
123  if (TransputerDetermineSystemCfg(NULL) != OPTO_NO_ERROR_CODE)
124  {
125  LOG_ERROR("Call to TransputerDetermineSystemCfg() failed.");
127  return PLUS_FAIL;
128  }
129  LOG_DEBUG("TransputerDetermineSystemCfg completed");
130 
131  // Do the initial load.
132  if (TransputerLoadSystem("system") != OPTO_NO_ERROR_CODE)
133  {
134  LOG_ERROR("Call to Certus TransputerLoadSystem() failed");
136  return PLUS_FAIL;
137  }
138 
139  // Wait for 1 second, according to the Certus documentation
140  vtkIGSIOAccurateTimer::Delay(1);
141 
142  // Do the initialization
143  if (TransputerInitializeSystem(0) != OPTO_NO_ERROR_CODE)
144  {
145  // optionally, use "OPTO_LOG_ERRORS_FLAG" argument to above
146  LOG_ERROR("Call to Certus TransputerInitializeSystem() failed");
148  return PLUS_FAIL;
149  }
150 
151  // Load the standard camera parameters
152  if (OptotrakLoadCameraParameters("standard") != OPTO_NO_ERROR_CODE)
153  {
154  LOG_ERROR("Call to OptotrakLoadCameraParameters() failed");
156  return PLUS_FAIL;
157  }
158 
159  return PLUS_SUCCESS;
160 }
161 
162 //----------------------------------------------------------------------------
164 {
165  this->StopRecording();
166 
167  // Shut down the system
168  this->ShutdownCertusSystem();
169 
170  return PLUS_SUCCESS;
171 }
172 
173 //----------------------------------------------------------------------------
175 {
176  // Connect to device
177  if (this->Connect() != PLUS_SUCCESS)
178  {
179  return PLUS_FAIL;
180  }
181 
182  // Get the Optotrak status
183  int nNumSensors;
184  int nNumOdaus;
185  int nFlags;
186  if (OptotrakGetStatus(&nNumSensors, &nNumOdaus, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &nFlags) != OPTO_NO_ERROR_CODE)
187  {
188  LOG_ERROR("Call to OptotrakGetStatus() failed");
190  return PLUS_FAIL;
191  }
192 
193  // Make sure that the attached system is a Certus
194  if ((nFlags & (OPTOTRAK_3020_FLAG | OPTOTRAK_CERTUS_FLAG)) != OPTOTRAK_CERTUS_FLAG)
195  {
196  LOG_ERROR("Only Certus is supported. Attached device is not Certus.");
197  return PLUS_FAIL;
198  }
199 
200  // Check to make sure configuration is what we expect
201  if ((nNumSensors != 1 || nNumOdaus != 1))
202  {
203  LOG_DEBUG("Certus configuration: " << nNumSensors << " sensors, "
204  << nNumOdaus << " odaus");
205  //successFlag = 0;
206  }
207 
208  return PLUS_SUCCESS;
209 }
210 
211 //----------------------------------------------------------------------------
213 {
214  // Just a simple shutdown command
215  if (TransputerShutdownSystem() != OPTO_NO_ERROR_CODE)
216  {
218  return PLUS_FAIL;
219  }
220 
221  return PLUS_SUCCESS;
222 }
223 
224 //----------------------------------------------------------------------------
226 {
227  // count the number of markers on all tools first
228  if (OptotrakSetupCollection(
229  this->NumberOfMarkers, /* Number of markers in the collection. */
230  (float)100.0, /* Frequency to collect data frames at. */
231  (float)2500.0, /* Marker frequency for marker maximum on-time. */
232  30, /* Dynamic or Static Threshold value to use. */
233  160, /* Minimum gain code amplification to use. */
234  0, /* Stream mode for the data buffers. */
235  (float)0.35, /* Marker Duty Cycle to use. */
236  (float)7.0, /* Voltage to use when turning on markers. */
237  (float)1.0, /* Number of seconds of data to collect. */
238  (float)0.0, /* Number of seconds to pre-trigger data by. */
239  OPTOTRAK_BUFFER_RAW_FLAG) != OPTO_NO_ERROR_CODE)
240  {
241  return PLUS_FAIL;
242  }
243 
244  // Activate the markers
245  if (OptotrakActivateMarkers() != OPTO_NO_ERROR_CODE)
246  {
247  LOG_ERROR("Cannot activate the markers");
248  return PLUS_FAIL;
249  }
250 
251  return PLUS_SUCCESS;
252 }
253 
254 //----------------------------------------------------------------------------
256 {
257  if (OptotrakDeActivateMarkers() != OPTO_NO_ERROR_CODE)
258  {
259  LOG_ERROR("Cannot activate the markers");
260  return PLUS_FAIL;
261  }
262 
263  return PLUS_SUCCESS;
264 }
265 
266 //----------------------------------------------------------------------------
268 {
269  // If device is already tracking, return success.
270  if (this->Recording)
271  {
272  return PLUS_SUCCESS;
273  }
274 
275  // Perform initialization of the system
276  PlusStatus status = this->InitializeCertusSystem();
277 
278  // Shut down the system
279  this->ShutdownCertusSystem();
280 
281  return status;
282 }
283 
284 //----------------------------------------------------------------------------
286 {
287  if (this->Recording)
288  {
289  return PLUS_SUCCESS;
290  }
291 
292  // Attempt to initialize the Certus
293  // and enable all the tools
294  if (!this->InitializeCertusSystem()
295  || !this->EnableToolPorts())
296  {
298  this->ShutdownCertusSystem();
299  return PLUS_FAIL;
300  }
301 
302  // count the number of markers on all tools first
303  if (!this->ActivateCertusMarkers())
304  {
306  this->ShutdownCertusSystem();
307  return PLUS_FAIL;
308  }
309 
310  return PLUS_SUCCESS;
311 }
312 
313 //----------------------------------------------------------------------------
315 {
316  if (OptotrakDeActivateMarkers() != OPTO_NO_ERROR_CODE)
317  {
319  }
320 
321  if (!this->DisableToolPorts())
322  {
324  }
325 
326  return PLUS_SUCCESS;
327 }
328 
329 //----------------------------------------------------------------------------
331 {
332  int tool;
333  int missing[VTK_CERTUS_NTOOLS];
334  long statusFlags[VTK_CERTUS_NTOOLS];
335  double transform[VTK_CERTUS_NTOOLS][8];
336 
337  if (!this->Recording)
338  {
339  LOG_ERROR("called Update() when Certus was not tracking");
340  return PLUS_FAIL;
341  }
342 
343  // initialize transformations to identity
344  for (tool = 0; tool < VTK_CERTUS_NTOOLS; tool++)
345  {
346  missing[tool] = 1;
347 
348  transform[tool][0] = 1.0;
349  transform[tool][1] = transform[tool][2] = transform[tool][3] = 0.0;
350  transform[tool][4] = transform[tool][5] = transform[tool][6] = 0.0;
351  transform[tool][7] = 0.0;
352  }
353 
354  unsigned int uFrameNumber = 0;
355  unsigned int uElements = 0;
356  unsigned int uFlags = 0;
357  OptotrakRigidStruct* rigidBodyData;
358  rigidBodyData = new OptotrakRigidStruct[this->NumberOfRigidBodies];
359 
360  if (DataGetLatestTransforms2(&uFrameNumber, &uElements, &uFlags,
361  rigidBodyData, 0) != OPTO_NO_ERROR_CODE)
362  {
364  delete [] rigidBodyData;
365  return PLUS_FAIL;
366  }
367 
368  LOG_TRACE("Found " << uElements << " rigid bodies, expected " << this->NumberOfRigidBodies
369  << " with " << this->NumberOfMarkers << " markers");
370 
371  for (int rigidCounter = 0; rigidCounter < this->NumberOfRigidBodies;
372  rigidCounter++)
373  {
374  OptotrakRigidStruct& rigidBody = rigidBodyData[rigidCounter];
375  long rigidId = rigidBody.RigidId;
376 
377  std::map<int, int>::iterator rigidBodyMapIterator = this->RigidBodyMap.find(rigidId);
378  if (rigidBodyMapIterator != this->RigidBodyMap.end())
379  {
380  tool = rigidBodyMapIterator->second;
381  }
382  else
383  {
384  LOG_ERROR("InternalUpdate: bad rigid body ID " << rigidId);
385  continue;
386  }
387 
388  if ((rigidBody.flags & OPTOTRAK_UNDETERMINED_FLAG) == 0)
389  {
390  // this is done to keep the code similar to POLARIS
391  double* trans = transform[tool];
392  trans[0] = rigidBody.transformation.quaternion.rotation.q0;
393  trans[1] = rigidBody.transformation.quaternion.rotation.qx;
394  trans[2] = rigidBody.transformation.quaternion.rotation.qy;
395  trans[3] = rigidBody.transformation.quaternion.rotation.qz;
396  trans[4] = rigidBody.transformation.quaternion.translation.x;
397  trans[5] = rigidBody.transformation.quaternion.translation.y;
398  trans[6] = rigidBody.transformation.quaternion.translation.z;
399  trans[7] = rigidBody.QuaternionError;
400  LOG_TRACE("Rigid body " << rigidCounter << " (rigidId=" << rigidId << ") translation: " << trans[4] << ", " << trans[5] << ", " << trans[6]);
401  }
402  else
403  {
404  LOG_TRACE("Rigid body " << rigidCounter << " (rigidId=" << rigidId << ") undetermined");
405  }
406 
407  statusFlags[tool] = rigidBody.flags;
408  }
409 
410  delete [] rigidBodyData;
411 
412  const double unfilteredTimestamp = vtkIGSIOAccurateTimer::GetSystemTime();
413 
414  for (tool = 0; tool < VTK_CERTUS_NTOOLS; tool++)
415  {
416  if (this->PortEnabled[tool] == 0)
417  {
418  // The tools that are not connected and not in the configuration file were disabled when connecting
419  continue;
420  }
421 
422  // convert status flags from Optotrak format to vtkTracker format
423  ToolStatus status = TOOL_OK;
424  this->SetToolLED(tool, 0, TR_LED_ON);
425  if ((statusFlags[tool] & OPTOTRAK_UNDETERMINED_FLAG) != 0)
426  {
427  status = TOOL_MISSING;
428  this->SetToolLED(tool, 0, TR_LED_FLASH);
429  }
430 
431  ndiTransformToMatrixd(transform[tool], *this->SendMatrix->Element);
432  this->SendMatrix->Transpose();
433 
434  std::ostringstream toolPortName;
435  toolPortName << tool;
436  vtkPlusDataSource* trackerTool = NULL;
437  if (this->GetToolByPortName(toolPortName.str().c_str(), trackerTool) != PLUS_SUCCESS)
438  {
439  LOG_ERROR("Failed to get tool by port name: " << toolPortName.str());
440  }
441  else
442  {
443  // send the matrix and status to the tool's vtkPlusDataBuffer
444  this->ToolTimeStampedUpdate(trackerTool->GetId(), this->SendMatrix, status, (unsigned long)uFrameNumber, unfilteredTimestamp);
445  }
446  }
447 
448  return PLUS_SUCCESS;
449 }
450 
451 //----------------------------------------------------------------------------
452 // Enable all tool ports that have tools plugged into them.
454 {
455  int toolCounter = 0;
456 
457  // reset our information about the tool ports
458  for (toolCounter = 0; toolCounter < VTK_CERTUS_NTOOLS; toolCounter++)
459  {
460  if (this->PortEnabled[toolCounter])
461  {
462  LOG_DEBUG("disabling tool " << toolCounter);
463  if (RigidBodyDelete(this->PortHandle[toolCounter]) != OPTO_NO_ERROR_CODE)
464  {
466  }
467  }
468  this->PortEnabled[toolCounter] = 0;
469  }
470 
471  // stop tracking
472  if (this->Recording)
473  {
474  LOG_DEBUG("DeActivating Markers");
475  if (!this->DeActivateCertusMarkers())
476  {
478  }
479  }
480 
481  // device handles (including status)
482  int nDeviceHandles = 0;
483  DeviceHandle* deviceHandles;
484 
485  int allDevicesEnabled = 0;
486  for (int trialNumber = 0;
487  trialNumber < 3 && !allDevicesEnabled;
488  trialNumber++)
489  {
490  LOG_DEBUG("Getting Number Device Handles");
491  if (OptotrakGetNumberDeviceHandles(&nDeviceHandles) != OPTO_NO_ERROR_CODE)
492  {
494  return PLUS_FAIL;
495  }
496 
497  if (nDeviceHandles <= 0)
498  {
499  LOG_ERROR("EnableToolPorts: no Optotrack strobers found");
500  return PLUS_FAIL;
501  }
502 
503  // get all device handles and the status of each one
504  deviceHandles = new DeviceHandle[nDeviceHandles];
505 
506  unsigned int flags = 0;
507  LOG_DEBUG("Getting Device Handles for " << nDeviceHandles << " devices");
508  if (OptotrakGetDeviceHandles(deviceHandles, nDeviceHandles, &flags)
509  != OPTO_NO_ERROR_CODE)
510  {
512  delete [] deviceHandles;
513  return PLUS_FAIL;
514  }
515 
516  // initialize this to 1 (set to 0 if unenabled handles found)
517  allDevicesEnabled = 1;
518 
519  // free any unoccupied handles, enable any initialized handles
520  for (int deviceCounter = 0;
521  deviceCounter < nDeviceHandles;
522  deviceCounter++)
523  {
524  int ph = deviceHandles[deviceCounter].nID;
525  DeviceHandleStatus status = deviceHandles[deviceCounter].dtStatus;
526 
527  if (status == DH_STATUS_UNOCCUPIED)
528  {
529  LOG_DEBUG("Delete port handle " << ph);
530  if (OptotrakDeviceHandleFree(ph) != OPTO_NO_ERROR_CODE)
531  {
533  }
534  allDevicesEnabled = 0;
535  }
536  else if (status == DH_STATUS_INITIALIZED)
537  {
538  LOG_DEBUG("Enable port handle " << ph);
539  if (OptotrakDeviceHandleEnable(ph) != OPTO_NO_ERROR_CODE)
540  {
542  }
543  // enabling a strober will make other tools appear,
544  // so let's be paranoid and always set this to zero
545  allDevicesEnabled = 0;
546  }
547  }
548  }
549 
550  // reset the number of markers and rigid bodies to zero
551  this->NumberOfMarkers = 0;
552  this->NumberOfRigidBodies = 0;
553 
554  // get information for all tools
555  for (int deviceCounter = 0;
556  deviceCounter < nDeviceHandles;
557  deviceCounter++)
558  {
559  int ph = deviceHandles[deviceCounter].nID;
560  DeviceHandleStatus status = deviceHandles[deviceCounter].dtStatus;
561 
562  if (status == DH_STATUS_UNOCCUPIED)
563  {
564  // this shouldn't happen, but just in case
565  continue;
566  }
567 
568  DeviceHandleProperty* properties = 0;
569  int nProperties = 0;
570  LOG_DEBUG("Getting number of properties for port handle " << ph);
571  if (OptotrakDeviceHandleGetNumberProperties(ph, &nProperties)
572  != OPTO_NO_ERROR_CODE
573  || nProperties == 0)
574  {
576  }
577  else
578  {
579  properties = new DeviceHandleProperty[nProperties];
580  LOG_DEBUG("Getting " << nProperties << " properties for handle " << ph);
581  if (OptotrakDeviceHandleGetProperties(ph, properties, nProperties)
582  != OPTO_NO_ERROR_CODE)
583  {
585  }
586  else
587  {
588  // the properties of interest
589  static const int deviceNameMaxlen = 128;
590  char deviceName[deviceNameMaxlen + 1];
591  int hasROM = 0;
592  int nToolPorts = 0;
593  int nSwitches = 0;
594  int nVLEDs = 0;
595  int nSubPort = 0;
596  int nMarkersToFire = 0;
597  int status = 0;
598 
599  for (int propCounter = 0; propCounter < nProperties; propCounter++)
600  {
601  unsigned int propertyID = properties[propCounter].uPropertyID;
602  if (propertyID == DH_PROPERTY_NAME)
603  {
604  strncpy(deviceName, properties[propCounter].dtData.szData,
605  deviceNameMaxlen);
606  deviceName[deviceNameMaxlen] = '\0';
607  }
608  else if (propertyID == DH_PROPERTY_HAS_ROM)
609  {
610  hasROM = properties[propCounter].dtData.nData;
611  }
612  else if (propertyID == DH_PROPERTY_TOOLPORTS)
613  {
614  nToolPorts = properties[propCounter].dtData.nData;
615  }
616  else if (propertyID == DH_PROPERTY_SWITCHES)
617  {
618  nSwitches = properties[propCounter].dtData.nData;
619  }
620  else if (propertyID == DH_PROPERTY_VLEDS)
621  {
622  nVLEDs = properties[propCounter].dtData.nData;
623  }
624  else if (propertyID == DH_PROPERTY_SUBPORT)
625  {
626  nSubPort = properties[propCounter].dtData.nData;
627  }
628  else if (propertyID == DH_PROPERTY_MARKERSTOFIRE)
629  {
630  nMarkersToFire = properties[propCounter].dtData.nData;
631  }
632  else if (propertyID == DH_PROPERTY_STATUS)
633  {
634  status = properties[propCounter].dtData.nData;
635  }
636  }
637 
638  // verify that this is a tool, and not a strober
639  if (hasROM && nToolPorts == 0)
640  {
641  // assume only one strober: index tools by SubPort
642  int port = nSubPort - 1;
643 
644  LOG_INFO("Found tool port " << port << " for device " << deviceName);
645 
646  if (port >= 0 && port < VTK_CERTUS_NTOOLS)
647  {
648  if (this->PortEnabled[port] &&
649  this->PortHandle[port] != ph)
650  {
651  LOG_ERROR("Port number " << port << " is already "
652  "taken by a different tool");
653  }
654  else
655  {
656  this->PortHandle[port] = ph;
657  this->PortEnabled[port] = (status == DH_STATUS_ENABLED);
658 
659  std::ostringstream toolPortName;
660  toolPortName << port;
661  vtkPlusDataSource* trackerTool = NULL;
662  if (this->GetToolByPortName(toolPortName.str().c_str(), trackerTool) != PLUS_SUCCESS)
663  {
664  LOG_WARNING("Undefined connected tool found in the strober on port '" << toolPortName.str() << "' with name '" << deviceName << "', disabled it until not defined in the config file: " << vtkPlusConfig::GetInstance()->GetDeviceSetConfigurationFileName().c_str());
665  this->PortEnabled[port] = 0;
666  }
667  }
668 
669  this->NumberOfMarkers += nMarkersToFire;
670  }
671 
672  delete [] properties;
673  }
674  }
675  }
676  }
677 
678  if (deviceHandles)
679  {
680  delete [] deviceHandles;
681  }
682 
683  this->RigidBodyMap.clear();
684  // add rigid bodies
685  for (toolCounter = 0; toolCounter < VTK_CERTUS_NTOOLS; toolCounter++)
686  {
687  if (this->PortEnabled[toolCounter])
688  {
689  int ph = this->PortHandle[toolCounter];
690  int rigidID = this->NumberOfRigidBodies;
691  LOG_DEBUG("Adding rigid body for port handle" << ph);
692  if (RigidBodyAddFromDeviceHandle(ph,
693  rigidID, // rigID is port handle
694  OPTOTRAK_QUATERN_RIGID_FLAG |
695  OPTOTRAK_RETURN_QUATERN_FLAG)
696  != OPTO_NO_ERROR_CODE)
697  {
699  }
700  else
701  {
702  this->RigidBodyMap[rigidID] = toolCounter;
703  // increment the number of rigid bodies
704  this->NumberOfRigidBodies++;
705 
706  std::ostringstream toolPortName;
707  toolPortName << toolCounter;
708  vtkPlusDataSource* trackerTool = NULL;
709  if (this->GetToolByPortName(toolPortName.str().c_str(), trackerTool) != PLUS_SUCCESS)
710  {
711  LOG_ERROR("Failed to get tool by port name: " << toolPortName.str());
712  continue;
713  }
714  }
715  }
716  }
717 
718  // re-start the tracking
719  if (this->Recording)
720  {
721  LOG_DEBUG("Activating Markers");
722  if (!this->ActivateCertusMarkers())
723  {
725  return PLUS_FAIL;
726  }
727  }
728 
729  return PLUS_SUCCESS;
730 }
731 
732 //----------------------------------------------------------------------------
733 // Disable all enabled tool ports.
735 {
736  // stop tracking
737  if (this->Recording)
738  {
739  if (!this->DeActivateCertusMarkers())
740  {
742  }
743  }
744 
745  // disable the enabled ports
746  for (int toolCounter = 0; toolCounter < VTK_CERTUS_NTOOLS; toolCounter++)
747  {
748  if (this->PortEnabled[toolCounter])
749  {
750  if (RigidBodyDelete(this->PortHandle[toolCounter]) != OPTO_NO_ERROR_CODE)
751  {
753  }
754  }
755  this->PortEnabled[toolCounter] = 0;
756  }
757 
758  // re-start the tracking
759  if (this->Recording)
760  {
761  if (!this->ActivateCertusMarkers())
762  {
764  }
765  }
766 
767  return PLUS_SUCCESS;
768 }
769 
770 //----------------------------------------------------------------------------
772 {
773  int tool;
774 
775  for (tool = 0; tool < VTK_CERTUS_NTOOLS; tool++)
776  {
777  if (this->PortHandle[tool] == handle)
778  {
779  return tool;
780  }
781  }
782 
783  return -1;
784 }
785 
786 //----------------------------------------------------------------------------
787 // change the state of an LED on the tool
789 {
790  if (this->Recording &&
791  portNumber >= 0 && portNumber < VTK_CERTUS_NTOOLS &&
792  led >= 0 && led < 3)
793  {
794  VLEDState pstate = vtkNDICertusMapVLEDState[led];
795  int ph = this->PortHandle[portNumber];
796  if (ph == 0)
797  {
798  return PLUS_FAIL;
799  }
800 
801  OptotrakDeviceHandleSetVisibleLED(ph, led + 1, pstate);
802  }
803 
804  return PLUS_FAIL;
805 }
806 
static VLEDState vtkNDICertusMapVLEDState[]
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
int PortHandle[VTK_CERTUS_NTOOLS]
virtual std::string GetSdkVersion()
std::string GetDeviceSetConfigurationFileName()
igsioStatus PlusStatus
Definition: PlusCommon.h:40
virtual PlusStatus ToolTimeStampedUpdate(const std::string &aToolSourceId, vtkMatrix4x4 *matrix, ToolStatus status, unsigned long frameNumber, double unfilteredtimestamp, const igsioFieldMapType *customFields=NULL)
bool RequirePortNameInDeviceSetConfiguration
for i
double AcquisitionRate
#define PLUS_FAIL
Definition: PlusCommon.h:43
int port
Definition: phidget22.h:2454
static vtkPlusConfig * GetInstance()
virtual PlusStatus InternalDisconnect()
const char ** deviceName
Definition: phidget22.h:1316
Interface for the NDI Optotrak Certus tracking device.
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
PlusStatus GetToolByPortName(const char *aPortName, vtkPlusDataSource *&aSource)
virtual PlusStatus Connect()
#define VTK_CERTUS_NTOOLS
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
int * state
Definition: phidget22.h:3207
virtual PlusStatus StopRecording()
#define vtkPrintCertusErrorMacro()
virtual PlusStatus InternalConnect()
const char int const char int flags
Definition: phidget22.h:2552
PlusStatus SetToolLED(int portNumber, int led, LedState state)
bool StartThreadForInternalUpdates
vtkStandardNewMacro(vtkPlusNDICertusTracker)
std::map< int, int > RigidBodyMap
static char vtkCertusErrorString[MAX_ERROR_STRING_LENGTH+1]
int PortEnabled[VTK_CERTUS_NTOOLS]
Interface to a 3D positioning tool, video source, or generalized data stream.