PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkPlusWitMotionTracker.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 #include "PlusSerialLine.h"
10 #include "vtkPlusDataSource.h"
11 
12 // VTK includes
13 #include <vtkMatrix4x4.h>
14 #include <vtkMath.h>
15 #include <vtkObjectFactory.h>
16 #include <vtkTransform.h>
17 
18 //-------------------------------------------------------------------------
19 
21 
22 //-------------------------------------------------------------------------
23 
24 namespace
25 {
26  const char WIT_IMU_DATA_FRAME = 0x55;
27  const char WIT_ACCELERATION_FRAME = 0x51;
28  const char WIT_VELOCITY_FRAME = 0x52;
29  const char WIT_ORIENTATION_FRAME = 0x53;
30 }
31 
32 //-------------------------------------------------------------------------
34  : Accelerometer(nullptr)
35 {
36 }
37 
38 //-------------------------------------------------------------------------
40 {
41 
42 }
43 
44 //-------------------------------------------------------------------------
46 {
47  if (this->GetToolByPortName("OrientationSensor", this->Accelerometer) != PLUS_SUCCESS)
48  {
49  LOG_ERROR("Unable to locate tool with PortName=\"OrientationSensor\". This is required.");
50  return PLUS_FAIL;
51  }
52 
53  return PLUS_SUCCESS;
54 }
55 
56 //-------------------------------------------------------------------------
57 // Receive Response from WIT-Motion Accelerometer
59 {
60  StreamBufferType::size_type usRxLength;
61 
62  // Continue reading from serial port until we get orientation data
63  while (this->Serial->GetNumberOfBytesAvailableForReading() > 0)
64  {
65  usRxLength = this->Serial->Read(this->StreamData.data(), this->StreamData.size());
66  if (this->StreamData.data()[0] == WIT_IMU_DATA_FRAME && this->StreamData.data()[1] == WIT_ORIENTATION_FRAME)
67  {
68  return PLUS_SUCCESS;
69  }
70  }
71  return PLUS_FAIL;
72 }
73 
74 //-------------------------------------------------------------------------
76 {
77  if (ReceiveData() == PLUS_SUCCESS)
78  {
79  if (this->DecodeData() == PLUS_SUCCESS && this->StreamData.data()[1] == WIT_ORIENTATION_FRAME)
80  {
81  // Only do a transform update if we receive new orientation data
82  vtkNew<vtkTransform> tran;
83  tran->Identity();
84  tran->PostMultiply();
85  tran->RotateX(this->Orientation[0]);
86  tran->RotateY(this->Orientation[1]);
87  tran->RotateZ(this->Orientation[2]);
88 
89  // This device has no frame numbering, so use internal frame counting
90  this->ToolTimeStampedUpdate(this->Accelerometer->GetId(), tran->GetMatrix(), TOOL_OK, this->FrameNumber++, UNDEFINED_TIMESTAMP);
91  }
92  }
93 
94  return PLUS_SUCCESS;
95 }
96 
97 //-------------------------------------------------------------------------
99 {
100  switch (this->StreamData.data()[1])
101  {
102  case WIT_ACCELERATION_FRAME:
103  {
104  this->Acceleration[0] = (short(this->StreamData.data()[3] << 8 | this->StreamData.data()[2])) / 32768.0 * 16;
105  this->Acceleration[1] = (short(this->StreamData.data()[5] << 8 | this->StreamData.data()[4])) / 32768.0 * 16;
106  this->Acceleration[2] = (short(this->StreamData.data()[7] << 8 | this->StreamData.data()[6])) / 32768.0 * 16;
107  this->Acceleration[3] = (short(this->StreamData.data()[9] << 8 | this->StreamData.data()[8])) / 340.0 + 36.25;
108 
109  break;
110  }
111  case WIT_VELOCITY_FRAME:
112  {
113  this->Velocity[0] = (short(this->StreamData.data()[3] << 8 | this->StreamData.data()[2])) / 32768.0 * 2000;
114  this->Velocity[1] = (short(this->StreamData.data()[5] << 8 | this->StreamData.data()[4])) / 32768.0 * 2000;
115  this->Velocity[2] = (short(this->StreamData.data()[7] << 8 | this->StreamData.data()[6])) / 32768.0 * 2000;
116  this->Velocity[3] = (short(this->StreamData.data()[9] << 8 | this->StreamData.data()[8])) / 340.0 + 36.25;
117 
118  break;
119  }
120  case WIT_ORIENTATION_FRAME:
121  {
122  this->Orientation[0] = (short(this->StreamData.data()[3] << 8 | this->StreamData.data()[2])) / 32768.0 * 180;
123  this->Orientation[1] = (short(this->StreamData.data()[5] << 8 | this->StreamData.data()[4])) / 32768.0 * 180;
124  this->Orientation[2] = (short(this->StreamData.data()[7] << 8 | this->StreamData.data()[6])) / 32768.0 * 180;
125  this->Temperature = (short(this->StreamData.data()[9] << 8 | this->StreamData.data()[8])) / 100;
126 
127  break;
128  }
129  }
130 
131  return PLUS_SUCCESS;
132 }
igsioStatus PlusStatus
Definition: PlusCommon.h:40
int Read(BYTE *data, int maxNumberOfBytesToRead)
virtual PlusStatus ToolTimeStampedUpdate(const std::string &aToolSourceId, vtkMatrix4x4 *matrix, ToolStatus status, unsigned long frameNumber, double unfilteredtimestamp, const igsioFieldMapType *customFields=NULL)
std::array< double, 4 > Velocity
virtual PlusStatus InternalUpdate()
std::array< double, 4 > Acceleration
#define PLUS_FAIL
Definition: PlusCommon.h:43
virtual PlusStatus NotifyConfigured()
std::array< double, 4 > Orientation
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
PlusStatus GetToolByPortName(const char *aPortName, vtkPlusDataSource *&aSource)
vtkStandardNewMacro(vtkPlusWitMotionTracker)
vtkPlusDataSource * Accelerometer
Interface for acquiring data from a Microchip MM7150 motion module.
unsigned int GetNumberOfBytesAvailableForReading() const