PlusLib  2.9.0
Software library for tracked ultrasound image acquisition, calibration, and processing.
vtkPlusOptimetConoProbeMeasurer.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 "PlusMath.h"
11 
12 #include "vtkMath.h"
13 #include "vtkMatrix4x4.h"
14 #include "vtkMultiThreader.h"
15 #include "vtkObjectFactory.h"
16 #include "vtkPlusDataSource.h"
17 #include "vtkTransform.h"
18 #include "vtkXMLDataElement.h"
19 #include "vtksys/SystemTools.hxx"
20 
21 #include <math.h>
22 #include <sstream>
23 #include <stdio.h>
24 #include <conio.h>
25 #include <stdlib.h>
26 
27 #include <Smart32Interface.h>
28 
30 
31 //-----------------------------------------------------------------------
33 {
34  this->MeasurementTool = NULL;
36  this->AcquisitionRate = 100;
37 
38  // ConoProbe specific
39  this->ConoProbe = NULL;
40  this->LensOriginAlignment[0] = 1.0;
41  this->LensOriginAlignment[1] = 1.0;
42  this->LensOriginAlignment[2] = 1.0;
43  this->LensOriginAlignment[3] = 1.0;
44  this->LensOriginAlignment[4] = 1.0;
45  this->LensOriginAlignment[5] = 1.0;
46  this->DelayBetweenMeasurements = 1;
47  this->Frequency= 100;
48  this->CoarseLaserPower = 13;
49  this->FineLaserPower = 0;
50  this->ProbeDialogOpen = false;
51  this->LaserPower = 0;
52 
53  // Thread
54  this->Thread = vtkMultiThreader::New();
55  this->ThreadID = -1;
56 
58 }
59 
60 //-------------------------------------------------------------------------
62 {
63  this->Stop();
64  if (this->Thread)
65  {
66  this->Thread->Delete();
67  }
68 
69  this->MeasurementTool = NULL;
70  if (this->ConoProbe)
71  {
72  ISmart::Destroy(this->ConoProbe);
73  this->ConoProbe = NULL;
74  }
75 }
76 
77 //-------------------------------------------------------------------------
78 void vtkPlusOptimetConoProbeMeasurer::PrintSelf( ostream& os, vtkIndent indent )
79 {
80  Superclass::PrintSelf( os, indent );
81 }
82 
83 //-------------------------------------------------------------------------
85 {
86  LOG_TRACE( "vtkPlusOptimetConoProbeMeasurer::Connect" );
87 
88  this->ConoProbe = ISmart::Create();
89  try
90  {
91  // Initialize the probe with IP 1.2.3.4 and LAN IP 1.2.3.9
92  this->ConoProbe->Init(0x01020304, 0x01020309, 10000);
93  }
94  catch (const SmartException& e)
95  {
96  LOG_ERROR(e.ErrorString());
97  return PLUS_FAIL;
98  }
99 
100  try
101  {
102  // Set acquisition parameters
103  this->ConoProbe->SetAcquisitionParams(AcquisitionMode::TimeAcquisitionMode, this->Frequency, this->CalculateCompositeLaserPower(this->CoarseLaserPower, this->FineLaserPower), this->DelayBetweenMeasurements);
104  this->SetLaserPower(this->CalculateCompositeLaserPower(this->CoarseLaserPower, this->FineLaserPower));
105  }
106  catch (const SmartException& e)
107  {
108  LOG_ERROR(e.ErrorString());
109  return PLUS_FAIL;
110  }
111 
112  this->MeasurementTool = NULL;
113  GetToolByPortName("Measurement", this->MeasurementTool);
114 
115  LOG_DEBUG("Successfully connected to ConoProbe device");
116  return PLUS_SUCCESS;
117 }
118 
119 //-------------------------------------------------------------------------
121 {
122  LOG_TRACE( "vtkPlusOptimetConoProbeMeasurer::InternalDisconnect" );
123  this->MeasurementTool = NULL;
124  if (this->ConoProbe)
125  {
126  ISmart::Destroy(this->ConoProbe);
127  this->ConoProbe = NULL;
128  }
129  return PLUS_SUCCESS;
130 }
131 
132 //-------------------------------------------------------------------------
134 {
135  LOG_TRACE( "vtkPlusOptimetConoProbeMeasurer::InternalUpdate" );
136 
137  if (this->MeasurementTool != NULL)
138  {
139  vtkSmartPointer<vtkTransform> measurementToMeasurerTransform = vtkSmartPointer<vtkTransform>::New();
140  vtkSmartPointer<vtkTransform> parametersToMeasurerTransform = vtkSmartPointer<vtkTransform>::New();
141 
142  if (!this->ProbeDialogOpen)
143  {
144  Measurement measurement;
145  try
146  {
147  // Get ConoProbe measurement and write to MeasurementToMeasurerTransform
148  measurement = this->ConoProbe->GetSingleMeasurement();
149  }
150  catch (const SmartException& e)
151  {
152  LOG_ERROR(e.ErrorString());
153  return PLUS_FAIL;
154  }
155  catch (const SmartExceptionBadResponse& e)
156  {
157  LOG_WARNING(e.MessageType());
158  }
159 
160  // Get distance (mm), Snr (%), Total, and set correct lens origin parameters
161  double d = measurement.Distance;
162  double snr = measurement.Snr / 10;
163  double total = measurement.Total;
164  double dx = this->LensOriginAlignment[0];
165  double dy = this->LensOriginAlignment[1];
166  double dz = this->LensOriginAlignment[2];
167  double lx = this->LensOriginAlignment[3];
168  double ly = this->LensOriginAlignment[4];
169  double lz = this->LensOriginAlignment[5];
170 
171  // Create transforms
172  measurementToMeasurerTransform->Translate(dx * d + lx, dy * d + ly, dz * d + lz);
173  double params[16]{ d, snr, total, 0.0,
174  this->Frequency, this->LaserPower, 0.0, 0.0,
175  0.0, 0.0, 0.0, 0.0,
176  0.0, 0.0, 0.0, 0.0, };
177  parametersToMeasurerTransform->SetMatrix(params);
178  }
179  else
180  {
181  measurementToMeasurerTransform->Identity();
182  parametersToMeasurerTransform->Identity();
183  }
184 
185  // Create frame number and time stamp
186  unsigned long frameNumber = this->MeasurementTool->GetFrameNumber() + 1 ;
187  const double unfilteredTimestamp = vtkIGSIOAccurateTimer::GetSystemTime();
188 
189  // Send transforms
190  igsioTransformName name("Measurement", this->GetToolReferenceFrameName());
191  this->ToolTimeStampedUpdate(name.GetTransformName().c_str(), measurementToMeasurerTransform->GetMatrix(), ToolStatus::TOOL_OK, frameNumber, unfilteredTimestamp);
192  igsioTransformName parameters("Parameters", this->GetToolReferenceFrameName());
193  this->ToolTimeStampedUpdate(parameters.GetTransformName().c_str(), parametersToMeasurerTransform->GetMatrix(), ToolStatus::TOOL_OK, frameNumber, unfilteredTimestamp);
194  }
195 
196  return PLUS_SUCCESS;
197 }
198 
199 //----------------------------------------------------------------------------
201 {
202  XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_READING(deviceConfig, rootConfigElement);
203 
204  double lensOriginAlignment[6];
205  if (deviceConfig->GetVectorAttribute("LensOriginAlignment", 6, lensOriginAlignment))
206  {
207  {
208  this->LensOriginAlignment[0] = lensOriginAlignment[0];
209  this->LensOriginAlignment[1] = lensOriginAlignment[1];
210  this->LensOriginAlignment[2] = lensOriginAlignment[2];
211  this->LensOriginAlignment[3] = lensOriginAlignment[3];
212  this->LensOriginAlignment[4] = lensOriginAlignment[4];
213  this->LensOriginAlignment[5] = lensOriginAlignment[5];
214  }
215  }
216 
217  int delayBetweenMeasurements = 0;
218  if ( deviceConfig->GetScalarAttribute("DelayBetweenMeasurements", delayBetweenMeasurements ) )
219  {
220  {
221  this->DelayBetweenMeasurements = static_cast<unsigned short>(delayBetweenMeasurements);
222  }
223  }
224 
225  int frequency = 0;
226  if ( deviceConfig->GetScalarAttribute("Frequency", frequency ) )
227  {
228  {
229  this->Frequency = static_cast<unsigned short>(frequency);
230  }
231  }
232 
233  int coarseLaserPower = 0;
234  if ( deviceConfig->GetScalarAttribute("CoarseLaserPower", coarseLaserPower ) )
235  {
236  {
237  this->CoarseLaserPower = static_cast<unsigned short>(coarseLaserPower);
238  }
239  }
240 
241  int fineLaserPower = 0;
242  if ( deviceConfig->GetScalarAttribute("FineLaserPower", fineLaserPower ) )
243  {
244  {
245  this->FineLaserPower = static_cast<unsigned short>(fineLaserPower);
246  }
247  }
248 
249  return PLUS_SUCCESS;
250 }
251 
252 //----------------------------------------------------------------------------
254 {
255  XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_WRITING(deviceConfig, rootConfigElement);
256 
257  deviceConfig->SetIntAttribute("DelayBetweenMeasurements", static_cast<unsigned int>(this->DelayBetweenMeasurements));
258  deviceConfig->SetIntAttribute("Frequency", static_cast<unsigned int>(this->Frequency));
259  deviceConfig->SetIntAttribute("CoarseLaserPower", static_cast<unsigned int>(this->CoarseLaserPower));
260  deviceConfig->SetIntAttribute("FineLaserPower", static_cast<unsigned int>(this->FineLaserPower));
261 
262  return PLUS_SUCCESS;
263 }
264 
265 //---------------------------------------------------------------------------
267 {
268  if (this->ThreadID == 0)
269  {
270  return PLUS_FAIL;
271  }
272  this->ProbeDialogOpen = true;
273  this->ThreadID = 0;
274  this->Thread->SpawnThread((vtkThreadFunctionType)&vtkPlusOptimetConoProbeMeasurer::ProbeDialogThread, this);
275 
276  return PLUS_SUCCESS;
277 }
278 
279 //---------------------------------------------------------------------------
281 {
282  if (this->ThreadID == 0)
283  {
284  this->ThreadID = -1;
285  this->ProbeDialogOpen = false;
286  this->Thread->TerminateThread(0);
287 
288  return PLUS_SUCCESS;
289  }
290  else
291  {
292  return PLUS_FAIL;
293  }
294 }
295 
296 //----------------------------------------------------------------------------
297 void* vtkPlusOptimetConoProbeMeasurer::ProbeDialogThread(void* ptr)
298 {
299  vtkMultiThreader::ThreadInfo* vinfo = static_cast<vtkMultiThreader::ThreadInfo*>(ptr);
300  vtkPlusOptimetConoProbeMeasurer* logic = reinterpret_cast<vtkPlusOptimetConoProbeMeasurer*>(vinfo->UserData);
301 
302  ProbeDialogParams p;
303  ProbeDialogResult r;
304 
305  ZeroMemory(&p, sizeof (ProbeDialogParams));
306  ZeroMemory(&r, sizeof (ProbeDialogResult));
307 
308  p.DlgProc = NULL;
309  p.Units = MMUnits;
310  p.Power = logic->CoarseLaserPower;
311  p.FinePower = logic->FineLaserPower;
312  p.Frequency = logic->Frequency;
313  p.DlgProc = NULL;
314 
315  bool okPressed = ISmart::ShowProbeDialog(&logic->ConoProbe, 1, &p, &r);
316 
317  logic->ConoProbe->SetAcquisitionParams(AcquisitionMode::TimeAcquisitionMode, logic->Frequency, logic->CalculateCompositeLaserPower(r.Power, r.FinePower), logic->DelayBetweenMeasurements);
318  logic->SetLaserPower(logic->CalculateCompositeLaserPower(r.Power, r.FinePower));
319  logic->SetFrequency(r.Frequency);
320 
321  logic->Stop();
322 
323  return NULL;
324 }
325 
326 //----------------------------------------------------------------------------
327 unsigned short vtkPlusOptimetConoProbeMeasurer::CalculateCompositeLaserPower(UINT16 coarseLaserPower, UINT16 fineLaserPower)
328 {
329  unsigned short compositeLaserPower = coarseLaserPower;
330  compositeLaserPower <<= 6;
331  compositeLaserPower |= fineLaserPower;
332  return compositeLaserPower;
333 }
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
vtkStandardNewMacro(vtkPlusOptimetConoProbeMeasurer)
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_WRITING(deviceConfig, rootConfigElement)
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)
bool RequirePortNameInDeviceSetConfiguration
double AcquisitionRate
#define PLUS_FAIL
Definition: PlusCommon.h:43
void PrintSelf(ostream &os, vtkIndent indent)
Image slice number p
Definition: algo4.m:14
#define PLUS_SUCCESS
Definition: PlusCommon.h:44
PlusStatus GetToolByPortName(const char *aPortName, vtkPlusDataSource *&aSource)
virtual void SetFrequency(UINT16)
#define XML_FIND_DEVICE_ELEMENT_REQUIRED_FOR_READING(deviceConfig, rootConfigElement)
virtual void SetLaserPower(UINT16)
bool StartThreadForInternalUpdates
virtual PlusStatus WriteConfiguration(vtkXMLDataElement *config)
Interface for the Optimet ConoProbe This class talks with Optimet ConoProbe over the Optimet Smart32 ...
std::string GetToolReferenceFrameName() const
double frequency
Definition: phidget22.h:3246
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *config)