PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkDataCollectorFileTest.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 
12 #include "PlusConfigure.h"
13 #include "igsioTrackedFrame.h"
14 #include "vtkPlusDataCollector.h"
15 #include "vtkMatrix4x4.h"
16 #include "vtkPlusChannel.h"
17 #include "vtkPlusDataSource.h"
18 #include "vtkSmartPointer.h"
19 #include "vtkIGSIOTransformRepository.h"
20 #include "vtkXMLUtilities.h"
21 #include "vtksys/CommandLineArguments.hxx"
22 
23 static const int COMPARE_TRANSFORM_TOLERANCE = 0.001;
24 
25 PlusStatus CompareTransform(igsioTransformName& transformName, vtkIGSIOTransformRepository* transformRepository, double xExpected, double yExpected, double zExpected)
26 {
27  vtkSmartPointer<vtkMatrix4x4> transformMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
28  ToolStatus toolStatus(TOOL_INVALID);
29  if (transformRepository->GetTransform(transformName, transformMatrix, &toolStatus) != PLUS_SUCCESS || toolStatus != TOOL_OK)
30  {
31  std::string transformNameStr;
32  transformName.GetTransformName(transformNameStr);
33  LOG_ERROR("Unable to get transform " << transformNameStr);
34  return PLUS_FAIL;
35  }
36  PlusStatus status = PLUS_SUCCESS;
37  std::string transformNameStr;
38  transformName.GetTransformName(transformNameStr);
39  double actualValue = transformMatrix ->GetElement(0, 3);
40  if (fabs(actualValue - xExpected) > COMPARE_TRANSFORM_TOLERANCE)
41  {
42  LOG_ERROR("Transform " << transformNameStr << " x translation does not match (actual=" << actualValue << ", expected=" << xExpected << ")");
43  status = PLUS_FAIL;
44  }
45  actualValue = transformMatrix ->GetElement(1, 3);
46  if (fabs(actualValue - yExpected) > COMPARE_TRANSFORM_TOLERANCE)
47  {
48  LOG_ERROR("Transform " << transformNameStr << " y translation does not match (actual=" << actualValue << ", expected=" << yExpected << ")");
49  status = PLUS_FAIL;
50  }
51  actualValue = transformMatrix ->GetElement(2, 3);
52  if (fabs(actualValue - zExpected) > COMPARE_TRANSFORM_TOLERANCE)
53  {
54  LOG_ERROR("Transform " << transformNameStr << " z translation does not match (actual=" << actualValue << ", expected=" << zExpected << ")");
55  status = PLUS_FAIL;
56  }
57  return status;
58 }
59 
60 int main(int argc, char** argv)
61 {
62 
63  // Check command line arguments.
64  std::string inputConfigFileName;
65  int verboseLevel = vtkPlusLogger::LOG_LEVEL_UNDEFINED;
66 
67  vtksys::CommandLineArguments args;
68  args.Initialize(argc, argv);
69 
70  args.AddArgument("--config-file", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputConfigFileName, "Name of the input configuration file.");
71  args.AddArgument("--verbose", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &verboseLevel, "Verbose level (1=error only, 2=warning, 3=info, 4=debug 5=trace)");
72 
73  if (! args.Parse())
74  {
75  std::cerr << "Problem parsing arguments." << std::endl;
76  std::cout << "Help: " << args.GetHelp() << std::endl;
77  return 1;
78  }
79 
80  vtkPlusLogger::Instance()->SetLogLevel(verboseLevel);
81 
82  // Prepare and start data collection
83  vtkSmartPointer<vtkXMLDataElement> configRootElement = vtkSmartPointer<vtkXMLDataElement>::New();
84  if (PlusXmlUtils::ReadDeviceSetConfigurationFromFile(configRootElement, inputConfigFileName.c_str()) == PLUS_FAIL)
85  {
86  LOG_ERROR("Unable to read configuration from file " << inputConfigFileName.c_str());
87  return EXIT_FAILURE;
88  }
89 
91 
92  vtkSmartPointer<vtkPlusDataCollector> dataCollector = vtkSmartPointer<vtkPlusDataCollector>::New();
93 
94  if (dataCollector->ReadConfiguration(configRootElement) != PLUS_SUCCESS)
95  {
96  LOG_ERROR("Reading configuration file failed " << inputConfigFileName);
97  exit(EXIT_FAILURE);
98  }
99 
100  LOG_DEBUG("Initializing data collector... ");
101  dataCollector->Connect();
102  dataCollector->Start();
103 
104  if (!dataCollector->GetConnected())
105  {
106  LOG_ERROR("Unable to start data collection!");
107  return 1;
108  }
109 
110  // Create the used objects
111  igsioTrackedFrame trackedFrame;
112 
113  igsioTransformName referenceToTrackerTransformName("Reference", "Tracker");
114  igsioTransformName probeToTrackerTransformName("Probe", "Tracker");
115  igsioTransformName stylusToTrackerTransformName("Stylus", "Tracker");
116 
117  vtkSmartPointer<vtkIGSIOTransformRepository> transformRepository = vtkSmartPointer<vtkIGSIOTransformRepository>::New();
118 
119  PlusStatus compareStatus = PLUS_SUCCESS;
120 
121  vtkIGSIOAccurateTimer::Delay(5.0); // wait for 5s until the frames are acquired into the buffer
122 
123  // Check some transforms to ensure that the correct data is returned by the data collector
124  // THIS TEST ONLY WORKS WITH THIS SEQUENCE METAFILE: PlusLib\data\TestImages\fCal_Test_Calibration.mha
125 
126  // Replay starts with the first frame, acquired at SystemTime=0, therefore there is an offset between
127  // the timestamps in the file and the acquisition timestamp. The offset is the timestamp of the first frame in the file.
128  vtkPlusDevice* aDevice(NULL);
129  vtkPlusChannel* aChannel(NULL);
130  if (dataCollector->GetDevice(aDevice, "TrackedVideoDevice") != PLUS_SUCCESS)
131  {
132  LOG_ERROR("Unable to locate device \'TrackedVideoDevice\'");
133  exit(EXIT_FAILURE);
134  }
135  if (aDevice->GetOutputChannelByName(aChannel, "TrackedVideoStream") != PLUS_SUCCESS)
136  {
137  LOG_ERROR("Unable to locate channel \'TrackedVideoStream\'");
138  exit(EXIT_FAILURE);
139  }
140  vtkPlusDataSource* aSource = NULL;
141  aChannel->GetVideoSource(aSource);
142  double recordingStartTime = aSource->GetStartTime();
143  double timestampOfFirstFrameInFile = 2572.905343;
144  double timeOffset = timestampOfFirstFrameInFile - recordingStartTime;
145 
146  // Frame 0001
147  aChannel->GetTrackedFrame(2572.983529 - timeOffset, trackedFrame);
148  transformRepository->SetTransforms(trackedFrame);
149 
150  if (CompareTransform(referenceToTrackerTransformName, transformRepository, 338.415, -68.1145, -24.7944) != PLUS_SUCCESS)
151  {
152  LOG_ERROR("Test failed on frame 1");
153  compareStatus = PLUS_FAIL;
154  }
155  if (CompareTransform(probeToTrackerTransformName, transformRepository, 284.39, -37.1955, -13.1199) != PLUS_SUCCESS)
156  {
157  LOG_ERROR("Test failed on frame 1");
158  compareStatus = PLUS_FAIL;
159  }
160 
161  vtkSmartPointer<vtkMatrix4x4> stylusToTrackerTransformMatrix = vtkSmartPointer<vtkMatrix4x4>::New();
162  ToolStatus toolStatus(TOOL_INVALID);
163  if (transformRepository->GetTransform(stylusToTrackerTransformName, stylusToTrackerTransformMatrix, &toolStatus) != PLUS_SUCCESS)
164  {
165  std::string transformNameStr;
166  stylusToTrackerTransformName.GetTransformName(transformNameStr);
167  LOG_ERROR("Test failed on frame 1: unable to get transform " << transformNameStr);
168  }
169  if (toolStatus != TOOL_OK)
170  {
171  std::string transformNameStr;
172  stylusToTrackerTransformName.GetTransformName(transformNameStr);
173  LOG_ERROR("Test failed on frame 1: Invalid transform received, while valid transform was expected for " << transformNameStr);
174  }
175 
176  // Frame 0013
177  aChannel->GetTrackedFrame(2573.921586 - timeOffset, trackedFrame);
178  transformRepository->SetTransforms(trackedFrame);
179 
180  if (CompareTransform(referenceToTrackerTransformName, transformRepository, 338.658, -68.523, -24.9476) != PLUS_SUCCESS)
181  {
182  LOG_ERROR("Test failed on frame 13");
183  compareStatus = PLUS_FAIL;
184  }
185  if (CompareTransform(probeToTrackerTransformName, transformRepository, 284.863, -34.9189, -13.0288) != PLUS_SUCCESS)
186  {
187  LOG_ERROR("Test failed on frame 13");
188  compareStatus = PLUS_FAIL;
189  }
190  toolStatus = TOOL_INVALID;
191  if (transformRepository->GetTransform(stylusToTrackerTransformName, stylusToTrackerTransformMatrix, &toolStatus) != PLUS_SUCCESS)
192  {
193  std::string transformNameStr;
194  stylusToTrackerTransformName.GetTransformName(transformNameStr);
195  LOG_ERROR("Test failed on frame 13: unable to get transform " << transformNameStr);
196  }
197  if (toolStatus != TOOL_OK)
198  {
199  std::string transformNameStr;
200  stylusToTrackerTransformName.GetTransformName(transformNameStr);
201  LOG_ERROR("Test failed on frame 13: Invalid transform received, while valid transform was expected for " << transformNameStr);
202  }
203 
204  dataCollector->Stop();
205  dataCollector->Disconnect();
206 
207  if (compareStatus != PLUS_SUCCESS)
208  {
209  return 1;
210  }
211  return 0;
212 }
static const int COMPARE_TRANSFORM_TOLERANCE
Abstract interface for tracker and video devices.
Definition: vtkPlusDevice.h:60
virtual PlusStatus GetTrackedFrame(double timestamp, igsioTrackedFrame &trackedFrame, bool enableImageData=true)
igsioStatus PlusStatus
Definition: PlusCommon.h:40
#define PLUS_FAIL
Definition: PlusCommon.h:43
static vtkPlusConfig * GetInstance()
PlusStatus GetOutputChannelByName(vtkPlusChannel *&aChannel, const char *aChannelId)
int main(int argc, char **argv)
virtual double GetStartTime()
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
PlusStatus CompareTransform(igsioTransformName &transformName, vtkIGSIOTransformRepository *transformRepository, double xExpected, double yExpected, double zExpected)
static vtkIGSIOLogger * Instance()
Contains an optional timestamped circular buffer containing the video images and a number of timestam...
PlusStatus GetVideoSource(vtkPlusDataSource *&aVideoSource) const
void SetDeviceSetConfigurationData(vtkXMLDataElement *deviceSetConfigurationData)
static PlusStatus ReadDeviceSetConfigurationFromFile(vtkXMLDataElement *config, const char *filename)
Definition: PlusXmlUtils.h:23
Interface to a 3D positioning tool, video source, or generalized data stream.