PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkPlusUSDigitalEncodersTracker.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 
9 #include "vtkMatrix4x4.h"
10 #include "vtkObjectFactory.h"
11 #include "vtkPlusDataSource.h"
12 #include "vtkTransform.h"
13 #include "vtkXMLDataElement.h"
14 #include "vtksys/SystemTools.hxx"
15 #include "vtkMath.h"
16 #include "vtkVector.h"
17 
18 #include "SEIDrv.h"
19 #include <sstream>
20 
22 
24 
25 // Define command strings
29 
30 
31 class vtkPlusUSDigitalEncodersTracker::vtkPlusUSDigitalEncoderInfo
32 {
33 public:
34  std::string Model;
35  std::string Version;
36  long Addr = 0;
37  long Addr2 = 0;
38 
39  // Supporting Modes:
40  /*
41  The mode is changed temporarily and will be effective until the encoder is
42  reset, powered down, or another mode change command is received. It is
43  not stored in the EEPROM. Mode byte as follows:
44 
45  |7| 6 |5| 4 | 3 | 2 | 1 | 0 |
46  |0|/256|0|incr|size|multi|stb|rev|
47 
48  Reverse: rev = 1, the position increases counter clockwise.
49  rev = 0, the position increases clockwise.
50  Strobe: stb = 1, the encoder operates in strobe mode: it waits for a strobe
51  request before reading the position; this mode is used to
52  synchronize multiple encoders. After entering this mode, wait
53  at least 2 msec before sending the first strobe command.
54  stb = 0, the encoder operates in asynchronous
55  mode: it reads the position within 2 milliseconds and sends
56  the most current position when requested. The data can be
57  from 0 to 2 milliseconds old.
58  Multi: multi = 1, multi-turn mode: a 32 bit counter keeps track of the
59  position (it increases or decreases over multiple turns, i.e. 3 1/
60  2 turns at a resolution of 100 would be 350). This counter is
61  cleared at reset.
62  multi = 0, single-turn mode: position is between zero and the max
63  resolution, according to the shaft angle.
64  Note: in older versions (V1.X), this bit indicated a fast mode
65  (3msec update rate) with a 9 bit accuracy.
66  Also, any other command besides position inquires can corrupt
67  the multi-turn position.
68  Size: only effective in single-turn mode:
69  size = 1: the encoder always sends the position in 2 bytes, even
70  if the resolution is 256 decimal or less.
71  size = 0: the position is sent as 1 byte if the resolution is up to
72  256 decimal, or as 2 bytes if above 256 decimal.
73  In multi-turn mode, the position is always 4 bytes and this bit is
74  ignored.
75  Incr: only effective in multi-turn mode:
76  incr = 1: the encoder sends the position change since the last
77  request, as a 32 bit signed number.
78  incr = 0: the encoder sends the position as a 32 bit signed
79  number.
80  /256: only available for analog version,
81  only effective in multi-turn mode:
82  /256 = 1: the encoder position is divided by 256.
83  /256 = 0: the encoder position is normal.
84  */
85  long Mode = 4;// Defaul mode : Strobe (OFF), MultiTurn(On), Size(OFF), Incr (OFF), /256 (OFF)
86  long Resolution = 3600;
87  bool Connected = false;
88  int Motion = 0; // 0 : Linear motion , 1: Rotation
89  double PulseSpacing = 0.0;
90  double PulseSpacing2 = 0.0;
91  vtkSmartPointer<vtkTransform> LocalTransform = vtkSmartPointer<vtkTransform>::New();
92  vtkVector3d LocalAxis;
93  vtkVector3d LocalAxis2;
94 public:
95  vtkSmartPointer<vtkMatrix4x4> ToolToEncoderMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
96  vtkSmartPointer<vtkMatrix4x4> EncoderToReference = vtkSmartPointer<vtkMatrix4x4>::New();
97  igsioTransformName TransformName;
98  std::string PortName;
99 };
100 
101 //-------------------------------------------------------------------------
103 {
104  this->SetDeviceId("TrackerDevice");
105 
106  // No callback function provided by the device, so the data capture thread
107  // will be used to poll the hardware and add new items to the buffer
108  this->StartThreadForInternalUpdates = true;
109  this->AcquisitionRate = 50; //increase this default (vtkPlusDevice has 30)
110 }
111 
112 //-------------------------------------------------------------------------
114 {
115  if(this->Connected)
116  {
117  this->Disconnect();
118  }
119 }
120 
121 //-------------------------------------------------------------------------
122 void vtkPlusUSDigitalEncodersTracker::PrintSelf(ostream& os, vtkIndent indent)
123 {
124  Superclass::PrintSelf(os, indent);
125 }
126 
127 //-------------------------------------------------------------------------
129 {
130  LOG_TRACE("vtkPlusUSDigitalEncodersTracker::Connect");
131 
132  // SEI Initialization.
133  // Start the SEI Server Program, and look for devices on the SEI bus with
134  // the zero COM port to look on all com ports, and the AUTOASSIGN means
135  // that if there are address conflicts on the SEI bus, the device
136  // addresses will automatically be reassigned so there are no conflicts
137  int devicesExpected = this->coreXY ? 2 : 15; // only search for 2 devices for coreXY, otherwise search for max amount of 15 on the SEI bus
138  long EncoderStatus = ::InitializeSEI(0, REINITIALIZE | AUTOASSIGN | NORESET, devicesExpected);
139  if(EncoderStatus != 0)
140  {
141  LOG_ERROR("Failed to initialize SEI!");
142  return PLUS_FAIL;
143  }
144  this->IdAddress.clear();
145 
146  long numberofConnectedEncoders = ::GetNumberOfDevices();
147  if(this->coreXY)
148  {
149  if(numberofConnectedEncoders < 2)
150  {
151  LOG_ERROR("Number of connected USDigital encoder(s) is less than 2!");
152  LOG_ERROR("There are " << numberofConnectedEncoders << " encoders connected");
153  return PLUS_FAIL;
154  }
155  }
156  EncoderInfoMapType::iterator encoderInfoPos;
157  for(long deviceID = 0; deviceID < numberofConnectedEncoders; ++deviceID)
158  {
159  // Support multiple US digital A2 encoders.
160  char model[100];
161  long serialNumber = 0;
162  char version[100];
163  long address = 0;
164  long retVal;
165 
166  if(::GetDeviceInfo(deviceID, serialNumber, address, model, version) != 0)
167  {
168  LOG_ERROR("Failed to get SEI device info for device number: " << deviceID);
169  return PLUS_FAIL;
170  }
171 
172  encoderInfoPos = this->EncoderMap.find(deviceID);
173 
174  if(encoderInfoPos == this->EncoderMap.end())
175  {
176  LOG_WARNING("Unregistered encoder is detected");
177  }
178  else
179  {
180  encoderInfoPos->second->Connected = true;
181  encoderInfoPos->second->Model = model;
182  encoderInfoPos->second->Version = version;
183  retVal = ::A2SetMode(address, encoderInfoPos->second->Mode);
184  if(retVal != 0)
185  {
186  LOG_ERROR("Failed to set SEI device mode for device SN: " << serialNumber << ", deviceID: " << deviceID);
187  return PLUS_FAIL;
188  }
189 
190  //check whether we need to reset the encoder
191  long pos;
192  retVal = ::A2GetPosition(address, &pos);
193  if(retVal != 0)
194  {
195  retVal = ::A2SetPosition(address, 0); // reset the value of the encoder
196  if(retVal != 0)
197  {
198  LOG_ERROR("Failed to set initial position for SEI device SN: " << serialNumber << ", deviceID: " << deviceID);
199  return PLUS_FAIL;
200  }
201  else
202  {
203  LOG_INFO("The encoder's position had to be reset to zero. SEI device SN: " << serialNumber << ", deviceID: " << deviceID);
204  }
205  }
206  if(deviceID != address) //update address in encoderInfo
207  {
208  if(encoderInfoPos->second->Addr == deviceID)
209  {
210  encoderInfoPos->second->Addr = address;
211  }
212  else if(encoderInfoPos->second->Addr2 == deviceID)
213  {
214  encoderInfoPos->second->Addr2 = address;
215  }
216  else
217  {
218  LOG_WARNING("Could not establish configuration address to deviceID correspondence");
219  }
220  }
221  this->IdAddress[deviceID] = address;
222  }
223  }
224 
225  return PLUS_SUCCESS;
226 }
227 
228 //-------------------------------------------------------------------------
230 {
231  LOG_TRACE("vtkPlusUSDigitalEncodersTracker::Disconnect");
232  this->StopRecording();
233 
234  if(::IsInitialized() != 1)
235  {
236  // Device not yet initialized
237  return PLUS_SUCCESS;
238  }
239 
240  ::CloseSEI();
241 
242  return PLUS_SUCCESS;
243 }
244 
245 //-------------------------------------------------------------------------
247 {
248  LOG_TRACE("vtkPlusUSDigitalEncodersTracker::Probe");
249 
250  if(this->Recording)
251  {
252  return PLUS_SUCCESS;
253  }
254 
255  if(!this->Connect())
256  {
257  LOG_ERROR("Unable to connect to USDigital Encoders");
258  return PLUS_FAIL;
259  }
260 
261  this->Disconnect();
262 
263  return PLUS_SUCCESS;
264 }
265 
266 //-------------------------------------------------------------------------
268 {
269  LOG_TRACE("vtkPlusUSDigitalEncodersTracker::InternalStartRecording");
270  return PLUS_SUCCESS;
271 }
272 
273 //-------------------------------------------------------------------------
275 {
276  LOG_TRACE("vtkPlusUSDigitalEncodersTracker::InternalStopRecording");
277  return PLUS_SUCCESS;
278 }
279 
280 //-------------------------------------------------------------------------
282 {
283  LOG_TRACE("vtkPlusUSDigitalEncodersTracker::InternalUpdate");
284 
285  if(!this->Recording)
286  {
287  LOG_ERROR("called Update() when not tracking");
288  return PLUS_FAIL;
289  }
290 
291  for(auto it = EncoderList.begin(); it != EncoderList.end(); ++it)
292  {
293  RETURN_WITH_FAIL_IF(!it->Connected, "USDigital encoder(s) not connected!");
294 
295  long encoderValue;
296  long errorCode;
297  vtkSmartPointer<vtkTransform> tempTransform = vtkSmartPointer<vtkTransform>::New();
298 
299  // Read encoder positions and transform it into XY position in mm
300  errorCode = ::A2GetPosition(it->Addr, &encoderValue);
301  RETURN_WITH_FAIL_IF(errorCode, "Unable to read position of first encoder with address: " << it->Addr);
302  vtkVector3d localmovement = it->LocalAxis;
303 
304  if(it->Addr2 != 0) //coreXY
305  {
306  double firstEnc = encoderValue * it->PulseSpacing;
307 
308  errorCode = ::A2GetPosition(it->Addr2, &encoderValue);
309  RETURN_WITH_FAIL_IF(errorCode, "Unable to read position of second encoder with address: " << it->Addr2);
310 
311  double secondEnc = encoderValue * it->PulseSpacing2;
312 
313  double firstAxis = firstEnc + secondEnc;
314  double secondAxis = firstEnc - secondEnc;
315 
316  //now make a transform matrix out of this translation and add it into PLUS system
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());
322  }
323  else //single encoder
324  {
325  // Update transformation matrix of the connected US digital encoder
326  if(it->Motion == 0)
327  {
328  vtkMath::MultiplyScalar(localmovement.GetData(), encoderValue * it->PulseSpacing);
329  tempTransform->Translate(localmovement.GetData());
330  }
331  else if(it->Motion == 1)
332  {
333  // Check the unit of rotation angle .... (degree or radian)
334  tempTransform->RotateWXYZ(encoderValue * it->PulseSpacing, localmovement.GetData());
335  }
336  else
337  {
338  LOG_ERROR("Un-supported motion type");
339  }
340  }
341 
342  vtkMatrix4x4::Multiply4x4(it->ToolToEncoderMatrix, tempTransform->GetMatrix(), it->EncoderToReference);
343  this->TransformRepository->SetTransform(it->TransformName, it->EncoderToReference);
344 
345  vtkPlusDataSource* tool = NULL;
346  if(this->GetToolByPortName(it->PortName.c_str(), tool) != PLUS_SUCCESS)
347  {
348  LOG_ERROR("Unable to find tool with port name: " << it->PortName);
349  }
350 
351  // Device has no frame numbering, so just auto increment tool frame number
352  unsigned long frameNumber = tool->GetFrameNumber() + 1;
353  const double unfilteredTimestamp = vtkIGSIOAccurateTimer::GetSystemTime();
354  this->ToolTimeStampedUpdate(tool->GetId(),
355  it->EncoderToReference, TOOL_OK, frameNumber, unfilteredTimestamp);
356  }
357 
358  return PLUS_SUCCESS;
359 }
360 
361 //----------------------------------------------------------------------------
363 {
364  XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_READING(deviceConfig, rootConfigElement);
365 
366  XML_FIND_NESTED_ELEMENT_REQUIRED(dataSourcesElement, deviceConfig, "DataSources");
367 
368  this->TransformRepository->Clear();
369  this->EncoderMap.clear();
370  this->EncoderList.clear();
371  long deviceID = 0;
372 
373  for(int encoderIndex = 0; encoderIndex < dataSourcesElement->GetNumberOfNestedElements(); encoderIndex++)
374  {
375  vtkXMLDataElement* encoderInfoElement = dataSourcesElement->GetNestedElement(encoderIndex);
376  if(STRCASECMP(encoderInfoElement->GetName(), "DataSource") != 0)
377  {
378  // if this is not a data source element, skip it
379  continue;
380  }
381 
382  vtkPlusUSDigitalEncoderInfo encoderInfo;
383 
384  const char* portName = encoderInfoElement->GetAttribute("PortName");
385  if(portName == NULL)
386  {
387  LOG_ERROR("Tool portname is not specified");
388  continue;
389  }
390 
391  const char* id = encoderInfoElement->GetAttribute("Id");
392  if(id == NULL)
393  {
394  LOG_ERROR("Tool Id is missing!");
395  continue;
396  }
397 
398  vtkPlusDataSource* tool = NULL;
399  if(this->GetToolByPortName(portName, tool) != PLUS_SUCCESS)
400  {
401  LOG_ERROR("GetTool for port " << portName << " failed");
402  continue;
403  }
404  if(tool == NULL)
405  {
406  LOG_ERROR("Tool with ID " << id << " was not found");
407  continue;
408  }
409  encoderInfo.PortName = portName;
410 
411 
412  // ---- Get a name of transformation
413  const char* toAttribute = encoderInfoElement->GetAttribute("ToolReferenceFrame");
414  if(!toAttribute)
415  {
416  toAttribute = deviceConfig->GetAttribute("ToolReferenceFrame");
417  if(!toAttribute)
418  {
419  toAttribute = deviceConfig->GetAttribute("Id");
420  LOG_WARNING("Device's attribute 'ToolReferenceFrame' is missing (Device Id='" << toAttribute << "')!");
421  }
422  }
423 
424  igsioTransformName transformName(id, toAttribute);
425  if(!transformName.IsValid())
426  {
427  LOG_ERROR("Invalid transform name (From: '" << id << "' To: '" << toAttribute << "')");
428  continue;
429  }
430 
431  encoderInfo.TransformName = transformName;
432 
433  if(this->TransformRepository->IsExistingTransform(encoderInfo.TransformName) != PLUS_SUCCESS)
434  {
435  this->TransformRepository->SetTransform(encoderInfo.TransformName,
436  encoderInfo.EncoderToReference);
437  }
438 
439  double vectorMatrix[16] = { 0 };
440  if(encoderInfoElement->GetVectorAttribute("ToolToEncoderMatrix", 16, vectorMatrix))
441  {
442  encoderInfo.ToolToEncoderMatrix->DeepCopy(vectorMatrix);
443  }
444  else
445  {
446  encoderInfo.ToolToEncoderMatrix->Identity();
447  }
448 
449  // Reading the MotionType of an US Digital Encoder
450  std::string motiontype = encoderInfoElement->GetAttribute("MotionType");
451  if(motiontype.empty())
452  {
453  LOG_ERROR("Cannot read the MotionType of an US Digital Encoder");
454  continue;
455  }
456  std::transform(motiontype.begin(), motiontype.end(), motiontype.begin(), ::tolower);
457  LOG_INFO("Motion Type :: " << motiontype);
458  if(motiontype.find("linear") != std::string::npos)
459  {
460  encoderInfo.Motion = 0;
461  }
462  else if(motiontype.find("rotation") != std::string::npos)
463  {
464  encoderInfo.Motion = 1;
465  }
466  else
467  {
468  LOG_ERROR("Motion type of a US Digital Encoder unrecognized!");
469  continue;
470  }
471 
472  // Reading the pulse spacing of an US Digital Encoder
473  // Linear Motion : mm /pulses
474  // Rotation : rad/pulses
475  const char* pulseSpacing = encoderInfoElement->GetAttribute("PulseSpacing");
476  if(pulseSpacing == NULL)
477  {
478  LOG_ERROR("Cannot read the PulseSpacing of an US Digital Encoder");
479  continue;
480  }
481  encoderInfo.PulseSpacing = atof(pulseSpacing);
482 
483  const char* pulseSpacing2 = encoderInfoElement->GetAttribute("PulseSpacing2");
484  this->coreXY = (pulseSpacing2 != NULL);
485  if(this->coreXY)
486  {
487  encoderInfo.PulseSpacing2 = atof(pulseSpacing2);
488  }
489  else
490  {
491  LOG_INFO("PulseSpacing2 not found - this is not a coreXY configuration. Tool Id: " << id);
492  }
493 
494  if(!encoderInfoElement->GetVectorAttribute("LocalAxis", 3, encoderInfo.LocalAxis.GetData()))
495  {
496  LOG_ERROR("Unable to find 'LocalAxis' attribute of an encoder in the configuration file");
497  continue;
498  }
499 
500  if(this->coreXY)
501  {
502  if(!encoderInfoElement->GetVectorAttribute("LocalAxis2", 3, encoderInfo.LocalAxis2.GetData()))
503  {
504  LOG_ERROR("Unable to find 'LocalAxis2' attribute in the configuration file");
505  continue;
506  }
507  }
508 
509  // Reading the mode of a US Digital Encoder
510  const char* mode = encoderInfoElement->GetAttribute("Mode");
511  if(mode == NULL)
512  {
513  LOG_ERROR("Cannot read the Mode of an US Digital Encoder");
514  continue;
515  }
516  encoderInfo.Mode = atol(mode);
517 
518  // Reading the resolution of an US Digital Encoder
519  const char* resolution = encoderInfoElement->GetAttribute("Resolution");
520  if(resolution == NULL)
521  {
522  LOG_ERROR("Cannot read the Resolution of an US Digital Encoder");
523  continue;
524  }
525  encoderInfo.Resolution = atol(resolution);
526 
527  encoderInfo.Addr = deviceID++;
528  if(this->coreXY)
529  {
530  encoderInfo.Addr2 = deviceID++;
531  }
532  EncoderList.push_back(encoderInfo);
533 
534  this->EncoderMap[encoderInfo.Addr] = &EncoderList.back();
535  if(this->coreXY) //enter this encoderInfo twice (once for each deviceID)
536  {
537  this->EncoderMap[encoderInfo.Addr2] = &EncoderList.back();
538  }
539  }
540 
541  return PLUS_SUCCESS;
542 }
543 
544 //----------------------------------------------------------------------------
546 {
547  LOG_WARNING("Writing configuration for USDigitalEncoders is not supported");
548  return PLUS_SUCCESS;
549 }
550 
551 //----------------------------------------------------------------------------
553 {
554  long r = ::IsInitialized();
555  RETURN_WITH_FAIL_IF(r != 1, "Device not yet initialized!");
556  return PLUS_SUCCESS;
557 }
558 
559 //----------------------------------------------------------------------------
561 {
562  RETURN_WITH_FAIL_IF(::A2SetStrobe() != 0, "Failed to set US digital A2 Encoders as Strobe mode.");
563  return PLUS_SUCCESS;
564 }
565 
566 //----------------------------------------------------------------------------
568 {
569  RETURN_WITH_FAIL_IF(::A2SetSleep() != 0, "Failed to set US digital A2 Encoders as Sleep mode.");
570  return PLUS_SUCCESS;
571 }
572 
573 //----------------------------------------------------------------------------
575 {
576  RETURN_WITH_FAIL_IF(::A2SetWakeup() != 0, "Failed to set US digital A2 Encoders as Wakeup mode.");
577  return PLUS_SUCCESS;
578 }
579 
580 //----------------------------------------------------------------------------
582 {
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.");
587  return PLUS_SUCCESS;
588 }
589 
590 //----------------------------------------------------------------------------
592 {
593  EncoderListType::iterator it;
594  for(it = this->EncoderList.begin(); it != this->EncoderList.end(); ++it)
595  {
596  if(::A2SetOrigin(it->Addr) != 0)
597  {
598  return PLUS_FAIL;
599  }
600 
601  if(it->Addr2 != 0) //coreXY
602  {
603  if(::A2SetOrigin(it->Addr2) != 0)
604  {
605  return PLUS_FAIL;
606  }
607  }
608  }
609  return PLUS_SUCCESS;
610 }
611 
612 //----------------------------------------------------------------------------
614 {
615  IDtoAddressType::iterator enc = this->IdAddress.find(id);
616  RETURN_WITH_FAIL_IF(enc == this->IdAddress.end(), "Non-existent device ID: " << id);
617  RETURN_WITH_FAIL_IF(::A2SetMode(enc->second, mode) != 0,
618  "Failed to set the mode of an US digital A2 Encoder.");
619  return PLUS_SUCCESS;
620 }
621 
622 //----------------------------------------------------------------------------
624 {
625  IDtoAddressType::iterator enc = this->IdAddress.find(id);
626  RETURN_WITH_FAIL_IF(enc == this->IdAddress.end(), "Non-existent device ID: " << id);
627  RETURN_WITH_FAIL_IF(::A2GetMode(enc->second, mode) != 0,
628  "Failed to get the mode of an US digital A2 Encoder.");
629  return PLUS_SUCCESS;
630 }
631 
632 //----------------------------------------------------------------------------
634 {
635  IDtoAddressType::iterator enc = this->IdAddress.find(id);
636  RETURN_WITH_FAIL_IF(enc == this->IdAddress.end(), "Non-existent device ID: " << id);
637 
638  RETURN_WITH_FAIL_IF(::A2SetResolution(enc->second, res) != 0,
639  "Failed to set the resoultion of an US digital A2 Encoder.");
640  return PLUS_SUCCESS;
641 }
642 
643 //----------------------------------------------------------------------------
645 {
646  IDtoAddressType::iterator enc = this->IdAddress.find(id);
647  RETURN_WITH_FAIL_IF(enc == this->IdAddress.end(), "Non-existent device ID: " << id);
648 
649  RETURN_WITH_FAIL_IF(::A2GetResolution(enc->second, res) != 0,
650  "Failed to get the resoultion of an US digital A2 Encoder.");
651  return PLUS_SUCCESS;
652 }
653 
654 //----------------------------------------------------------------------------
656 {
657  IDtoAddressType::iterator enc = this->IdAddress.find(id);
658  RETURN_WITH_FAIL_IF(enc == this->IdAddress.end(), "Non-existent device ID: " << id);
659 
660  RETURN_WITH_FAIL_IF(::A2SetPosition(enc->second, pos) != 0,
661  "Failed to set the position of an US digital A2 Encoder.");
662  return PLUS_SUCCESS;
663 }
664 
665 //----------------------------------------------------------------------------
667 {
668  IDtoAddressType::iterator enc = this->IdAddress.find(id);
669  RETURN_WITH_FAIL_IF(enc == this->IdAddress.end(), "Non-existent device ID: " << id);
670 
671  RETURN_WITH_FAIL_IF(::A2GetPosition(enc->second, pos) != 0,
672  "Failed to get the position of an US digital A2 Encoder.");
673  return PLUS_SUCCESS;
674 }
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
bool IsInitialized()
Definition: SEIDrv.cpp:107
Phidget_MeshMode mode
Definition: phidget22.h:1332
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)
void PrintSelf(ostream &os, vtkIndent indent)
long GetDeviceInfo(long devnum, long &serialnum, long &addr, char *model, char *firmwareVersion)
Definition: SEIDrv.cpp:117
double AcquisitionRate
long A2SetWakeup()
Definition: SEIDrv.cpp:174
void CloseSEI()
Definition: SEIDrv.cpp:141
#define PLUS_FAIL
Definition: PlusCommon.h:43
PlusStatus GetUSDigitalA2EncoderResoultionWithID(long id, long *res)
long InitializeSEI(long comm, long mode, int devicesExpected)
Definition: SEIDrv.cpp:67
PlusStatus SetUSDigitalA2EncoderResoultionWithID(long id, long res)
virtual PlusStatus Disconnect()
long A2GetMode(long address, long *mode)
Definition: SEIDrv.cpp:193
long A2SetOrigin(long address)
Definition: SEIDrv.cpp:179
long A2SetSleep()
Definition: SEIDrv.cpp:169
PlusStatus GetUSDigitalA2EncoderPositionWithID(long id, long *pos)
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
PlusStatus GetToolByPortName(const char *aPortName, vtkPlusDataSource *&aSource)
virtual PlusStatus Connect()
long A2SetPosition(long address, long pos)
Definition: SEIDrv.cpp:281
Interface for multiple US Digital A2, A2T, A4, HBA2, HBA4 or HD25A encoders to generate pose informat...
const char * address
Definition: phidget22.h:2552
vtkSmartPointer< vtkIGSIOTransformRepository > TransformRepository
long A2GetPosition(long address, long *pos)
Definition: SEIDrv.cpp:259
virtual PlusStatus StopRecording()
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_READING(deviceConfig, rootConfigElement)
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *config)
bool StartThreadForInternalUpdates
const long AUTOASSIGN
Definition: SEIDrv.h:22
PlusStatus SetUSDigitalA2EncoderPositionWithID(long id, long pos)
long A2SetMode(long address, long mode)
Definition: SEIDrv.cpp:212
vtkStandardNewMacro(vtkPlusUSDigitalEncodersTracker)
long A2SetResolution(long address, long res)
Definition: SEIDrv.cpp:245
long GetNumberOfDevices()
Definition: SEIDrv.cpp:112
const long REINITIALIZE
Definition: SEIDrv.h:27
Phidget_DeviceID * deviceID
Definition: phidget22.h:1313
long A2GetResolution(long address, long *res)
Definition: SEIDrv.cpp:226
PlusStatus SetUSDigitalA2EncoderModeWithID(long id, long mode)
long A2SetStrobe()
Definition: SEIDrv.cpp:158
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *config)
PlusStatus GetUSDigitalA2EncoderModeWithID(long id, long *mode)
const long NORESET
Definition: SEIDrv.h:25
void SetDeviceId(const std::string &id)
Interface to a 3D positioning tool, video source, or generalized data stream.