15#include "mitkIGTConfig.h"
17#include "mitkIGTHardwareException.h"
19#include <itksys/SystemTools.hxx>
21#include <itkCommand.h>
23#include <vtkConeSource.h>
48 return m_OpenIGTLinkClient->GetPortNumber();
58 mitk::NavigationToolStorage::Pointer returnValue = mitk::NavigationToolStorage::New();
60 if (m_OpenIGTLinkClient->GetPortNumber() == -1)
62 MITK_WARN <<
"Connection not initialized, aborting (invalid port number).";
63 return mitk::NavigationToolStorage::New();
69 m_IGTLDeviceSource->Connect();
70 m_IGTLDeviceSource->StartCommunication();
72 catch (std::runtime_error &e)
74 MITK_WARN <<
"AutoDetection: Open IGT Link device retruned an error while trying to connect: " << e.what();
75 return mitk::NavigationToolStorage::New();
80 mitk::IGTLMessage::Pointer receivedMessage = ReceiveMessage(100);
82 const char* msgType = receivedMessage->GetIGTLMessageType();
84 if (std::string(msgType).empty())
86 MITK_INFO <<
"Did not receive a message. Do you have to start the stream manually at the server?";
87 MITK_INFO <<
"Waiting for 10 seconds ...";
88 receivedMessage = ReceiveMessage(10000);
89 msgType = receivedMessage->GetIGTLMessageType();
91 MITK_INFO <<
"################# got message type: " << msgType;
92 mitk::OpenIGTLinkTrackingDevice::TrackingMessageType type = GetMessageTypeFromString(msgType);
108 returnValue = DiscoverToolsAndConvertToNavigationTools(type);
113 m_IGTLDeviceSource->StopCommunication();
114 m_IGTLDeviceSource->Disconnect();
116 catch (std::runtime_error &e)
118 MITK_WARN <<
"AutoDetection: Open IGT Link device retruned an error while trying to disconnect: " << e.what();
119 return mitk::NavigationToolStorage::New();
126mitk::NavigationToolStorage::Pointer mitk::OpenIGTLinkTrackingDevice::DiscoverToolsAndConvertToNavigationTools(mitk::OpenIGTLinkTrackingDevice::TrackingMessageType type,
int NumberOfMessagesToWait)
128 MITK_INFO <<
"Start discovering tools by " << type <<
" messages";
129 mitk::NavigationToolStorage::Pointer returnValue = mitk::NavigationToolStorage::New();
130 std::map<std::string, int> toolNameMap;
132 for (
int j = 0; j<NumberOfMessagesToWait; j++)
134 std::this_thread::sleep_for(std::chrono::milliseconds(20));
135 m_IGTLDeviceSource->Update();
140 igtl::TransformMessage::Pointer msg =
dynamic_cast<igtl::TransformMessage*
>(m_IGTLDeviceSource->GetOutput()->GetMessage().GetPointer());
141 if (msg ==
nullptr || msg.IsNull()) { MITK_INFO <<
"Received message is invalid / null. Skipping..";
continue; }
142 int count = toolNameMap[msg->GetDeviceName()];
143 if (count == 0) { toolNameMap[msg->GetDeviceName()] = 1; }
144 else { toolNameMap[msg->GetDeviceName()]++; }
149 igtl::TrackingDataMessage::Pointer msg =
dynamic_cast<igtl::TrackingDataMessage*
>(m_IGTLDeviceSource->GetOutput()->GetMessage().GetPointer());
150 if (msg ==
nullptr || msg.IsNull()) { MITK_INFO <<
"Received message is invalid / null. Skipping..";
continue; }
151 for (
int k = 0; k < msg->GetNumberOfTrackingDataElements(); k++)
153 igtl::TrackingDataElement::Pointer tde;
154 msg->GetTrackingDataElement(k, tde);
157 int count = toolNameMap[tde->GetName()];
158 if (count == 0) { toolNameMap[tde->GetName()] = 1; }
159 else { toolNameMap[tde->GetName()]++; }
165 MITK_WARN <<
"Only TRANSFORM and TDATA is currently supported, skipping!";
171 for (std::map<std::string, int>::iterator it = toolNameMap.begin(); it != toolNameMap.end(); ++it)
173 MITK_INFO <<
"Found tool: " << it->first;
175 std::stringstream name;
178 std::stringstream identifier;
179 identifier <<
"AutoDetectedTool-" << i;
182 mitk::NavigationTool::Pointer newTool = ConstructDefaultOpenIGTLinkTool(name.str(), identifier.str());
184 returnValue->AddTool(newTool);
192 return m_OpenIGTLinkClient->GetHostname();
197 m_OpenIGTLinkClient->SetPortNumber(portNumber);
202 m_OpenIGTLinkClient->SetHostname(hostname);
212 mitk::OpenIGTLinkTrackingTool::Pointer t;
214 if (this->InternalAddTool(t) ==
false)
216 return t.GetPointer();
221 m_AllTools.push_back(tool);
227 if (m_OpenIGTLinkClient->GetPortNumber() == -1)
229 MITK_WARN <<
"Connection not initialized, aborting (invalid port number).";
235 m_IGTLDeviceSource->Connect();
236 m_IGTLDeviceSource->StartCommunication();
238 catch (std::runtime_error &e)
240 MITK_WARN <<
"Open IGT Link device retruned an error while trying to connect: " << e.what();
244 mitk::IGTLMessage::Pointer receivedMessage = ReceiveMessage(waitingTime);
248 if (receivedMessage.IsNull())
250 MITK_WARN <<
"No message was received. Is there really a server?";
253 else if (!receivedMessage->IsDataValid())
255 MITK_WARN <<
"Received invalid message.";
259 const char* msgType = receivedMessage->GetIGTLMessageType();
261 mitk::OpenIGTLinkTrackingDevice::TrackingMessageType type = GetMessageTypeFromString(msgType);
263 mitk::NavigationToolStorage::Pointer foundTools = this->DiscoverToolsAndConvertToNavigationTools(type);
264 if (foundTools.IsNull() || (foundTools->GetToolCount() == 0)) {
return false; }
265 for (
unsigned int i = 0; i < foundTools->GetToolCount(); i++) { AddNewToolForName(foundTools->GetTool(i)->GetToolName(), i); }
266 MITK_INFO <<
"Found tools: " << foundTools->GetToolCount();
272 mitk::IGTLMessage::Pointer receivedMessage;
274 mitk::IGTLMessageFactory::Pointer msgFactory = m_OpenIGTLinkClient->GetMessageFactory();
275 std::string message[2] = {
"STT_QTDATA",
"STT_TDATA"};
277 for (
int i = 0; i < 2; i++)
279 igtl::MessageBase::Pointer sttMsg = msgFactory->CreateInstance(message[i]);
281 ((igtl::StartTrackingDataMessage*)sttMsg.GetPointer())->SetResolution(m_UpdateRate);
282 m_OpenIGTLinkClient->SendMessage(mitk::IGTLMessage::New(sttMsg));
285 std::chrono::high_resolution_clock::time_point time = std::chrono::high_resolution_clock::now();
286 std::chrono::milliseconds d = std::chrono::milliseconds(waitingTime);
288 while (!(receivedMessage.IsNotNull() && receivedMessage->IsDataValid()))
290 m_IGTLDeviceSource->Update();
291 receivedMessage = m_IGTLDeviceSource->GetOutput();
293 if ((time + d) < std::chrono::high_resolution_clock::now())
296 std::this_thread::sleep_for(std::chrono::milliseconds(100));
298 return receivedMessage;
301void mitk::OpenIGTLinkTrackingDevice::AddNewToolForName(std::string name,
int i)
303 mitk::OpenIGTLinkTrackingTool::Pointer newTool = mitk::OpenIGTLinkTrackingTool::New();
306 std::stringstream defaultName;
307 defaultName <<
"OpenIGTLinkTool#" << i;
308 name = defaultName.str();
310 MITK_INFO <<
"Added tool " << name <<
" to tracking device.";
311 newTool->SetToolName(name);
312 InternalAddTool(newTool);
315mitk::NavigationTool::Pointer mitk::OpenIGTLinkTrackingDevice::ConstructDefaultOpenIGTLinkTool(std::string name, std::string identifier)
317 mitk::NavigationTool::Pointer newTool = mitk::NavigationTool::New();
318 newTool->GetDataNode()->SetName(name);
319 newTool->SetIdentifier(identifier);
329 if (this->GetState() != Tracking)
331 MITK_ERROR <<
"Method was called in the wrong state, something went wrong!";
335 m_IGTLMsgToNavDataFilter->Update();
337 for (std::size_t j = 0; j < m_IGTLMsgToNavDataFilter->GetNumberOfIndexedOutputs(); ++j)
339 mitk::NavigationData::Pointer currentNavData = m_IGTLMsgToNavDataFilter->GetOutput(j);
340 const char* name = currentNavData->GetName();
341 for (std::size_t i = 0; i < m_AllTools.size(); i++)
343 if (
strcmp(m_AllTools.at(i)->GetToolName(), name) == 0)
345 m_AllTools.at(i)->SetDataValid(currentNavData->IsDataValid());
346 m_AllTools.at(i)->SetPosition(currentNavData->GetPosition());
347 m_AllTools.at(i)->SetOrientation(currentNavData->GetOrientation());
348 m_AllTools.at(i)->SetIGTTimeStamp(currentNavData->GetIGTTimeStamp());
357 if (this->GetState() != Ready)
359 MITK_WARN <<
"Cannot start tracking, device is not ready!";
365 m_IGTLDeviceSource->StartCommunication();
368 mitk::IGTLMessageFactory::Pointer msgFactory = m_OpenIGTLinkClient->GetMessageFactory();
369 std::string message =
"STT_TDATA";
372 catch (std::runtime_error &e)
374 MITK_WARN <<
"Open IGT Link device retruned an error while starting communication: " << e.what();
379 m_IGTLMsgToNavDataFilter = mitk::IGTLMessageToNavigationDataFilter::New();
380 m_IGTLMsgToNavDataFilter->SetNumberOfExpectedOutputs(this->GetToolCount());
381 m_IGTLMsgToNavDataFilter->ConnectTo(m_IGTLDeviceSource);
384 typedef itk::SimpleMemberCommand< mitk::OpenIGTLinkTrackingDevice > CurCommandType;
385 CurCommandType::Pointer messageReceivedCommand = CurCommandType::New();
387 m_MessageReceivedObserverTag = m_OpenIGTLinkClient->AddObserver(mitk::MessageReceivedEvent(), messageReceivedCommand);
389 m_OpenIGTLinkClient->EnableNoBufferingMode(
true);
390 this->SetState(Tracking);
397 if (this->GetState() != Tracking)
399 MITK_WARN <<
"Cannot open connection, device is already connected!";
403 m_OpenIGTLinkClient->RemoveObserver(m_MessageReceivedObserverTag);
407 m_IGTLDeviceSource->StopCommunication();
409 catch (std::runtime_error &e)
411 MITK_WARN <<
"Open IGT Link device retruned an error while stopping communication: " << e.what();
414 m_OpenIGTLinkClient->EnableNoBufferingMode(
false);
415 this->SetState(Ready);
421 return (
unsigned int)this->m_AllTools.size();
426 if (toolNumber >= this->GetToolCount())
429 return this->m_AllTools[toolNumber];
435 if (this->GetState() != Setup)
437 MITK_WARN <<
"Cannot open connection, device is already connected!";
443 m_IGTLDeviceSource->Connect();
445 catch (std::runtime_error &e)
447 MITK_WARN <<
"Open IGT Link device retruned an error while trying to connect: " << e.what();
450 this->SetState(Ready);
457 if (this->GetState() != Ready)
459 MITK_WARN <<
"Cannot close connection, device is in the wrong state!";
465 m_IGTLDeviceSource->Disconnect();
467 catch (std::runtime_error &e)
469 MITK_WARN <<
"Open IGT Link device retruned an error while trying to disconnect: " << e.what();
473 this->SetState(Setup);
480 return this->m_AllTools;
483mitk::OpenIGTLinkTrackingDevice::TrackingMessageType mitk::OpenIGTLinkTrackingDevice::GetMessageTypeFromString(
const char* messageTypeString)
485 if (
strcmp(messageTypeString,
"TDATA") == 0)
487 return mitk::OpenIGTLinkTrackingDevice::TrackingMessageType::TDATA;
489 else if (
strcmp(messageTypeString,
"QTDATA") == 0)
491 return mitk::OpenIGTLinkTrackingDevice::TrackingMessageType::QTDATA;
493 else if (
strcmp(messageTypeString,
"TRANSFORM") == 0)
495 return mitk::OpenIGTLinkTrackingDevice::TrackingMessageType::TRANSFORM;
499 return mitk::OpenIGTLinkTrackingDevice::TrackingMessageType::UNKNOWN;
OpenIGTLinkTrackingDevice()
bool StopTracking() override
Stops the tracking.
bool AutoDetectToolsAvailable() override
std::string GetHostname()
bool InternalAddTool(OpenIGTLinkTrackingTool::Pointer tool)
Adds a tool to the tracking device.
bool DiscoverTools(int WaitingTime=10000)
Discover the tools available from the connected OpenIGTLink device and adds these tools to this track...
bool StartTracking() override
Starts the tracking.
bool OpenConnection() override
Opens the connection to the device. This have to be done before the tracking is started.
mitk::IGTLTrackingDataDeviceSource::Pointer m_IGTLDeviceSource
bool CloseConnection() override
Closes the connection and clears all resources.
void SetHostname(std::string hostname)
TrackingTool * GetTool(unsigned int toolNumber) const override
mitk::IGTLClient::Pointer m_OpenIGTLinkClient
~OpenIGTLinkTrackingDevice() override
mitk::NavigationToolStorage::Pointer AutoDetectTools() override
mitk::TrackingTool * AddTool(const char *toolName, const char *fileName)
Create a new OpenIGTLink tool with toolName and fileName and add it to the list of tools.
unsigned int GetToolCount() const override
mitk::IGTLMessage::Pointer ReceiveMessage(int waitingTime)
bool IsDeviceInstalled() override
std::vector< OpenIGTLinkTrackingTool::Pointer > GetAllTools()
void SetPortNumber(int portNumber)
Interface for all Tracking Devices.
TrackingDeviceData m_Data
current device Data
int strcmp(const String &s1, const String &s2)