21 #include <itksys/SystemTools.hxx> 25 :
itk::Object(), m_TrackingDevice(nullptr), m_UseCRC(true)
94 switch (hardwareHandshake)
140 std::string fullcommand;
142 fullcommand =
"IRCHK:0001";
144 fullcommand =
"IRCHK 0001";
154 itksys::SystemTools::Delay(100);
164 if ((b ==
'0') || (b ==
'1'))
170 if (expectedCRC == readCRC)
186 std::string errorstring;
188 reply += errorstring;
189 static const std::string error(
"ERROR");
190 if (error.compare(0, 5, reply) == 0)
192 std::string errorcode;
199 if (expectedCRC == readCRC)
222 char stringQueryType[3];
223 sprintf(stringQueryType,
"%02X", queryType);
226 command = std::string(
"PHSR:") + std::string(stringQueryType);
228 command = std::string(
"PHSR ") + std::string(stringQueryType);
238 itksys::SystemTools::Delay(100);
242 static const std::string error(
"ERROR");
243 if (error.compare(0, 2, reply) == 0)
248 std::string errorcode;
255 if (expectedCRC == readCRC)
262 unsigned int numberOfHandles = 0;
266 s >> numberOfHandles;
267 if (numberOfHandles > 16)
273 std::string handleInformation;
274 portHandles->clear();
275 for (
unsigned int i = 0; i < numberOfHandles; i++)
278 *portHandles += handleInformation.substr(0, 2);
279 reply += handleInformation;
285 if (expectedCRC == readCRC)
307 command =
"PHRQ:*********1****";
309 command =
"PHRQ *********1****";
319 itksys::SystemTools::Delay(100);
323 static const std::string error(
"ERROR");
324 if (error.compare(0, 2, reply) == 0)
329 std::string errorcode;
336 if (expectedCRC == readCRC)
348 if (expectedCRC == readCRC)
366 if (sromDataLength > 1024)
369 if (sromDataLength == 0)
373 std::string basecommand;
375 basecommand =
"PVWR:";
377 basecommand =
"PVWR ";
379 std::string hexSROMData;
380 hexSROMData.reserve(2 * sromDataLength);
381 char hexcharacter[20];
382 for (
unsigned int i = 0; i < sromDataLength; i++)
384 sprintf(hexcharacter,
"%02X", sromData[i]);
386 hexSROMData += hexcharacter;
389 unsigned int zerosToPad = 128 - (hexSROMData.size() % 128);
391 hexSROMData.append(zerosToPad,
'0');
393 std::string fullcommand;
394 for (
unsigned int j = 0; j < hexSROMData.size(); j += 128)
396 sprintf(hexcharacter,
"%s%04X", portHandle->c_str(), j/2);
397 fullcommand = basecommand + hexcharacter + hexSROMData.substr(j, 128);
399 itksys::SystemTools::Delay(50);
420 std::string fullcommand;
422 fullcommand = std::string(
"PINIT:") + *portHandle;
424 fullcommand = std::string(
"PINIT ") + *portHandle;
435 itksys::SystemTools::Delay(100);
440 static const std::string okay(
"OKAYA896");
441 static const std::string error(
"ERROR");
442 static const std::string warning(
"WARNING7423");
444 if (okay.compare(0, 4, reply) == 0)
448 if (okay.compare(4, 4, reply, 0, 4) == 0)
453 else if (warning.compare(0, 4, reply) == 0)
457 if (warning.compare(4, 7, reply, 0, 7) == 0)
462 else if (error.compare(0, 4, reply) == 0)
467 std::string errorcode;
474 if (expectedCRC == readCRC)
495 if (portHandle !=
nullptr)
496 param = *portHandle + (char) prio;
506 if (
m_UseCRC) command =
"PHINF:" + portHandle;
507 else command =
"PHINF " + portHandle;
560 if ((count >= 1) && (count <= 9))
566 std::string fullcommand;
568 fullcommand =
"BEEP:" + p;
570 fullcommand =
"BEEP " + p;
581 itksys::SystemTools::Delay(100);
587 if ((b ==
'0') || (b ==
'1'))
593 if (expectedCRC == readCRC)
600 std::string errorstring;
602 reply += errorstring;
603 static const std::string error(
"ERROR");
604 if (error.compare(0, 5, reply) == 0)
606 std::string errorcode;
613 if (expectedCRC == readCRC)
629 std::string param =
"80";
630 if (resetFrameCounter ==
true)
645 std::string param = portHandle + state;
654 if(trackIndividualMarkers)
655 markerPositions->clear();
661 std::string fullcommand;
662 if (trackIndividualMarkers)
665 fullcommand =
"TX:1001";
667 fullcommand =
"TX 1001";
688 static const std::string error(
"ERROR");
689 if (error.compare(0, 2, reply) == 0)
693 std::string errorcode;
700 if (expectedCRC == readCRC)
712 std::stringstream converter;
713 unsigned int numberOfHandles = 0;
714 converter << std::hex << reply;
715 converter >> numberOfHandles;
720 for (
unsigned int i = 0; i < numberOfHandles; i++)
732 static const std::string missing(
"MISSING");
733 static const std::string disabled(
"DISABLED");
734 static const std::string unoccupied(
"UNOCCUPIED");
738 if (missing.compare(0, 6, s) == 0)
740 tool->SetErrorMessage(
"Tool is reported as 'missing'.");
741 tool->SetDataValid(
false);
745 else if (disabled.compare(0, 6, s) == 0)
747 tool->SetErrorMessage(
"Tool is reported as 'disabled'.");
748 tool->SetDataValid(
false);
752 else if (unoccupied.compare(0, 6, s) == 0)
754 tool->SetErrorMessage(
"Tool is reported as 'unoccupied'.");
755 tool->SetDataValid(
false);
762 signed int number = 0;
763 float localPos[3] = {0.0, 0.0, 0.0};
764 float localQuat[4] = {0.0, 0.0, 0.0, 0.0};
765 float localError = 0.0;
766 unsigned long localPortStatus = 0;
767 unsigned int localFrameNumber = 0;
770 converter << std::dec << s;
775 localQuat[0] = number / 10000.0;
776 for (
unsigned int i = 1; i < 4; i++)
780 converter << std::dec << s;
784 localQuat[i] = number / 10000.0;
787 for (
auto & localPo : localPos)
791 converter << std::dec << s;
795 localPo = number / 100.0;
800 converter << std::dec << s;
804 localError = number / 10000.0;
808 converter << std::hex << s;
809 converter >> localPortStatus;
815 converter << std::hex << s;
816 converter >> localFrameNumber;
821 mitk::Quaternion orientation(localQuat[1], localQuat[2], localQuat[3], localQuat[0]);
826 orientation[0] *= -1;
827 orientation[1] *= -1;
828 orientation[2] *= -1;
832 tool->SetOrientation(orientation);
834 position[0] = localPos[0];
835 position[1] = localPos[1];
836 position[2] = localPos[2];
837 tool->SetPosition(position);
838 tool->SetTrackingError(localError);
839 tool->SetErrorMessage(
"");
840 tool->SetDataValid(
true);
848 if(trackIndividualMarkers)
853 unsigned int numberOfMarkers = 0;
854 converter << std::hex << s;
855 converter >> numberOfMarkers;
859 unsigned int oovReplySize = (
unsigned int)ceil((
double)numberOfMarkers/4.0);
860 unsigned int nbMarkersInVolume = 0;
863 for (
unsigned int i = 0; i < oovReplySize; i++)
870 nbMarkersInVolume = numberOfMarkers-nbMarkersInVolume;
873 for (
unsigned int i = 0; i < nbMarkersInVolume; i++)
876 signed int number = 0;
879 for (
unsigned int i = 0; i < 3; i++)
883 converter << std::dec << s;
887 markerPosition[i] = number / 100.0;
889 markerPositions->push_back(markerPosition);
902 if (expectedCRC == readCRC)
911 if(trackIndividualMarkers)
912 markerPositions->clear();
927 markerPositions->clear();
933 std::string fullcommand;
935 fullcommand =
"TX:1001";
937 fullcommand =
"TX 1001";
946 static const std::string error(
"ERROR");
947 if (error.compare(0, 2, reply) == 0)
951 std::string errorcode;
958 if (expectedCRC == readCRC)
970 std::stringstream converter;
971 unsigned int numberOfHandles = 0;
972 converter << std::hex << reply;
973 converter >> numberOfHandles;
978 for (
unsigned int i = 0; i < numberOfHandles; i++)
990 static const std::string missing(
"MISSING");
991 static const std::string disabled(
"DISABLED");
992 static const std::string unoccupied(
"UNOCCUPIED");
996 if (missing.compare(0, 6, s) == 0)
998 tool->SetErrorMessage(
"Tool is reported as 'missing'.");
999 tool->SetDataValid(
false);
1003 else if (disabled.compare(0, 6, s) == 0)
1005 tool->SetErrorMessage(
"Tool is reported as 'disabled'.");
1006 tool->SetDataValid(
false);
1010 else if (unoccupied.compare(0, 6, s) == 0)
1012 tool->SetErrorMessage(
"Tool is reported as 'unoccupied'.");
1013 tool->SetDataValid(
false);
1020 signed int number = 0;
1021 float localPos[3] = {0.0, 0.0, 0.0};
1022 float localQuat[4] = {0.0, 0.0, 0.0, 0.0};
1023 float localError = 0.0;
1024 unsigned long localPortStatus = 0;
1025 unsigned int localFrameNumber = 0;
1028 converter << std::dec << s;
1029 converter >> number;
1033 localQuat[0] = number / 10000.0;
1034 for (
unsigned int i = 1; i < 4; i++)
1038 converter << std::dec << s;
1039 converter >> number;
1042 localQuat[i] = number / 10000.0;
1045 for (
auto & localPo : localPos)
1049 converter << std::dec << s;
1050 converter >> number;
1053 localPo = number / 100.0;
1058 converter << std::dec << s;
1059 converter >> number;
1062 localError = number / 10000.0;
1066 converter << std::hex << s;
1067 converter >> localPortStatus;
1073 converter << std::hex << s;
1074 converter >> localFrameNumber;
1079 mitk::Quaternion orientation(localQuat[1], localQuat[2], localQuat[3], localQuat[0]);
1080 tool->SetOrientation(orientation);
1082 position[0] = localPos[0];
1083 position[1] = localPos[1];
1084 position[2] = localPos[2];
1085 tool->SetPosition(position);
1086 tool->SetTrackingError(localError);
1087 tool->SetErrorMessage(
"");
1088 tool->SetDataValid(
true);
1098 unsigned int numberOfMarkers = 0;
1099 converter << std::hex << s;
1100 converter >> numberOfMarkers;
1104 unsigned int oovReplySize = (
unsigned int)ceil((
double)numberOfMarkers/4.0);
1105 unsigned int nbMarkersInVolume = 0;
1108 for (
unsigned int i = 0; i < oovReplySize; i++)
1115 nbMarkersInVolume = numberOfMarkers-nbMarkersInVolume;
1118 for (
unsigned int i = 0; i < nbMarkersInVolume; i++)
1121 signed int number = 0;
1124 for (
unsigned int i = 0; i < 3; i++)
1128 converter << std::dec << s;
1129 converter >> number;
1132 markerPosition[i] = number / 100.0;
1134 markerPositions->push_back(markerPosition);
1147 std::string readCRC;
1149 if (expectedCRC == readCRC)
1157 markerPositions->clear();
1171 std::cout <<
"BX() not implemented yet, using TX() instead." << std::endl;
1183 std::string fullcommand;
1185 fullcommand =
"VER:4";
1187 fullcommand =
"VER 4";
1199 static const std::string error(
"ERROR");
1200 if (error.compare(0, 6, reply) == 0)
1202 std::string errorcode;
1207 std::string readCRC;
1209 if (expectedCRC == readCRC)
1219 std::string upperCaseReply;
1220 upperCaseReply.resize(reply.size());
1221 std::transform (reply.begin(), reply.end(), upperCaseReply.begin(), toupper);
1222 if (upperCaseReply.find(
"POLARIS") != std::string::npos)
1224 else if (upperCaseReply.find(
"AURORA") != std::string::npos)
1230 itksys::SystemTools::Delay(500);
1246 if (markerPositions ==
nullptr)
1248 std::cout <<
"ERROR: markerPositions==nullptr" << std::endl;
1252 markerPositions->clear();
1256 std::cout <<
"ERROR: no tools present" << std::endl;
1263 std::cout <<
"ERROR: no tool present" << std::endl;
1267 if (portHandle.size() == 0)
1269 std::cout <<
"ERROR: no port handle" << std::endl;
1274 std::string fullcommand;
1276 fullcommand =
"3D:" + portHandle +
"5";
1278 fullcommand =
"3D " + portHandle +
"5";
1290 std::cout <<
"ERROR: receive_value != NDIOKAY" << std::endl;
1291 return receivevalue;
1294 static const std::string error(
"ERROR");
1295 if (error.compare(0, 3, reply) == 0)
1299 std::string errorcode;
1304 std::string readCRC;
1306 if (expectedCRC == readCRC)
1317 signed int number = 0;
1323 std::stringstream converter;
1324 unsigned int numberOfMarkers = 0;
1325 converter << std::dec << reply;
1326 converter >> numberOfMarkers;
1330 for (
unsigned int markerID = 0; markerID < numberOfMarkers; markerID++)
1335 for (
unsigned int i = 0; i < 3; i++)
1340 markerPositions->clear();
1341 std::cout <<
"ERROR: receive_value != NDIOKAY" << std::endl;
1342 return receivevalue;
1345 converter << std::dec << s;
1346 converter >> number;
1349 p[i] = number / 10000.0;
1355 markerPositions->clear();
1356 std::cout <<
"ERROR: receive_value != NDIOKAY" << std::endl;
1357 return receivevalue;
1360 converter << std::dec << s;
1361 converter >> number;
1369 markerPositions->clear();
1370 std::cout << std::endl << std::endl << std::endl <<
"ERROR: POS3D != NDIOKAY" << std::endl;
1371 return receivevalue;
1375 markerPositions->push_back(p);
1381 std::string readCRC;
1383 if (expectedCRC == readCRC)
1390 std::cout <<
"ERROR: receive_value != NDIOKAY" << std::endl;
1392 markerPositions->clear();
1412 if (parameter !=
nullptr)
1418 std::string fullcommand;
1420 fullcommand = command +
":" + p;
1422 fullcommand = command +
" " + p;
1437 itksys::SystemTools::Delay(100);
1451 else if (c ==
'1' || c ==
'2' || c ==
'4' || c ==
'8')
1453 else if (c ==
'3' || c ==
'5' || c ==
'9' || c ==
'6' || c ==
'A' || c ==
'C')
1455 else if (c ==
'7' || c ==
'B' || c ==
'D' || c ==
'E')
1474 static const std::string okay(
"OKAYA896");
1475 static const std::string error(
"ERROR");
1477 if (okay.compare(0, 4, reply) == 0)
1481 if (okay.compare(4, 4, reply, 0, 4) == 0)
1486 else if (error.compare(0, 4, reply) == 0)
1491 std::string errorcode;
1496 std::string readCRC;
1498 if (expectedCRC == readCRC)
1516 if (input->compare(
"01") == 0)
1518 else if (input->compare(
"02") == 0)
1520 else if (input->compare(
"03") == 0)
1522 else if (input->compare(
"04") == 0)
1524 else if (input->compare(
"05") == 0)
1526 else if (input->compare(
"06") == 0)
1528 else if (input->compare(
"07") == 0)
1530 else if (input->compare(
"08") == 0)
1532 else if (input->compare(
"09") == 0)
1534 else if (input->compare(
"0A") == 0)
1536 else if (input->compare(
"0B") == 0)
1538 else if (input->compare(
"0C") == 0)
1540 else if (input->compare(
"0D") == 0)
1542 else if (input->compare(
"0E") == 0)
1546 else if (input->compare(
"10") == 0)
1548 else if (input->compare(
"11") == 0)
1550 else if (input->compare(
"12") == 0)
1552 else if (input->compare(
"13") == 0)
1554 else if (input->compare(
"14") == 0)
1556 else if (input->compare(
"16") == 0)
1558 else if (input->compare(
"1B") == 0)
1560 else if (input->compare(
"1F") == 0)
1562 else if (input->compare(
"22") == 0)
1564 else if (input->compare(
"23") == 0)
1566 else if (input->compare(
"2A") == 0)
1568 else if (input->compare(
"2B") == 0)
1570 else if (input->compare(
"2C") == 0)
1572 else if (input->compare(
"2D") == 0)
1574 else if (input->compare(
"2E") == 0)
1576 else if (input->compare(
"2F") == 0)
1578 else if (input->compare(
"32") == 0)
1593 std::string command;
1595 command =
"APIREV:";
1597 command =
"APIREV ";
1615 static const std::string error(
"ERROR");
1616 if (error.compare(0, 6, reply) == 0)
1618 std::string errorcode;
1624 std::string readCRC;
1627 if (expectedCRC == readCRC)
1641 std::string readCRC;
1644 if (expectedCRC == readCRC)
1664 std::string command;
1666 command =
"SFLIST:03";
1668 command =
"SFLIST 03";
1682 static const std::string error(
"ERROR");
1683 if (error.compare(0,6,reply) == 0)
1685 std::string errorcode;
1691 std::string readCRC;
1694 if (expectedCRC == readCRC)
1703 std::stringstream converter;
1704 unsigned int numberOfVolumes = 0;
1705 converter << std::hex << reply[0];
1706 converter >> numberOfVolumes;
1710 if ( numberOfVolumes > 9 )
1712 MITK_WARN <<
"Number of volumes (" << numberOfVolumes
1713 <<
") is not smaller then ten as it was expected. Cannot get supported volumes.";
1714 numberOfVolumes = 0;
1715 reply[0] = numberOfVolumes;
1719 if (numberOfVolumes>0)
1722 for (
unsigned int i = 0; i<numberOfVolumes; i++)
1724 std::string currentVolume;
1728 currentVolume.append(reply,1,4);
1750 MITK_INFO <<
"Cannot get information of tracking volume " << i <<
". Abort getting of tracking volumes.";
1751 numberOfVolumes = 0;
1752 reply[0] = numberOfVolumes;
1759 MITK_INFO<<
"Standard volume supported \n";
1761 MITK_INFO<<
"Spectra pyramid volume supported \n";
1763 MITK_INFO<<
"Spectra extended pyramid volume supported \n";
1777 std::string readCRC;
1804 unsigned int numberOfVolumes;
1811 if (volumes.empty())
1816 unsigned int index = 1;
1817 auto it = volumes.begin();
1818 while (it != volumes.end())
1820 if ((*it) == deviceData.
Model)
1827 if (it == volumes.end() || index > numberOfVolumes)
1833 std::string command;
1840 std::stringstream s;
1856 static const std::string error(
"ERRO");
1857 if (error.compare(reply) == 0)
1863 std::string errorcode;
1869 std::string readCRC;
1872 if (expectedCRC == readCRC)
1881 std::string readCRC;
1884 if (expectedCRC == readCRC)
NDIErrorCode TSTART(bool resetFrameCounter=false)
Start Tracking Mode. The tracking system must be in setup mode and must be initialized.
NDIErrorCode ReceiveByte(char *answer)
lightweight receive function, that reads just one byte
NDIErrorCode TX(bool trackIndividualMarkers=false, MarkerPointContainerType *markerPositions=nullptr)
Report transformations in text mode. Optionally, individual markers can be tracked.
NDIPassiveTool * GetInternalTool(std::string portHandle)
returns the tool object that has been assigned the port handle or nullptr if no tool can be found ...
NDIErrorCode INIT()
Initialize the Measurement System.
std::vector< std::string > NDITrackingVolumeContainerType
vector of tracking volumes
NDIErrorCode PDIS(std::string *portHandle)
Port Disable. Will disable a port that has been enabled with PENA.
NDIErrorCode Send(const std::string *message, bool addCRC=true)
Send message to tracking device.
IlluminationActivationRate
activation rate of IR illuminator for NDI Polaris tracking device
NDIErrorCode POS3D(MarkerPointContainerType *markerPositions)
Report 3D Positions of single markers. can only be used in diagnostics mode.
NDIErrorCode Receive(std::string *answer, unsigned int numberOfBytes)
receive numberOfBytes bytes from tracking device
NDIErrorCode IRINIT()
Initialize the System to Check for Infrared.
virtual RotationMode GetRotationMode() const
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...
itk::Point< double > MarkerPointType
PHSRQueryType
Query mode for NDI tracking devices.
virtual void InvalidateAll()
invalidate all tools
NDIErrorCode VER(mitk::TrackingDeviceType &t)
returns if the tracking device is a Polaris or an Aurora system
static void info(const char *fmt,...)
NDIErrorCode ReceiveLine(std::string *answer)
receive characters until the first LF (The LF is included in the answer string)
NDIErrorCode TX1000(MarkerPointContainerType *markerPositions)
Report transformations in text mode.
NDIErrorCode BX()
Report transformations in binary mode.
const std::string CalcCRC(const std::string *input)
returns the CRC16 for input as a std::string
std::vector< int > TrackingVolumeDimensionType
List of the supported tracking volume dimensions.
NDIErrorCode TSTOP()
Stop Tracking Mode. The tracking system must be in Tracking mode.
NDIErrorCode VSEL(mitk::TrackingDeviceData deviceData)
Sets the tracking volume to the given type. Check available tracking volumes with SFLIST first...
NDIErrorCode PENA(std::string *portHandle, TrackingPriority prio)
Port Enable. Will enable a port that has been initialized with PINIT.
void ClearReceiveBuffer()
empty receive buffer of serial communication interface
NDIErrorCode DSTOP()
Stop the Diagnostic Mode.
NDITrackingDevice * m_TrackingDevice
tracking device to which the commands will be send
NDIErrorCode IRCHK(bool *IRdetected)
This version of IRCHK uses only the simple "presence of infrared light" call, that returns a binary "...
NDIErrorCode GenericCommand(const std::string command, const std::string *parameter=nullptr)
std::vector< MarkerPointType > MarkerPointContainerType
vnl_quaternion< ScalarType > Quaternion
NDIErrorCode COMM(mitk::SerialCommunication::BaudRate baudRate, mitk::SerialCommunication::DataBits dataBits, mitk::SerialCommunication::Parity parity, mitk::SerialCommunication::StopBits stopBits, mitk::SerialCommunication::HardwareHandshake hardwareHandshake)
Change Serial Communication Parameters.
unsigned int ByteToNbBitsOn(char &c) const
TrackingTool * GetTool(unsigned int toolNumber) const override
return the tool with index toolNumber
NDIErrorCode PHRQ(std::string *portHandle)
Port Handle Request. Will request a Port Handle for a wireless tool and return it in the string portH...
NDIProtocol()
Set whether to append a CRC16 checksum to each message.
NDIErrorCode BEEP(unsigned char count)
Sounding the measurement system beeper. The tracking system will beep one to nine times...
NDIErrorCode PVWR(std::string *portHandle, const unsigned char *sromData, unsigned int sromDataLength)
Port Virtual Write. Writes an SROM Image data to a tool.
std::string TrackingDeviceType
NDIErrorCode PHF(std::string *portHandle)
Port Handle Free. Frees the port handle.
NDIErrorCode ParseOkayError()
unsigned int GetToolCount() const override
return current number of tools
NDIErrorCode PHSR(PHSRQueryType queryType, std::string *portHandles)
Port Handle Search. Will write returned port handles to the string portHandles.
NDIErrorCode GetErrorCode(const std::string *input)
returns the error code for an Error String returned from the NDI tracking device
NDIErrorCode
Error codes of NDI tracking devices.
NDIErrorCode PHINF(std::string portHandle, std::string *portInfo)
NDIErrorCode DSTART()
Start the Diagnostic Mode.
NDIErrorCode APIREV(std::string *revision)
Gives information about the tool which is assosiated with the port handle. Writes portInfo to the str...
bool m_UseCRC
whether to append a CRC16 checksum to each message
NDIErrorCode PINIT(std::string *portHandle)
Port Initialize. Will initialize a Port that has been acquired with PHRQ and has been assigned a SROM...
NDIErrorCode PSOUT(std::string portHandle, std::string state)
Set GPIO Output (Aurora)
NDIErrorCode SFLIST(std::string *info)
Returns information about the supported feature of the tracking system.
NDIErrorCode IRATE(IlluminationActivationRate rate)
Setting the illuminator rate. Will set the refresh rate for the illuminator for wireless tools...