Code from Jay Jagadeesan for OgenIGTLink
From NAMIC Wiki
Home < Code from Jay Jagadeesan for OgenIGTLink
/*========================================================================= Program: Open IGT Link -- Example for Data Receiving Client Program Module: $RCSfile: $ Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) Insight Software Consortium. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include <iostream> #include <iomanip> #include <math.h> #include <cstdlib> #include <cstring> #include <stdio.h> #include <stdlib.h> #include <unistd.h> //Sound input files #include <lo/lo.h> #include "igtlOSUtil.h" #include "igtlMessageHeader.h" #include "igtlTransformMessage.h" #include "igtlPositionMessage.h" #include "igtlImageMessage.h" #include "igtlClientSocket.h" #include "igtlStatusMessage.h" #if OpenIGTLink_PROTOCOL_VERSION >= 2 #include "igtlPointMessage.h" #include "igtlTrajectoryMessage.h" #include "igtlStringMessage.h" #include "igtlTrackingDataMessage.h" #include "igtlQuaternionTrackingDataMessage.h" #include "igtlCapabilityMessage.h" #endif // OpenIGTLink_PROTOCOL_VERSION >= 2 int ReceiveTransform(igtl::Socket * socket, igtl::MessageHeader::Pointer& header, igtl::Matrix4x4 transformMatrix); int ReceivePosition(igtl::Socket * socket, igtl::MessageHeader::Pointer& header); int ReceiveImage(igtl::Socket * socket, igtl::MessageHeader::Pointer& header); int ReceiveStatus(igtl::Socket * socket, igtl::MessageHeader::Pointer& header); void ObtainPosOrFromTx(igtl::Matrix4x4 txMatrix, double pos[3], double orient[3]); #if OpenIGTLink_PROTOCOL_VERSION >= 2 int ReceivePoint(igtl::Socket * socket, igtl::MessageHeader::Pointer& header); int ReceiveTrajectory(igtl::Socket * socket, igtl::MessageHeader::Pointer& header); int ReceiveString(igtl::Socket * socket, igtl::MessageHeader::Pointer& header); int ReceiveTrackingData(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header); int ReceiveQuaternionTrackingData(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header); int ReceiveCapability(igtl::Socket * socket, igtl::MessageHeader * header); #endif //OpenIGTLink_PROTOCOL_VERSION >= 2 // Sound related stuff const char testdata[6] = "ABCDE"; int main(int argc, char* argv[]) { //------------------------------------------------------------ // Sound related stuff - initialization //------------------------------------------------------------ /* build a blob object from some data */ lo_blob btest = lo_blob_new(sizeof(testdata), testdata); /* an address to send messages to. sometimes it is better to let the server * pick a port number for you by passing NULL as the last argument */ // lo_address t = lo_address_new_from_url( "osc.unix://localhost/tmp/mysocket" ); lo_address t = lo_address_new("169.123.1.5", "7400"); /* send a message to /a/b/c/d with a mixtrure of float and string * arguments */ //lo_send(t, "/a/b/c/d", "sfsff", "one", 0.12345678f, "three", // -0.00000023001f, 1.0); /* send a 'blob' object to /a/b/c/d */ //lo_send(t, "/a/b/c/d", "b", btest); /* send a jamin scene change instruction with a 32bit integer argument */ //lo_send(t, "/jamin/scene", "i", 3); //------------------------------------------------------------ // Parse Arguments if (argc != 3) // check number of arguments { // If not correct, print usage std::cerr << " <hostname> : IP or host name" << std::endl; std::cerr << " <port> : Port # (18944 in Slicer default)" << std::endl; exit(0); } char* hostname = argv[1]; int port = atoi(argv[2]); //------------------------------------------------------------ // Establish Connection igtl::ClientSocket::Pointer socket; socket = igtl::ClientSocket::New(); int r = socket->ConnectToServer(hostname, port); if (r != 0) { std::cerr << "Cannot connect to the server." << std::endl; exit(0); } //------------------------------------------------------------ // Create a message buffer to receive header igtl::MessageHeader::Pointer headerMsg; headerMsg = igtl::MessageHeader::New(); //------------------------------------------------------------ // Allocate a time stamp igtl::TimeStamp::Pointer ts; ts = igtl::TimeStamp::New(); double pos[3], orient[3]; while (1) { //------------------------------------------------------------ // loop //for (int i = 0; i < 100; i ++) { // Initialize receive buffer headerMsg->InitPack(); // Receive generic header from the socket int r = socket->Receive(headerMsg->GetPackPointer(), headerMsg->GetPackSize()); if (r == 0) { socket->CloseSocket(); exit(0); } if (r != headerMsg->GetPackSize()) { continue; } // Deserialize the header headerMsg->Unpack(); // Get time stamp igtlUint32 sec; igtlUint32 nanosec; headerMsg->GetTimeStamp(ts); ts->GetTimeStamp(&sec, &nanosec); igtl::Matrix4x4 transformMatrix; std::cerr << "Time stamp: " << sec << "." << std::setw(9) << std::setfill('0') << nanosec << std::endl; // Check data type and receive data body if (strcmp(headerMsg->GetDeviceType(), "TRANSFORM") == 0) { ReceiveTransform(socket, headerMsg, transformMatrix); } else if (strcmp(headerMsg->GetDeviceType(), "POSITION") == 0) { ReceivePosition(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "IMAGE") == 0) { ReceiveImage(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "STATUS") == 0) { ReceiveStatus(socket, headerMsg); } #if OpenIGTLink_PROTOCOL_VERSION >= 2 else if (strcmp(headerMsg->GetDeviceType(), "POINT") == 0) { ReceivePoint(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "TRAJ") == 0) { ReceiveTrajectory(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "STRING") == 0) { ReceiveString(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "TDATA") == 0) { ReceiveTrackingData(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "QTDATA") == 0) { ReceiveQuaternionTrackingData(socket, headerMsg); } else if (strcmp(headerMsg->GetDeviceType(), "CAPABILITY") == 0) { ReceiveCapability(socket, headerMsg);; } #endif //OpenIGTLink_PROTOCOL_VERSION >= 2 else { std::cerr << "Receiving : " << headerMsg->GetDeviceType() << std::endl; socket->Skip(headerMsg->GetBodySizeToRead(), 0); } // Obtaining the position and orientation information ObtainPosOrFromTx(transformMatrix, pos, orient); // Sending the information to the audiolink /* send a jamin scene change instruction with a 32bit integer argument */ lo_send(t, "/dumpOSC/Distance", "i", int(pos[0])); //lo_send(t, "/jamin/scene", "i", int(pos[1])); //lo_send(t, "/jamin/scene", "i", int(pos[2])); lo_send(t, "/dumpOSC/Alpha", "i", int((pos[1]*180/3.1418)*100.0/90.0 )); //Elevation lo_send(t, "/dumpOSC/Beta", "i", int((pos[2]*180/3.1418)*100.0/90.0) ); // Azimuth //lo_send(t, "/jamin/scene", "i", int(orient[2]*180/3.1418)); //std::cout << "Transform position = " << pos[0] << " " << pos[1] << " " << pos[2] << std::endl; std::cout << "Transform orientation = " << orient[0] << " " << orient[1] << " " << orient[2] << std::endl; } } //------------------------------------------------------------ // Close connection (The example code never reaches this section ...) socket->CloseSocket(); } int ReceiveTransform(igtl::Socket * socket, igtl::MessageHeader::Pointer& header, igtl::Matrix4x4 transformMatrix) { std::cerr << "Receiving TRANSFORM data type." << std::endl; // Create a message buffer to receive transform data igtl::TransformMessage::Pointer transMsg; transMsg = igtl::TransformMessage::New(); transMsg->SetMessageHeader(header); transMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(transMsg->GetPackBodyPointer(), transMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = transMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { // Retrive the transform data igtl::Matrix4x4 matrix; transMsg->GetMatrix(matrix); igtl::PrintMatrix(matrix); std::cerr << std::endl; for (int i = 0; i < 4; i++) { for (int j =0; j < 4; j++) { transformMatrix[i][j] = matrix[i][j]; } } return 1; } return 0; } void ObtainPosOrFromTx(igtl::Matrix4x4 txMatrix, double pos[3], double orient[3]) { pos[0] = txMatrix[0][3]; pos[1] = txMatrix[1][3]; pos[2] = txMatrix[2][3]; orient[1] = atan2(-txMatrix[2][0],pow(pow(txMatrix[0][0],2)+pow(txMatrix[1][0],2),0.5) ); //beta orient[2] = atan2(txMatrix[2][1]/cos(orient[1]),txMatrix[2][2]/cos(orient[1]) ); // gamma orient[0] = atan2(txMatrix[1][0]/cos(orient[1]),txMatrix[0][0]/cos(orient[1]) ); //alpha } int ReceivePosition(igtl::Socket * socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving POSITION data type." << std::endl; // Create a message buffer to receive transform data igtl::PositionMessage::Pointer positionMsg; positionMsg = igtl::PositionMessage::New(); positionMsg->SetMessageHeader(header); positionMsg->AllocatePack(); // Receive position position data from the socket socket->Receive(positionMsg->GetPackBodyPointer(), positionMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = positionMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { // Retrive the transform data float position[3]; float quaternion[4]; positionMsg->GetPosition(position); positionMsg->GetQuaternion(quaternion); std::cerr << "position = (" << position[0] << ", " << position[1] << ", " << position[2] << ")" << std::endl; std::cerr << "quaternion = (" << quaternion[0] << ", " << quaternion[1] << ", " << quaternion[2] << ", " << quaternion[3] << ")" << std::endl << std::endl; return 1; } return 0; } int ReceiveImage(igtl::Socket * socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving IMAGE data type." << std::endl; // Create a message buffer to receive transform data igtl::ImageMessage::Pointer imgMsg; imgMsg = igtl::ImageMessage::New(); imgMsg->SetMessageHeader(header); imgMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(imgMsg->GetPackBodyPointer(), imgMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = imgMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { // Retrive the image data int size[3]; // image dimension float spacing[3]; // spacing (mm/pixel) int svsize[3]; // sub-volume size int svoffset[3]; // sub-volume offset int scalarType; // scalar type scalarType = imgMsg->GetScalarType(); imgMsg->GetDimensions(size); imgMsg->GetSpacing(spacing); imgMsg->GetSubVolume(svsize, svoffset); std::cerr << "Device Name : " << imgMsg->GetDeviceName() << std::endl; std::cerr << "Scalar Type : " << scalarType << std::endl; std::cerr << "Dimensions : (" << size[0] << ", " << size[1] << ", " << size[2] << ")" << std::endl; std::cerr << "Spacing : (" << spacing[0] << ", " << spacing[1] << ", " << spacing[2] << ")" << std::endl; std::cerr << "Sub-Volume dimensions : (" << svsize[0] << ", " << svsize[1] << ", " << svsize[2] << ")" << std::endl; std::cerr << "Sub-Volume offset : (" << svoffset[0] << ", " << svoffset[1] << ", " << svoffset[2] << ")" << std::endl << std::endl; return 1; } return 0; } int ReceiveStatus(igtl::Socket * socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving STATUS data type." << std::endl; // Create a message buffer to receive transform data igtl::StatusMessage::Pointer statusMsg; statusMsg = igtl::StatusMessage::New(); statusMsg->SetMessageHeader(header); statusMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(statusMsg->GetPackBodyPointer(), statusMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = statusMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { std::cerr << "========== STATUS ==========" << std::endl; std::cerr << " Code : " << statusMsg->GetCode() << std::endl; std::cerr << " SubCode : " << statusMsg->GetSubCode() << std::endl; std::cerr << " Error Name: " << statusMsg->GetErrorName() << std::endl; std::cerr << " Status : " << statusMsg->GetStatusString() << std::endl; std::cerr << "============================" << std::endl << std::endl; } return 0; } #if OpenIGTLink_PROTOCOL_VERSION >= 2 int ReceivePoint(igtl::Socket * socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving POINT data type." << std::endl; // Create a message buffer to receive transform data igtl::PointMessage::Pointer pointMsg; pointMsg = igtl::PointMessage::New(); pointMsg->SetMessageHeader(header); pointMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(pointMsg->GetPackBodyPointer(), pointMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = pointMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { int nElements = pointMsg->GetNumberOfPointElement(); for (int i = 0; i < nElements; i ++) { igtl::PointElement::Pointer pointElement; pointMsg->GetPointElement(i, pointElement); igtlUint8 rgba[4]; pointElement->GetRGBA(rgba); igtlFloat32 pos[3]; pointElement->GetPosition(pos); std::cerr << "========== Element #" << i << " ==========" << std::endl; std::cerr << " Name : " << pointElement->GetName() << std::endl; std::cerr << " GroupName : " << pointElement->GetGroupName() << std::endl; std::cerr << " RGBA : ( " << (int)rgba[0] << ", " << (int)rgba[1] << ", " << (int)rgba[2] << ", " << (int)rgba[3] << " )" << std::endl; std::cerr << " Position : ( " << std::fixed << pos[0] << ", " << pos[1] << ", " << pos[2] << " )" << std::endl; std::cerr << " Radius : " << std::fixed << pointElement->GetRadius() << std::endl; std::cerr << " Owner : " << pointElement->GetOwner() << std::endl; std::cerr << "================================" << std::endl << std::endl; } } return 1; } int ReceiveTrajectory(igtl::Socket * socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving TRAJECTORY data type." << std::endl; // Create a message buffer to receive transform data igtl::TrajectoryMessage::Pointer trajectoryMsg; trajectoryMsg = igtl::TrajectoryMessage::New(); trajectoryMsg->SetMessageHeader(header); trajectoryMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(trajectoryMsg->GetPackBodyPointer(), trajectoryMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = trajectoryMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { int nElements = trajectoryMsg->GetNumberOfTrajectoryElement(); for (int i = 0; i < nElements; i ++) { igtl::TrajectoryElement::Pointer trajectoryElement; trajectoryMsg->GetTrajectoryElement(i, trajectoryElement); igtlUint8 rgba[4]; trajectoryElement->GetRGBA(rgba); igtlFloat32 entry[3]; igtlFloat32 target[3]; trajectoryElement->GetEntryPosition(entry); trajectoryElement->GetTargetPosition(target); std::cerr << "========== Element #" << i << " ==========" << std::endl; std::cerr << " Name : " << trajectoryElement->GetName() << std::endl; std::cerr << " GroupName : " << trajectoryElement->GetGroupName() << std::endl; std::cerr << " RGBA : ( " << (int)rgba[0] << ", " << (int)rgba[1] << ", " << (int)rgba[2] << ", " << (int)rgba[3] << " )" << std::endl; std::cerr << " Entry Pt : ( " << std::fixed << entry[0] << ", " << entry[1] << ", " << entry[2] << " )" << std::endl; std::cerr << " Target Pt : ( " << std::fixed << target[0] << ", " << target[1] << ", " << target[2] << " )" << std::endl; std::cerr << " Radius : " << std::fixed << trajectoryElement->GetRadius() << std::endl; std::cerr << " Owner : " << trajectoryElement->GetOwner() << std::endl; std::cerr << "================================" << std::endl << std::endl; } } return 1; } int ReceiveString(igtl::Socket * socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving STRING data type." << std::endl; // Create a message buffer to receive transform data igtl::StringMessage::Pointer stringMsg; stringMsg = igtl::StringMessage::New(); stringMsg->SetMessageHeader(header); stringMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(stringMsg->GetPackBodyPointer(), stringMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = stringMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { std::cerr << "Encoding: " << stringMsg->GetEncoding() << "; " << "String: " << stringMsg->GetString() << std::endl << std::endl; } return 1; } int ReceiveTrackingData(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving TDATA data type." << std::endl; // Create a message buffer to receive transform data igtl::TrackingDataMessage::Pointer trackingData; trackingData = igtl::TrackingDataMessage::New(); trackingData->SetMessageHeader(header); trackingData->AllocatePack(); // Receive body from the socket socket->Receive(trackingData->GetPackBodyPointer(), trackingData->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = trackingData->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { int nElements = trackingData->GetNumberOfTrackingDataElements(); for (int i = 0; i < nElements; i ++) { igtl::TrackingDataElement::Pointer trackingElement; trackingData->GetTrackingDataElement(i, trackingElement); igtl::Matrix4x4 matrix; trackingElement->GetMatrix(matrix); std::cerr << "========== Element #" << i << " ==========" << std::endl; std::cerr << " Name : " << trackingElement->GetName() << std::endl; std::cerr << " Type : " << (int) trackingElement->GetType() << std::endl; std::cerr << " Matrix : " << std::endl; igtl::PrintMatrix(matrix); std::cerr << "================================" << std::endl << std::endl; } return 1; } return 0; } int ReceiveQuaternionTrackingData(igtl::ClientSocket::Pointer& socket, igtl::MessageHeader::Pointer& header) { std::cerr << "Receiving QTDATA data type." << std::endl; // Create a message buffer to receive transform data igtl::QuaternionTrackingDataMessage::Pointer quaternionTrackingData; quaternionTrackingData = igtl::QuaternionTrackingDataMessage::New(); quaternionTrackingData->SetMessageHeader(header); quaternionTrackingData->AllocatePack(); // Receive body from the socket socket->Receive(quaternionTrackingData->GetPackBodyPointer(), quaternionTrackingData->GetPackBodySize()); // Deserialize position and quaternion (orientation) data // If you want to skip CRC check, call Unpack() without argument. int c = quaternionTrackingData->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { int nElements = quaternionTrackingData->GetNumberOfQuaternionTrackingDataElements(); for (int i = 0; i < nElements; i ++) { igtl::QuaternionTrackingDataElement::Pointer quaternionTrackingElement; quaternionTrackingData->GetQuaternionTrackingDataElement(i, quaternionTrackingElement); float position[3]; float quaternion[4]; quaternionTrackingElement->GetPosition(position); quaternionTrackingElement->GetQuaternion(quaternion); std::cerr << "========== Element #" << i << " ==========" << std::endl; std::cerr << " Name : " << quaternionTrackingElement->GetName() << std::endl; std::cerr << " Type : " << (int) quaternionTrackingElement->GetType() << std::endl; std::cerr << " Position : "; igtl::PrintVector3(position); std::cerr << " Quaternion : "; igtl::PrintVector4(quaternion); std::cerr << "================================" << std::endl << std::endl; } return 1; } return 0; } int ReceiveCapability(igtl::Socket * socket, igtl::MessageHeader * header) { std::cerr << "Receiving CAPABILITY data type." << std::endl; // Create a message buffer to receive transform data igtl::CapabilityMessage::Pointer capabilMsg; capabilMsg = igtl::CapabilityMessage::New(); capabilMsg->SetMessageHeader(header); capabilMsg->AllocatePack(); // Receive transform data from the socket socket->Receive(capabilMsg->GetPackBodyPointer(), capabilMsg->GetPackBodySize()); // Deserialize the transform data // If you want to skip CRC check, call Unpack() without argument. int c = capabilMsg->Unpack(1); if (c & igtl::MessageHeader::UNPACK_BODY) // if CRC check is OK { int nTypes = capabilMsg->GetNumberOfTypes(); for (int i = 0; i < nTypes; i ++) { std::cerr << "Typename #" << i << ": " << capabilMsg->GetType(i) << std::endl; } } return 1; } #endif //OpenIGTLink_PROTOCOL_VERSION >= 2