MITK-IGT
IGT Extension of MITK
Loading...
Searching...
No Matches
mitkIGTLDeviceSource.cpp
Go to the documentation of this file.
1/*============================================================================
2
3The Medical Imaging Interaction Toolkit (MITK)
4
5Copyright (c) German Cancer Research Center (DKFZ)
6All rights reserved.
7
8Use of this source code is governed by a 3-clause BSD license that can be
9found in the LICENSE file.
10
11============================================================================*/
12
14
15#include "mitkIGTLDevice.h"
16#include "mitkIGTLMessage.h"
17
18#include <mitkUIDGenerator.h>
19
20//Microservices
21#include <usGetModuleContext.h>
22#include <usModule.h>
23#include <usServiceProperties.h>
24#include <usModuleContext.h>
25
26//itk
27#include <itkCommand.h>
28
31
33 : mitk::IGTLMessageSource(), m_IGTLDevice(nullptr)
34{
35 this->SetName("IGTLDeviceSource (no defined type)");
36}
37
39{
40 if (m_IGTLDevice.IsNotNull())
41 {
42 if (m_IGTLDevice->GetState() == mitk::IGTLDevice::Running)
43 {
44 this->StopCommunication();
45 }
46 if (m_IGTLDevice->GetState() == mitk::IGTLDevice::Ready)
47 {
48 this->Disconnect();
49 }
50 this->RemoveObservers();
51 m_IGTLDevice = nullptr;
52 }
53}
54
56{
57 if (m_IGTLDevice.IsNull())
58 return;
59
60 /* update output with message from the device */
61 IGTLMessage* msgOut = this->GetOutput();
62 assert(msgOut);
63 igtl::MessageBase::Pointer msgIn = dynamic_cast<igtl::MessageBase*>(m_IGTLDevice->GetNextImage2dMessage().GetPointer());
64 if (msgIn.IsNotNull())
65 {
66 assert(msgIn);
67
68 msgOut->SetMessage(msgIn);
69 msgOut->SetName(msgIn->GetDeviceName());
70 }
71 // else
72 // {
73 // MITK_ERROR("IGTLDeviceSource") << "Could not get the latest message.";
74 // }
75}
76
78{
79 if (this->m_IGTLDevice.IsNotNull())
80 {
81 this->m_IGTLDevice->RemoveObserver(m_IncomingMessageObserverTag);
82 this->m_IGTLDevice->RemoveObserver(m_IncomingCommandObserverTag);
83 this->m_IGTLDevice->RemoveObserver(m_LostConnectionObserverTag);
84 }
85}
86
88{
89 MITK_DEBUG << "Setting IGTLDevice to " << igtlDevice;
90 if (this->m_IGTLDevice.GetPointer() != igtlDevice)
91 {
92 //check if we want to override the device
93 if (this->m_IGTLDevice.IsNotNull())
94 {
95 //the device was set previously => we need to reset the observers
96 this->RemoveObservers();
97 }
98 //set the device
99 this->m_IGTLDevice = igtlDevice;
100 this->CreateOutputs();
101 std::stringstream name; // create a human readable name for the source
102 name << "OIGTL Device Source ( " << igtlDevice->GetName() << " )";
103 this->SetName(name.str());
104
105 //setup a observer that listens to new messages and new commands
106 typedef itk::SimpleMemberCommand<IGTLDeviceSource> DeviceSrcCommand;
107
108 DeviceSrcCommand::Pointer msgReceivedCommand = DeviceSrcCommand::New();
109 msgReceivedCommand->SetCallbackFunction(this, &IGTLDeviceSource::OnIncomingMessage);
110 this->m_IncomingMessageObserverTag =
111 this->m_IGTLDevice->AddObserver(mitk::MessageReceivedEvent(), msgReceivedCommand);
112
113 DeviceSrcCommand::Pointer cmdReceivedCommand = DeviceSrcCommand::New();
114 cmdReceivedCommand->SetCallbackFunction(this, &IGTLDeviceSource::OnIncomingCommand);
115 this->m_IncomingCommandObserverTag =
116 this->m_IGTLDevice->AddObserver(mitk::CommandReceivedEvent(), cmdReceivedCommand);
117
118 DeviceSrcCommand::Pointer connectionLostCommand = DeviceSrcCommand::New();
119 connectionLostCommand->SetCallbackFunction(this, &IGTLDeviceSource::OnLostConnection);
120 this->m_LostConnectionObserverTag =
121 this->m_IGTLDevice->AddObserver(mitk::LostConnectionEvent(), connectionLostCommand);
122 }
123}
124
126{
127 //if outputs are set then delete them
128 if (this->GetNumberOfOutputs() > 0)
129 {
130 for (int numOP = this->GetNumberOfOutputs() - 1; numOP >= 0; numOP--)
131 this->RemoveOutput(numOP);
132 this->Modified();
133 }
134
135 //fill the outputs if a valid OpenIGTLink device is set
136 if (m_IGTLDevice.IsNull())
137 return;
138
139 this->SetNumberOfIndexedOutputs(1);
140 if (this->GetOutput(0) == nullptr)
141 {
142 DataObjectPointer newOutput = this->MakeOutput(0);
143 this->SetNthOutput(0, newOutput);
144 this->Modified();
145 }
146}
147
149{
150 if (m_IGTLDevice.IsNull())
151 {
152 throw std::invalid_argument("mitk::IGTLDeviceSource: "
153 "No OpenIGTLink device set");
154 }
155 if (this->IsConnected())
156 {
157 return;
158 }
159 try
160 {
161 m_IGTLDevice->OpenConnection();
162 }
163 catch (mitk::Exception &e)
164 {
165 throw std::runtime_error(std::string("mitk::IGTLDeviceSource: Could not open"
166 "connection to OpenIGTLink device. Error: ") + e.GetDescription());
167 }
168}
169
171{
172 if (m_IGTLDevice.IsNull())
173 throw std::invalid_argument("mitk::IGTLDeviceSource: "
174 "No OpenIGTLink device set");
175 if (m_IGTLDevice->GetState() == mitk::IGTLDevice::Running)
176 return;
177 if (m_IGTLDevice->StartCommunication() == false)
178 throw std::runtime_error("mitk::IGTLDeviceSource: "
179 "Could not start communication");
180}
181
183{
184 if (m_IGTLDevice.IsNull())
185 throw std::invalid_argument("mitk::IGTLDeviceSource: "
186 "No OpenIGTLink device set");
187 if (m_IGTLDevice->CloseConnection() == false)
188 throw std::runtime_error("mitk::IGTLDeviceSource: Could not close connection"
189 " to OpenIGTLink device");
190}
191
193{
194 if (m_IGTLDevice.IsNull())
195 throw std::invalid_argument("mitk::IGTLDeviceSource: "
196 "No OpenIGTLink device set");
197 if (m_IGTLDevice->StopCommunication() == false)
198 throw std::runtime_error("mitk::IGTLDeviceSource: "
199 "Could not stop communicating");
200}
201
203{
204 this->Modified(); // make sure that we need to be updated
205 Superclass::UpdateOutputInformation();
206}
207
208void mitk::IGTLDeviceSource::SetInput(unsigned int idx, const IGTLMessage* msg)
209{
210 if (msg == nullptr) // if an input is set to nullptr, remove it
211 {
212 this->RemoveInput(idx);
213 }
214 else
215 {
216 // ProcessObject is not const-correct so a const_cast is required here
217 this->ProcessObject::SetNthInput(idx, const_cast<IGTLMessage*>(msg));
218 }
219 // this->CreateOutputsForAllInputs();
220}
221
223{
224 if (m_IGTLDevice.IsNull())
225 return false;
226
227 return (m_IGTLDevice->GetState() == mitk::IGTLDevice::Ready) ||
228 (m_IGTLDevice->GetState() == mitk::IGTLDevice::Running);
229}
230
232{
233 if (m_IGTLDevice.IsNull())
234 return false;
235
236 return m_IGTLDevice->GetState() == mitk::IGTLDevice::Running;
237}
238
240{
241 // Get Context
242 us::ModuleContext* context = us::GetModuleContext();
243
244 // Define ServiceProps
245 us::ServiceProperties props;
246 mitk::UIDGenerator uidGen =
247 mitk::UIDGenerator("org.mitk.services.IGTLDeviceSource.id_");
248 props[US_PROPKEY_ID] = uidGen.GetUID();
249 props[US_PROPKEY_DEVICENAME] = this->GetName();
250 props[US_PROPKEY_IGTLDEVICENAME] = m_Name;
251 props[US_PROPKEY_DEVICETYPE] = m_Type;
252 m_ServiceRegistration = context->RegisterService(this, props);
253
254 MITK_INFO << "Registered new DeviceSource as microservice: " << uidGen.GetUID();
255}
256
260
264
268
270{
271 if (this->GetNumberOfInputs() < 1)
272 return nullptr;
273
274 return static_cast<const IGTLMessage*>(this->ProcessObject::GetInput(0));
275}
276
278mitk::IGTLDeviceSource::GetInput(unsigned int idx) const
279{
280 if (this->GetNumberOfInputs() < 1)
281 return nullptr;
282
283 return static_cast<const IGTLMessage*>(this->ProcessObject::GetInput(idx));
284}
285
287mitk::IGTLDeviceSource::GetInput(std::string msgName) const
288{
289 const DataObjectPointerArray& inputs = const_cast<Self*>(this)->GetInputs();
290 for (DataObjectPointerArray::const_iterator it = inputs.begin();
291 it != inputs.end(); ++it)
292 if (std::string(msgName) ==
293 (static_cast<IGTLMessage*>(it->GetPointer()))->GetName())
294 return static_cast<IGTLMessage*>(it->GetPointer());
295 return nullptr;
296}
297
298itk::ProcessObject::DataObjectPointerArraySizeType
300{
301 DataObjectPointerArray outputs = this->GetInputs();
302 for (DataObjectPointerArray::size_type i = 0; i < outputs.size(); ++i)
303 if (msgName ==
304 (static_cast<IGTLMessage*>(outputs.at(i).GetPointer()))->GetName())
305 return i;
306 throw std::invalid_argument("output name does not exist");
307}
virtual void OnIncomingCommand()
This method is called when the IGTL device hold by this class receives a new command.
void RegisterAsMicroservice() override
Registers this object as a Microservice, making it available to every module and/or plugin....
const IGTLMessage * GetInput(void) const
Get the input of this filter.
DataObjectPointerArraySizeType GetInputIndex(std::string msgName)
return the index of the input with name msgName, throw std::invalid_argument exception if that name w...
void Disconnect()
Closes the connection to the OpenIGTLink device.
void Connect()
Establishes a connection to the OpenIGTLink device. If there is already a connection the method does ...
static const std::string US_PROPKEY_IGTLDEVICENAME
These Constants are used in conjunction with Microservices.
void UpdateOutputInformation() override
Used for pipeline update.
virtual bool IsCommunicating()
returns true if communication is in progress
virtual bool IsConnected()
returns true if a connection to the OpenIGTLink device is established
void CreateOutputs()
Create the necessary outputs for the m_IGTLDevice.
void StartCommunication()
starts the communication of the device. This needs to be called before Update() or GetOutput()->Updat...
virtual void RemoveObservers()
Removes all observers that listen to the igtl device.
virtual void OnIncomingMessage()
This method is called when the IGTL device hold by this class receives a new message.
void GenerateData() override
filter execute method
void StopCommunication()
stops the communication of the device.
virtual void SetIGTLDevice(mitk::IGTLDevice *td)
sets the OpenIGTLink device that will be used as a data source
virtual void SetInput(unsigned int idx, const IGTLMessage *msg)
Set input with id idx of this filter.
virtual void OnLostConnection()
This method is called when the IGTL device lost the connection to the other side.
Interface for all OpenIGTLink Devices.
OpenIGTLink message source.
static const std::string US_INTERFACE_NAME
These Constants are used in conjunction with Microservices.
A wrapper for the OpenIGTLink message type.
void SetMessage(igtl::MessageBase::Pointer msg)
Sets the OpenIGTLink message.
IGT Exceptions.