7 #include "PlusConfigure.h" 14 #if defined(_WIN32) && !defined(__WINDOWS_H) 25 #include "ndicapi_math.h" 27 #include "vtkTimerLog.h" 28 #include "vtkMatrix4x4.h" 29 #include "vtkTransform.h" 32 #include "vtkObjectFactory.h" 37 #define VTK_CERTUS_DEBUG_STATEMENTS 0 81 const int BUFSIZE = 200;
82 char version[BUFSIZE + 1];
84 OAPIGetVersionString(version, BUFSIZE);
85 return std::string(version);
93 os << indent <<
"SendMatrix: " << this->
SendMatrix <<
"\n";
94 this->SendMatrix->PrintSelf(os, indent.GetNextIndent());
102 #define vtkPrintCertusErrorMacro() \ 104 if (OptotrakGetErrorString(vtkCertusErrorString, MAX_ERROR_STRING_LENGTH+1) == 0) \ 106 LOG_ERROR(vtkCertusErrorString); \ 114 if (OptotrakSetProcessingFlags(OPTO_USE_INTERNAL_NIF) != OPTO_NO_ERROR_CODE)
116 LOG_ERROR(
"Call to OptotrakSetProcessingFlags() failed.");
121 LOG_DEBUG(
"TransputerDetermineSystemCfg start...");
123 if (TransputerDetermineSystemCfg(NULL) != OPTO_NO_ERROR_CODE)
125 LOG_ERROR(
"Call to TransputerDetermineSystemCfg() failed.");
129 LOG_DEBUG(
"TransputerDetermineSystemCfg completed");
132 if (TransputerLoadSystem(
"system") != OPTO_NO_ERROR_CODE)
134 LOG_ERROR(
"Call to Certus TransputerLoadSystem() failed");
140 vtkIGSIOAccurateTimer::Delay(1);
143 if (TransputerInitializeSystem(0) != OPTO_NO_ERROR_CODE)
146 LOG_ERROR(
"Call to Certus TransputerInitializeSystem() failed");
152 if (OptotrakLoadCameraParameters(
"standard") != OPTO_NO_ERROR_CODE)
154 LOG_ERROR(
"Call to OptotrakLoadCameraParameters() failed");
186 if (OptotrakGetStatus(&nNumSensors, &nNumOdaus, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &nFlags) != OPTO_NO_ERROR_CODE)
188 LOG_ERROR(
"Call to OptotrakGetStatus() failed");
194 if ((nFlags & (OPTOTRAK_3020_FLAG | OPTOTRAK_CERTUS_FLAG)) != OPTOTRAK_CERTUS_FLAG)
196 LOG_ERROR(
"Only Certus is supported. Attached device is not Certus.");
201 if ((nNumSensors != 1 || nNumOdaus != 1))
203 LOG_DEBUG(
"Certus configuration: " << nNumSensors <<
" sensors, " 204 << nNumOdaus <<
" odaus");
215 if (TransputerShutdownSystem() != OPTO_NO_ERROR_CODE)
228 if (OptotrakSetupCollection(
239 OPTOTRAK_BUFFER_RAW_FLAG) != OPTO_NO_ERROR_CODE)
245 if (OptotrakActivateMarkers() != OPTO_NO_ERROR_CODE)
247 LOG_ERROR(
"Cannot activate the markers");
257 if (OptotrakDeActivateMarkers() != OPTO_NO_ERROR_CODE)
259 LOG_ERROR(
"Cannot activate the markers");
316 if (OptotrakDeActivateMarkers() != OPTO_NO_ERROR_CODE)
339 LOG_ERROR(
"called Update() when Certus was not tracking");
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;
354 unsigned int uFrameNumber = 0;
355 unsigned int uElements = 0;
356 unsigned int uFlags = 0;
357 OptotrakRigidStruct* rigidBodyData;
360 if (DataGetLatestTransforms2(&uFrameNumber, &uElements, &uFlags,
361 rigidBodyData, 0) != OPTO_NO_ERROR_CODE)
364 delete [] rigidBodyData;
374 OptotrakRigidStruct& rigidBody = rigidBodyData[rigidCounter];
375 long rigidId = rigidBody.RigidId;
377 std::map<int, int>::iterator rigidBodyMapIterator = this->
RigidBodyMap.find(rigidId);
380 tool = rigidBodyMapIterator->second;
384 LOG_ERROR(
"InternalUpdate: bad rigid body ID " << rigidId);
388 if ((rigidBody.flags & OPTOTRAK_UNDETERMINED_FLAG) == 0)
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]);
404 LOG_TRACE(
"Rigid body " << rigidCounter <<
" (rigidId=" << rigidId <<
") undetermined");
407 statusFlags[tool] = rigidBody.flags;
410 delete [] rigidBodyData;
412 const double unfilteredTimestamp = vtkIGSIOAccurateTimer::GetSystemTime();
423 ToolStatus status = TOOL_OK;
425 if ((statusFlags[tool] & OPTOTRAK_UNDETERMINED_FLAG) != 0)
427 status = TOOL_MISSING;
431 ndiTransformToMatrixd(transform[tool], *this->
SendMatrix->Element);
434 std::ostringstream toolPortName;
435 toolPortName << tool;
439 LOG_ERROR(
"Failed to get tool by port name: " << toolPortName.str());
462 LOG_DEBUG(
"disabling tool " << toolCounter);
463 if (RigidBodyDelete(this->
PortHandle[toolCounter]) != OPTO_NO_ERROR_CODE)
474 LOG_DEBUG(
"DeActivating Markers");
482 int nDeviceHandles = 0;
483 DeviceHandle* deviceHandles;
485 int allDevicesEnabled = 0;
486 for (
int trialNumber = 0;
487 trialNumber < 3 && !allDevicesEnabled;
490 LOG_DEBUG(
"Getting Number Device Handles");
491 if (OptotrakGetNumberDeviceHandles(&nDeviceHandles) != OPTO_NO_ERROR_CODE)
497 if (nDeviceHandles <= 0)
499 LOG_ERROR(
"EnableToolPorts: no Optotrack strobers found");
504 deviceHandles =
new DeviceHandle[nDeviceHandles];
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)
512 delete [] deviceHandles;
517 allDevicesEnabled = 1;
520 for (
int deviceCounter = 0;
521 deviceCounter < nDeviceHandles;
524 int ph = deviceHandles[deviceCounter].nID;
525 DeviceHandleStatus status = deviceHandles[deviceCounter].dtStatus;
527 if (status == DH_STATUS_UNOCCUPIED)
529 LOG_DEBUG(
"Delete port handle " << ph);
530 if (OptotrakDeviceHandleFree(ph) != OPTO_NO_ERROR_CODE)
534 allDevicesEnabled = 0;
536 else if (status == DH_STATUS_INITIALIZED)
538 LOG_DEBUG(
"Enable port handle " << ph);
539 if (OptotrakDeviceHandleEnable(ph) != OPTO_NO_ERROR_CODE)
545 allDevicesEnabled = 0;
555 for (
int deviceCounter = 0;
556 deviceCounter < nDeviceHandles;
559 int ph = deviceHandles[deviceCounter].nID;
560 DeviceHandleStatus status = deviceHandles[deviceCounter].dtStatus;
562 if (status == DH_STATUS_UNOCCUPIED)
568 DeviceHandleProperty* properties = 0;
570 LOG_DEBUG(
"Getting number of properties for port handle " << ph);
571 if (OptotrakDeviceHandleGetNumberProperties(ph, &nProperties)
572 != OPTO_NO_ERROR_CODE
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)
589 static const int deviceNameMaxlen = 128;
596 int nMarkersToFire = 0;
599 for (
int propCounter = 0; propCounter < nProperties; propCounter++)
601 unsigned int propertyID = properties[propCounter].uPropertyID;
602 if (propertyID == DH_PROPERTY_NAME)
604 strncpy(
deviceName, properties[propCounter].dtData.szData,
608 else if (propertyID == DH_PROPERTY_HAS_ROM)
610 hasROM = properties[propCounter].dtData.nData;
612 else if (propertyID == DH_PROPERTY_TOOLPORTS)
614 nToolPorts = properties[propCounter].dtData.nData;
616 else if (propertyID == DH_PROPERTY_SWITCHES)
618 nSwitches = properties[propCounter].dtData.nData;
620 else if (propertyID == DH_PROPERTY_VLEDS)
622 nVLEDs = properties[propCounter].dtData.nData;
624 else if (propertyID == DH_PROPERTY_SUBPORT)
626 nSubPort = properties[propCounter].dtData.nData;
628 else if (propertyID == DH_PROPERTY_MARKERSTOFIRE)
630 nMarkersToFire = properties[propCounter].dtData.nData;
632 else if (propertyID == DH_PROPERTY_STATUS)
634 status = properties[propCounter].dtData.nData;
639 if (hasROM && nToolPorts == 0)
642 int port = nSubPort - 1;
644 LOG_INFO(
"Found tool port " <<
port <<
" for device " <<
deviceName);
651 LOG_ERROR(
"Port number " <<
port <<
" is already " 652 "taken by a different tool");
659 std::ostringstream toolPortName;
660 toolPortName <<
port;
672 delete [] properties;
680 delete [] deviceHandles;
691 LOG_DEBUG(
"Adding rigid body for port handle" << ph);
692 if (RigidBodyAddFromDeviceHandle(ph,
694 OPTOTRAK_QUATERN_RIGID_FLAG |
695 OPTOTRAK_RETURN_QUATERN_FLAG)
696 != OPTO_NO_ERROR_CODE)
706 std::ostringstream toolPortName;
707 toolPortName << toolCounter;
711 LOG_ERROR(
"Failed to get tool by port name: " << toolPortName.str());
721 LOG_DEBUG(
"Activating Markers");
750 if (RigidBodyDelete(this->
PortHandle[toolCounter]) != OPTO_NO_ERROR_CODE)
801 OptotrakDeviceHandleSetVisibleLED(ph, led + 1, pstate);
static VLEDState vtkNDICertusMapVLEDState[]
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
PlusStatus DeActivateCertusMarkers()
PlusStatus DisableToolPorts()
int PortHandle[VTK_CERTUS_NTOOLS]
virtual std::string GetSdkVersion()
PlusStatus ShutdownCertusSystem()
std::string GetDeviceSetConfigurationFileName()
virtual PlusStatus ToolTimeStampedUpdate(const std::string &aToolSourceId, vtkMatrix4x4 *matrix, ToolStatus status, unsigned long frameNumber, double unfilteredtimestamp, const igsioFieldMapType *customFields=NULL)
PlusStatus InitializeCertusSystem()
bool RequirePortNameInDeviceSetConfiguration
PlusStatus InternalStartRecording()
static vtkPlusConfig * GetInstance()
PlusStatus InternalStopRecording()
virtual PlusStatus InternalDisconnect()
vtkPlusNDICertusTracker()
Interface for the NDI Optotrak Certus tracking device.
PlusStatus GetToolByPortName(const char *aPortName, vtkPlusDataSource *&aSource)
virtual PlusStatus Connect()
PlusStatus InternalUpdate()
vtkMatrix4x4 * SendMatrix
#define VTK_CERTUS_NTOOLS
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
virtual PlusStatus StopRecording()
#define vtkPrintCertusErrorMacro()
PlusStatus EnableToolPorts()
virtual PlusStatus InternalConnect()
PlusStatus ActivateCertusMarkers()
const char int const char int flags
int GetToolFromHandle(int handle)
PlusStatus SetToolLED(int portNumber, int led, LedState state)
bool StartThreadForInternalUpdates
~vtkPlusNDICertusTracker()
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.