MITK-IGT
IGT Extension of MITK
Loading...
Searching...
No Matches
mitkNDITrackingDevice.cpp
Go to the documentation of this file.
1/*============================================================================
2
3The Medical Imaging Interaction Toolkit (MITK)
4
5Copyright (c) German Cancer Research Center (DKFZ)
6All rights reserved.
7
8Use of this source code is governed by a 3-clause BSD license that can be
9found in the LICENSE file.
10
11============================================================================*/
12
14#include "mitkIGTTimeStamp.h"
15#include "mitkIGTHardwareException.h"
16#include <cstdio>
17
18#include <itksys/SystemTools.hxx>
19
21
24
25// vtk
26#include <vtkSphereSource.h>
27
28const unsigned char CR = 0xD; // == '\r' - carriage return
29const unsigned char LF = 0xA; // == '\n' - line feed
30
32TrackingDevice(), m_DeviceName(""), m_PortNumber(mitk::SerialCommunication::COM5), m_BaudRate(mitk::SerialCommunication::BaudRate9600),
33m_DataBits(mitk::SerialCommunication::DataBits8), m_Parity(mitk::SerialCommunication::None), m_StopBits(mitk::SerialCommunication::StopBits1),
34m_HardwareHandshake(mitk::SerialCommunication::HardwareHandshakeOff),
35m_IlluminationActivationRate(Hz20), m_DataTransferMode(TX), m_6DTools(),
36m_SerialCommunication(nullptr), m_DeviceProtocol(nullptr),
37m_OperationMode(ToolTracking6D), m_MarkerPoints()
38{
40 m_6DTools.clear();
41 m_DeviceProtocol = NDIProtocol::New();
42 m_DeviceProtocol->SetTrackingDevice(this);
43 m_DeviceProtocol->UseCRCOn();
44 m_MarkerPoints.reserve(50); // a maximum of 50 marker positions can be reported by the tracking device
45}
46
48{
49 if (this->GetState() != Setup)
50 {
51 mitk::NDIPassiveTool* ndiTool = dynamic_cast<mitk::NDIPassiveTool*>(tool);
52 if (ndiTool == nullptr)
53 return false;
54
55 std::string portHandle = ndiTool->GetPortHandle();
56
57 //return false if the SROM Data has not been set
58 if (ndiTool->GetSROMData() == nullptr)
59 return false;
60
61 NDIErrorCode returnvalue;
62 returnvalue = m_DeviceProtocol->PVWR(&portHandle, ndiTool->GetSROMData(), ndiTool->GetSROMDataLength());
63 if (returnvalue != NDIOKAY)
64 return false;
65 returnvalue = m_DeviceProtocol->PINIT(&portHandle);
66 if (returnvalue != NDIOKAY)
67 return false;
68 returnvalue = m_DeviceProtocol->PENA(&portHandle, ndiTool->GetTrackingPriority()); // Enable tool
69 if (returnvalue != NDIOKAY)
70 return false;
71
72 return true;
73 }
74 else
75 {
76 return false;
77 }
78}
79
81{
82 m_RotationMode = r;
83}
84
86{
87 /* stop tracking and disconnect from tracking device */
88 if (GetState() == Tracking)
89 {
90 this->StopTracking();
91 }
92 if (GetState() == Ready)
93 {
94 this->CloseConnection();
95 }
96 /* cleanup tracking thread */
97 if (m_Thread.joinable())
98 m_Thread.join();
99
100 /* free serial communication interface */
101 if (m_SerialCommunication.IsNotNull())
102 {
103 m_SerialCommunication->ClearReceiveBuffer();
104 m_SerialCommunication->ClearSendBuffer();
105 m_SerialCommunication->CloseConnection();
106 m_SerialCommunication = nullptr;
107 }
108}
109
111{
112 if (this->GetState() != Setup)
113 return;
114 itkDebugMacro("setting PortNumber to " << _arg);
115 if (this->m_PortNumber != _arg)
116 {
117 this->m_PortNumber = _arg;
118 this->Modified();
119 }
120}
121
123{
124 if (this->GetState() != Setup)
125 return;
126 itkDebugMacro("setting eviceName to " << _arg);
127 if (this->m_DeviceName != _arg)
128 {
129 this->m_DeviceName = _arg;
130 this->Modified();
131 }
132}
133
135{
136 if (this->GetState() != Setup)
137 return;
138 itkDebugMacro("setting BaudRate to " << _arg);
139 if (this->m_BaudRate != _arg)
140 {
141 this->m_BaudRate = _arg;
142 this->Modified();
143 }
144}
145
147{
148 if (this->GetState() != Setup)
149 return;
150 itkDebugMacro("setting DataBits to " << _arg);
151 if (this->m_DataBits != _arg)
152 {
153 this->m_DataBits = _arg;
154 this->Modified();
155 }
156}
157
159{
160 if (this->GetState() != Setup)
161 return;
162 itkDebugMacro("setting Parity to " << _arg);
163 if (this->m_Parity != _arg)
164 {
165 this->m_Parity = _arg;
166 this->Modified();
167 }
168}
169
171{
172 if (this->GetState() != Setup)
173 return;
174 itkDebugMacro("setting StopBits to " << _arg);
175 if (this->m_StopBits != _arg)
176 {
177 this->m_StopBits = _arg;
178 this->Modified();
179 }
180}
181
183{
184 if (this->GetState() != Setup)
185 return;
186 itkDebugMacro("setting HardwareHandshake to " << _arg);
187 if (this->m_HardwareHandshake != _arg)
188 {
189 this->m_HardwareHandshake = _arg;
190 this->Modified();
191 }
192}
193
195{
196 if (this->GetState() == Tracking)
197 return;
198 itkDebugMacro("setting IlluminationActivationRate to " << _arg);
199 if (this->m_IlluminationActivationRate != _arg)
200 {
201 this->m_IlluminationActivationRate = _arg;
202 this->Modified();
203 if (this->GetState() == Ready) // if the connection to the tracking system is established, send the new rate to the tracking device too
204 m_DeviceProtocol->IRATE(this->m_IlluminationActivationRate);
205 }
206}
207
209{
210 itkDebugMacro("setting DataTransferMode to " << _arg);
211 if (this->m_DataTransferMode != _arg)
212 {
213 this->m_DataTransferMode = _arg;
214 this->Modified();
215 }
216}
217
218mitk::NDIErrorCode mitk::NDITrackingDevice::Send(const std::string* input, bool addCRC)
219{
220 if (input == nullptr)
221 return SERIALSENDERROR;
222
223 std::string message;
224
225 if (addCRC == true)
226 message = *input + CalcCRC(input) + std::string(1, CR);
227 else
228 message = *input + std::string(1, CR);
229
230 //unsigned int messageLength = message.length() + 1; // +1 for CR
231
232 // Clear send buffer
233 this->ClearSendBuffer();
234 // Send the date to the device
235 std::lock_guard<std::mutex> lock(m_SerialCommunicationMutex);
236 long returnvalue = m_SerialCommunication->Send(message);
237
238 if (returnvalue == 0)
239 return SERIALSENDERROR;
240 else
241 return NDIOKAY;
242}
243
244mitk::NDIErrorCode mitk::NDITrackingDevice::Receive(std::string* answer, unsigned int numberOfBytes)
245{
246 if (answer == nullptr)
247 return SERIALRECEIVEERROR;
248
249 std::lock_guard<std::mutex> lock(m_SerialCommunicationMutex);
250 long returnvalue = m_SerialCommunication->Receive(*answer, numberOfBytes); // never read more bytes than the device has send, the function will block until enough bytes are send...
251
252 if (returnvalue == 0)
253 return SERIALRECEIVEERROR;
254 else
255 return NDIOKAY;
256}
257
259{
260 if (answer == nullptr)
261 return SERIALRECEIVEERROR;
262
263 std::string m;
264
265 std::lock_guard<std::mutex> lock(m_SerialCommunicationMutex);
266
267 long returnvalue = m_SerialCommunication->Receive(m, 1);
268
269 if ((returnvalue == 0) || (m.size() != 1))
270 return SERIALRECEIVEERROR;
271
272 *answer = m.at(0);
273 return NDIOKAY;
274}
275
277{
278 if (answer == nullptr)
279 return SERIALRECEIVEERROR;
280
281 std::string m;
282
283 std::lock_guard<std::mutex> lock(m_SerialCommunicationMutex);
284
285 do
286 {
287 long returnvalue = m_SerialCommunication->Receive(m, 1);
288 if ((returnvalue == 0) || (m.size() != 1))
289 return SERIALRECEIVEERROR;
290 *answer += m;
291 } while (m.at(0) != LF);
292 return NDIOKAY;
293}
294
296{
297 std::lock_guard<std::mutex> lock(m_SerialCommunicationMutex);
298 m_SerialCommunication->ClearSendBuffer();
299}
300
302{
303 std::lock_guard<std::mutex> lock(m_SerialCommunicationMutex);
304 m_SerialCommunication->ClearReceiveBuffer();
305}
306
307const std::string mitk::NDITrackingDevice::CalcCRC(const std::string* input)
308{
309 if (input == nullptr)
310 return "";
311 /* the crc16 calculation code is taken from the NDI API guide example code section */
312 static int oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
313 unsigned int data; // copy of the input string's current character
314 unsigned int crcValue = 0; // the crc value is stored here
315 unsigned int* puCRC16 = &crcValue; // the algorithm uses a pointer to crcValue, so it's easier to provide that than to change the algorithm
316 for (unsigned int i = 0; i < input->length(); i++)
317 {
318 data = (*input)[i];
319 data = (data ^ (*(puCRC16)& 0xff)) & 0xff;
320 *puCRC16 >>= 8;
321 if (oddparity[data & 0x0f] ^ oddparity[data >> 4])
322 {
323 *(puCRC16) ^= 0xc001;
324 }
325 data <<= 6;
326 *puCRC16 ^= data;
327 data <<= 1;
328 *puCRC16 ^= data;
329 }
330 // crcValue contains now the CRC16 value. Convert it to a string and return it
331 char returnvalue[13];
332 sprintf(returnvalue, "%04X", crcValue); // 4 hexadecimal digit with uppercase format
333 return std::string(returnvalue);
334}
335
337{
338 //this->m_ModeMutex.lock();
339 if (this->GetState() != Setup)
340 {
341 mitkThrowException(mitk::IGTException) << "Can only try to open the connection if in setup mode";
342 }
343
344 m_SerialCommunication = mitk::SerialCommunication::New();
345
346 /* init local com port to standard com settings for a NDI tracking device:
347 9600 baud, 8 data bits, no parity, 1 stop bit, no hardware handshake */
348 if (m_DeviceName.empty())
349 m_SerialCommunication->SetPortNumber(m_PortNumber);
350 else
351 m_SerialCommunication->SetDeviceName(m_DeviceName);
352 m_SerialCommunication->SetBaudRate(mitk::SerialCommunication::BaudRate9600);
353 m_SerialCommunication->SetDataBits(mitk::SerialCommunication::DataBits8);
354 m_SerialCommunication->SetParity(mitk::SerialCommunication::None);
355 m_SerialCommunication->SetStopBits(mitk::SerialCommunication::StopBits1);
356 m_SerialCommunication->SetSendTimeout(5000);
357 m_SerialCommunication->SetReceiveTimeout(5000);
358 if (m_SerialCommunication->OpenConnection() == 0) // 0 == ERROR_VALUE
359 {
360 m_SerialCommunication->CloseConnection();
361 m_SerialCommunication = nullptr;
362 mitkThrowException(mitk::IGTHardwareException) << "Can not open serial port";
363 }
364
365 /* Reset Tracking device by sending a serial break for 500ms */
366 m_SerialCommunication->SendBreak(400);
367
368 /* Read answer from tracking device (RESETBE6F) */
369 static const std::string reset("RESETBE6F\r");
370 std::string answer = "";
371 this->Receive(&answer, reset.length()); // read answer (should be RESETBE6F)
372 this->ClearReceiveBuffer(); // flush the receive buffer of all remaining data (carriage return, strings other than reset
373 if (reset.compare(answer) != 0) // check for RESETBE6F
374 {
375 if (m_SerialCommunication.IsNotNull())
376 {
377 m_SerialCommunication->CloseConnection();
378 m_SerialCommunication = nullptr;
379 }
380 mitkThrowException(mitk::IGTHardwareException) << "Hardware Reset of tracking device did not work";
381 }
382
383 /* Now the tracking device isSetData reset, start initialization */
384 NDIErrorCode returnvalue;
385
386 /* set device com settings to new values and wait for the device to change them */
387 returnvalue = m_DeviceProtocol->COMM(m_BaudRate, m_DataBits, m_Parity, m_StopBits, m_HardwareHandshake);
388
389 if (returnvalue != NDIOKAY)
390 {
391 mitkThrowException(mitk::IGTHardwareException) << "Could not set comm settings in trackingdevice";
392 }
393
394 //after changing COMM wait at least 100ms according to NDI Api documentation page 31
395 itksys::SystemTools::Delay(500);
396
397 /* now change local com settings accordingly */
398 m_SerialCommunication->CloseConnection();
399 m_SerialCommunication->SetBaudRate(m_BaudRate);
400 m_SerialCommunication->SetDataBits(m_DataBits);
401 m_SerialCommunication->SetParity(m_Parity);
402 m_SerialCommunication->SetStopBits(m_StopBits);
403 m_SerialCommunication->SetHardwareHandshake(m_HardwareHandshake);
404 m_SerialCommunication->SetSendTimeout(5000);
405 m_SerialCommunication->SetReceiveTimeout(5000);
406 m_SerialCommunication->OpenConnection();
407
408 /* initialize the tracking device */
409 returnvalue = m_DeviceProtocol->INIT();
410 if (returnvalue != NDIOKAY)
411 {
412 mitkThrowException(mitk::IGTHardwareException) << "Could not initialize the tracking device";
413 }
414
415 if (this->GetType() == mitk::UnspecifiedTrackingTypeInformation::GetTrackingDeviceName()) // if the type of tracking device is not specified, try to query the connected device
416 {
417 mitk::TrackingDeviceType deviceType;
418 returnvalue = m_DeviceProtocol->VER(deviceType);
419 if ((returnvalue != NDIOKAY) || (deviceType == mitk::UnspecifiedTrackingTypeInformation::GetTrackingDeviceName()))
420 {
421 mitkThrowException(mitk::IGTHardwareException) << "Could not determine tracking device type. Please set manually and try again.";
422 }
423 this->SetType(deviceType);
424 }
425
426 /**** Optional Polaris specific code, Work in progress
427 // start diagnostic mode
428 returnvalue = m_DeviceProtocol->DSTART();
429 if (returnvalue != NDIOKAY)
430 {
431 this->SetErrorMessage("Could not start diagnostic mode");
432 return false;
433 }
434 else // we are in diagnostic mode
435 {
436 // initialize extensive IR checking
437 returnvalue = m_DeviceProtocol->IRINIT();
438 if (returnvalue != NDIOKAY)
439 {
440 this->SetErrorMessage("Could not initialize intense infrared light checking");
441 return false;
442 }
443 bool intenseIR = false;
444 returnvalue = m_DeviceProtocol->IRCHK(&intenseIR);
445 if (returnvalue != NDIOKAY)
446 {
447 this->SetErrorMessage("Could not execute intense infrared light checking");
448 return false;
449 }
450 if (intenseIR == true)
451 // do something - warn the user, raise exception, write to protocol or similar
452 std::cout << "Warning: Intense infrared light detected. Accurate tracking will probably not be possible.\n";
453
454 // stop diagnictic mode
455 returnvalue = m_DeviceProtocol->DSTOP();
456 if (returnvalue != NDIOKAY)
457 {
458 this->SetErrorMessage("Could not stop diagnostic mode");
459 return false;
460 }
461 }
462 *** end of optional polaris code ***/
463
468 /* First, check if the tracking device has port handles that need to be freed and free them */
469 returnvalue = FreePortHandles();
470 // non-critical, therefore no error handling
471
475 {
476 std::lock_guard<std::mutex> lock(m_ToolsMutex);
477 std::string portHandle;
478 auto endIt = m_6DTools.end();
479 for (auto it = m_6DTools.begin(); it != endIt; ++it)
480 {
481 /* get a port handle for the tool */
482 returnvalue = m_DeviceProtocol->PHRQ(&portHandle);
483 if (returnvalue == NDIOKAY)
484 {
485 (*it)->SetPortHandle(portHandle.c_str());
486 /* now write the SROM file of the tool to the tracking system using PVWR */
488 {
489 returnvalue = m_DeviceProtocol->PVWR(&portHandle, (*it)->GetSROMData(), (*it)->GetSROMDataLength());
490 if (returnvalue != NDIOKAY)
491 {
492 mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not write SROM file for tool '") + (*it)->GetToolName() + std::string("' to tracking device")).c_str();
493 }
494
495 returnvalue = m_DeviceProtocol->PINIT(&portHandle);
496 if (returnvalue != NDIOKAY)
497 {
498 mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not initialize tool '") + (*it)->GetToolName()).c_str();
499 }
500
501 if ((*it)->IsEnabled() == true)
502 {
503 returnvalue = m_DeviceProtocol->PENA(&portHandle, (*it)->GetTrackingPriority()); // Enable tool
504 if (returnvalue != NDIOKAY)
505 {
506 mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not enable port '") + portHandle +
507 std::string("' for tool '") + (*it)->GetToolName() + std::string("'")).c_str();
508 }
509 }
510 }
511 }
512 }
513 } // end of toolsmutexlockholder scope
514
515 /* check for wired tools and add them too */
516 if (this->DiscoverWiredTools() == false) // query the tracking device for wired tools and add them to our tool list
517 return false; // \TODO: could we continue anyways?
518
519 /*POLARIS: set the illuminator activation rate */
521 {
522 returnvalue = m_DeviceProtocol->IRATE(this->m_IlluminationActivationRate);
523 if (returnvalue != NDIOKAY)
524 {
525 mitkThrowException(mitk::IGTHardwareException) << "Could not set the illuminator activation rate";
526 }
527 }
528 /* finish - now all tools should be added, initialized and enabled, so that tracking can be started */
529 this->SetState(Ready);
530 try
531 {
532 SetVolume(this->m_Data);
533 }
534 catch (const mitk::IGTHardwareException& e)
535 {
536 MITK_WARN << e.GetDescription();
537 }
538
539 return true;
540}
541
543{
544 NDIErrorCode returnvalue;
545 std::string portHandle;
546 returnvalue = m_DeviceProtocol->PHSR(OCCUPIED, &portHandle);
547
548 if (returnvalue != NDIOKAY)
549 {
550 mitkThrowException(mitk::IGTHardwareException) << "Could not obtain a list of port handles that are connected";
551 }
552
553 /* if there are port handles that need to be initialized, initialize them. Furthermore instantiate tools for each handle that has no tool yet. */
554 std::string ph;
555
556 for (unsigned int i = 0; i < portHandle.size(); i += 2)
557 {
558 ph = portHandle.substr(i, 2);
559 mitk::NDIPassiveTool* pt = this->GetInternalTool(ph);
560 if (pt == nullptr) // if we don't have a tool, something is wrong. Tools should be discovered first by calling DiscoverWiredTools()
561 continue;
562
563 if (pt->GetSROMData() == nullptr)
564 continue;
565
566 returnvalue = m_DeviceProtocol->PVWR(&ph, pt->GetSROMData(), pt->GetSROMDataLength());
567 if (returnvalue != NDIOKAY)
568 {
569 mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not write SROM file for tool '") + pt->GetToolName() + std::string("' to tracking device")).c_str();
570 }
571
572 returnvalue = m_DeviceProtocol->PINIT(&ph);
573 if (returnvalue != NDIOKAY)
574 {
575 mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not initialize tool '") + pt->GetToolName()).c_str();
576 }
577
578 if (pt->IsEnabled() == true)
579 {
580 returnvalue = m_DeviceProtocol->PENA(&ph, pt->GetTrackingPriority()); // Enable tool
581 if (returnvalue != NDIOKAY)
582 {
583 mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not enable port '") + portHandle +
584 std::string("' for tool '") + pt->GetToolName() + std::string("'")).c_str();
585 }
586 }
587 }
588 return true;
589}
590
592{
593 if (this->GetState() != Setup)
594 {
596 }
597
598 m_SerialCommunication = mitk::SerialCommunication::New();
599 //m_DeviceProtocol = mitk::NDIProtocol::New();
600 //m_DeviceProtocol->SetTrackingDevice(this);
601 //m_DeviceProtocol->UseCRCOn();
602 /* init local com port to standard com settings for a NDI tracking device:
603 9600 baud, 8 data bits, no parity, 1 stop bit, no hardware handshake
604 */
605 if (m_DeviceName.empty())
606 m_SerialCommunication->SetPortNumber(m_PortNumber);
607 else
608 m_SerialCommunication->SetDeviceName(m_DeviceName);
609
610 m_SerialCommunication->SetBaudRate(mitk::SerialCommunication::BaudRate9600);
611 m_SerialCommunication->SetDataBits(mitk::SerialCommunication::DataBits8);
612 m_SerialCommunication->SetParity(mitk::SerialCommunication::None);
613 m_SerialCommunication->SetStopBits(mitk::SerialCommunication::StopBits1);
614 m_SerialCommunication->SetSendTimeout(5000);
615 m_SerialCommunication->SetReceiveTimeout(5000);
616 if (m_SerialCommunication->OpenConnection() == 0) // error
617 {
618 m_SerialCommunication = nullptr;
620 }
621
622 /* Reset Tracking device by sending a serial break for 500ms */
623 m_SerialCommunication->SendBreak(400);
624
625 /* Read answer from tracking device (RESETBE6F) */
626 static const std::string reset("RESETBE6F\r");
627 std::string answer = "";
628 this->Receive(&answer, reset.length()); // read answer (should be RESETBE6F)
629 this->ClearReceiveBuffer(); // flush the receive buffer of all remaining data (carriage return, strings other than reset
630 if (reset.compare(answer) != 0) // check for RESETBE6F
631 {
632 m_SerialCommunication->CloseConnection();
633 m_SerialCommunication = nullptr;
634 mitkThrowException(mitk::IGTHardwareException) << "Hardware Reset of tracking device did not work";
635 }
636
637 /* Now the tracking device is reset, start initialization */
638 NDIErrorCode returnvalue;
639
640 /* initialize the tracking device */
641 //returnvalue = m_DeviceProtocol->INIT();
642 //if (returnvalue != NDIOKAY)
643 //{
644 // this->SetErrorMessage("Could not initialize the tracking device");
645 // return mitk::TrackingSystemNotSpecified;
646 //}
647
648 mitk::TrackingDeviceType deviceType;
649 returnvalue = m_DeviceProtocol->VER(deviceType);
650 if ((returnvalue != NDIOKAY) || (deviceType == mitk::UnspecifiedTrackingTypeInformation::GetTrackingDeviceName()))
651 {
652 m_SerialCommunication = nullptr;
654 }
655 m_SerialCommunication = nullptr;
656 return deviceType;
657}
658
660{
661 if (this->GetState() != Setup)
662 {
663 //init before closing to force the field generator from aurora to switch itself off
664 m_DeviceProtocol->INIT();
665 /* close the serial connection */
666 m_SerialCommunication->CloseConnection();
667 /* invalidate all tools */
668 this->InvalidateAll();
669 /* return to setup mode */
670 this->SetState(Setup);
671 m_SerialCommunication = nullptr;
672 }
673 return true;
674}
675
677{
678 if (this->GetOperationMode() == ToolTracking6D)
679 this->TrackTools(); // call TrackTools() from the original object
680 else if (this->GetOperationMode() == MarkerTracking3D)
681 this->TrackMarkerPositions(); // call TrackMarkerPositions() from the original object
682 else if (this->GetOperationMode() == ToolTracking5D)
683 this->TrackMarkerPositions(); // call TrackMarkerPositions() from the original object
684 else if (this->GetOperationMode() == HybridTracking)
685 {
686 this->TrackToolsAndMarkers();
687 }
688}
689
691{
692 if (this->GetState() != Ready)
693 return false;
694
695 this->SetState(Tracking); // go to mode Tracking
696 this->m_StopTrackingMutex.lock(); // update the local copy of m_StopTracking
697 this->m_StopTracking = false;
698 this->m_StopTrackingMutex.unlock();
699
700 m_Thread = std::thread(&NDITrackingDevice::ThreadStartTracking, this); // start a new thread that executes the TrackTools() method
702 return true;
703}
704
706{
707 /* lock the TrackingFinishedMutex to signal that the execution rights are now transfered to the tracking thread */
708 std::lock_guard<std::mutex> lock(m_TrackingFinishedMutex);
709
710 if (this->GetState() != Tracking)
711 return;
712
713 NDIErrorCode returnvalue;
714 returnvalue = m_DeviceProtocol->TSTART();
715 if (returnvalue != NDIOKAY)
716 return;
717
718 bool localStopTracking; // Because m_StopTracking is used by two threads, access has to be guarded by a mutex. To minimize thread locking, a local copy is used here
719 this->m_StopTrackingMutex.lock(); // update the local copy of m_StopTracking
720 localStopTracking = this->m_StopTracking;
721 this->m_StopTrackingMutex.unlock();
722 while ((this->GetState() == Tracking) && (localStopTracking == false))
723 {
724 if (this->m_DataTransferMode == TX)
725 {
726 returnvalue = this->m_DeviceProtocol->TX();
727 if (!((returnvalue == NDIOKAY) || (returnvalue == NDICRCERROR) || (returnvalue == NDICRCDOESNOTMATCH))) // right now, do not stop on crc errors
728 break;
729 }
730 else
731 {
732 returnvalue = this->m_DeviceProtocol->BX();
733 if (returnvalue != NDIOKAY)
734 break;
735 }
736 /* Update the local copy of m_StopTracking */
737 this->m_StopTrackingMutex.lock();
738 localStopTracking = m_StopTracking;
739 this->m_StopTrackingMutex.unlock();
740 }
741 /* StopTracking was called, thus the mode should be changed back to Ready now that the tracking loop has ended. */
742
743 returnvalue = m_DeviceProtocol->TSTOP();
744 if (returnvalue != NDIOKAY)
745 {
746 mitkThrowException(mitk::IGTHardwareException) << "An error occured while tracking tools.";
747 }
748
749 return; // returning from this function (and ThreadStartTracking()) this will end the thread and transfer control back to main thread by releasing trackingFinishedLockHolder
750}
751
753{
754 std::lock_guard<std::mutex> lock(m_TrackingFinishedMutex);
755
756 if (m_OperationMode == ToolTracking6D)
757 return;
758
759 if (this->GetState() != Tracking)
760 return;
761
762 NDIErrorCode returnvalue;
763
764 returnvalue = m_DeviceProtocol->DSTART(); // Start Diagnostic Mode
765 if (returnvalue != NDIOKAY)
766 return;
767
768 bool localStopTracking; // Because m_StopTracking is used by two threads, access has to be guarded by a mutex. To minimize thread locking, a local copy is used here
769 this->m_StopTrackingMutex.lock(); // update the local copy of m_StopTracking
770 localStopTracking = this->m_StopTracking;
771 this->m_StopTrackingMutex.unlock();
772 while ((this->GetState() == Tracking) && (localStopTracking == false))
773 {
774 m_MarkerPointsMutex.lock(); // lock points data structure
775 returnvalue = this->m_DeviceProtocol->POS3D(&m_MarkerPoints); // update points data structure with new position data from tracking device
776 m_MarkerPointsMutex.unlock();
777 if (!((returnvalue == NDIOKAY) || (returnvalue == NDICRCERROR) || (returnvalue == NDICRCDOESNOTMATCH))) // right now, do not stop on crc errors
778 {
779 std::cout << "Error in POS3D: could not read data. Possibly no markers present." << std::endl;
780 }
781 /* Update the local copy of m_StopTracking */
782 this->m_StopTrackingMutex.lock();
783 localStopTracking = m_StopTracking;
784 this->m_StopTrackingMutex.unlock();
785
786 itksys::SystemTools::Delay(1);
787 }
788 /* StopTracking was called, thus the mode should be changed back to Ready now that the tracking loop has ended. */
789 returnvalue = m_DeviceProtocol->DSTOP();
790 if (returnvalue != NDIOKAY)
791 return; // how can this thread tell the application, that an error has occured?
792
793 this->SetState(Ready);
794 return; // returning from this function (and ThreadStartTracking()) this will end the thread
795}
796
798{
799 std::lock_guard<std::mutex> lock(m_TrackingFinishedMutex);
800 if (m_OperationMode != HybridTracking)
801 return;
802
803 NDIErrorCode returnvalue;
804
805 returnvalue = m_DeviceProtocol->TSTART(); // Start Diagnostic Mode
806 if (returnvalue != NDIOKAY)
807 return;
808
809 bool localStopTracking; // Because m_StopTracking is used by two threads, access has to be guarded by a mutex. To minimize thread locking, a local copy is used here
810 this->m_StopTrackingMutex.lock(); // update the local copy of m_StopTracking
811 localStopTracking = this->m_StopTracking;
812 this->m_StopTrackingMutex.unlock();
813 while ((this->GetState() == Tracking) && (localStopTracking == false))
814 {
815 m_MarkerPointsMutex.lock(); // lock points data structure
816 returnvalue = this->m_DeviceProtocol->TX(true, &m_MarkerPoints); // update points data structure with new position data from tracking device
817 m_MarkerPointsMutex.unlock();
818 if (!((returnvalue == NDIOKAY) || (returnvalue == NDICRCERROR) || (returnvalue == NDICRCDOESNOTMATCH))) // right now, do not stop on crc errors
819 {
820 std::cout << "Error in TX: could not read data. Possibly no markers present." << std::endl;
821 }
822 /* Update the local copy of m_StopTracking */
823 this->m_StopTrackingMutex.lock();
824 localStopTracking = m_StopTracking;
825 this->m_StopTrackingMutex.unlock();
826 }
827 /* StopTracking was called, thus the mode should be changed back to Ready now that the tracking loop has ended. */
828
829 returnvalue = m_DeviceProtocol->TSTOP();
830 if (returnvalue != NDIOKAY)
831 return; // how can this thread tell the application, that an error has occurred?
832
833 this->SetState(Ready);
834 return; // returning from this function (and ThreadStartTracking()) this will end the thread
835}
836
838{
839 std::lock_guard<std::mutex> lock(m_ToolsMutex);
840 if (toolNumber < m_6DTools.size())
841 return m_6DTools.at(toolNumber);
842 return nullptr;
843}
844
846{
847 std::lock_guard<std::mutex> lock(m_ToolsMutex);
848 auto end = m_6DTools.end();
849 for (auto iterator = m_6DTools.begin(); iterator != end; ++iterator)
850 if (name.compare((*iterator)->GetToolName()) == 0)
851 return *iterator;
852 return nullptr;
853}
854
856{
857 std::lock_guard<std::mutex> lock(m_ToolsMutex);
858 auto end = m_6DTools.end();
859 for (auto iterator = m_6DTools.begin(); iterator != end; ++iterator)
860 if (portHandle.compare((*iterator)->GetPortHandle()) == 0)
861 return *iterator;
862 return nullptr;
863}
864
866{
867 std::lock_guard<std::mutex> lock(m_ToolsMutex);
868 return m_6DTools.size();
869}
870
871bool mitk::NDITrackingDevice::Beep(unsigned char count)
872{
873 if (this->GetState() != Setup)
874 {
875 return (m_DeviceProtocol->BEEP(count) == NDIOKAY);
876 }
877 else
878 {
879 return false;
880 }
881}
882
883mitk::TrackingTool* mitk::NDITrackingDevice::AddTool(const char* toolName, const char* fileName, TrackingPriority p /*= NDIPassiveTool::Dynamic*/)
884{
885 mitk::NDIPassiveTool::Pointer t = mitk::NDIPassiveTool::New();
886 if (t->LoadSROMFile(fileName) == false)
887 return nullptr;
888 t->SetToolName(toolName);
889 t->SetTrackingPriority(p);
890 if (this->InternalAddTool(t) == false)
891 return nullptr;
892 return t.GetPointer();
893}
894
896{
897 if (tool == nullptr)
898 return false;
899 NDIPassiveTool::Pointer p = tool;
900 /* if the connection to the tracking device is already established, add the new tool to the device now */
901 if (this->GetState() == Ready)
902 {
903 /* get a port handle for the tool */
904 std::string newPortHandle;
905 NDIErrorCode returnvalue;
906 returnvalue = m_DeviceProtocol->PHRQ(&newPortHandle);
907 if (returnvalue == NDIOKAY)
908 {
909 p->SetPortHandle(newPortHandle.c_str());
910 /* now write the SROM file of the tool to the tracking system using PVWR */
911 returnvalue = m_DeviceProtocol->PVWR(&newPortHandle, p->GetSROMData(), p->GetSROMDataLength());
912 if (returnvalue != NDIOKAY)
913 {
914 mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not write SROM file for tool '") + p->GetToolName() + std::string("' to tracking device")).c_str();
915 }
916 /* initialize the port handle */
917 returnvalue = m_DeviceProtocol->PINIT(&newPortHandle);
918 if (returnvalue != NDIOKAY)
919 {
920 mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not initialize port '") + newPortHandle +
921 std::string("' for tool '") + p->GetToolName() + std::string("'")).c_str();
922 }
923 /* enable the port handle */
924 if (p->IsEnabled() == true)
925 {
926 returnvalue = m_DeviceProtocol->PENA(&newPortHandle, p->GetTrackingPriority()); // Enable tool
927 if (returnvalue != NDIOKAY)
928 {
929 mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not enable port '") + newPortHandle +
930 std::string("' for tool '") + p->GetToolName() + std::string("'")).c_str();
931 }
932 }
933 }
934 /* now that the tool is added to the device, add it to list too */
935 m_ToolsMutex.lock();
936 this->m_6DTools.push_back(p);
937 m_ToolsMutex.unlock();
938 this->Modified();
939 return true;
940 }
941 else if (this->GetState() == Setup)
942 {
943 /* In Setup mode, we only add it to the list, so that OpenConnection() can add it later */
944 m_ToolsMutex.lock();
945 this->m_6DTools.push_back(p);
946 m_ToolsMutex.unlock();
947 this->Modified();
948 return true;
949 }
950 else // in Tracking mode, no tools can be added
951 return false;
952}
953
955{
956 mitk::NDIPassiveTool* ndiTool = dynamic_cast<mitk::NDIPassiveTool*>(tool);
957 if (ndiTool == nullptr)
958 return false;
959
960 std::string portHandle = ndiTool->GetPortHandle();
961 /* a valid portHandle has length 2. If a valid handle exists, the tool is already added to the tracking device, so we have to remove it there
962 if the connection to the tracking device has already been established.
963 */
964 if ((portHandle.length() == 2) && (this->GetState() == Ready)) // do not remove a tool in tracking mode
965 {
966 NDIErrorCode returnvalue;
967 returnvalue = m_DeviceProtocol->PHF(&portHandle);
968 if (returnvalue != NDIOKAY)
969 return false;
970 /* Now that the tool is removed from the tracking device, remove it from our tool list too */
971 std::lock_guard<std::mutex> lock(m_ToolsMutex);
972 auto end = m_6DTools.end();
973 for (auto iterator = m_6DTools.begin(); iterator != end; ++iterator)
974 {
975 if (iterator->GetPointer() == ndiTool)
976 {
977 m_6DTools.erase(iterator);
978 this->Modified();
979 return true;
980 }
981 }
982 return false;
983 }
984 else if (this->GetState() == Setup) // in Setup Mode, we are not connected to the tracking device, so we can just remove the tool from the tool list
985 {
986 std::lock_guard<std::mutex> lock(m_ToolsMutex);
987 auto end = m_6DTools.end();
988 for (auto iterator = m_6DTools.begin(); iterator != end; ++iterator)
989 {
990 if ((*iterator).GetPointer() == ndiTool)
991 {
992 m_6DTools.erase(iterator);
993 this->Modified();
994 return true;
995 }
996 }
997 return false;
998 }
999 return false;
1000}
1001
1003{
1004 std::lock_guard<std::mutex> lock(m_ToolsMutex);
1005 auto end = m_6DTools.end();
1006 for (auto iterator = m_6DTools.begin(); iterator != end; ++iterator)
1007 (*iterator)->SetDataValid(false);
1008}
1009
1011{
1012 if (GetState() == Tracking)
1013 return false;
1014
1015 m_OperationMode = mode;
1016 return true;
1017}
1018
1020{
1021 return m_OperationMode;
1022}
1023
1025{
1026 m_MarkerPointsMutex.lock();
1027 *markerpositions = m_MarkerPoints; // copy the internal vector to the one provided
1028 m_MarkerPointsMutex.unlock();
1029 return (markerpositions->size() != 0);
1030}
1031
1033{
1034 /* First, check for disconnected tools and remove them */
1035 this->FreePortHandles();
1036
1037 //NDI handling (PHSR 02, PINIT, PHSR 02, PHSR 00) => all initialized and all handles available
1038 //creation of MITK tools
1039 //NDI enable all tools (PENA)
1040 //NDI get all serial numbers (PHINF)
1041
1046 /* check for occupied port handles on channel 0 */
1047 std::string portHandle;
1048 NDIErrorCode returnvalue = m_DeviceProtocol->PHSR(OCCUPIED, &portHandle);
1049
1050 if (returnvalue != NDIOKAY)
1051 {
1052 mitkThrowException(mitk::IGTHardwareException) << "Could not obtain a list of port handles that are connected on channel 0.";
1053 }
1054
1055 /* Initialize all port handles on channel 0 */
1056 for (unsigned int i = 0; i < portHandle.size(); i += 2)
1057 {
1058 std::string ph = portHandle.substr(i, 2);
1059 returnvalue = m_DeviceProtocol->PINIT(&ph);
1060
1061 if (returnvalue != NDIOKAY)
1062 {
1063 mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not initialize port '") + ph + std::string("."));
1064 }
1065 }
1066
1067 /* check for occupied port handles on channel 1 (initialize automatically, portHandle is empty although additional tools were detected) */
1068 //For a split port on a dual 5DOF tool, the first PHSR sent will report only one port handle. After the port handle is
1069 //initialized, it is assigned to channel 0. You must then use PHSR again to assign a port handle to channel 1. The
1070 //port handle for channel 1 is initialized automatically.
1071 returnvalue = m_DeviceProtocol->PHSR(OCCUPIED, &portHandle);
1072
1073 if (returnvalue != NDIOKAY)
1074 {
1075 mitkThrowException(mitk::IGTHardwareException) << "Could not obtain a list of port handles that are connected on channel 1.";
1076 }
1077
1078 /* read all port handles */
1079 returnvalue = m_DeviceProtocol->PHSR(ALL, &portHandle);
1080
1081 if (returnvalue != NDIOKAY)
1082 {
1083 mitkThrowException(mitk::IGTHardwareException) << "Could not obtain a list of port handles that are connected on all channels.";
1084 }
1085
1091 for (unsigned int i = 0; i < portHandle.size(); i += 2)
1092 {
1093 std::string ph = portHandle.substr(i, 2);
1094 if (this->GetInternalTool(ph) != nullptr) // if we already have a tool with this handle
1095 continue; // then skip the initialization
1096
1097 //define tracking priority
1098 auto trackingPriority = mitk::NDIPassiveTool::Dynamic;
1099
1100 //instantiate an object for each tool that is connected
1101 mitk::NDIPassiveTool::Pointer newTool = mitk::NDIPassiveTool::New();
1102 newTool->SetPortHandle(ph.c_str());
1103 newTool->SetTrackingPriority(trackingPriority);
1104
1105 //set a name for identification
1106 newTool->SetToolName((std::string("Port ") + ph).c_str());
1107
1108 /* enable the port handle */
1109 returnvalue = m_DeviceProtocol->PENA(&ph, trackingPriority); // Enable tool
1110
1111 if (returnvalue != NDIOKAY)
1112 {
1113 mitkThrowException(mitk::IGTHardwareException) << (std::string("Could not enable port '") + ph +
1114 std::string("' for tool '") + newTool->GetToolName() + std::string("'")).c_str();
1115 }
1116
1117 //we have to temporarily unlock m_ModeMutex here to avoid a deadlock with another lock inside InternalAddTool()
1118 if (this->InternalAddTool(newTool) == false)
1119 {
1120 mitkThrowException(mitk::IGTException) << "Error while adding new tool";
1121 }
1122 }
1123
1128 // after initialization readout serial numbers of automatically detected tools
1129 for (unsigned int i = 0; i < portHandle.size(); i += 2)
1130 {
1131 std::string ph = portHandle.substr(i, 2);
1132
1133 std::string portInfo;
1134 NDIErrorCode returnvaluePort = m_DeviceProtocol->PHINF(ph, &portInfo);
1135 if ((returnvaluePort == NDIOKAY) && (portInfo.size() > 31))
1136 dynamic_cast<mitk::NDIPassiveTool*>(this->GetInternalTool(ph))->SetSerialNumber(portInfo.substr(23, 8));
1137 MITK_INFO << "portInfo: " << portInfo;
1138 itksys::SystemTools::Delay(10);
1139 }
1140
1141 return true;
1142}
1143
1145{
1146 /* first search for port handles that need to be freed: e.g. because of a reset of the tracking system */
1147 NDIErrorCode returnvalue = NDIOKAY;
1148 std::string portHandle;
1149 returnvalue = m_DeviceProtocol->PHSR(FREED, &portHandle);
1150 if (returnvalue != NDIOKAY)
1151 {
1152 mitkThrowException(mitk::IGTHardwareException) << "Could not obtain a list of port handles that need to be freed";
1153 }
1154
1155 /* if there are port handles that need to be freed, free them */
1156 if (portHandle.empty() == true)
1157 return returnvalue;
1158
1159 std::string ph;
1160 for (unsigned int i = 0; i < portHandle.size(); i += 2)
1161 {
1162 ph = portHandle.substr(i, 2);
1163
1164 mitk::NDIPassiveTool* t = this->GetInternalTool(ph);
1165 if (t != nullptr) // if we have a tool for the port handle that needs to be freed
1166 {
1167 if (this->RemoveTool(t) == false) // remove it (this will free the port too)
1168 returnvalue = NDIERROR;
1169 }
1170 else // we don't have a tool, the port handle exists only in the tracking device
1171 {
1172 returnvalue = m_DeviceProtocol->PHF(&ph); // free it there
1173 // What to do if port handle could not be freed? This seems to be a non critical error
1174 if (returnvalue != NDIOKAY)
1175 {
1176 mitkThrowException(mitk::IGTHardwareException) << "Could not free all port handles";
1177 }
1178 }
1179 }
1180 return returnvalue;
1181}
1182
1184{
1185 std::string revision;
1186 if (m_DeviceProtocol->APIREV(&revision) != mitk::NDIOKAY || revision.empty() || (revision.size() != 9))
1187 {
1188 MITK_ERROR << "Could not receive firmware revision number!";
1189 return 0;
1190 }
1191
1192 const std::string majrevno = revision.substr(2, 3); //cut out "004" from "D.004.001"
1193
1194 return std::atoi(majrevno.c_str());
1195}
1196
1198{
1199 static std::string revision;
1200 if (m_DeviceProtocol->APIREV(&revision) != mitk::NDIOKAY || revision.empty() || (revision.size() != 9))
1201 {
1202 MITK_ERROR << "Could not receive firmware revision number!";
1203 revision = "";
1204 return revision.c_str();
1205 }
1206 return revision.c_str();
1207}
1208
1210{
1211 if (this->GetType() == mitk::NDIAuroraTypeInformation::GetTrackingDeviceName()) { return true; }
1212 else { return false; }
1213}
1214
1216{
1217 //For Aurora, only AutoDetecion or loading of toolStorage should be used. It is not possible to add a single tool.
1218 if (this->GetType() == mitk::NDIAuroraTypeInformation::GetTrackingDeviceName()) { return false; }
1219 //For Polaris, a single tool can be added, there is no autoDetection.
1220 else { return true; }
1221}
1222
1223mitk::NavigationToolStorage::Pointer mitk::NDITrackingDevice::AutoDetectTools()
1224{
1225 mitk::NavigationToolStorage::Pointer autoDetectedStorage = mitk::NavigationToolStorage::New();
1227 {
1228 try
1229 {
1230 this->OpenConnection();
1231 this->StartTracking();
1232 }
1233 catch (mitk::Exception& e)
1234 {
1235 MITK_WARN << "Warning, can not auto-detect tools! (" << e.GetDescription() << ")";
1236 return autoDetectedStorage;
1237 }
1238
1239 for (unsigned int i = 0; i < this->GetToolCount(); i++)
1240 {
1241 //create a navigation tool with sphere as surface
1242 std::stringstream toolname;
1243 toolname << "AutoDetectedTool" << i;
1244 mitk::NavigationTool::Pointer newTool = mitk::NavigationTool::New();
1245 newTool->SetSerialNumber(dynamic_cast<mitk::NDIPassiveTool*>(this->GetTool(i))->GetSerialNumber());
1246 newTool->SetIdentifier(toolname.str());
1247 newTool->SetTrackingDeviceType(mitk::NDIAuroraTypeInformation::GetTrackingDeviceName());
1248 newTool->GetDataNode()->SetName(toolname.str());
1249 autoDetectedStorage->AddTool(newTool);
1250 }
1251 this->StopTracking();
1252 this->CloseConnection();
1253 }
1254 return autoDetectedStorage;
1255}
1256
1258{
1259 if (numberOfVolumes == nullptr || volumes == nullptr || volumesDimensions == nullptr)
1260 return false;
1261
1262 static std::string info;
1263 if (m_DeviceProtocol->SFLIST(&info) != mitk::NDIOKAY || info.empty())
1264 {
1265 MITK_ERROR << "Could not receive tracking volume information of tracking system!";
1266 return false;
1267 }
1268
1269 /*info contains the following:
1270 <HEX:number of volumes> (+n times:) <HEX:shape type> <shape parameters D1-D10> <HEX:reserved / number of wavelength supported> <metal resistant / supported wavelength>
1271 */
1272 (*numberOfVolumes) = (unsigned int)std::atoi(info.substr(0, 1).c_str());
1273
1274 for (unsigned int i = 0; i < (*numberOfVolumes); i++)
1275 {
1276 //e.g. for cube: "9-025000+025000-025000+025000-055000-005000+000000+000000+000000+00000011"
1277 //for dome: "A+005000+048000+005000+066000+000000+000000+000000+000000+000000+00000011"
1278
1279 std::string::size_type offset, end;
1280 offset = (i * 73) + 1;
1281 end = 73 + (i * 73);
1282 std::string currentVolume = info.substr(offset, end);//i=0: from 1 to 73 characters; i=1: from 75 to 148 char;
1283 // if i>0 then we have a return statement <LF> infront
1284 if (i > 0)
1285 currentVolume = currentVolume.substr(1, currentVolume.size());
1286 if (currentVolume.compare(0, 1, NDIPolarisTypeInformation::GetDeviceDataPolarisOldModel().HardwareCode) == 0)
1288 if (currentVolume.compare(0, 3, NDIPolarisTypeInformation::GetDeviceDataPolarisSpectra().HardwareCode) == 0)
1291 {
1292 currentVolume = currentVolume.substr(1, currentVolume.size());
1294 }
1295 if (currentVolume.compare(0, 1, NDIPolarisTypeInformation::GetDeviceDataPolarisVicra().HardwareCode) == 0)
1296 volumes->push_back(NDIPolarisTypeInformation::GetDeviceDataPolarisVicra().Model);
1297 else if (currentVolume.compare(0, 1, mitk::NDIAuroraTypeInformation::GetDeviceDataAuroraPlanarCube().HardwareCode) == 0)
1298 volumes->push_back(mitk::NDIAuroraTypeInformation::GetDeviceDataAuroraPlanarCube().Model);//alias cube
1299 else if (currentVolume.compare(0, 1, mitk::NDIAuroraTypeInformation::GetDeviceDataAuroraPlanarDome().HardwareCode) == 0)
1301
1302 //fill volumesDimensions
1303 for (unsigned int index = 0; index < 10; index++)
1304 {
1305 std::string::size_type offD, endD;
1306 offD = 1 + (index * 7); //7 digits per dimension and the first is the type of volume
1307 endD = offD + 7;
1308 int dimension = std::atoi(currentVolume.substr(offD, endD).c_str());
1309 dimension /= 100; //given in mm. 7 digits are xxxx.xx according to NDI //strange, the last two digits (11) also for the metal flag get read also...
1310 volumesDimensions->push_back(dimension);
1311 }
1312 }
1313
1314 return true;
1315}
1316
1318{
1319 if (m_DeviceProtocol->VSEL(volume) != mitk::NDIOKAY)
1320 {
1321 mitkThrowException(mitk::IGTHardwareException) << "Could not set volume!";
1322 }
1323 return true;
1324}
An object of this class represents an exception of the MITK-IGT module.
An object of this class represents an exception of the MITK-IGT module which are releated to the hard...
static IGTTimeStamp * GetInstance()
returns a pointer to the current instance of mitkTimeStamp
void Start(itk::Object::Pointer device)
starts the time-acquisition
static TrackingDeviceData GetDeviceDataAuroraPlanarDome()
static TrackingDeviceData GetDeviceDataAuroraPlanarCube()
Implementation of a passive NDI optical tool.
virtual unsigned int GetSROMDataLength() const
get length of SROMData char array
virtual const unsigned char * GetSROMData() const
get loaded srom file as unsigned char array
TrackingPriority
tracking priority for NDI tracking devices
static TrackingDeviceData GetDeviceDataPolarisSpectra()
static TrackingDeviceData GetDeviceDataPolarisOldModel()
static TrackingDeviceData GetDeviceDataPolarisVicra()
static TrackingDeviceData GetDeviceDataSpectraExtendedPyramid()
Tool6DContainerType m_6DTools
list of 6D tools
virtual void InvalidateAll()
invalidate all tools
virtual void SetDataBits(const DataBits _arg)
set number of data bits
NDIPassiveTool * GetInternalTool(std::string portHandle)
returns the tool object that has been assigned the port handle or nullptr if no tool can be found
virtual void SetHardwareHandshake(const HardwareHandshake _arg)
set use hardware handshake for serial communication
virtual int GetMajorFirmwareRevisionNumber()
Get major revision number from tracking device should not be called directly after starting to track.
virtual void SetParity(const Parity _arg)
set parity mode
NDIErrorCode Send(const std::string *message, bool addCRC=true)
Send message to tracking device.
virtual void SetDataTransferMode(const DataTransferMode _arg)
set data transfer mode to text (TX) or binary (BX).
NDIErrorCode ReceiveLine(std::string *answer)
receive characters until the first LF (The LF is included in the answer string)
virtual bool SetVolume(mitk::TrackingDeviceData volume)
Sets the desired tracking volume. Returns true if the volume type could be set. It is set in the Open...
virtual bool Beep(unsigned char count)
Beep the tracking device 1 to 9 times.
unsigned int GetToolCount() const override
return current number of tools
virtual void TrackToolsAndMarkers()
continuously polls serial interface for new 3D marker positions and 6D tool positions until StopTrack...
TrackingTool * GetTool(unsigned int toolNumber) const override
return the tool with index toolNumber
virtual const char * GetFirmwareRevisionNumber()
Get revision number from tracking device as string should not be called directly after starting to tr...
virtual bool SetOperationMode(OperationMode mode)
set operation mode to 6D tool tracking, 3D marker tracking or 6D&3D hybrid tracking (see OperationMod...
virtual bool UpdateTool(mitk::TrackingTool *tool)
reloads the srom file and reinitializes the tool
std::vector< int > TrackingVolumeDimensionType
List of the supported tracking volume dimensions.
bool OpenConnection() override
Set the type of the NDI Tracking Device because it can not jet handle this itself.
virtual void SetStopBits(const StopBits _arg)
set number of stop bits
NDIErrorCode Receive(std::string *answer, unsigned int numberOfBytes)
receive numberOfBytes bytes from tracking device
MarkerPointContainerType m_MarkerPoints
container for markers (3D point tracking mode)
NDIProtocol::Pointer m_DeviceProtocol
create and parse NDI protocol strings
virtual void SetDeviceName(std::string _arg)
set device name (e.g. COM1, /dev/ttyUSB0). If this is set, PortNumber will be ignored
virtual bool GetMarkerPositions(MarkerPointContainerType *markerpositions)
Get 3D marker positions (operation mode must be set to MarkerTracking3D or HybridTracking)
void ClearSendBuffer()
empty send buffer of serial communication interface
virtual bool InternalAddTool(NDIPassiveTool *tool)
Add a passive 6D tool to the list of tracked tools. This method is used by AddTool.
mitk::NavigationToolStorage::Pointer AutoDetectTools() override
virtual void SetPortNumber(const PortNumber _arg)
set port number for serial communication
NDIErrorCode FreePortHandles()
free all port handles that need to be freed
virtual void SetIlluminationActivationRate(const IlluminationActivationRate _arg)
set activation rate of IR illumator for polaris
virtual mitk::TrackingDeviceType TestConnection()
TestConnection() tries to connect to a NDI tracking device on the current port/device and returns whi...
virtual bool GetSupportedVolumes(unsigned int *numberOfVolumes, NDITrackingVolumeContainerType *volumes, TrackingVolumeDimensionType *volumesDimensions)
Get number of supported tracking volumes, a vector containing the supported volumes and a vector cont...
virtual void SetBaudRate(const BaudRate _arg)
set baud rate for serial communication
NDIErrorCode ReceiveByte(char *answer)
lightweight receive function, that reads just one byte
void ClearReceiveBuffer()
empty receive buffer of serial communication interface
void SetRotationMode(RotationMode r) override
const std::string CalcCRC(const std::string *input)
returns the CRC16 for input as a std::string
bool StartTracking() override
Start the tracking.
void ThreadStartTracking()
start method for the tracking thread.
std::vector< std::string > NDITrackingVolumeContainerType
vector of tracking volumes
~NDITrackingDevice() override
Destructor.
virtual OperationMode GetOperationMode()
get current operation mode
bool CloseConnection() override
Closes the connection.
virtual bool RemoveTool(TrackingTool *tool)
Remove a passive 6D tool from the list of tracked tools.
bool DiscoverWiredTools()
retrieves all wired tools from the tracking device
virtual void TrackTools()
TrackTools() continuously polls serial interface for new 6d tool positions until StopTracking is call...
virtual void TrackMarkerPositions()
continuously polls serial interface for new 3D marker positions until StopTracking is called.
mitk::TrackingTool * GetToolByName(std::string name) const override
Returns the tool with the given tool name.
mitk::TrackingTool * AddTool(const char *toolName, const char *fileName, TrackingPriority p=NDIPassiveTool::Dynamic)
Create a passive 6D tool with toolName and fileName and add it to the list of tools.
serial communication interface
Interface for all Tracking Devices.
TrackingDeviceData m_Data
current device Data
Interface for all Tracking Tools.
virtual const char * GetToolName() const
every tool has a name thatgit can be used to identify it.
virtual bool IsEnabled() const
returns whether the tool is enabled or disabled
const unsigned char CR
const unsigned char LF
IGT Exceptions.
DataTransferMode
Data transfer mode for NDI tracking devices.
IlluminationActivationRate
activation rate of IR illuminator for NDI Polaris tracking device
std::vector< MarkerPointType > MarkerPointContainerType
std::string TrackingDeviceType
OperationMode
Error codes of NDI tracking devices.
NDIErrorCode
Error codes of NDI tracking devices.
@ SERIALRECEIVEERROR
@ NDICRCDOESNOTMATCH
@ SERIALSENDERROR