MITK-IGT
IGT Extension of MITK
Loading...
Searching...
No Matches
mitkPolhemusTrackingDevice.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#include "mitkPolhemusTool.h"
15#include "mitkIGTConfig.h"
16#include "mitkIGTTimeStamp.h"
17#include "mitkIGTHardwareException.h"
18#include <itksys/SystemTools.hxx>
19#include <iostream>
20#include <mutex>
22
24{
25 //set the type of this tracking device
27 m_Device = mitk::PolhemusInterface::New();
28}
29
33
38
40{
41 //Only add tool if port isn't already used.
42 for (auto _tool : m_AllTools)
43 {
44 if (_tool->GetToolPort() == toolPort)
45 {
46 MITK_DEBUG << "There is already a tool connected to this port. Returning existing tool";
47 return _tool;
48 }
49 }
50
51 mitk::PolhemusTool::Pointer t = mitk::PolhemusTool::New();
52 t->SetToolName(toolName);
53 t->SetToolPort(toolPort);
54 if (this->InternalAddTool(t) == false)
55 return nullptr;
56 return t.GetPointer();
57}
58
59bool mitk::PolhemusTrackingDevice::InternalAddTool(PolhemusTool::Pointer tool)
60{
61 m_AllTools.push_back(tool);
62 return true;
63}
64
66{
67 bool success = m_Device->StartTracking();
68 if (success)
69 {
71 this->SetState(Tracking);
72 this->m_StopTrackingMutex.lock();
73 this->m_StopTracking = false;
74 this->m_StopTrackingMutex.unlock();
75 if (m_Thread.joinable()) {m_Thread.detach();}
76 m_Thread = std::thread(&PolhemusTrackingDevice::ThreadStartTracking, this); // start a new thread that executes the TrackTools() methodreturn true;
77 }
78 else
79 {
80 this->SetState(Ready);
81 mitkThrowException(mitk::IGTHardwareException) << "Error while trying to start the device!";
82 }
83 return success;
84}
85
87{
88 m_Device->StopTracking();
89 return Superclass::StopTracking();
90}
91
93{
94 return (unsigned int)this->m_AllTools.size();
95}
96
98{
99 if (toolNumber >= this->GetToolCount())
100 return nullptr;
101 else
102 return this->m_AllTools[toolNumber];
103}
104
106{
107 //reset everything
108 if (m_Device.IsNull()) { m_Device = mitk::PolhemusInterface::New(); }
109 if (!m_Device->Connect()) //Connect the device, if it fails, throw an error.
110 {
111 MITK_ERROR << "Cannot connect Polhemus device!";
112 CloseConnection();
113 return false;
114 }
115
116 //Ready must be set here, 'cause if tools don't match we need to be able to disconnect.
117 this->SetState(Ready);
118
119 //check if connected ports of Polhemus matches the tools in the toolStorage.
120 std::vector<int> toolPorts = m_Device->GetToolPorts();
121
122 //first, check size.
123 if (this->GetToolCount() != toolPorts.size())
124 {
125 MITK_ERROR << "Cannot connect device, number of tools in toolstorage doesn't match the number of tools connected to Polhemus device!";
126 CloseConnection();
127 return false;
128 }
129
130 //second, check if toolStorage identifier is included in this port.
131 for (auto _tool : m_AllTools)
132 {
133 if (std::find(toolPorts.begin(), toolPorts.end(), _tool->GetToolPort()) == toolPorts.end())
134 {
135 MITK_ERROR << "Cannot connect device, tool " << _tool->GetToolPort() << " is not connected to its port.";
136 CloseConnection();
137 return false;
138 }
139 else
140 {
141 //erase this port to avoid that two tools want to connect to the same port.
142 toolPorts.erase(std::find(toolPorts.begin(), toolPorts.end(), _tool->GetToolPort()));
143 }
144 }
145
146 m_Device->SetHemisphereTrackingEnabled(m_HemisphereTrackingEnabled);
147
148 return true;
149}
150
152{
153 bool returnValue = true;
154 if (this->GetState() == Setup)
155 return true;
156
157 returnValue = m_Device->Disconnect();
158
159 this->SetState(Setup);
160 return returnValue;
161}
162
167
168std::vector<mitk::PolhemusTool::Pointer> mitk::PolhemusTrackingDevice::GetAllTools()
169{
170 return this->m_AllTools;
171}
172
174{
175 try
176 {
177 /* lock the TrackingFinishedMutex to signal that the execution rights are now transfered to the tracking thread */
178 std::lock_guard<std::mutex> trackingFinishedLockHolder(m_TrackingFinishedMutex); // keep lock until end of scope
179
180 bool localStopTracking; // Because m_StopTracking is used by two threads, access has to be guarded by a mutex. To minimize thread locking, a local copy is used here
181 this->m_StopTrackingMutex.lock(); // update the local copy of m_StopTracking
182 localStopTracking = this->m_StopTracking;
183 this->m_StopTrackingMutex.unlock();
184 Sleep(100);//Wait a bit until the tracker is ready...
185
186 while ((this->GetState() == Tracking) && (localStopTracking == false))
187 {
188 std::vector<mitk::PolhemusInterface::trackingData> lastData = this->GetDevice()->GetLastFrame();
189
190 if (lastData.size() != m_AllTools.size())
191 {
192 MITK_WARN << "Tool count is corrupt. Hardware gives " << lastData.size() << " tools, MITK expects " << m_AllTools.size() << " tools. Aborting!";
193 }
194 else
195 {
196 std::vector<mitk::PolhemusTool::Pointer> allTools = this->GetAllTools();
197 for (size_t i = 0; i < allTools.size(); i++)
198 {
199 mitk::PolhemusTool::Pointer currentTool = allTools.at(i);
200
201 const int distortionLevel = lastData.at(i).distortionLevel;
202
203 if (distortionLevel == 0)
204 {
205 currentTool->SetDataValid(true);
206 }
207 else
208 {
209 currentTool->SetDataValid(false);
210 }
211
212 currentTool->SetDistortionLevel(distortionLevel);
213 currentTool->SetPosition(lastData.at(i).pos);
214 currentTool->SetOrientation(lastData.at(i).rot);
215 currentTool->SetIGTTimeStamp(mitk::IGTTimeStamp::GetInstance()->GetElapsed());
216 }
217 }
218 /* Update the local copy of m_StopTracking */
219 this->m_StopTrackingMutex.lock();
220 localStopTracking = m_StopTracking;
221 this->m_StopTrackingMutex.unlock();
222 }
223 }
224 catch (...)
225 {
226 this->StopTracking();
227 mitkThrowException(mitk::IGTHardwareException) << "Error while trying to track tools. Thread stopped.";
228 }
229}
230
232{
233 this->TrackTools();
234}
235
240
241mitk::NavigationToolStorage::Pointer mitk::PolhemusTrackingDevice::AutoDetectTools()
242{
243 std::vector<mitk::PolhemusInterface::trackingData> singeFrameData = this->m_Device->AutoDetectTools();
244 MITK_INFO << "Found " << singeFrameData.size() << " tools.";
245 mitk::NavigationToolStorage::Pointer returnValue = mitk::NavigationToolStorage::New();
246 for each (mitk::PolhemusInterface::trackingData t in singeFrameData)
247 {
248 mitk::NavigationTool::Pointer newTool = mitk::NavigationTool::New();
249
250 std::stringstream name;
251 name << "Sensor-" << ((int)t.id);
252 newTool->GetDataNode()->SetName(name.str());
253
254 //The identifier defines, which plug is used (e.g. "Sens 2" --> 2).
255 std::stringstream identifier;
256 identifier << ((int)t.id);
257 newTool->SetIdentifier(identifier.str());
258
260 returnValue->AddTool(newTool);
261 }
262 return returnValue;
263}
264
266{
267 //We need to remember if HemisphereTracking is switch on for this reason:
268 /* m_Device->SetHemi works only if the device is connected. However, GUI can also change if it is not connected.
269 In this case, we remember it in the m_HemisphereTrackingEnabled variable. And when connecting, we know, which
270 status is wanted from the user by GUI.
271 */
272 m_HemisphereTrackingEnabled = _HemisphereTrackingEnabled;
273 this->m_Device->SetHemisphereTrackingEnabled(_HemisphereTrackingEnabled);
274}
275
277{
278 this->m_Device->ToggleHemisphere(_tool);
279}
280
281void mitk::PolhemusTrackingDevice::SetHemisphere(int _tool, mitk::Vector3D _hemisphere)
282{
283 //If you set a hemisphere vector which is unequal (0|0|0), this means, that there is no hemisphere tracking any more
284 //disable the option, so that it can be reactivated... Also if it is just a single tool.
285 if (_hemisphere.GetNorm() != 0)
286 m_HemisphereTrackingEnabled = false;
287
288 this->m_Device->SetHemisphere(_tool, _hemisphere);
289}
290
292{
293 return this->m_Device->GetHemisphere(_tool);
294}
295
297{
298 return this->m_Device->GetHemisphereTrackingEnabled(_tool);
299}
300
302{
303 return this->m_Device->AdjustHemisphere(_tool);
304}
An object of this class represents an exception of the MITK-IGT module which are releated to the hard...
static IGTTimeStamp * GetInstance()
returns a pointer to the current instance of mitkTimeStamp
void Start(itk::Object::Pointer device)
starts the time-acquisition
An object of this class represents the interface to Polhemus trackers. All variables with the name "t...
std::vector< PolhemusTool::Pointer > GetAllTools()
void SetHemisphere(int _tool, mitk::Vector3D _hemisphere)
TrackingTool * GetTool(unsigned int toolNumber) const override
void TrackTools()
This method tracks tools as long as the variable m_Mode is set to "Tracking". Tracking tools means gr...
virtual unsigned int GetToolCount() const override
virtual bool StopTracking() override
Stops the tracking.
virtual bool OpenConnection() override
Opens the connection to the device. This have to be done before the tracking is started.
void SetHemisphereTrackingEnabled(bool _HemisphereTrackingEnabled)
bool InternalAddTool(PolhemusTool::Pointer tool)
Adds a tool to the tracking device.
virtual bool StartTracking() override
Starts the tracking.
virtual mitk::NavigationToolStorage::Pointer AutoDetectTools()
virtual bool CloseConnection() override
Closes the connection and clears all resources.
mitk::TrackingTool * AddTool(const char *toolName, int toolPort)
Create a new Polhemus tool with toolName and add it to the list of tools.
PolhemusInterface::Pointer m_Device
represents the interface to the tracking hardware
Interface for all Tracking Devices.
TrackingDeviceData m_Data
current device Data
Interface for all Tracking Tools.
IGT Exceptions.