PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkPlusReadTrackedSignals.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 "vtkObjectFactory.h"
10 #include "vtkTransform.h"
11 #include "vtkMath.h"
12 #include "vtkDoubleArray.h"
13 #include "vtkTable.h"
14 
16 #include "vtkIGSIOTransformRepository.h"
17 #include "vtkIGSIOTrackedFrameList.h"
18 #include "igsioTrackedFrame.h"
19 
20 #include "vtkXMLDataElement.h"
21 #include "vtkXMLUtilities.h"
22 
23 //-----------------------------------------------------------------------------
25 
26 //-----------------------------------------------------------------------------
28 {
30  m_SignalTimeRangeMax = -1.0;
31 
32  this->ObjectMarkerCoordinateFrame = NULL;
33  this->ReferenceCoordinateFrame = NULL;
35 }
36 
37 //-----------------------------------------------------------------------------
39 {
40 }
41 
42 //----------------------------------------------------------------------------
43 void vtkPlusReadTrackedSignals::PrintSelf(ostream& os, vtkIndent indent)
44 {
45  this->Superclass::PrintSelf(os, indent);
46 }
47 
48 //-----------------------------------------------------------------------------
49 void vtkPlusReadTrackedSignals::SetTrackerFrames(vtkIGSIOTrackedFrameList* trackerFrames)
50 {
51  m_TrackerFrames = trackerFrames;
52 }
53 
54 //-----------------------------------------------------------------------------
55 void vtkPlusReadTrackedSignals::SetSignalTimeRange(double rangeMin, double rangeMax)
56 {
57  m_SignalTimeRangeMin = rangeMin;
58  m_SignalTimeRangeMax = rangeMax;
59 }
60 
61 
62 //-----------------------------------------------------------------------------
64 {
65  if (m_TrackerFrames == NULL)
66  {
67  LOG_ERROR("Tracker input data verification failed: no tracker data is set");
68  return PLUS_FAIL;
69  }
70  // Make sure tracker frame list is not empty
71  if (m_TrackerFrames->GetNumberOfTrackedFrames() == 0)
72  {
73  LOG_ERROR("Tracker input data verification failed: tracker data set is empty");
74  return PLUS_FAIL;
75  }
76  return PLUS_SUCCESS;
77 }
78 
79 //-----------------------------------------------------------------------------
81 {
82  vtkSmartPointer<vtkIGSIOTransformRepository> transformRepository = vtkSmartPointer<vtkIGSIOTransformRepository>::New();
83 
84  vtkSmartPointer<vtkMatrix4x4> pivotToReferenceTransform = vtkSmartPointer<vtkMatrix4x4>::New();
85  igsioTransformName transformName(ObjectMarkerCoordinateFrame, ReferenceCoordinateFrame);
86  itk::Point<double, 3> stylusTip;
87  stylusTip[0] = stylusTip[1] = stylusTip[2] = 0.0;
88  itk::Point<double, 3> zeroRef;
89  zeroRef[0] = zeroRef[1] = zeroRef[2] = 0.0;
90 
91  m_SignalTimestamps.clear();
92  m_SignalStylusRef.clear();
93  m_SignalStylusTipRef.clear();
94  m_SignalStylusTipSpeed.clear();
95 
96  // Find the mean tracker position
97  itk::Point<double, 3> trackerPositionSum;
98  trackerPositionSum[0] = trackerPositionSum[1] = trackerPositionSum[2] = 0.0;
99 
100  std::deque< itk::Point<double, 3> > trackerPositions;
101  int numberOfValidFrames = 0;
102  bool signalTimeRangeDefined = (m_SignalTimeRangeMin <= m_SignalTimeRangeMax);
103  double previousStylusTipPosition = 0.0;
104  for (unsigned int frame = 0; frame < m_TrackerFrames->GetNumberOfTrackedFrames(); ++frame)
105  {
106  igsioTrackedFrame* trackedFrame = m_TrackerFrames->GetTrackedFrame(frame);
107 
108  if (signalTimeRangeDefined && (trackedFrame->GetTimestamp() < m_SignalTimeRangeMin || trackedFrame->GetTimestamp() > m_SignalTimeRangeMax))
109  {
110  // frame is out of the specified signal range
111  continue;
112  }
113 
114  transformRepository->SetTransforms(*trackedFrame);
115 
116  vtkSmartPointer<vtkMatrix4x4> probeToReferenceTransform = vtkSmartPointer<vtkMatrix4x4>::New();
117  ToolStatus toolStatus(TOOL_INVALID);
118  transformRepository->GetTransform(transformName, probeToReferenceTransform, &toolStatus);
119  if (toolStatus != TOOL_OK)
120  {
121  // There is no available transform for this frame; skip that frame
122  LOG_INFO("There is no available transform for this frame; skip frame " << trackedFrame->GetTimestamp() << " [s]")
123  continue;
124  }
125 
126  // Store current tracker position
127  itk::Point<double, 3> currTrackerPosition;
128  currTrackerPosition[0] = probeToReferenceTransform->GetElement(0, 3);
129  currTrackerPosition[1] = probeToReferenceTransform->GetElement(1, 3);
130  currTrackerPosition[2] = probeToReferenceTransform->GetElement(2, 3);
131  trackerPositions.push_back(currTrackerPosition);
132 
133  // Add current tracker position to the running total
134  trackerPositionSum[0] = trackerPositionSum[0] + probeToReferenceTransform->GetElement(0, 3);
135  trackerPositionSum[1] = trackerPositionSum[1] + probeToReferenceTransform->GetElement(1, 3);
136  trackerPositionSum[2] = trackerPositionSum[2] + probeToReferenceTransform->GetElement(2, 3);
137  ++numberOfValidFrames;
138 
139  m_SignalTimestamps.push_back(trackedFrame->GetTimestamp()); // These timestamps will be in the desired time range
140  m_SignalStylusRef.push_back(currTrackerPosition.EuclideanDistanceTo(zeroRef));
141 
142  vtkMatrix4x4::Multiply4x4(probeToReferenceTransform, this->StylusTipToStylusTransform, pivotToReferenceTransform);
143  stylusTip[0] = pivotToReferenceTransform->GetElement(0, 3);
144  stylusTip[1] = pivotToReferenceTransform->GetElement(1, 3);
145  stylusTip[2] = pivotToReferenceTransform->GetElement(2, 3);
146 
147  m_SignalStylusTipRef.push_back(stylusTip.EuclideanDistanceTo(zeroRef));
148  m_SignalStylusTipSpeed.push_back(stylusTip.EuclideanDistanceTo(zeroRef) - previousStylusTipPosition);
149  previousStylusTipPosition = stylusTip.EuclideanDistanceTo(zeroRef);
150  }
151 
152  return PLUS_SUCCESS;
153 }
154 
155 //-----------------------------------------------------------------------------
157 {
158  XML_FIND_NESTED_ELEMENT_REQUIRED(pivotCalibrationElement, aConfig, "vtkPlusPivotCalibrationAlgo");
159  XML_READ_CSTRING_ATTRIBUTE_REQUIRED(ObjectMarkerCoordinateFrame, pivotCalibrationElement);
160  XML_READ_CSTRING_ATTRIBUTE_REQUIRED(ReferenceCoordinateFrame, pivotCalibrationElement);
161  XML_READ_CSTRING_ATTRIBUTE_REQUIRED(ObjectPivotPointCoordinateFrame, pivotCalibrationElement);
162 
163  vtkSmartPointer<vtkIGSIOTransformRepository> transformRepositoryCalibration = vtkSmartPointer<vtkIGSIOTransformRepository>::New();
164 
165  if (transformRepositoryCalibration->ReadConfiguration(aConfig) != PLUS_SUCCESS)
166  {
167  LOG_ERROR("Failed to read CoordinateDefinitions!");
168  exit(EXIT_FAILURE);
169  }
170 
171  igsioTransformName StylusTipToStylusTransformName(ObjectPivotPointCoordinateFrame, ObjectMarkerCoordinateFrame);
172  this->StylusTipToStylusTransform = vtkSmartPointer<vtkMatrix4x4>::New();
173  if (transformRepositoryCalibration->GetTransform(StylusTipToStylusTransformName, this->StylusTipToStylusTransform) != PLUS_SUCCESS)
174  {
175  LOG_ERROR("Failed to read StylusTipToStylu Coordinate Definition!");
176  exit(EXIT_FAILURE);
177  }
178 
179  return PLUS_SUCCESS;
180 }
181 
182 //-----------------------------------------------------------------------------
184 {
186  {
187  return PLUS_FAIL;
188  }
190  {
191  return PLUS_FAIL;
192  }
193  return PLUS_SUCCESS;
194 }
195 
196 //-----------------------------------------------------------------------------
197 void vtkPlusReadTrackedSignals::GetTimestamps(std::deque<double>& timestamps)
198 {
199  timestamps = m_SignalTimestamps;
200 }
201 
202 //-----------------------------------------------------------------------------
203 void vtkPlusReadTrackedSignals::GetSignalStylusRef(std::deque<double>& signalComponent)
204 {
205  signalComponent = m_SignalStylusRef;
206 }
207 //-----------------------------------------------------------------------------
208 void vtkPlusReadTrackedSignals::GetSignalStylusTipRef(std::deque<double>& signalComponent)
209 {
210  signalComponent = m_SignalStylusTipRef;
211 }
212 //-----------------------------------------------------------------------------
213 void vtkPlusReadTrackedSignals::GetSignalStylusTipSpeed(std::deque<double>& signalComponent)
214 {
215  signalComponent = m_SignalStylusTipSpeed;
216 }
std::deque< double > m_SignalStylusRef
std::deque< double > m_SignalStylusTipSpeed
igsioStatus PlusStatus
Definition: PlusCommon.h:40
#define PLUS_FAIL
Definition: PlusCommon.h:43
PlusStatus ReadConfiguration(vtkXMLDataElement *aConfig)
vtkStandardNewMacro(vtkPlusReadTrackedSignals)
vtkSmartPointer< vtkMatrix4x4 > StylusTipToStylusTransform
vtkIGSIOTrackedFrameList * m_TrackerFrames
void SetTrackerFrames(vtkIGSIOTrackedFrameList *trackerFrames)
void GetTimestamps(std::deque< double > &timestamps)
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
std::deque< double > m_SignalTimestamps
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
Extract the motion component along the the principal axis of the motion. Used for computing a positio...
std::deque< double > m_SignalStylusTipRef
void GetSignalStylusRef(std::deque< double > &signalComponent)
void GetSignalStylusTipSpeed(std::deque< double > &signalComponent)
void GetSignalStylusTipRef(std::deque< double > &signalComponent)
void SetSignalTimeRange(double rangeMin, double rangeMax)