Fraxinus  16.5.0-fx-rc8
An IGT application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
cxIgstkToolManager.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 This file is part of CustusX, an Image Guided Therapy Application.
3 
4 Copyright (c) 2008-2014, SINTEF Department of Medical Technology
5 All rights reserved.
6 
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 
10 1. Redistributions of source code must retain the above copyright notice,
11  this list of conditions and the following disclaimer.
12 
13 2. Redistributions in binary form must reproduce the above copyright notice,
14  this list of conditions and the following disclaimer in the documentation
15  and/or other materials provided with the distribution.
16 
17 3. Neither the name of the copyright holder nor the names of its contributors
18  may be used to endorse or promote products derived from this software
19  without specific prior written permission.
20 
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
25 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 =========================================================================*/
32 
33 #include "cxIgstkToolManager.h"
34 
35 #include "cxLogger.h"
36 #include "cxTypeConversions.h"
37 
38 namespace cx
39 {
40 
41 void sampleInfo2xml(const igstk::NDITracker::TrackingSampleInfo& info, QDomElement& node)
42 {
43  node.setAttribute("timestamp", QString("%1").arg(info.m_TimeStamp, 0, 'f', 0));
44  node.setAttribute("error", QString("%1").arg(info.m_Error, 0, 'f', 3));
45  node.setAttribute("frame", QString("%1").arg(info.m_FrameNumber));
46  node.setAttribute("portstatus", QString("0b%1").arg(info.m_PortStatus, 16, 2, QChar('0')));
47  node.setAttribute("toolinformation", QString("0b%1").arg(info.m_ToolInformation, 8, 2, QChar('0')));
48  QString markers;
49  for (unsigned i=0; i<info.m_MarkerInformation.size(); ++i)
50  markers += QString::number(info.m_MarkerInformation[i]);
51  node.setAttribute("markers", markers);
52 }
53 
54 
56  std::vector<ToolFileParser::ToolInternalStructure> toolStructures,
57  ToolFileParser::ToolInternalStructure referenceToolStructure) :
58  mInitAnsweres(0), mInternalInitialized(false)
59 {
60  mTimer = 0;
61 
62  this->createTracker(trackerStructure);
63  this->createTools(toolStructures, referenceToolStructure);
64  this->setReferenceAndTrackerOnTools();
65 
66  connect(mTracker.get(), SIGNAL(tracking(bool)), this, SIGNAL(tracking(bool)));
67  connect(mTracker.get(), SIGNAL(error()), this, SIGNAL(error()));
68 
69  connect(mTracker.get(), SIGNAL(initialized(bool)), this, SLOT(deviceInitializedSlot(bool)));
70  connect(mTracker.get(), SIGNAL(tracking(bool)), this, SLOT(trackerTrackingSlot(bool)));
71 
72  mTimer = new QTimer();
73  connect(mTimer, SIGNAL(timeout()), this, SLOT(checkTimeoutsAndRequestTransformSlot()));
74 
75  igstk::RealTimeClock::Initialize();
76 }
77 
79 {
80  this->trackSlot(false);
81  this->initializeSlot(false);
82 }
83 
84 std::map<QString, IgstkToolPtr> IgstkToolManager::getTools()
85 {
86  QMutexLocker sentry(&mToolMutex);
87  return mTools;
88 }
89 
91 {
92  QMutexLocker sentry(&mReferenceMutex);
93  return mReferenceTool;
94 }
95 
96 void IgstkToolManager::setReferenceAndTrackerOnTools()
97 {
98  if (!mReferenceTool)
99  {
100  reportWarning("Tracking is configured without a reference tool.");
101  }
102 
103  std::map<QString, IgstkToolPtr>::iterator it;
104  for (it = mTools.begin(); it != mTools.end(); ++it)
105  {
106  if (mReferenceTool)
107  it->second->setReference(mReferenceTool);
108  if (mTracker)
109  it->second->setTracker(mTracker);
110  }
111 }
112 
113 void IgstkToolManager::createTracker(ToolFileParser::TrackerInternalStructure trackerStructure)
114 {
115  TrackerPtr tracker(new IgstkTracker(trackerStructure));
116  if (tracker->isValid())
117  mTracker = tracker;
118  else
119  reportWarning("Invalid tracker.");
120 }
121 
122 void IgstkToolManager::createTools(std::vector<ToolFileParser::ToolInternalStructure> toolStructures,
123  ToolFileParser::ToolInternalStructure referenceToolStructure)
124 {
125  for (unsigned i = 0; i < toolStructures.size(); ++i)
126  {
127  this->addIgstkTools(toolStructures[i]);
128  }
129  if (!referenceToolStructure.mUid.isEmpty())
130  {
131  IgstkToolPtr refTool = this->addIgstkTools(referenceToolStructure);
132  if (refTool->isValid())
133  mReferenceTool = refTool;
134  }
135 }
136 
137 IgstkToolPtr IgstkToolManager::addIgstkTools(ToolFileParser::ToolInternalStructure& toolStructure)
138 {
139  IgstkToolPtr igstkTool(new IgstkTool(toolStructure));
140  if (igstkTool->isValid())
141  {
142  QMutexLocker sentry(&mToolMutex);
143  mTools[igstkTool->getUid()] = igstkTool;
144  connect(igstkTool.get(), SIGNAL(attachedToTracker(bool)), this, SLOT(deviceInitializedSlot(bool)));
145  }
146  else
147  {
148  reportWarning(toolStructure.mUid + " is not valid.");
149  }
150  return igstkTool;
151 }
152 
153 void IgstkToolManager::trackerTrackingSlot(bool isTracking)
154 {
155  int igstkPulsingDriveRate = 10;
156  if (isTracking)
157  mTimer->start(igstkPulsingDriveRate);
158  else
159  mTimer->stop();
160 }
161 
163 {
164  if (on)
165  {
166  connect(mTracker.get(), SIGNAL(initialized(bool)), this, SLOT(attachToolsWhenTrackerIsInitializedSlot(bool)));
167  if (!mTracker->isOpen())
168  mTracker->open();
169  }
170  else
171  {
172  mTracker->detachTools(mTools); //not sure we have to detach all tools before we close, read NDI manual
173  if (mTracker->isOpen())
174  mTracker->close();
175  }
176 }
177 
179 {
180  if (on && !mTracker->isTracking())
181  mTracker->startTracking();
182  else if (!on && mTracker->isTracking())
183  mTracker->stopTracking();
184 }
185 
186 void IgstkToolManager::checkTimeoutsAndRequestTransformSlot()
187 {
188  igstk::PulseGenerator::CheckTimeouts();
189 
190  std::map<QString, IgstkToolPtr>::iterator it = mTools.begin();
191  for (; it != mTools.end(); ++it)
192  {
193  if (!it->second)
194  continue;
195 
196  if (mReferenceTool)
197  it->second->getPointer()->RequestComputeTransformTo(mReferenceTool->getPointer());
198  else
199  it->second->getPointer()->RequestComputeTransformTo(mTracker->getPointer());
200  }
201 }
202 
203 void IgstkToolManager::deviceInitializedSlot(bool deviceInit)
204 {
205  int numberOfDevices = mTools.size() + 1; //+1 is the tracker
206 
207  if (deviceInit)
208  {
209  mInitAnsweres++;
210 
211  if (mInitAnsweres == numberOfDevices)
212  {
213  mInternalInitialized = true;
214  emit initialized(true);
215  }
216  }
217  else
218  {
219  mInitAnsweres--;
220 
221  if (mInitAnsweres < numberOfDevices)
222  {
223  if (mInternalInitialized)
224  {
225  mInitAnsweres = 0;
226  mInternalInitialized = false;
227  emit initialized(false);
228  }
229  }
230  }
231 }
232 
233 void IgstkToolManager::attachToolsWhenTrackerIsInitializedSlot(bool open)
234 {
235  if (!open)
236  return;
237 
238  disconnect(mTracker.get(), SIGNAL(initialized(bool)), this, SLOT(attachToolsWhenTrackerIsInitializedSlot(bool)));
239  mTracker->attachTools(mTools);
240 }
241 
242 void IgstkToolManager::printStatus()
243 {
244  std::cout << "mInternalInitialized " << mInternalInitialized << std::endl;
245  std::cout << "mInitAnsweres " << mInitAnsweres << std::endl;
246  std::cout << "mTracker->isValid() " << mTracker->isValid() << std::endl;
247  std::cout << "mTracker->isOpen() " << mTracker->isOpen() << std::endl;
248  std::cout << "mTracker->isInitialized() " << mTracker->isInitialized() << std::endl;
249  std::cout << "mTracker->isTracking() " << mTracker->isTracking() << std::endl;
250  std::cout << "mTools.size() " << string_cast(mTools.size()) << std::endl;
251 }
252 }
std::map< QString, IgstkToolPtr > getTools()
ThreadSafe.
IgstkToolManager(ToolFileParser::TrackerInternalStructure trackerStructure, std::vector< ToolFileParser::ToolInternalStructure > toolStructures, ToolFileParser::ToolInternalStructure referenceToolStructure)
boost::shared_ptr< class IgstkTool > IgstkToolPtr
void trackSlot(bool on)
tracking on or off
std::string string_cast(const T &val)
void tracking(bool on)
void initializeSlot(bool on)
connects to the hardware
void reportWarning(QString msg)
Definition: cxLogger.cpp:91
void sampleInfo2xml(const igstk::NDITracker::TrackingSampleInfo &info, QDomElement &node)
void initialized(bool on)
when all trackers and tools are initialized == true, else false
boost::shared_ptr< IgstkTracker > TrackerPtr
IgstkToolPtr getRefereceTool()
ThreadSafe.