PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkPlusMicrochipTracker.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"
9 
10 #include "PlusSerialLine.h"
11 #include "vtkMatrix4x4.h"
12 #include "vtkMath.h"
13 #include "vtkObjectFactory.h"
14 #include "vtkPlusDataSource.h"
15 
16 //#include <deque>
17 
19 
20 //-------------------------------------------------------------------------
22 {
23  this->OrientationSensorToTracker = vtkMatrix4x4::New();
24  this->OrientationSensorTool = NULL;
25 }
26 
27 //-------------------------------------------------------------------------
29 {
30  this->OrientationSensorToTracker->Delete();
31  this->OrientationSensorToTracker = NULL;
32 }
33 
34 //-------------------------------------------------------------------------
36 {
37  LOG_TRACE("vtkPlusMicrochipTracker::Connect");
39  {
40  return PLUS_FAIL;
41  }
42  this->OrientationSensorTool = NULL;
43  return GetToolByPortName("OrientationSensor", this->OrientationSensorTool);
44 }
45 
46 //-------------------------------------------------------------------------
48 {
49  LOG_TRACE("vtkPlusMicrochipTracker::Disconnect");
51  {
52  return PLUS_FAIL;
53  }
54  this->OrientationSensorTool = NULL;
55  return PLUS_SUCCESS;
56 }
57 
58 //-------------------------------------------------------------------------
60 {
61  // Either update or send commands - but not simultaneously
62  igsioLockGuard<vtkIGSIORecursiveCriticalSection> updateMutexGuardedLock(this->Mutex);
63 
64  std::string textReceived;
65  double unfilteredTimestamp = vtkIGSIOAccurateTimer::GetSystemTime();
66 
67  // Determine the maximum time to spend in the loop (acquisition time period, but maximum 1 sec)
68  double maxReadTimeSec = (this->AcquisitionRate < 1.0) ? 1.0 : 1 / this->AcquisitionRate;
69  double startTime = vtkIGSIOAccurateTimer::GetSystemTime();
70  while (this->Serial->GetNumberOfBytesAvailableForReading() > 0)
71  {
72  unfilteredTimestamp = vtkIGSIOAccurateTimer::GetSystemTime();
73  ReceiveResponse(textReceived);
74  //LOG_DEBUG("Received from serial device: "<<textReceived);
75  if (vtkIGSIOAccurateTimer::GetSystemTime() - startTime > maxReadTimeSec)
76  {
77  // force exit from the loop if continuously receiving data
78  break;
79  }
80  }
81 
82  if (this->OrientationSensorTool != NULL)
83  {
84  // LOG_TRACE("roll="<<this->EulerRoll.GetValue() <<", pitch="<<this->EulerPitch.GetValue() <<", yaw="<<this->EulerYaw.GetValue());
85 
86  double rotationQuat[4] = {1, 0, 0, 0};
87 
88  // The hardware only provides output if the orientation is changed, therefore if no message is received then assume that
89  // the transform has not changed.
90  if (!textReceived.empty() && vtkPlusMicrochipTracker::ParseMessage(textReceived, rotationQuat) == PLUS_SUCCESS)
91  {
92  double rotationMatrix[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
93  vtkMath::QuaternionToMatrix3x3(rotationQuat, rotationMatrix);
94  for (int row = 0; row < 3; row++)
95  {
96  for (int col = 0; col < 3; col++)
97  {
98  this->OrientationSensorToTracker->Element[row][col] = rotationMatrix[row][col];
99  }
100  }
101  }
102 
103  // This device has no frame numbering, so just auto increment tool frame number
104  unsigned long frameNumber = this->OrientationSensorTool->GetFrameNumber() + 1 ;
105  ToolTimeStampedUpdate(this->OrientationSensorTool->GetId(), this->OrientationSensorToTracker, TOOL_OK, frameNumber, unfilteredTimestamp);
106  }
107 
108  return PLUS_SUCCESS;
109 }
110 
111 //-------------------------------------------------------------------------
112 PlusStatus vtkPlusMicrochipTracker::ParseMessage(std::string& textReceived, double* rotationQuat)
113 {
114  // Example message to parse:
115  // X: 0.713 Y:-0.036 Z: 0.008 W: 0.699
116  // VTK quaternion (rotationQuat)is in the form [w, x, y, z].
117  if (textReceived.size() < 35)
118  {
119  LOG_ERROR("Failed to parse message: " << textReceived << " (expected longer message)")
120  return PLUS_FAIL;
121  }
122  rotationQuat[1] = atof(textReceived.substr(2, 6).c_str());
123  rotationQuat[2] = atof(textReceived.substr(11, 6).c_str());
124  rotationQuat[3] = atof(textReceived.substr(20, 6).c_str());
125  rotationQuat[0] = atof(textReceived.substr(29, 6).c_str());
126  return PLUS_SUCCESS;
127 }
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)
double AcquisitionRate
#define PLUS_FAIL
Definition: PlusCommon.h:43
Interface for acquiring data from a Microchip MM7150 motion module.
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
PlusStatus GetToolByPortName(const char *aPortName, vtkPlusDataSource *&aSource)
vtkStandardNewMacro(vtkPlusMicrochipTracker)
unsigned int GetNumberOfBytesAvailableForReading() const
vtkSmartPointer< vtkIGSIORecursiveCriticalSection > Mutex
virtual PlusStatus InternalDisconnect()
virtual PlusStatus ReceiveResponse(std::string &textReceived, ReplyTermination acceptReply=REQUIRE_LINE_ENDING)
PlusStatus ParseMessage(std::string &textReceived, double *rotationQuat)