7 #include "PlusConfigure.h" 9 #include "vtkMatrix4x4.h" 10 #include "vtkObjectFactory.h" 12 #include "vtkTransform.h" 13 #include "vtkXMLDataElement.h" 14 #include "vtksys/SystemTools.hxx" 16 #include "vtkVector.h" 31 class vtkPlusUSDigitalEncodersTracker::vtkPlusUSDigitalEncoderInfo
86 long Resolution = 3600;
89 double PulseSpacing = 0.0;
90 double PulseSpacing2 = 0.0;
91 vtkSmartPointer<vtkTransform> LocalTransform = vtkSmartPointer<vtkTransform>::New();
92 vtkVector3d LocalAxis;
93 vtkVector3d LocalAxis2;
95 vtkSmartPointer<vtkMatrix4x4> ToolToEncoderMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
96 vtkSmartPointer<vtkMatrix4x4> EncoderToReference = vtkSmartPointer<vtkMatrix4x4>::New();
97 igsioTransformName TransformName;
130 LOG_TRACE(
"vtkPlusUSDigitalEncodersTracker::Connect");
137 int devicesExpected = this->
coreXY ? 2 : 15;
139 if(EncoderStatus != 0)
141 LOG_ERROR(
"Failed to initialize SEI!");
149 if(numberofConnectedEncoders < 2)
151 LOG_ERROR(
"Number of connected USDigital encoder(s) is less than 2!");
152 LOG_ERROR(
"There are " << numberofConnectedEncoders <<
" encoders connected");
156 EncoderInfoMapType::iterator encoderInfoPos;
161 long serialNumber = 0;
168 LOG_ERROR(
"Failed to get SEI device info for device number: " <<
deviceID);
176 LOG_WARNING(
"Unregistered encoder is detected");
180 encoderInfoPos->second->Connected =
true;
181 encoderInfoPos->second->Model = model;
182 encoderInfoPos->second->Version = version;
186 LOG_ERROR(
"Failed to set SEI device mode for device SN: " << serialNumber <<
", deviceID: " <<
deviceID);
198 LOG_ERROR(
"Failed to set initial position for SEI device SN: " << serialNumber <<
", deviceID: " <<
deviceID);
203 LOG_INFO(
"The encoder's position had to be reset to zero. SEI device SN: " << serialNumber <<
", deviceID: " <<
deviceID);
208 if(encoderInfoPos->second->Addr ==
deviceID)
210 encoderInfoPos->second->Addr =
address;
212 else if(encoderInfoPos->second->Addr2 ==
deviceID)
214 encoderInfoPos->second->Addr2 =
address;
218 LOG_WARNING(
"Could not establish configuration address to deviceID correspondence");
231 LOG_TRACE(
"vtkPlusUSDigitalEncodersTracker::Disconnect");
248 LOG_TRACE(
"vtkPlusUSDigitalEncodersTracker::Probe");
257 LOG_ERROR(
"Unable to connect to USDigital Encoders");
269 LOG_TRACE(
"vtkPlusUSDigitalEncodersTracker::InternalStartRecording");
276 LOG_TRACE(
"vtkPlusUSDigitalEncodersTracker::InternalStopRecording");
283 LOG_TRACE(
"vtkPlusUSDigitalEncodersTracker::InternalUpdate");
287 LOG_ERROR(
"called Update() when not tracking");
293 RETURN_WITH_FAIL_IF(!it->Connected,
"USDigital encoder(s) not connected!");
297 vtkSmartPointer<vtkTransform> tempTransform = vtkSmartPointer<vtkTransform>::New();
301 RETURN_WITH_FAIL_IF(errorCode,
"Unable to read position of first encoder with address: " << it->Addr);
302 vtkVector3d localmovement = it->LocalAxis;
306 double firstEnc = encoderValue * it->PulseSpacing;
309 RETURN_WITH_FAIL_IF(errorCode,
"Unable to read position of second encoder with address: " << it->Addr2);
311 double secondEnc = encoderValue * it->PulseSpacing2;
313 double firstAxis = firstEnc + secondEnc;
314 double secondAxis = firstEnc - secondEnc;
317 vtkMath::MultiplyScalar(localmovement.GetData(), firstAxis);
318 tempTransform->Translate(localmovement.GetData());
319 localmovement = it->LocalAxis2;
320 vtkMath::MultiplyScalar(localmovement.GetData(), secondAxis);
321 tempTransform->Translate(localmovement.GetData());
328 vtkMath::MultiplyScalar(localmovement.GetData(), encoderValue * it->PulseSpacing);
329 tempTransform->Translate(localmovement.GetData());
331 else if(it->Motion == 1)
334 tempTransform->RotateWXYZ(encoderValue * it->PulseSpacing, localmovement.GetData());
338 LOG_ERROR(
"Un-supported motion type");
342 vtkMatrix4x4::Multiply4x4(it->ToolToEncoderMatrix, tempTransform->GetMatrix(), it->EncoderToReference);
348 LOG_ERROR(
"Unable to find tool with port name: " << it->PortName);
352 unsigned long frameNumber = tool->GetFrameNumber() + 1;
353 const double unfilteredTimestamp = vtkIGSIOAccurateTimer::GetSystemTime();
355 it->EncoderToReference, TOOL_OK, frameNumber, unfilteredTimestamp);
366 XML_FIND_NESTED_ELEMENT_REQUIRED(dataSourcesElement, deviceConfig,
"DataSources");
373 for(
int encoderIndex = 0; encoderIndex < dataSourcesElement->GetNumberOfNestedElements(); encoderIndex++)
375 vtkXMLDataElement* encoderInfoElement = dataSourcesElement->GetNestedElement(encoderIndex);
376 if(STRCASECMP(encoderInfoElement->GetName(),
"DataSource") != 0)
382 vtkPlusUSDigitalEncoderInfo encoderInfo;
384 const char* portName = encoderInfoElement->GetAttribute(
"PortName");
387 LOG_ERROR(
"Tool portname is not specified");
391 const char*
id = encoderInfoElement->GetAttribute(
"Id");
394 LOG_ERROR(
"Tool Id is missing!");
401 LOG_ERROR(
"GetTool for port " << portName <<
" failed");
406 LOG_ERROR(
"Tool with ID " <<
id <<
" was not found");
409 encoderInfo.PortName = portName;
413 const char* toAttribute = encoderInfoElement->GetAttribute(
"ToolReferenceFrame");
416 toAttribute = deviceConfig->GetAttribute(
"ToolReferenceFrame");
419 toAttribute = deviceConfig->GetAttribute(
"Id");
420 LOG_WARNING(
"Device's attribute 'ToolReferenceFrame' is missing (Device Id='" << toAttribute <<
"')!");
424 igsioTransformName transformName(
id, toAttribute);
425 if(!transformName.IsValid())
427 LOG_ERROR(
"Invalid transform name (From: '" <<
id <<
"' To: '" << toAttribute <<
"')");
431 encoderInfo.TransformName = transformName;
436 encoderInfo.EncoderToReference);
439 double vectorMatrix[16] = { 0 };
440 if(encoderInfoElement->GetVectorAttribute(
"ToolToEncoderMatrix", 16, vectorMatrix))
442 encoderInfo.ToolToEncoderMatrix->DeepCopy(vectorMatrix);
446 encoderInfo.ToolToEncoderMatrix->Identity();
450 std::string motiontype = encoderInfoElement->GetAttribute(
"MotionType");
451 if(motiontype.empty())
453 LOG_ERROR(
"Cannot read the MotionType of an US Digital Encoder");
456 std::transform(motiontype.begin(), motiontype.end(), motiontype.begin(), ::tolower);
457 LOG_INFO(
"Motion Type :: " << motiontype);
458 if(motiontype.find(
"linear") != std::string::npos)
460 encoderInfo.Motion = 0;
462 else if(motiontype.find(
"rotation") != std::string::npos)
464 encoderInfo.Motion = 1;
468 LOG_ERROR(
"Motion type of a US Digital Encoder unrecognized!");
475 const char* pulseSpacing = encoderInfoElement->GetAttribute(
"PulseSpacing");
476 if(pulseSpacing == NULL)
478 LOG_ERROR(
"Cannot read the PulseSpacing of an US Digital Encoder");
481 encoderInfo.PulseSpacing = atof(pulseSpacing);
483 const char* pulseSpacing2 = encoderInfoElement->GetAttribute(
"PulseSpacing2");
484 this->
coreXY = (pulseSpacing2 != NULL);
487 encoderInfo.PulseSpacing2 = atof(pulseSpacing2);
491 LOG_INFO(
"PulseSpacing2 not found - this is not a coreXY configuration. Tool Id: " <<
id);
494 if(!encoderInfoElement->GetVectorAttribute(
"LocalAxis", 3, encoderInfo.LocalAxis.GetData()))
496 LOG_ERROR(
"Unable to find 'LocalAxis' attribute of an encoder in the configuration file");
502 if(!encoderInfoElement->GetVectorAttribute(
"LocalAxis2", 3, encoderInfo.LocalAxis2.GetData()))
504 LOG_ERROR(
"Unable to find 'LocalAxis2' attribute in the configuration file");
510 const char*
mode = encoderInfoElement->GetAttribute(
"Mode");
513 LOG_ERROR(
"Cannot read the Mode of an US Digital Encoder");
516 encoderInfo.Mode = atol(
mode);
519 const char* resolution = encoderInfoElement->GetAttribute(
"Resolution");
520 if(resolution == NULL)
522 LOG_ERROR(
"Cannot read the Resolution of an US Digital Encoder");
525 encoderInfo.Resolution = atol(resolution);
547 LOG_WARNING(
"Writing configuration for USDigitalEncoders is not supported");
555 RETURN_WITH_FAIL_IF(r != 1,
"Device not yet initialized!");
562 RETURN_WITH_FAIL_IF(::
A2SetStrobe() != 0,
"Failed to set US digital A2 Encoders as Strobe mode.");
569 RETURN_WITH_FAIL_IF(::
A2SetSleep() != 0,
"Failed to set US digital A2 Encoders as Sleep mode.");
576 RETURN_WITH_FAIL_IF(::
A2SetWakeup() != 0,
"Failed to set US digital A2 Encoders as Wakeup mode.");
583 IDtoAddressType::iterator enc = this->
IdAddress.find(
id);
584 RETURN_WITH_FAIL_IF(enc == this->
IdAddress.end(),
"Non-existent device ID: " << id);
585 RETURN_WITH_FAIL_IF(::
A2SetOrigin(enc->second) != 0,
586 "Failed to set US digital A2 Encoder's origin point as current position.");
593 EncoderListType::iterator it;
615 IDtoAddressType::iterator enc = this->
IdAddress.find(
id);
616 RETURN_WITH_FAIL_IF(enc == this->
IdAddress.end(),
"Non-existent device ID: " << id);
618 "Failed to set the mode of an US digital A2 Encoder.");
625 IDtoAddressType::iterator enc = this->
IdAddress.find(
id);
626 RETURN_WITH_FAIL_IF(enc == this->
IdAddress.end(),
"Non-existent device ID: " << id);
628 "Failed to get the mode of an US digital A2 Encoder.");
635 IDtoAddressType::iterator enc = this->
IdAddress.find(
id);
636 RETURN_WITH_FAIL_IF(enc == this->
IdAddress.end(),
"Non-existent device ID: " << id);
639 "Failed to set the resoultion of an US digital A2 Encoder.");
646 IDtoAddressType::iterator enc = this->
IdAddress.find(
id);
647 RETURN_WITH_FAIL_IF(enc == this->
IdAddress.end(),
"Non-existent device ID: " << id);
650 "Failed to get the resoultion of an US digital A2 Encoder.");
657 IDtoAddressType::iterator enc = this->
IdAddress.find(
id);
658 RETURN_WITH_FAIL_IF(enc == this->
IdAddress.end(),
"Non-existent device ID: " << id);
661 "Failed to set the position of an US digital A2 Encoder.");
668 IDtoAddressType::iterator enc = this->
IdAddress.find(
id);
669 RETURN_WITH_FAIL_IF(enc == this->
IdAddress.end(),
"Non-existent device ID: " << id);
672 "Failed to get the position of an US digital A2 Encoder.");
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
PlusStatus InternalStopRecording()
static const char * USDIGITALENCODER_COMMAND_SET_ORIGIN
static const char * USDIGITALENCODER_COMMAND_SET_ALL_ORIGIN
PlusStatus SetUSDigitalA2EncoderOriginWithID(long id)
IDtoAddressType IdAddress
virtual PlusStatus ToolTimeStampedUpdate(const std::string &aToolSourceId, vtkMatrix4x4 *matrix, ToolStatus status, unsigned long frameNumber, double unfilteredtimestamp, const igsioFieldMapType *customFields=NULL)
void PrintSelf(ostream &os, vtkIndent indent)
long GetDeviceInfo(long devnum, long &serialnum, long &addr, char *model, char *firmwareVersion)
PlusStatus GetUSDigitalA2EncoderResoultionWithID(long id, long *res)
virtual PlusStatus InternalDisconnect()
long InitializeSEI(long comm, long mode, int devicesExpected)
PlusStatus SetUSDigitalA2EncoderResoultionWithID(long id, long res)
PlusStatus SetUSDigitalA2EncodersStrobeMode()
virtual PlusStatus Disconnect()
long A2GetMode(long address, long *mode)
long A2SetOrigin(long address)
PlusStatus GetUSDigitalA2EncoderPositionWithID(long id, long *pos)
PlusStatus SetAllUSDigitalA2EncoderOrigin()
vtkPlusUSDigitalEncodersTracker()
PlusStatus GetToolByPortName(const char *aPortName, vtkPlusDataSource *&aSource)
virtual PlusStatus Connect()
long A2SetPosition(long address, long pos)
Interface for multiple US Digital A2, A2T, A4, HBA2, HBA4 or HD25A encoders to generate pose informat...
~vtkPlusUSDigitalEncodersTracker()
vtkSmartPointer< vtkIGSIOTransformRepository > TransformRepository
long A2GetPosition(long address, long *pos)
virtual PlusStatus StopRecording()
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_READING(deviceConfig, rootConfigElement)
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *config)
EncoderInfoMapType EncoderMap
PlusStatus InternalUpdate()
PlusStatus InternalConnect()
bool StartThreadForInternalUpdates
PlusStatus SetUSDigitalA2EncodersSleep()
PlusStatus SetUSDigitalA2EncoderPositionWithID(long id, long pos)
long A2SetMode(long address, long mode)
virtual PlusStatus IsStepperAlive()
EncoderListType EncoderList
vtkStandardNewMacro(vtkPlusUSDigitalEncodersTracker)
long A2SetResolution(long address, long res)
PlusStatus InternalStartRecording()
long GetNumberOfDevices()
PlusStatus SetUSDigitalA2EncodersWakeup()
Phidget_DeviceID * deviceID
long A2GetResolution(long address, long *res)
PlusStatus SetUSDigitalA2EncoderModeWithID(long id, long mode)
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *config)
PlusStatus GetUSDigitalA2EncoderModeWithID(long id, long *mode)
void SetDeviceId(const std::string &id)
static const char * USDIGITALENCODER_COMMAND_GET_POSITION
Interface to a 3D positioning tool, video source, or generalized data stream.