8 #include "PlusConfigure.h" 10 #include "igsioTrackedFrame.h" 18 #include "vtkIGSIORecursiveCriticalSection.h" 19 #include "vtkIGSIOTrackedFrameList.h" 20 #include "vtkIGSIOTransformRepository.h" 23 #include <vtkImageData.h> 24 #include <vtkObjectFactory.h> 25 #include <vtkPoints.h> 26 #include <vtkPolyData.h> 27 #include <vtkPolyDataReader.h> 30 #include <igtlCommandMessage.h> 31 #include <igtlImageMessage.h> 32 #include <igtlImageMetaMessage.h> 33 #include <igtlMessageHeader.h> 35 #include <igtlPointMessage.h> 36 #include <igtlPolyDataMessage.h> 37 #include <igtlStatusMessage.h> 38 #include <igtlStringMessage.h> 39 #include <igtlTrackingDataMessage.h> 42 #include <igtlioPolyDataConverter.h> 46 #elif defined(__APPLE__) 48 #elif defined(__linux__) 58 const double DELAY_ON_SENDING_ERROR_SEC = 0.02;
59 const double DELAY_ON_NO_NEW_FRAMES_SEC = 0.005;
60 const int NUMBER_OF_RECENT_COMMAND_IDS_STORED = 10;
61 const int IGTL_EMPTY_DATA_SIZE = -1;
62 const double SERVER_START_CHECK_DELAY_SEC = 2.0;
63 const double SERVER_START_CHECK_DELAY_INTERVAL_SEC = 0.05;
75 int vtkPlusOpenIGTLinkServer::ClientIdCounter = 1;
76 const float vtkPlusOpenIGTLinkServer::CLIENT_SOCKET_TIMEOUT_SEC = 0.5f;
80 : ServerSocket(
igtl::ServerSocket::New())
81 , TransformRepository(NULL)
83 , Threader(vtkSmartPointer<vtkMultiThreader>::New())
84 , IGTLProtocolVersion(OpenIGTLink_PROTOCOL_VERSION)
85 , IGTLHeaderVersion(IGTL_HEADER_VERSION_2)
87 , NumberOfRetryAttempts(10)
88 , DelayBetweenRetryAttemptsSec(0.05)
89 , MaxNumberOfIgtlMessagesToSend(100)
90 , ConnectionReceiverThreadId(-1)
91 , DataSenderThreadId(-1)
93 , IgtlClientsMutex(vtkSmartPointer<vtkIGSIORecursiveCriticalSection>::New())
94 , LastSentTrackedFrameTimestamp(0)
95 , MaxTimeSpentWithProcessingMs(50)
96 , LastProcessingTimePerFrameMs(-1)
97 , SendValidTransformsOnly(true)
98 , DefaultClientSendTimeoutSec(CLIENT_SOCKET_TIMEOUT_SEC)
99 , DefaultClientReceiveTimeoutSec(CLIENT_SOCKET_TIMEOUT_SEC)
100 , IgtlMessageCrcCheckEnabled(0)
102 , MessageResponseQueueMutex(vtkSmartPointer<vtkIGSIORecursiveCriticalSection>::New())
103 , BroadcastChannel(NULL)
104 , LogWarningOnNoDataAvailable(true)
105 , KeepAliveIntervalSec(CLIENT_SOCKET_TIMEOUT_SEC / 2.0)
107 , MissingInputGracePeriodSec(0.0)
108 , BroadcastStartTime(0.0)
109 , NewClientConnected(false)
120 this->SetConfigFilename(NULL);
128 igsioLockGuard<vtkIGSIORecursiveCriticalSection> igtlClientsMutexGuardedLock(this->IgtlClientsMutex);
129 for (std::list<ClientData>::iterator clientIterator = this->IgtlClients.begin(); clientIterator != this->IgtlClients.end(); ++clientIterator)
131 if (clientIterator->ClientId == clientId)
141 LOG_ERROR(
"Requested clientId " << clientId <<
" not found in list.");
145 igsioLockGuard<vtkIGSIORecursiveCriticalSection> mutexGuardedLock(this->MessageResponseQueueMutex);
146 this->MessageResponseQueue[clientId].push_back(
message);
154 this->Superclass::PrintSelf(os, indent);
160 if (this->DataCollector == NULL)
162 LOG_WARNING(
"Tried to start OpenIGTLink server without a vtkPlusDataCollector");
166 if (this->ConnectionReceiverThreadId < 0)
168 this->ConnectionActive.Request =
true;
169 this->ConnectionReceiverThreadId = this->Threader->SpawnThread((vtkThreadFunctionType)&
ConnectionReceiverThread,
this);
172 if (this->DataSenderThreadId < 0)
174 this->DataSenderActive.Request =
true;
175 this->DataSenderThreadId = this->Threader->SpawnThread((vtkThreadFunctionType)&
DataSenderThread,
this);
179 RETRY_UNTIL_TRUE(this->ConnectionActive.Respond,
180 vtkMath::Round(SERVER_START_CHECK_DELAY_SEC / SERVER_START_CHECK_DELAY_INTERVAL_SEC),
181 SERVER_START_CHECK_DELAY_INTERVAL_SEC);
182 if (!this->ConnectionActive.Respond)
184 LOG_ERROR(
"Unable to initialize receiver and sender processes.");
188 std::ostringstream ss;
189 ss <<
"Data sent by default: ";
190 this->DefaultClientInfo.
PrintSelf(ss, vtkIndent(0));
193 this->PlusCommandProcessor->SetPlusServer(
this);
195 this->BroadcastStartTime = vtkIGSIOAccurateTimer::GetSystemTime();
204 if (this->ConnectionReceiverThreadId >= 0)
206 this->ConnectionActive.Request =
false;
207 while (this->ConnectionActive.Respond)
210 vtkIGSIOAccurateTimer::DelayWithEventProcessing(0.2);
212 this->ConnectionReceiverThreadId = -1;
213 LOG_DEBUG(
"ConnectionReceiverThread stopped");
217 std::vector< int > clientIds;
220 igsioLockGuard<vtkIGSIORecursiveCriticalSection> igtlClientsMutexGuardedLock(this->IgtlClientsMutex);
221 for (std::list<ClientData>::iterator clientIterator = this->IgtlClients.begin(); clientIterator != this->IgtlClients.end(); ++clientIterator)
223 clientIds.push_back(clientIterator->ClientId);
226 for (std::vector< int >::iterator it = clientIds.begin(); it != clientIds.end(); ++it)
231 LOG_INFO(
"Plus OpenIGTLink server stopped.");
241 int r =
self->ServerSocket->CreateServer(self->ListeningPort);
244 LOG_ERROR(
"Cannot create a server socket.");
250 self->ConnectionActive.Respond =
true;
253 while (self->ConnectionActive.Request)
255 igtl::ClientSocket::Pointer newClientSocket =
self->ServerSocket->WaitForConnection(CLIENT_SOCKET_TIMEOUT_SEC * 1000);
256 if (newClientSocket.IsNotNull())
259 igsioLockGuard<vtkIGSIORecursiveCriticalSection> igtlClientsMutexGuardedLock(self->IgtlClientsMutex);
261 self->IgtlClients.push_back(newClient);
262 self->NewClientConnected =
true;
264 ClientData* client = &(
self->IgtlClients.back());
265 client->
ClientId =
self->ClientIdCounter;
266 self->ClientIdCounter++;
268 client->
ClientSocket->SetReceiveTimeout(self->DefaultClientReceiveTimeoutSec * 1000);
269 client->
ClientSocket->SetSendTimeout(self->DefaultClientSendTimeoutSec * 1000);
274 for (std::vector<PlusIgtlClientInfo::ImageStream>::iterator imageStreamIterator = client->
ClientInfo.
ImageStreams.begin();
280 imageStream->
FrameConverter = vtkSmartPointer<vtkIGSIOFrameConverter>::New();
283 for (std::vector<PlusIgtlClientInfo::VideoStream>::iterator videoStreamIterator = client->
ClientInfo.
VideoStreams.begin();
289 videoStream->
FrameConverter = vtkSmartPointer<vtkIGSIOFrameConverter>::New();
294 std::string
address =
"unknown";
295 #if (OPENIGTLINK_VERSION_MAJOR > 1) || ( OPENIGTLINK_VERSION_MAJOR == 1 && OPENIGTLINK_VERSION_MINOR > 9 ) || ( OPENIGTLINK_VERSION_MAJOR == 1 && OPENIGTLINK_VERSION_MINOR == 9 && OPENIGTLINK_VERSION_PATCH > 4 ) 296 newClientSocket->GetSocketAddressAndPort(
address,
port);
298 LOG_INFO(
"Received new client connection (client " << client->
ClientId <<
" at " <<
address <<
":" <<
port <<
"). Number of connected clients: " << self->GetNumberOfConnectedClients());
306 if (self->ServerSocket.IsNotNull())
308 self->ServerSocket->CloseSocket();
312 self->ConnectionReceiverThreadId = -1;
313 self->ConnectionActive.Respond =
false;
321 self->DataSenderActive.Respond =
true;
327 if (self->DataCollector->GetDevices(aCollection) !=
PLUS_SUCCESS || aCollection.size() == 0)
329 LOG_ERROR(
"Unable to retrieve devices. Check configuration and connection.");
343 if (aChannel == NULL)
346 if (!self->GetOutputChannelId().empty())
350 LOG_ERROR(
"Unable to start data sending. OutputChannelId not found: " << self->GetOutputChannelId());
366 if (aChannel == NULL)
368 LOG_WARNING(
"There are no channels to broadcast. Only command processing is available.");
371 self->BroadcastChannel = aChannel;
372 if (self->BroadcastChannel)
377 double elapsedTimeSinceLastPacketSentSec = 0;
378 while (self->ConnectionActive.Request && self->DataSenderActive.Request)
380 bool clientsConnected =
false;
382 igsioLockGuard<vtkIGSIORecursiveCriticalSection> igtlClientsMutexGuardedLock(self->IgtlClientsMutex);
383 if (!self->IgtlClients.empty())
385 clientsConnected =
true;
388 if (!clientsConnected)
391 vtkIGSIOAccurateTimer::Delay(0.2);
392 self->LastSentTrackedFrameTimestamp = 0;
396 if (self->HasGracePeriodExpired())
398 self->GracePeriodLogLevel = vtkPlusLogger::LOG_LEVEL_WARNING;
410 self->DataSenderThreadId = -1;
411 self->DataSenderActive.Respond =
false;
418 vtkSmartPointer<vtkIGSIOTrackedFrameList> trackedFrameList = vtkSmartPointer<vtkIGSIOTrackedFrameList>::New();
419 double startTimeSec = vtkIGSIOAccurateTimer::GetSystemTime();
422 if (
self.LastProcessingTimePerFrameMs < 1)
425 self.LastProcessingTimePerFrameMs = 1;
427 int numberOfFramesToGet = std::max(
self.MaxTimeSpentWithProcessingMs /
self.LastProcessingTimePerFrameMs, 1);
429 numberOfFramesToGet = std::min(numberOfFramesToGet,
self.MaxNumberOfIgtlMessagesToSend);
431 if (
self.BroadcastChannel != NULL)
433 if ((
self.BroadcastChannel->
HasVideoSource() && !
self.BroadcastChannel->GetVideoDataAvailable())
434 || (
self.BroadcastChannel->
ToolCount() > 0 && !
self.BroadcastChannel->GetTrackingDataAvailable())
435 || (
self.BroadcastChannel->
FieldCount() > 0 && !
self.BroadcastChannel->GetFieldDataAvailable()))
437 if (
self.LogWarningOnNoDataAvailable)
439 LOG_DYNAMIC(
"No data is broadcasted, as no data is available yet.",
self.GracePeriodLogLevel);
444 double oldestDataTimestamp = 0;
447 if (
self.LastSentTrackedFrameTimestamp < oldestDataTimestamp)
449 LOG_INFO(
"OpenIGTLink broadcasting started. No data was available between " <<
self.LastSentTrackedFrameTimestamp <<
"-" << oldestDataTimestamp <<
"sec, therefore no data were broadcasted during this time period.");
452 static vtkIGSIOLogHelper logHelper(60.0, 500000);
453 CUSTOM_RETURN_WITH_FAIL_IF(
self.BroadcastChannel->
GetTrackedFrameList(
self.LastSentTrackedFrameTimestamp, trackedFrameList, numberOfFramesToGet) !=
PLUS_SUCCESS,
454 "Failed to get tracked frame list from data collector (last recorded timestamp: " << std::fixed <<
self.LastSentTrackedFrameTimestamp);
460 if (trackedFrameList->GetNumberOfTrackedFrames() == 0)
462 vtkIGSIOAccurateTimer::Delay(DELAY_ON_NO_NEW_FRAMES_SEC);
463 elapsedTimeSinceLastPacketSentSec += vtkIGSIOAccurateTimer::GetSystemTime() - startTimeSec;
466 if (elapsedTimeSinceLastPacketSentSec >
self.KeepAliveIntervalSec)
469 elapsedTimeSinceLastPacketSentSec = 0;
476 for (
unsigned int i = 0;
i < trackedFrameList->GetNumberOfTrackedFrames(); ++
i)
479 self.SendTrackedFrame(*trackedFrameList->GetTrackedFrame(
i));
480 elapsedTimeSinceLastPacketSentSec = 0;
484 double computationTimeMs = (vtkIGSIOAccurateTimer::GetSystemTime() - startTimeSec) * 1000.0;
487 if (trackedFrameList->GetNumberOfTrackedFrames() > 0)
489 self.LastProcessingTimePerFrameMs = computationTimeMs / trackedFrameList->GetNumberOfTrackedFrames();
497 igsioLockGuard<vtkIGSIORecursiveCriticalSection> mutexGuardedLock(
self.MessageResponseQueueMutex);
498 if (!
self.MessageResponseQueue.empty())
500 for (ClientIdToMessageListMap::iterator it =
self.MessageResponseQueue.begin(); it !=
self.MessageResponseQueue.end(); ++it)
502 igsioLockGuard<vtkIGSIORecursiveCriticalSection> igtlClientsMutexGuardedLock(
self.IgtlClientsMutex);
503 igtl::ClientSocket::Pointer clientSocket = NULL;
505 for (std::list<ClientData>::iterator clientIterator =
self.IgtlClients.begin(); clientIterator !=
self.IgtlClients.end(); ++clientIterator)
507 if (clientIterator->ClientId == it->first)
509 clientSocket = clientIterator->ClientSocket;
513 if (clientSocket.IsNull())
515 LOG_WARNING(
"Message reply cannot be sent to client " << it->first <<
", probably client has been disconnected.");
519 for (std::vector<igtl::MessageBase::Pointer>::iterator messageIt = it->second.begin(); messageIt != it->second.end(); ++messageIt)
521 clientSocket->Send((*messageIt)->GetBufferPointer(), (*messageIt)->GetBufferSize());
524 self.MessageResponseQueue.clear();
534 self.PlusCommandProcessor->PopCommandResponses(replies);
535 if (!replies.empty())
537 for (PlusCommandResponseList::iterator responseIt = replies.begin(); responseIt != replies.end(); responseIt++)
539 igtl::MessageBase::Pointer igtlResponseMessage =
self.CreateIgtlMessageFromCommandResponse(*responseIt);
540 if (igtlResponseMessage.IsNull())
542 LOG_ERROR(
"Failed to create OpenIGTLink message from command response");
545 igtlResponseMessage->Pack();
548 LOG_DEBUG(
"Send command reply to client " << (*responseIt)->GetClientId() <<
": " << igtlResponseMessage->GetDeviceName());
549 igsioLockGuard<vtkIGSIORecursiveCriticalSection> igtlClientsMutexGuardedLock(
self.IgtlClientsMutex);
550 igtl::ClientSocket::Pointer clientSocket = NULL;
551 for (std::list<ClientData>::iterator clientIterator =
self.IgtlClients.begin(); clientIterator !=
self.IgtlClients.end(); ++clientIterator)
553 if (clientIterator->ClientId == (*responseIt)->GetClientId())
555 clientSocket = clientIterator->ClientSocket;
560 if (clientSocket.IsNull())
562 LOG_WARNING(
"Message reply cannot be sent to client " << (*responseIt)->GetClientId() <<
", probably client has been disconnected");
565 clientSocket->Send(igtlResponseMessage->GetBufferPointer(), igtlResponseMessage->GetBufferSize());
580 std::deque<uint32_t> previousCommandIds;
583 igtl::ClientSocket::Pointer clientSocket = client->
ClientSocket;
586 igtl::MessageHeader::Pointer headerMsg =
self->IgtlMessageFactory->CreateHeaderMessage(IGTL_HEADER_VERSION_1);
590 headerMsg->InitBuffer();
594 igtlUint64 bytesReceived = clientSocket->Receive(headerMsg->GetBufferPointer(), headerMsg->GetBufferSize(), timeout);
595 if (bytesReceived == IGTL_EMPTY_DATA_SIZE || bytesReceived != headerMsg->GetBufferSize())
597 vtkIGSIOAccurateTimer::Delay(0.1);
601 headerMsg->Unpack(self->IgtlMessageCrcCheckEnabled);
604 igsioLockGuard<vtkIGSIORecursiveCriticalSection> igtlClientsMutexGuardedLock(self->IgtlClientsMutex);
613 igtl::MessageBase::Pointer bodyMessage =
self->IgtlMessageFactory->CreateReceiveMessage(headerMsg);
614 if (bodyMessage.IsNull())
616 LOG_ERROR(
"Unable to receive message from client: " << client->
ClientId);
622 igtl::PlusClientInfoMessage::Pointer clientInfoMsg = dynamic_cast<igtl::PlusClientInfoMessage*>(bodyMessage.GetPointer());
623 clientInfoMsg->SetMessageHeader(headerMsg);
624 clientInfoMsg->AllocateBuffer();
627 clientSocket->Receive(clientInfoMsg->GetBufferBodyPointer(), clientInfoMsg->GetBufferBodySize(), timeout);
629 int c = clientInfoMsg->Unpack(self->IgtlMessageCrcCheckEnabled);
630 if (c & igtl::MessageHeader::UNPACK_BODY || clientInfoMsg->GetBufferBodySize() == 0)
633 igsioLockGuard<vtkIGSIORecursiveCriticalSection> igtlClientsMutexGuardedLock(self->IgtlClientsMutex);
634 client->
ClientInfo = clientInfoMsg->GetClientInfo();
635 LOG_DEBUG(
"Client info message received from client " << clientId);
638 else if (
typeid(*bodyMessage) ==
typeid(igtl::GetStatusMessage))
641 clientSocket->Skip(headerMsg->GetBodySizeToRead(), 0);
643 igtl::StatusMessage::Pointer replyMsg = dynamic_cast<igtl::StatusMessage*>(self->IgtlMessageFactory->CreateSendMessage(
"STATUS", client->
ClientInfo.
GetClientHeaderVersion()).GetPointer());
644 replyMsg->SetCode(igtl::StatusMessage::STATUS_OK);
646 clientSocket->Send(replyMsg->GetBufferPointer(), replyMsg->GetBufferSize());
648 else if (
typeid(*bodyMessage) ==
typeid(igtl::StringMessage)
651 igtl::StringMessage::Pointer stringMsg = dynamic_cast<igtl::StringMessage*>(bodyMessage.GetPointer());
652 stringMsg->SetMessageHeader(headerMsg);
653 stringMsg->AllocateBuffer();
655 clientSocket->Receive(stringMsg->GetBufferBodyPointer(), stringMsg->GetBufferBodySize(), timeout);
658 int c = stringMsg->Unpack(self->IgtlMessageCrcCheckEnabled);
659 if (c & igtl::MessageHeader::UNPACK_BODY || stringMsg->GetBufferBodySize() == 0)
661 std::string
deviceName(headerMsg->GetDeviceName());
671 #if (_MSC_VER == 1500) 678 catch (std::invalid_argument e)
680 LOG_ERROR(
"Unable to extract command UID from device name string.");
688 if (std::find(previousCommandIds.begin(), previousCommandIds.end(), uid) != previousCommandIds.end())
691 LOG_WARNING(
"Already received a command with id = " << uid <<
" from client " << clientId <<
". This repeated command will be ignored.");
695 previousCommandIds.push_back(uid);
696 if (previousCommandIds.size() > NUMBER_OF_RECENT_COMMAND_IDS_STORED)
698 previousCommandIds.pop_front();
701 LOG_DEBUG(
"Received command from client " << clientId <<
", device " <<
deviceName <<
" with UID " << uid <<
": " << stringMsg->GetString());
703 vtkSmartPointer<vtkXMLDataElement> cmdElement = vtkSmartPointer<vtkXMLDataElement>::Take(vtkXMLUtilities::ReadElementFromString(stringMsg->GetString()));
704 std::string commandName = std::string(cmdElement->GetAttribute(
"Name") == NULL ?
"" : cmdElement->GetAttribute(
"Name"));
706 self->PlusCommandProcessor->QueueCommand(
false, clientId, commandName, stringMsg->GetString(),
deviceName, uid, stringMsg->GetMetaData());
710 else if (
typeid(*bodyMessage) ==
typeid(igtl::CommandMessage))
712 igtl::CommandMessage::Pointer commandMsg = dynamic_cast<igtl::CommandMessage*>(bodyMessage.GetPointer());
713 commandMsg->SetMessageHeader(headerMsg);
714 commandMsg->AllocateBuffer();
716 void* bodyPointer(commandMsg->GetBufferBodyPointer());
717 igtlUint64 bodySize(commandMsg->GetBufferBodySize());
719 igtlUint64 bytesReceived = clientSocket->Receive(bodyPointer, bodySize, timeout);
720 if (bytesReceived == IGTL_EMPTY_DATA_SIZE || bytesReceived != bodySize)
722 LOG_ERROR(
"Failed to receive command message from client " << clientId);
726 int c = commandMsg->Unpack(self->IgtlMessageCrcCheckEnabled);
727 if (c & igtl::MessageHeader::UNPACK_BODY || commandMsg->GetBufferBodySize() == 0)
729 std::string
deviceName(headerMsg->GetDeviceName());
732 uid = commandMsg->GetCommandId();
734 if (std::find(previousCommandIds.begin(), previousCommandIds.end(), uid) != previousCommandIds.end())
737 LOG_WARNING(
"Already received a command with id = " << uid <<
" from client " << clientId <<
". This repeated command will be ignored.");
741 previousCommandIds.push_back(uid);
742 if (previousCommandIds.size() > NUMBER_OF_RECENT_COMMAND_IDS_STORED)
744 previousCommandIds.pop_front();
747 LOG_DEBUG(
"Received header version " << commandMsg->GetHeaderVersion() <<
" command " << commandMsg->GetCommandName()
748 <<
" from client " << clientId <<
", device " <<
deviceName <<
" with UID " << uid <<
": " << commandMsg->GetCommandContent());
750 self->PlusCommandProcessor->QueueCommand(
true, clientId, commandMsg->GetCommandName(), commandMsg->GetCommandContent(),
deviceName, uid, commandMsg->GetMetaData());
754 LOG_ERROR(
"STRING message unpacking failed for client " << clientId);
757 else if (
typeid(*bodyMessage) ==
typeid(igtl::StartTrackingDataMessage))
761 igtl::StartTrackingDataMessage::Pointer startTracking = dynamic_cast<igtl::StartTrackingDataMessage*>(bodyMessage.GetPointer());
762 startTracking->SetMessageHeader(headerMsg);
763 startTracking->AllocateBuffer();
765 clientSocket->Receive(startTracking->GetBufferBodyPointer(), startTracking->GetBufferBodySize(), timeout);
767 int c = startTracking->Unpack(self->IgtlMessageCrcCheckEnabled);
768 if (c & igtl::MessageHeader::UNPACK_BODY || startTracking->GetBufferBodySize() == 0)
775 LOG_ERROR(
"Client " << clientId <<
" STT_TDATA failed: could not retrieve startTracking message");
780 igtl::RTSTrackingDataMessage* rtsMsg = dynamic_cast<igtl::RTSTrackingDataMessage*>(msg.GetPointer());
781 rtsMsg->SetStatus(0);
783 self->QueueMessageResponseForClient(client->
ClientId, msg);
785 else if (
typeid(*bodyMessage) ==
typeid(igtl::StopTrackingDataMessage))
787 igtl::StopTrackingDataMessage::Pointer stopTracking = dynamic_cast<igtl::StopTrackingDataMessage*>(bodyMessage.GetPointer());
788 stopTracking->SetMessageHeader(headerMsg);
789 stopTracking->AllocateBuffer();
791 clientSocket->Receive(stopTracking->GetBufferBodyPointer(), stopTracking->GetBufferBodySize(), timeout);
795 igtl::RTSTrackingDataMessage* rtsMsg = dynamic_cast<igtl::RTSTrackingDataMessage*>(msg.GetPointer());
796 rtsMsg->SetStatus(0);
798 self->QueueMessageResponseForClient(client->
ClientId, msg);
800 else if (
typeid(*bodyMessage) ==
typeid(igtl::GetPolyDataMessage))
802 igtl::GetPolyDataMessage::Pointer polyDataMessage = dynamic_cast<igtl::GetPolyDataMessage*>(bodyMessage.GetPointer());
803 polyDataMessage->SetMessageHeader(headerMsg);
804 polyDataMessage->AllocateBuffer();
806 clientSocket->Receive(polyDataMessage->GetBufferBodyPointer(), polyDataMessage->GetBufferBodySize(), timeout);
808 int c = polyDataMessage->Unpack(self->IgtlMessageCrcCheckEnabled);
809 if (c & igtl::MessageHeader::UNPACK_BODY || polyDataMessage->GetBufferBodySize() == 0)
811 std::string fileName;
813 if (polyDataMessage->GetHeaderVersion() > IGTL_HEADER_VERSION_1)
815 if (!polyDataMessage->GetMetaDataElement(
"filename", fileName))
817 fileName = polyDataMessage->GetDeviceName();
818 if (fileName.empty())
820 LOG_ERROR(
"GetPolyData message sent with no filename in either metadata or deviceName field.");
827 fileName = polyDataMessage->GetDeviceName();
828 if (fileName.empty())
830 LOG_ERROR(
"GetPolyData message sent with no filename in either metadata or deviceName field.");
835 vtkSmartPointer<vtkPolyDataReader> reader = vtkSmartPointer<vtkPolyDataReader>::New();
836 reader->SetFileName(fileName.c_str());
839 auto polyData = reader->GetOutput();
840 if (polyData !=
nullptr)
843 igtl::PolyDataMessage* polyMsg = dynamic_cast<igtl::PolyDataMessage*>(msg.GetPointer());
845 igtlioPolyDataConverter::ContentData
data;
846 data.deviceName =
"PlusServer";
847 data.polydata = polyData;
849 igtlioBaseConverter::HeaderData header;
850 header.deviceName =
"PlusServer";
852 igtlioPolyDataConverter::toIGTL(header,
data, (igtl::PolyDataMessage::Pointer*)&msg);
853 if (!msg->SetMetaDataElement(
"fileName", IANA_TYPE_US_ASCII, fileName))
855 LOG_ERROR(
"Filename too long to be sent back to client. Aborting.");
858 self->QueueMessageResponseForClient(client->
ClientId, msg);
862 igtl::MessageBase::Pointer msg =
self->IgtlMessageFactory->CreateSendMessage(
"RTS_POLYDATA", polyDataMessage->GetHeaderVersion());
863 igtl::RTSPolyDataMessage* rtsPolyMsg = dynamic_cast<igtl::RTSPolyDataMessage*>(msg.GetPointer());
864 rtsPolyMsg->SetStatus(
false);
865 self->QueueMessageResponseForClient(client->
ClientId, rtsPolyMsg);
869 LOG_ERROR(
"Client " << clientId <<
" GET_POLYDATA failed: could not retrieve message");
873 else if (
typeid(*bodyMessage) ==
typeid(igtl::StatusMessage))
876 clientSocket->Skip(headerMsg->GetBodySizeToRead(), 0);
878 else if (
typeid(*bodyMessage) ==
typeid(igtl::GetImageMetaMessage))
880 igtl::GetImageMetaMessage::Pointer getImageMetaMsg = dynamic_cast<igtl::GetImageMetaMessage*>(bodyMessage.GetPointer());
881 getImageMetaMsg->SetMessageHeader(headerMsg);
882 getImageMetaMsg->AllocateBuffer();
884 clientSocket->Receive(getImageMetaMsg->GetBufferBodyPointer(), getImageMetaMsg->GetBufferBodySize(), timeout);
886 int c = getImageMetaMsg->Unpack(self->IgtlMessageCrcCheckEnabled);
887 if (c & igtl::MessageHeader::UNPACK_BODY || getImageMetaMsg->GetBufferBodySize() == 0)
891 if (headerMsg->GetDeviceName() != NULL)
895 self->PlusCommandProcessor->QueueGetImageMetaData(clientId,
deviceName);
899 LOG_ERROR(
"Client " << clientId <<
" GET_IMGMETA failed: could not retrieve message");
903 else if (
typeid(*bodyMessage) ==
typeid(igtl::GetImageMessage))
905 igtl::GetImageMessage::Pointer getImageMsg = dynamic_cast<igtl::GetImageMessage*>(bodyMessage.GetPointer());
906 getImageMsg->SetMessageHeader(headerMsg);
907 getImageMsg->AllocateBuffer();
909 clientSocket->Receive(getImageMsg->GetBufferBodyPointer(), getImageMsg->GetBufferBodySize(), timeout);
911 int c = getImageMsg->Unpack(self->IgtlMessageCrcCheckEnabled);
912 if (c & igtl::MessageHeader::UNPACK_BODY || getImageMsg->GetBufferBodySize() == 0)
915 if (headerMsg->GetDeviceName() != NULL)
921 LOG_ERROR(
"Please select the image you want to acquire");
924 self->PlusCommandProcessor->QueueGetImage(clientId,
deviceName);
928 LOG_ERROR(
"Client " << clientId <<
" GET_IMAGE failed: could not retrieve message");
933 else if (
typeid(*bodyMessage) ==
typeid(igtl::GetPointMessage))
935 igtl::GetPointMessage* getPointMsg = dynamic_cast<igtl::GetPointMessage*>(bodyMessage.GetPointer());
936 getPointMsg->SetMessageHeader(headerMsg);
937 getPointMsg->AllocateBuffer();
939 clientSocket->Receive(getPointMsg->GetBufferBodyPointer(), getPointMsg->GetBufferBodySize(), timeout);
941 int c = getPointMsg->Unpack(self->IgtlMessageCrcCheckEnabled);
942 if (c & igtl::MessageHeader::UNPACK_BODY || getPointMsg->GetBufferBodySize() == 0)
944 std::string fileName;
945 if (!getPointMsg->GetMetaDataElement(
"Filename", fileName))
947 fileName = getPointMsg->GetDeviceName();
950 if (igsioCommon::Tail(fileName, 4) !=
"fcsv")
952 LOG_WARNING(
"Filename does not end in fcsv. GetPoint behaviour may not function correctly.");
955 if (!vtksys::SystemTools::FileExists(fileName) &&
958 LOG_ERROR(
"File: " << fileName <<
" requested but does not exist. Cannot get POINT data from it.");
963 igtl::PointMessage* pointMsg = dynamic_cast<igtl::PointMessage*>(msg.GetPointer());
965 std::ifstream
t(fileName);
971 LOG_ERROR(
"Cannot read file: " << fileName);
975 std::stringstream buffer;
977 std::vector<std::string> lines = igsioCommon::SplitStringIntoTokens(buffer.str(),
'\n',
false);
978 for (std::vector<std::string>::iterator it = lines.begin(); it != lines.end(); ++it)
980 std::string
line = igsioCommon::Trim(*it);
986 std::vector<std::string> tokens = igsioCommon::SplitStringIntoTokens(
line,
',',
true);
987 igtl::PointElement::Pointer elem = igtl::PointElement::New();
988 elem->SetPosition(std::stof(tokens[1]), std::stof(tokens[2]), std::stof(tokens[3]));
989 elem->SetName(tokens[0].c_str());
990 elem->SetGroupName(
"Point");
991 pointMsg->AddPointElement(elem);
994 self->QueueMessageResponseForClient(client->
ClientId, pointMsg);
998 LOG_ERROR(
"Client " << clientId <<
" GET_POINT failed: could not retrieve message");
1005 LOG_WARNING(
"Unknown OpenIGTLink message is received from client " << clientId <<
". Device type: " << headerMsg->GetMessageType()
1006 <<
". Device name: " << headerMsg->GetDeviceName() <<
".");
1007 clientSocket->Skip(headerMsg->GetBodySizeToRead(), 0);
1020 int numberOfErrors = 0;
1023 if (this->TransformRepository != NULL)
1025 if (this->TransformRepository->SetTransforms(trackedFrame) !=
PLUS_SUCCESS)
1027 LOG_ERROR(
"Failed to set current transforms to transform repository");
1033 double timestampSystem = trackedFrame.GetTimestamp();
1034 double timestampUniversal = vtkIGSIOAccurateTimer::GetUniversalTimeFromSystemTime(timestampSystem);
1035 trackedFrame.SetTimestamp(timestampUniversal);
1037 std::vector<int> disconnectedClientIds;
1040 igsioLockGuard<vtkIGSIORecursiveCriticalSection> igtlClientsMutexGuardedLock(this->IgtlClientsMutex);
1041 if (this->NewClientConnected)
1043 for (std::list<ClientData>::iterator clientIterator = this->IgtlClients.begin(); clientIterator != this->IgtlClients.end(); ++clientIterator)
1045 std::vector<PlusIgtlClientInfo::VideoStream> videoStreams = (*clientIterator).ClientInfo.VideoStreams;
1046 for (std::vector<PlusIgtlClientInfo::VideoStream>::iterator videoStream = videoStreams.begin(); videoStream != videoStreams.end(); ++videoStream)
1048 vtkIGSIOFrameConverter* frameConverter = videoStream->FrameConverter;
1051 frameConverter->RequestKeyFrameOn();
1056 this->NewClientConnected =
false;
1058 for (std::list<ClientData>::iterator clientIterator = this->IgtlClients.begin(); clientIterator != this->IgtlClients.end(); ++clientIterator)
1060 igtl::ClientSocket::Pointer clientSocket = (*clientIterator).ClientSocket;
1063 std::vector<igtl::MessageBase::Pointer> igtlMessages;
1064 std::vector<igtl::MessageBase::Pointer>::iterator igtlMessageIterator;
1066 if (this->IgtlMessageFactory->PackMessages(clientIterator->ClientId, clientIterator->ClientInfo, igtlMessages, trackedFrame, this->SendValidTransformsOnly, this->TransformRepository) !=
PLUS_SUCCESS)
1068 LOG_WARNING(
"Failed to pack all IGT messages");
1072 for (igtlMessageIterator = igtlMessages.begin(); igtlMessageIterator != igtlMessages.end(); ++igtlMessageIterator)
1074 igtl::MessageBase::Pointer igtlMessage = (*igtlMessageIterator);
1075 if (igtlMessage.IsNull())
1081 RETRY_UNTIL_TRUE((retValue = clientSocket->Send(igtlMessage->GetBufferPointer(), igtlMessage->GetBufferSize())) != 0, this->NumberOfRetryAttempts, this->DelayBetweenRetryAttemptsSec);
1084 disconnectedClientIds.push_back(clientIterator->ClientId);
1085 auto ts = igtl::TimeStamp::New();
1086 igtlMessage->GetTimeStamp(ts);
1087 LOG_INFO(
"Client disconnected - could not send " << igtlMessage->GetMessageType() <<
" message to client (device name: " << igtlMessage->GetDeviceName()
1088 <<
" Timestamp: " << std::fixed << ts->GetTimeStamp() <<
").");
1093 clientIterator->ClientInfo.SetLastTDATASentTimeStamp(trackedFrame.GetTimestamp());
1099 for (std::vector< int >::iterator it = disconnectedClientIds.begin(); it != disconnectedClientIds.end(); ++it)
1105 trackedFrame.SetTimestamp(timestampSystem);
1116 igsioLockGuard<vtkIGSIORecursiveCriticalSection> igtlClientsMutexGuardedLock(this->IgtlClientsMutex);
1117 for (std::list<ClientData>::iterator clientIterator = this->IgtlClients.begin(); clientIterator != this->IgtlClients.end(); ++clientIterator)
1119 if (clientIterator->ClientId != clientId)
1123 clientIterator->DataReceiverActive.first =
false;
1129 bool clientDataReceiverThreadStillActive =
false;
1132 clientDataReceiverThreadStillActive =
false;
1135 igsioLockGuard<vtkIGSIORecursiveCriticalSection> igtlClientsMutexGuardedLock(this->IgtlClientsMutex);
1136 for (std::list<ClientData>::iterator clientIterator = this->IgtlClients.begin(); clientIterator != this->IgtlClients.end(); ++clientIterator)
1138 if (clientIterator->ClientId != clientId)
1142 if (clientIterator->DataReceiverThreadId >= 0)
1144 if (clientIterator->DataReceiverActive.second)
1147 clientDataReceiverThreadStillActive =
true;
1155 this->Threader->TerminateThread(clientIterator->DataReceiverThreadId);
1156 clientIterator->DataReceiverThreadId = -1;
1162 if (clientDataReceiverThreadStillActive)
1165 vtkIGSIOAccurateTimer::DelayWithEventProcessing(0.2);
1168 while (clientDataReceiverThreadStillActive);
1172 std::string
address =
"unknown";
1174 igsioLockGuard<vtkIGSIORecursiveCriticalSection> igtlClientsMutexGuardedLock(this->IgtlClientsMutex);
1175 for (std::list<ClientData>::iterator clientIterator = this->IgtlClients.begin(); clientIterator != this->IgtlClients.end(); ++clientIterator)
1177 if (clientIterator->ClientId != clientId)
1181 if (clientIterator->ClientSocket.IsNotNull())
1183 #if (OPENIGTLINK_VERSION_MAJOR > 1) || ( OPENIGTLINK_VERSION_MAJOR == 1 && OPENIGTLINK_VERSION_MINOR > 9 ) || ( OPENIGTLINK_VERSION_MAJOR == 1 && OPENIGTLINK_VERSION_MINOR == 9 && OPENIGTLINK_VERSION_PATCH > 4 ) 1184 clientIterator->ClientSocket->GetSocketAddressAndPort(
address,
port);
1186 clientIterator->ClientSocket->CloseSocket();
1188 this->IgtlClients.erase(clientIterator);
1199 LOG_TRACE(
"Keep alive packet sent to clients...");
1201 std::vector< int > disconnectedClientIds;
1205 igsioLockGuard<vtkIGSIORecursiveCriticalSection> igtlClientsMutexGuardedLock(this->IgtlClientsMutex);
1207 for (std::list<ClientData>::iterator clientIterator = this->IgtlClients.begin(); clientIterator != this->IgtlClients.end(); ++clientIterator)
1209 auto replyMsg = igtl::StatusMessage::New();
1210 replyMsg->SetCode(igtl::StatusMessage::STATUS_OK);
1215 (retValue = clientIterator->ClientSocket->Send(replyMsg->GetPackPointer(), replyMsg->GetPackSize())) != 0,
1216 this->NumberOfRetryAttempts, this->DelayBetweenRetryAttemptsSec);
1219 disconnectedClientIds.push_back(clientIterator->ClientId);
1220 auto ts = igtl::TimeStamp::New();
1221 replyMsg->GetTimeStamp(ts);
1223 LOG_DEBUG(
"Client disconnected - could not send " << replyMsg->GetMessageType() <<
" message to client (device name: " << replyMsg->GetDeviceName()
1224 <<
" Timestamp: " << std::fixed << ts->GetTimeStamp() <<
").");
1230 for (std::vector< int >::iterator it = disconnectedClientIds.begin(); it != disconnectedClientIds.end(); ++it)
1240 igsioLockGuard<vtkIGSIORecursiveCriticalSection> igtlClientsMutexGuardedLock(this->IgtlClientsMutex);
1241 return this->IgtlClients.size();
1247 igsioLockGuard<vtkIGSIORecursiveCriticalSection> igtlClientsMutexGuardedLock(this->IgtlClientsMutex);
1248 for (std::list<ClientData>::const_iterator it = this->IgtlClients.begin(); it != this->IgtlClients.end(); ++it)
1250 if (it->ClientId == clientId)
1252 outClientInfo = it->ClientInfo;
1263 LOG_TRACE(
"vtkPlusOpenIGTLinkServer::ReadConfiguration");
1265 if (aFilename.empty())
1267 LOG_ERROR(
"Unable to configure PlusServer without an acceptable config file submitted.");
1270 this->SetConfigFilename(aFilename);
1272 XML_READ_SCALAR_ATTRIBUTE_REQUIRED(
int, ListeningPort, serverElement);
1273 XML_READ_STRING_ATTRIBUTE_REQUIRED(OutputChannelId, serverElement);
1274 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
double, MissingInputGracePeriodSec, serverElement);
1275 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
double, MaxTimeSpentWithProcessingMs, serverElement);
1276 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
int, MaxNumberOfIgtlMessagesToSend, serverElement);
1277 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
int, NumberOfRetryAttempts, serverElement);
1278 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
double, DelayBetweenRetryAttemptsSec, serverElement);
1279 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
double, KeepAliveIntervalSec, serverElement);
1280 XML_READ_BOOL_ATTRIBUTE_OPTIONAL(SendValidTransformsOnly, serverElement);
1281 XML_READ_BOOL_ATTRIBUTE_OPTIONAL(IgtlMessageCrcCheckEnabled, serverElement);
1282 XML_READ_BOOL_ATTRIBUTE_OPTIONAL(LogWarningOnNoDataAvailable, serverElement);
1292 vtkXMLDataElement* defaultClientInfo = serverElement->FindNestedElementWithName(
"DefaultClientInfo");
1293 if (defaultClientInfo != NULL)
1301 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
float, DefaultClientSendTimeoutSec, serverElement);
1302 XML_READ_SCALAR_ATTRIBUTE_OPTIONAL(
float, DefaultClientReceiveTimeoutSec, serverElement);
1310 return this->PlusCommandProcessor->ExecuteCommands();
1316 return (vtkIGSIOAccurateTimer::GetSystemTime() - this->BroadcastStartTime) > this->MissingInputGracePeriodSec;
1322 if (serverElement == NULL)
1324 LOG_ERROR(
"NULL configuration sent to vtkPlusOpenIGTLinkServer::Start. Unable to start PlusServer.");
1331 LOG_ERROR(
"Failed to read PlusOpenIGTLinkServer configuration");
1338 LOG_ERROR(
"Failed to start Plus OpenIGTLink server");
1365 int replyHeaderVersion = IGTL_HEADER_VERSION_1;
1369 LOG_ERROR(
"Unable to find client with ID: " << response->
GetClientId());
1378 igtl::StringMessage::Pointer igtlMessage = dynamic_cast<igtl::StringMessage*>(this->IgtlMessageFactory->CreateSendMessage(
"STRING", replyHeaderVersion).GetPointer());
1379 igtlMessage->SetDeviceName(stringResponse->
GetDeviceName().c_str());
1380 igtlMessage->SetString(stringResponse->
GetMessage());
1381 LOG_DEBUG(
"String response: " << stringResponse->
GetMessage());
1382 return igtlMessage.GetPointer();
1389 if (imageName.empty())
1391 imageName =
"PlusServerImage";
1394 vtkSmartPointer<vtkMatrix4x4> imageToReferenceTransform = vtkSmartPointer<vtkMatrix4x4>::New();
1400 vtkImageData* imageData = imageResponse->
GetImageData();
1401 if (imageData == NULL)
1403 LOG_ERROR(
"Invalid image data in command response");
1407 igtl::ImageMessage::Pointer igtlMessage = dynamic_cast<igtl::ImageMessage*>(this->IgtlMessageFactory->CreateSendMessage(
"IMAGE", replyHeaderVersion).GetPointer());
1408 igtlMessage->SetDeviceName(imageName.c_str());
1412 LOG_ERROR(
"Failed to create image mesage from command response");
1415 return igtlMessage.GetPointer();
1419 if (polydataResponse)
1422 if (polydataName.empty())
1424 polydataName =
"UnknownFile";
1427 vtkSmartPointer<vtkPolyData> polyData = polydataResponse->
GetPolyData();
1428 if (polyData == NULL)
1430 LOG_ERROR(
"Missing polydata in command response");
1434 igtl::PolyDataMessage::Pointer igtlMessage = dynamic_cast<igtl::PolyDataMessage*>(this->IgtlMessageFactory->CreateSendMessage(
"POLYDATA", replyHeaderVersion).GetPointer());
1435 igtlMessage->SetDeviceName(
"PlusServer");
1436 igtlMessage->SetMetaDataElement(
"fileName", IANA_TYPE_US_ASCII, polydataName);
1440 LOG_ERROR(
"Failed to create polydata mesage from command response");
1443 return igtlMessage.GetPointer();
1447 if (imageMetaDataResponse)
1449 std::string imageMetaDataName =
"PlusServerImageMetaData";
1450 igsioCommon::ImageMetaDataList imageMetaDataList;
1452 igtl::ImageMetaMessage::Pointer igtlMessage = dynamic_cast<igtl::ImageMetaMessage*>(this->IgtlMessageFactory->CreateSendMessage(
"IMGMETA", replyHeaderVersion).GetPointer());
1453 igtlMessage->SetDeviceName(imageMetaDataName.c_str());
1456 LOG_ERROR(
"Failed to create image mesage from command response");
1459 return igtlMessage.GetPointer();
1463 if (commandResponse)
1468 igtl::StringMessage::Pointer igtlMessage = dynamic_cast<igtl::StringMessage*>(this->IgtlMessageFactory->CreateSendMessage(
"STRING", replyHeaderVersion).GetPointer());
1471 std::ostringstream replyStr;
1472 replyStr <<
"<CommandReply";
1473 replyStr <<
" Status=\"" << (commandResponse->
GetStatus() ==
PLUS_SUCCESS ?
"SUCCESS" :
"FAIL") <<
"\"";
1474 replyStr <<
" Message=\"";
1476 vtkXMLUtilities::EncodeString(commandResponse->
GetResultString().c_str(), VTK_ENCODING_NONE, replyStr, VTK_ENCODING_NONE, 1 );
1480 igtlMessage->SetString(replyStr.str().c_str());
1481 LOG_DEBUG(
"Command response: " << replyStr.str());
1482 return igtlMessage.GetPointer();
1487 igtl::RTSCommandMessage::Pointer igtlMessage = dynamic_cast<igtl::RTSCommandMessage*>(this->IgtlMessageFactory->CreateSendMessage(
"RTS_COMMAND", replyHeaderVersion).GetPointer());
1489 igtlMessage->SetDeviceName(commandResponse->
GetDeviceName().c_str());
1491 igtlMessage->SetCommandId(commandResponse->
GetOriginalId());
1494 std::ostringstream replyStr;
1498 replyStr <<
"<CommandReply";
1499 replyStr <<
" Name=\"" << commandResponse->
GetCommandName() <<
"\"";
1500 replyStr <<
" Status=\"" << (commandResponse->
GetStatus() ?
"SUCCESS" :
"FAIL") <<
"\"";
1503 replyStr <<
" Error=\"" << commandResponse->
GetErrorString() <<
"\"";
1505 replyStr <<
" Message=\"" << commandResponse->
GetResultString() <<
"\"></CommandReply>";
1506 igtlMessage->SetMetaDataElement(
"Message", IANA_TYPE_US_ASCII, commandResponse->
GetResultString());
1512 igtlMessage->SetCommandContent(replyStr.str());
1514 for (igtl::MessageBase::MetaDataMap::const_iterator it = begin(commandResponse->
GetParameters()); it != end(commandResponse->
GetParameters()); ++it)
1516 igtlMessage->SetMetaDataElement(it->first, it->second.first, it->second.second);
1519 igtlMessage->SetMetaDataElement(
"Status", IANA_TYPE_US_ASCII, (commandResponse->
GetStatus() ?
"SUCCESS" :
"FAIL"));
1522 igtlMessage->SetMetaDataElement(
"Error", IANA_TYPE_US_ASCII, commandResponse->
GetErrorString());
1525 LOG_DEBUG(
"Command response: " << replyStr.str());
1526 return igtlMessage.GetPointer();
1530 LOG_ERROR(
"vtkPlusOpenIGTLinkServer::CreateIgtlMessageFromCommandResponse failed: invalid command response");
static const double SAMPLING_SKIPPING_MARGIN_SEC
int ProcessPendingCommands()
static PlusStatus PackImageMessage(igtl::ImageMessage::Pointer imageMessage, igsioTrackedFrame &trackedFrame, const vtkMatrix4x4 &imageToReferenceTransform, vtkIGSIOFrameConverter *frameConverter=NULL)
virtual PlusStatus ReadConfiguration(vtkXMLDataElement *serverElement, const std::string &aFilename)
static std::string GenerateReplyDeviceName(uint32_t uid)
bool HasVideoSource() const
Abstract interface for tracker and video devices.
static vtkPlusCommandStringResponse * SafeDownCast(vtkObject *o)
PlusStatus StopOpenIGTLinkService()
static PlusStatus SendCommandResponses(vtkPlusOpenIGTLinkServer &self)
std::vector< ImageStream > ImageStreams
IGTL message helper class for PlusServer ClientInfo class.
Class to abstract away specific sequence file read/write details.
std::vector< std::string > IgtlMessageTypes
void PrintServerInfo(vtkPlusOpenIGTLinkServer *self)
void SetClientHeaderVersion(int version)
PlusStatus SetClientInfoFromXmlData(const char *strXmlData)
virtual void PrintSelf(ostream &os, vtkIndent indent) VTK_OVERRIDE
std::vector< std::string > StringNames
vtkSmartPointer< vtkIGSIOFrameConverter > FrameConverter
std::vector< vtkPlusDevice * > DeviceCollection
const igtl::MessageBase::MetaDataMap & GetParameters() const
PlusIgtlClientInfo ClientInfo
vtkPlusOpenIGTLinkServer()
std::vector< igsioTransformName > TransformNames
Creates a PlusCommand from a string. If the commands are to be executed on the main thread then call ...
virtual uint32_t GetOriginalId()
vtkPlusOpenIGTLinkServer * Server
std::pair< bool, bool > DataReceiverActive
Active flag for thread (first: request, second: respond )
static vtkPlusConfig * GetInstance()
int ClientId
Unique client identifier. First valid value is 1.
virtual std::string GetErrorString()
static PlusStatus SendMessageResponses(vtkPlusOpenIGTLinkServer &self)
virtual vtkMatrix4x4 * GetImageToReferenceTransform()
void DisconnectClient(int clientId)
static PlusStatus PackImageMetaMessage(igtl::ImageMetaMessage::Pointer imageMetaMessage, igsioCommon::ImageMetaDataList &imageMetaDataList)
PlusStatus GetOutputChannelByName(vtkPlusChannel *&aChannel, const char *aChannelId)
virtual PlusStatus SendTrackedFrame(igsioTrackedFrame &trackedFrame)
virtual std::string GetMessage()
Manages devices that record image or positional data.
virtual PlusStatus GetClientInfo(unsigned int clientId, PlusIgtlClientInfo &outClientInfo) const
PlusStatus Start(vtkPlusDataCollector *dataCollector, vtkIGSIOTransformRepository *transformRepository, vtkXMLDataElement *serverElement, const std::string &configFilePath)
static vtkPlusCommandImageResponse * SafeDownCast(vtkObject *o)
ChannelContainerConstIterator GetOutputChannelsStart() const
virtual std::string GetPolyDataName()
virtual bool GetRespondWithCommandMessage()
virtual PlusStatus GetMostRecentTimestamp(double &ts)
virtual vtkImageData * GetImageData()
virtual void SetDataCollector(vtkPlusDataCollector *)
PlusStatus GetTrackedFrameList(double &aTimestampOfLastFrameAlreadyGot, vtkIGSIOTrackedFrameList *aTrackedFrameList, int aMaxNumberOfFramesToAdd)
bool HasGracePeriodExpired()
virtual std::string GetCommandName()
vtkStandardNewMacro(vtkPlusOpenIGTLinkServer)
std::vector< VideoStream > VideoStreams
Factory class of supported OpenIGTLink message types.
virtual unsigned int GetClientId()
static void * DataReceiverThread(vtkMultiThreader::ThreadInfo *data)
virtual PlusStatus GetStatus()
int GetClientHeaderVersion() const
static void * ConnectionReceiverThread(vtkMultiThreader::ThreadInfo *data)
igtl::ClientSocket::Pointer ClientSocket
IGTL client socket instance.
void SetTDATARequested(bool val)
virtual vtkPolyData * GetPolyData()
virtual std::string GetDeviceName()
PlusStatus QueueMessageResponseForClient(int clientId, igtl::MessageBase::Pointer message)
static std::string GetPrefixFromCommandDeviceName(const std::string &deviceName)
static bool IsCommandDeviceName(const std::string &deviceName)
static std::string GetUidFromCommandDeviceName(const std::string &deviceName)
virtual PlusStatus GetOldestTimestamp(double &ts)
virtual std::string GetResultString()
static vtkPlusCommandRTSCommandResponse * SafeDownCast(vtkObject *o)
std::vector< vtkPlusDevice * >::iterator DeviceCollectionIterator
Contains an optional timestamped circular buffer containing the video images and a number of timestam...
static PlusStatus SendLatestFramesToClients(vtkPlusOpenIGTLinkServer &self, double &elapsedTimeSinceLastPacketSentSec)
virtual std::string GetImageName()
PlusStatus StartOpenIGTLinkService()
static vtkPlusCommandPolydataResponse * SafeDownCast(vtkObject *o)
virtual bool GetUseDefaultFormat()
This class provides a network interface for data acquired by Plus as an OpenIGTLink server.
std::list< vtkSmartPointer< vtkPlusCommandResponse > > PlusCommandResponseList
virtual unsigned int GetNumberOfConnectedClients() const
This class provides client information for vtkPlusOpenIGTLinkServer.
virtual ~vtkPlusOpenIGTLinkServer()
void SetTDATAResolution(int val)
igtl::MessageBase::Pointer CreateIgtlMessageFromCommandResponse(vtkPlusCommandResponse *response)
virtual int OutputChannelCount() const
virtual void SetTransformRepository(vtkIGSIOTransformRepository *)
vtkSmartPointer< vtkIGSIOFrameConverter > FrameConverter
static PlusStatus PackPolyDataMessage(igtl::PolyDataMessage::Pointer polydataMessage, vtkSmartPointer< vtkPolyData > polyData, double timestamp)
static const std::string DEVICE_NAME_REPLY
static void * DataSenderThread(vtkMultiThreader::ThreadInfo *data)
virtual void PrintSelf(ostream &os, vtkIndent indent)