PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkPlusAscension3DGTrackerBase.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 "PlusConfigure.h"
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 <sstream>
16 
17 static const char QUALITY_PORT_NAME_1[] = "quality1";
18 static const char QUALITY_PORT_NAME_2[] = "quality2";
19 static const char QUALITY_PORT_NAME_3[] = "quality3";
20 
21 static const char PROP_QUALITY_ERROR_SLOPE[] = "QualityErrorSlope";
22 static const char PROP_QUALITY_ERROR_OFFSET[] = "QualityErrorOffset";
23 static const char PROP_QUALITY_ERROR_SENSITIVITY[] = "QualityErrorSensitivity";
24 static const char PROP_QUALITY_FILTER_ALPHA[] = "QualityFilterAlpha";
25 
28 
29 //-------------------------------------------------------------------------
31 {
32  this->AscensionRecordBuffer = NULL;
33 
34  this->TransmitterAttached = false;
35  this->NumberOfSensors = 0;
36  this->FilterAcWideNotch = 0;
37  this->FilterAcNarrowNotch = 0;
38  this->FilterDcAdaptive = 0.0;
39  this->FilterLargeChange = 0;
40  this->FilterAlpha = false;
41  this->Hemisphere = FRONT;
42 
44 
45  // 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
46  this->StartThreadForInternalUpdates = true;
47  this->AcquisitionRate = 50;
48 }
49 
50 //-------------------------------------------------------------------------
52 {
53  if (this->Recording)
54  {
55  this->StopRecording();
56  }
57 
58  if (this->AscensionRecordBuffer != NULL)
59  {
60  delete this->AscensionRecordBuffer;
61  this->AscensionRecordBuffer = NULL;
62  }
63 }
64 
65 //-------------------------------------------------------------------------
66 void vtkPlusAscension3DGTrackerBase::PrintSelf(ostream& os, vtkIndent indent)
67 {
68  Superclass::PrintSelf(os, indent);
69 }
70 
71 //-------------------------------------------------------------------------
73 {
74  LOG_TRACE("vtkAscension3DGTracker::Connect");
75 
76  if (this->Probe() != PLUS_SUCCESS)
77  {
78  LOG_ERROR("Connection probe failed");
79  return PLUS_FAIL;
80  }
81 
82  this->CheckReturnStatus(InitializeBIRDSystem());
83 
84  SYSTEM_CONFIGURATION systemConfig;
85 
86  if (this->CheckReturnStatus(GetBIRDSystemConfiguration(&systemConfig)) != PLUS_SUCCESS)
87  {
88  LOG_ERROR("Connection initialization failed");
89  return PLUS_FAIL;
90  }
91 
92  // Change to metric units.
93  int metric = 1;
94  if (this->CheckReturnStatus(SetSystemParameter(METRIC, &metric, sizeof(metric))) != PLUS_SUCCESS)
95  {
96  LOG_ERROR("Connection set to metric units failed");
97  return PLUS_FAIL;
98  }
99 
100  // Go through all tools.
101 
103 
104  for (int sensorID = 0; sensorID < systemConfig.numberSensors; ++ sensorID)
105  {
106  // Set data format
107  this->CheckReturnStatus(SetSensorParameter(sensorID, DATA_FORMAT, &formatType, sizeof(formatType)));
108 
109  // Set filtering
110  this->CheckReturnStatus(SetSensorParameter(sensorID, FILTER_AC_WIDE_NOTCH, &this->FilterAcWideNotch, sizeof(int)));
111  this->CheckReturnStatus(SetSensorParameter(sensorID, FILTER_AC_NARROW_NOTCH, &this->FilterAcNarrowNotch, sizeof(int)));
112  this->CheckReturnStatus(SetSensorParameter(sensorID, FILTER_DC_ADAPTIVE, &this->FilterDcAdaptive, sizeof(double)));
113  this->CheckReturnStatus(SetSensorParameter(sensorID, FILTER_LARGE_CHANGE, &this->FilterLargeChange, sizeof(int)));
114  this->CheckReturnStatus(SetSensorParameter(sensorID, HEMISPHERE, &this->Hemisphere, sizeof(int)));
115 
116  tagADAPTIVE_PARAMETERS alphaStruct;
117  alphaStruct.alphaMin[0] = alphaStruct.alphaMin[1] = alphaStruct.alphaMin[2] = alphaStruct.alphaMin[3]
118  = alphaStruct.alphaMin[4] = alphaStruct.alphaMin[5] = alphaStruct.alphaMin[6] = 655;
119  alphaStruct.alphaMax[0] = alphaStruct.alphaMax[1] = alphaStruct.alphaMax[2] = alphaStruct.alphaMax[3]
120  = alphaStruct.alphaMax[4] = alphaStruct.alphaMax[5] = alphaStruct.alphaMax[6] = 29491;
121  alphaStruct.vm[0] = 2;
122  alphaStruct.vm[1] = alphaStruct.vm[2] = alphaStruct.vm[3]
123  = alphaStruct.vm[4] = alphaStruct.vm[5] = alphaStruct.vm[6] = 4;
124  alphaStruct.alphaOn = this->FilterAlpha;
125  this->CheckReturnStatus(SetSensorParameter(sensorID, FILTER_ALPHA_PARAMETERS, &alphaStruct, sizeof(alphaStruct)));
126 
127  DEVICE_STATUS status = GetSensorStatus(sensorID);
128 
129  this->SensorSaturated.push_back((status & SATURATED) ? true : false);
130  this->SensorAttached.push_back((status & NOT_ATTACHED) ? false : true);
131  this->SensorInMotion.push_back((status & OUT_OF_MOTIONBOX) ? false : true);
132  this->TransmitterAttached = ((status & NO_TRANSMITTER_ATTACHED) ? false : true);
133 
134  std::ostringstream portName;
135  portName << sensorID;
136  vtkPlusDataSource* tool = NULL;
137  if (this->GetToolByPortName(portName.str().c_str(), tool) != PLUS_SUCCESS)
138  {
139  // No tool is defined for this sensor
140  if (this->SensorAttached[ sensorID ])
141  {
142  LOG_WARNING("A sensor is attached to port '" << portName.str() << "', but no tool is defined for this port. The sensor is disabled it until not defined in the config file: " << vtkPlusConfig::GetInstance()->GetDeviceSetConfigurationFileName());
143  this->SensorAttached[ sensorID ] = false;
144  }
145  continue;
146  }
147  // Tool is defined for this sensor
148  if (tool == NULL)
149  {
150  LOG_ERROR("Invalid tool");
151  continue;
152  }
153 
154  if (!this->SensorAttached[ sensorID ])
155  {
156  // A sensor is expected but not attached. A warning will be logged later.
157  continue;
158  }
159 
160  // Sensor is attached and tool is defined
161 
162  std::string slopeStr = tool->GetCustomProperty(PROP_QUALITY_ERROR_SLOPE);
163  std::string offsetStr = tool->GetCustomProperty(PROP_QUALITY_ERROR_OFFSET);
164  std::string sensitivityStr = tool->GetCustomProperty(PROP_QUALITY_ERROR_SENSITIVITY);
165  std::string alphaStr = tool->GetCustomProperty(PROP_QUALITY_FILTER_ALPHA);
166  if (!slopeStr.empty() || !offsetStr.empty() || !sensitivityStr.empty() || !alphaStr.empty())
167  {
168  // at least one sensitivity parameter is defined
169  tagQUALITY_PARAMETERS qualityStruct;
170  // The slope should have a value between –127 and +127. (Default is 0)
171  // The offset should have a value between –127 and +127. (The default is 0)
172  // The sensitivity should have a value between 0 and +127 (Default is 2)
173  // The alpha should have a value between 0 and 127. (The default is 12)
174  qualityStruct.error_slope = 0;
175  qualityStruct.error_offset = 0;
176  qualityStruct.error_sensitivity = 2;
177  qualityStruct.filter_alpha = 12;
178  if (!slopeStr.empty() && igsioCommon::StringToDouble(slopeStr.c_str(), qualityStruct.error_slope) != PLUS_SUCCESS)
179  {
180  LOG_ERROR("Failed to parse " << PROP_QUALITY_ERROR_SLOPE << " attribute in tool " << tool->GetPortName());
181  }
182  if (!offsetStr.empty() && igsioCommon::StringToDouble(offsetStr.c_str(), qualityStruct.error_offset) != PLUS_SUCCESS)
183  {
184  LOG_ERROR("Failed to parse " << PROP_QUALITY_ERROR_OFFSET << " attribute in tool " << tool->GetPortName());
185  }
186  if (!sensitivityStr.empty() && igsioCommon::StringToDouble(sensitivityStr.c_str(), qualityStruct.error_sensitivity) != PLUS_SUCCESS)
187  {
188  LOG_ERROR("Failed to parse " << PROP_QUALITY_ERROR_SENSITIVITY << " attribute in tool " << tool->GetPortName());
189  }
190  if (!alphaStr.empty() && igsioCommon::StringToDouble(alphaStr.c_str(), qualityStruct.filter_alpha) != PLUS_SUCCESS)
191  {
192  LOG_ERROR("Failed to parse " << PROP_QUALITY_FILTER_ALPHA << " attribute in tool " << tool->GetPortName());
193  }
194  this->CheckReturnStatus(SetSensorParameter(sensorID, QUALITY, &qualityStruct, sizeof(qualityStruct)));
195  }
196 
197  }
198 
199  this->NumberOfSensors = systemConfig.numberSensors;
200 
201  if (this->AscensionRecordBuffer == NULL)
202  {
203  this->AscensionRecordBuffer = new AscensionRecordType[this->NumberOfSensors ];
204  }
205 
206  // Check that all tools were connected that was defined in the configuration file
207  for (DataSourceContainerConstIterator it = this->GetToolIteratorBegin(); it != this->GetToolIteratorEnd(); ++it)
208  {
209  if (IsQualityPortName(it->second->GetPortName()))
210  {
211  // Quality port is a virtual port, no real sensor is associated
212  continue;
213  }
214  std::stringstream convert(it->second->GetPortName());
215  int port(-1);
216  if (!(convert >> port))
217  {
218  LOG_ERROR("Failed to convert tool '" << it->second->GetSourceId() << "' port name '" << it->second->GetPortName() << "' to integer, please check config file: " << vtkPlusConfig::GetInstance()->GetDeviceSetConfigurationFileName());
219  return PLUS_FAIL;
220  }
221 
222  if (!this->SensorAttached[ port ])
223  {
224  LOG_ERROR("Sensor not attached for tool '" << it->second->GetSourceId() << "' on port name '" << it->second->GetPortName() << "', please check config file: " << vtkPlusConfig::GetInstance()->GetDeviceSetConfigurationFileName());
225  }
226  }
227  return PLUS_SUCCESS;
228 }
229 
230 //-------------------------------------------------------------------------
232 {
233  LOG_TRACE("vtkAscension3DGTracker::Disconnect");
234  return this->StopRecording();
235 }
236 
237 //-------------------------------------------------------------------------
239 {
240  LOG_TRACE("vtkAscension3DGTracker::Probe");
241 
242  return PLUS_SUCCESS;
243 }
244 
245 //-------------------------------------------------------------------------
247 {
248  LOG_TRACE("vtkAscension3DGTracker::InternalStartRecording");
249  if (this->Recording)
250  {
251  return PLUS_SUCCESS;
252  }
253 
254  // Turn on the first attached transmitter.
255 
256  BOARD_CONFIGURATION boardConfig;
257  this->CheckReturnStatus(GetBoardConfiguration(0, &boardConfig));
258 
259  short selectID = TRANSMITTER_OFF;
260  int i = 0;
261  bool found = false;
262  while ((i < boardConfig.numberTransmitters) && (found == false))
263  {
264  TRANSMITTER_CONFIGURATION transConfig;
265  this->CheckReturnStatus(GetTransmitterConfiguration(i, &transConfig));
266  if (transConfig.attached)
267  {
268  selectID = i;
269  found = true;
270  }
271  ++ i;
272  }
273 
274  if (this->CheckReturnStatus(SetSystemParameter(SELECT_TRANSMITTER, &selectID, sizeof(selectID))) != PLUS_SUCCESS)
275  {
276  LOG_ERROR("Select transmitter failed");
277  return PLUS_FAIL;
278  }
279 
280  return PLUS_SUCCESS;
281 }
282 
283 //-------------------------------------------------------------------------
285 {
286  LOG_TRACE("vtkAscension3DGTracker::InternalStopRecording");
287 
288  short selectID = vtkPlusAscension3DGTrackerBase::TRANSMITTER_OFF;
289  if (this->CheckReturnStatus(SetSystemParameter(SELECT_TRANSMITTER, &selectID, sizeof(selectID)))
290  != PLUS_SUCCESS)
291  {
292  LOG_ERROR("Select transmitter failed");
293  return PLUS_FAIL;
294  }
295 
296  if (this->CheckReturnStatus(CloseBIRDSystem())
297  != PLUS_SUCCESS)
298  {
299  LOG_ERROR("Unable to close BIRD system");
300  return PLUS_FAIL;
301  }
302 
303  return PLUS_SUCCESS;
304 }
305 
306 //-------------------------------------------------------------------------
308 {
309  LOG_TRACE("vtkAscension3DGTracker::InternalUpdate");
310 
311  if (! this->Recording)
312  {
313  LOG_ERROR("called Update() when not tracking");
314  return PLUS_FAIL;
315  }
316 
317  SYSTEM_CONFIGURATION sysConfig;
318  if (this->CheckReturnStatus(GetBIRDSystemConfiguration(&sysConfig))
319  != PLUS_SUCCESS)
320  {
321  LOG_ERROR("Cannot get system configuration");
322  return PLUS_FAIL;
323  }
324 
325  if (this->GetNumberOfSensors() != sysConfig.numberSensors)
326  {
327  LOG_ERROR("Changing sensors while tracking is not supported. Reconnect necessary.");
328  this->StopRecording();
329  this->Disconnect();
330  return PLUS_FAIL;
331  }
332 
333  AscensionRecordType* record = static_cast<AscensionRecordType*>(this->AscensionRecordBuffer);
334  if (record == NULL)
335  {
336  LOG_ERROR("Ascension record buffer is invalid, reconnect necessary.");
337  return PLUS_FAIL;
338  }
339 
340 #ifdef ATC_READ_ALL_SENSOR_AT_ONCE
341  // Request data for all the sensors at once
342  if (this->CheckReturnStatus(GetAsynchronousRecord(ALL_SENSORS, record, sysConfig.numberSensors * sizeof(AscensionRecordType))) != PLUS_SUCCESS)
343  {
344  LOG_ERROR("Cannot get synchronous record");
345  return PLUS_FAIL;
346  }
347 #else
348  // Request data from each sensor one-by-one. This method works well in some cases (with 3DGm systems?) when the
349  // ALL_SENSORS data request times out.
350  // Scan the sensors and request a record if the sensor is physically attached
351  for (int sensorIndex = 0; sensorIndex < sysConfig.numberSensors; sensorIndex++)
352  {
353  if (this->SensorAttached[sensorIndex])
354  {
355  // sensor attached so get record
356  if (this->CheckReturnStatus(GetAsynchronousRecord(sensorIndex, record + sensorIndex, sizeof(*record))) != PLUS_SUCCESS)
357  {
358  LOG_ERROR("Cannot get synchronous record for sensor " << sensorIndex);
359  return PLUS_FAIL;
360  }
361  }
362  }
363 #endif
364 
365  // Set up reference matrix.
366 
367  bool saturated(false), attached(false), inMotionBox(false);
368  bool transmitterRunning(false), transmitterAttached(false), globalError(false);
369 
370  ToolStatus toolStatus = TOOL_OK;
371  const double unfilteredTimestamp = vtkIGSIOAccurateTimer::GetSystemTime();
372  int numberOfErrors(0);
373  // Vector to store the quality value for each tool
374  std::vector<unsigned short> qualityValues(sysConfig.numberSensors, 0);
375  for (unsigned short sensorIndex = 0; sensorIndex < sysConfig.numberSensors; ++ sensorIndex)
376  {
377  if (!this->SensorAttached[sensorIndex])
378  {
379  // Sensor disabled because it was not defined in the configuration file
380  continue;
381  }
382 
383  DEVICE_STATUS status = GetSensorStatus(sensorIndex);
384  if (status == 0)
385  {
386  toolStatus = TOOL_OK;
387  }
388  else
389  {
390  toolStatus = TOOL_INVALID;
391  if (status & NO_TRANSMITTER_ATTACHED)
392  {
393  LOG_WARNING("Attempting to produce data but no transmitter is attached");
394  }
395  if (status & NO_TRANSMITTER_RUNNING)
396  {
397  LOG_WARNING("Attempting to produce data but the transmitter is not running");
398  }
399  if (status & SATURATED)
400  {
401  LOG_WARNING("Signal is saturated for sensor index " << sensorIndex);
402  }
403  if (status & NOT_ATTACHED)
404  {
405  // Don't log a warning, it may happen frequently and we encode the information in the toolStatus
406  toolStatus = TOOL_MISSING;
407  }
408  else if (status & OUT_OF_MOTIONBOX)
409  {
410  // Don't log a warning, it may happen frequently and we encode the information in the toolStatus
411  toolStatus = TOOL_OUT_OF_VIEW;
412  }
413  }
414 
415  vtkSmartPointer< vtkMatrix4x4 > mToolToTracker = vtkSmartPointer< vtkMatrix4x4 >::New();
416  mToolToTracker->Identity();
417  for (int row = 0; row < 3; ++ row)
418  {
419  for (int col = 0; col < 3; ++ col)
420  {
421  mToolToTracker->SetElement(row, col, record[ sensorIndex ].s[ row ][ col ]);
422  }
423  }
424  qualityValues[sensorIndex] = record[sensorIndex].quality;
425 
426  mToolToTracker->Invert();
427 
428  mToolToTracker->SetElement(0, 3, record[ sensorIndex ].x);
429  mToolToTracker->SetElement(1, 3, record[ sensorIndex ].y);
430  mToolToTracker->SetElement(2, 3, record[ sensorIndex ].z);
431 
432  std::ostringstream toolPortName;
433  toolPortName << sensorIndex;
434 
435  vtkPlusDataSource* tool = NULL;
436  if (this->GetToolByPortName(toolPortName.str().c_str(), tool) != PLUS_SUCCESS)
437  {
438  LOG_ERROR("Unable to find tool on port: " << toolPortName.str());
439  numberOfErrors++;
440  continue;
441  }
442 
443  // Devices has no frame numbering, so just auto increment tool frame number
444  unsigned long frameNumber = tool->GetFrameNumber() + 1 ;
445  this->ToolTimeStampedUpdate(tool->GetSourceId(), mToolToTracker, toolStatus, frameNumber, unfilteredTimestamp);
446  }
447 
448  vtkPlusAscension3DGTrackerBase::QualityToolTimeStampedUpdate(QUALITY_PORT_NAME_1, 0, qualityValues, unfilteredTimestamp);
449  vtkPlusAscension3DGTrackerBase::QualityToolTimeStampedUpdate(QUALITY_PORT_NAME_2, 3, qualityValues, unfilteredTimestamp);
450  vtkPlusAscension3DGTrackerBase::QualityToolTimeStampedUpdate(QUALITY_PORT_NAME_3, 6, qualityValues, unfilteredTimestamp);
451 
452  return (numberOfErrors > 0 ? PLUS_FAIL : PLUS_SUCCESS);
453 }
454 
455 //-------------------------------------------------------------------------
456 PlusStatus vtkPlusAscension3DGTrackerBase::CheckReturnStatus(int status)
457 {
458  if (status != BIRD_ERROR_SUCCESS)
459  {
460  char buffer[ 512 ];
461  GetErrorText(status, buffer, sizeof(buffer), SIMPLE_MESSAGE);
462  LOG_ERROR(buffer);
463  return PLUS_FAIL;
464  }
465  return PLUS_SUCCESS;
466 }
467 
468 //----------------------------------------------------------------------------
470 {
471  XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_READING(deviceConfig, rootConfigElement);
472 
473  XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(int, FilterAcWideNotch, deviceConfig);
474  XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(int, FilterAcNarrowNotch, deviceConfig);
475  XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(double, FilterDcAdaptive, deviceConfig);
476  XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(int, FilterLargeChange, deviceConfig);
477  XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(int, FilterAlpha, deviceConfig);
478  XML_READ_ENUM_ATTRIBUTE_OPTIONAL(Hemisphere, deviceConfig, vtkPlusAscension3DGTrackerBase::GetHemisphereTypeAsString, 0, 6);
479 
480  XML_FIND_NESTED_ELEMENT_REQUIRED(dataSourcesElement, deviceConfig, "DataSources");
481 
482  for (int toolIndex = 0; toolIndex < dataSourcesElement->GetNumberOfNestedElements(); toolIndex++)
483  {
484  vtkXMLDataElement* toolDataElement = dataSourcesElement->GetNestedElement(toolIndex);
485  if (STRCASECMP(toolDataElement->GetName(), "DataSource") != 0)
486  {
487  // if this is not a data source element, skip it
488  continue;
489  }
490 
491  if (toolDataElement->GetAttribute("Type") != NULL && STRCASECMP(toolDataElement->GetAttribute("Type"), "Tool") != 0)
492  {
493  // if this is not a Tool element, skip it
494  continue;
495  }
496 
497  const char* portName = toolDataElement->GetAttribute("PortName");
498  if (portName == NULL)
499  {
500  LOG_ERROR("Cannot set sensor-specific parameters: tool portname is undefined");
501  continue;
502  }
503  vtkPlusDataSource* tool = NULL;
504  if (this->GetToolByPortName(portName, tool) != PLUS_SUCCESS)
505  {
506  LOG_ERROR("Cannot set sensor-specific parameters: tool " << portName << " was not found");
507  continue;
508  }
509  if (tool == NULL)
510  {
511  LOG_ERROR("Cannot set sensor-specific parameters: tool " << portName << " was not found");
512  continue;
513  }
514 
515  const char* paramValue = toolDataElement->GetAttribute(PROP_QUALITY_ERROR_SLOPE);
516  if (paramValue != NULL)
517  {
518  tool->SetCustomProperty(PROP_QUALITY_ERROR_SLOPE, paramValue);
519  }
520 
521  paramValue = toolDataElement->GetAttribute(PROP_QUALITY_ERROR_OFFSET);
522  if (paramValue != NULL)
523  {
524  tool->SetCustomProperty(PROP_QUALITY_ERROR_OFFSET, paramValue);
525  }
526 
527  paramValue = toolDataElement->GetAttribute(PROP_QUALITY_ERROR_SENSITIVITY);
528  if (paramValue != NULL)
529  {
531  }
532 
533  paramValue = toolDataElement->GetAttribute(PROP_QUALITY_FILTER_ALPHA);
534  if (paramValue != NULL)
535  {
536  tool->SetCustomProperty(PROP_QUALITY_FILTER_ALPHA, paramValue);
537  }
538 
539  }
540 
541  return PLUS_SUCCESS;
542 }
543 
544 //----------------------------------------------------------------------------
546 {
547  XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_WRITING(trackerConfig, rootConfigElement);
548 
549  trackerConfig->SetIntAttribute("FilterAcWideNotch", this->GetFilterAcWideNotch());
550  trackerConfig->SetIntAttribute("FilterAcNarrowNotch", this->GetFilterAcNarrowNotch());
551  trackerConfig->SetDoubleAttribute("FilterDcAdaptive", this->GetFilterDcAdaptive());
552  trackerConfig->SetIntAttribute("FilterLargeChange", this->GetFilterLargeChange());
553  trackerConfig->SetIntAttribute("FilterAlpha", (this->GetFilterAlpha() ? 1 : 0));
554  trackerConfig->SetAttribute("Hemisphere", vtkPlusAscension3DGTrackerBase::GetHemisphereTypeAsString(this->GetHemisphere()).c_str());
555 
556  return PLUS_SUCCESS;
557 }
558 
559 //----------------------------------------------------------------------------
560 bool vtkPlusAscension3DGTrackerBase::IsQualityPortName(const char* name)
561 {
562  if (name == NULL)
563  {
564  return false;
565  }
566 
567  return this->IsQualityPortName(std::string(name));
568 }
569 
570 //----------------------------------------------------------------------------
571 bool vtkPlusAscension3DGTrackerBase::IsQualityPortName(const std::string& name)
572 {
573  if (name == QUALITY_PORT_NAME_1 || name == QUALITY_PORT_NAME_2 || name == QUALITY_PORT_NAME_3)
574  {
575  return true;
576  }
577  return false;
578 }
579 
580 //----------------------------------------------------------------------------
581 PlusStatus vtkPlusAscension3DGTrackerBase::QualityToolTimeStampedUpdate(const char* qualityToolPortName, unsigned int sensorStartIndex, const std::vector<unsigned short>& qualityValues, double unfilteredTimestamp)
582 {
583  vtkPlusDataSource* qualityTool = NULL;
584  if (this->GetToolByPortName(qualityToolPortName, qualityTool) != PLUS_SUCCESS)
585  {
586  // the tool is not defined, no need to store the quality values in them
587  return PLUS_SUCCESS;
588  }
589  if (qualityTool == NULL)
590  {
591  LOG_ERROR("Quality tool port name " << qualityToolPortName << " is invalid");
592  return PLUS_FAIL;
593  }
594  vtkSmartPointer< vtkMatrix4x4 > qualityStorageMatrix = vtkSmartPointer< vtkMatrix4x4 >::New();
595  qualityStorageMatrix->SetElement(0, 3, -1);
596  qualityStorageMatrix->SetElement(1, 3, -1);
597  qualityStorageMatrix->SetElement(2, 3, -1);
598  for (unsigned short valueIndex = 0; valueIndex < 3; ++valueIndex)
599  {
600  unsigned int sensorIndex = valueIndex + sensorStartIndex;
601  double qualityValue = -1;
602  if (sensorIndex < qualityValues.size())
603  {
604  qualityValue = qualityValues[sensorIndex];
605  }
606  qualityStorageMatrix->SetElement(valueIndex, 3, qualityValue);
607  }
608 
609  // Devices has no frame numbering, so just auto increment tool frame number
610  unsigned long frameNumber = qualityTool->GetFrameNumber() + 1 ;
611  return this->ToolTimeStampedUpdate(qualityTool->GetSourceId(), qualityStorageMatrix, TOOL_OK, frameNumber, unfilteredTimestamp);
612 }
613 
614 //----------------------------------------------------------------------------
616 {
617  switch (type)
618  {
619  case FRONT: return "FRONT";
620  case BACK: return "BACK";
621  case TOP: return "TOP";
622  case BOTTOM: return "BOTTOM";
623  case LEFT: return "LEFT";
624  case RIGHT: return "RIGHT";
625  default:
626  LOG_ERROR("Unknown hemisphere type: " << type);
627  return "";
628  }
629 }
630 
631 //----------------------------------------------------------------------------
633 {
634  if (typeStr == NULL)
635  {
636  LOG_ERROR("Invalid hemisphere type string");
637  return -1;
638  }
639  for (int i = 0; i < 6; i++)
640  {
641  if (igsioCommon::IsEqualInsensitive(vtkPlusAscension3DGTrackerBase::GetHemisphereTypeAsString(i), typeStr))
642  {
643  return i;
644  }
645  }
646  LOG_ERROR("Unknown hemisphere type string: "<<typeStr);
647  return -1;
648 }
DataSourceContainer::const_iterator DataSourceContainerConstIterator
ATC3DGm_API int GetErrorText(int errorCode, char *pBuffer, int bufferSize, enum MESSAGE_TYPE type)
std::string GetCustomProperty(const std::string &propertyName)
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
USHORT numberTransmitters
Definition: ATC3DGm.h:480
int * attached
Definition: phidget22.h:1289
vtkStandardNewMacro(vtkPlusAscension3DGTrackerBase)
ATC3DGm_API int SetSensorParameter(USHORT sensorID, enum SENSOR_PARAMETER_TYPE parameterType, void *pBuffer, int bufferSize)
Definition: ATC3DGm.h:316
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_WRITING(deviceConfig, rootConfigElement)
ATC3DGm_API int GetBIRDSystemConfiguration(SYSTEM_CONFIGURATION *systemConfiguration)
std::string GetSourceId() const
USHORT alphaMin[7]
Definition: ATC3DGm.h:520
#define ALL_SENSORS
Definition: ATC3DGm.h:425
static const char QUALITY_PORT_NAME_3[]
std::string GetDeviceSetConfigurationFileName()
#define NO_TRANSMITTER_RUNNING
Definition: ATC3DGm.h:211
igsioStatus PlusStatus
Definition: PlusCommon.h:40
static const char QUALITY_PORT_NAME_2[]
virtual PlusStatus ToolTimeStampedUpdate(const std::string &aToolSourceId, vtkMatrix4x4 *matrix, ToolStatus status, unsigned long frameNumber, double unfilteredtimestamp, const igsioFieldMapType *customFields=NULL)
bool RequirePortNameInDeviceSetConfiguration
#define SATURATED
Definition: ATC3DGm.h:205
for i
double AcquisitionRate
#define PLUS_FAIL
Definition: PlusCommon.h:43
ATC3DGm_API int InitializeBIRDSystem(void)
ATC3DGm_API int SetSystemParameter(enum SYSTEM_PARAMETER_TYPE parameterType, void *pBuffer, int bufferSize)
ATC3DGm_API int GetTransmitterConfiguration(USHORT transmitterID, TRANSMITTER_CONFIGURATION *transmitterConfiguration)
int port
Definition: phidget22.h:2454
DOUBLE_POSITION_ANGLES_MATRIX_QUATERNION_TIME_Q_BUTTON_RECORD AscensionRecordType
static vtkPlusConfig * GetInstance()
#define NO_TRANSMITTER_ATTACHED
Definition: ATC3DGm.h:215
Definition: ATC3DGm.h:317
virtual PlusStatus Disconnect()
#define NOT_ATTACHED
Definition: ATC3DGm.h:204
virtual int GetFilterAcNarrowNotch()
static const char QUALITY_PORT_NAME_1[]
void SetCustomProperty(const std::string &propertyName, const std::string &propertyValue)
ATC3DGm_API DEVICE_STATUS GetSensorStatus(USHORT sensorID)
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
PlusStatus GetToolByPortName(const char *aPortName, vtkPlusDataSource *&aSource)
void PrintSelf(ostream &os, vtkIndent indent)
Definition: ATC3DGm.h:315
static const char PROP_QUALITY_FILTER_ALPHA[]
virtual double GetFilterDcAdaptive()
ULONG DEVICE_STATUS
Definition: ATC3DGm.h:447
virtual PlusStatus StopRecording()
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_READING(deviceConfig, rootConfigElement)
Definition: ATC3DGm.h:320
USHORT alphaMax[7]
Definition: ATC3DGm.h:521
int x
Definition: phidget22.h:4265
static int GetHemisphereTypeFromString(const char *typeStr)
ATC3DGm_API int GetAsynchronousRecord(USHORT sensorID, void *pRecord, int recordSize)
bool StartThreadForInternalUpdates
DataSourceContainerConstIterator GetToolIteratorBegin() const
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *config)
Definition: ATC3DGm.h:319
static const char PROP_QUALITY_ERROR_OFFSET[]
#define OUT_OF_MOTIONBOX
Definition: ATC3DGm.h:216
Direction vectors of rods y
Definition: algo3.m:15
Interface for the Ascension 3DG magnetic tracker.
DATA_FORMAT_TYPE
Definition: ATC3DGm.h:329
static std::string GetHemisphereTypeAsString(int type)
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *config)
USHORT error_sensitivity
Definition: ATC3DGm.h:530
DataSourceContainerConstIterator GetToolIteratorEnd() const
static const char PROP_QUALITY_ERROR_SLOPE[]
ATC3DGm_API int GetBoardConfiguration(USHORT boardID, BOARD_CONFIGURATION *boardConfiguration)
static const char PROP_QUALITY_ERROR_SENSITIVITY[]
ATC3DGm_API int CloseBIRDSystem(void)
Interface to a 3D positioning tool, video source, or generalized data stream.