Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "mitkVirtualTrackingDevice.h"
00019
00020 #include <stdlib.h>
00021 #include <stdio.h>
00022 #include <time.h>
00023 #include <mitkTimeStamp.h>
00024 #include <itksys/SystemTools.hxx>
00025 #include <itkMutexLockHolder.h>
00026
00027 typedef itk::MutexLockHolder<itk::FastMutexLock> MutexLockHolder;
00028
00029
00030 mitk::VirtualTrackingDevice::VirtualTrackingDevice() : mitk::TrackingDevice(),
00031 m_AllTools(), m_ToolsMutex(NULL), m_MultiThreader(NULL), m_ThreadID(-1), m_RefreshRate(100), m_NumberOfControlPoints(20)
00032 {
00033 m_Type = VirtualTracker;
00034 m_Bounds[0] = m_Bounds[2] = m_Bounds[4] = -400.0;
00035 m_Bounds[1] = m_Bounds[3] = m_Bounds[5] = 400.0;
00036 m_ToolsMutex = itk::FastMutexLock::New();
00037 }
00038
00039
00040 mitk::VirtualTrackingDevice::~VirtualTrackingDevice()
00041 {
00042 if (this->GetState() == Tracking)
00043 {
00044 this->StopTracking();
00045 }
00046 if (this->GetState() == Ready)
00047 {
00048 this->CloseConnection();
00049 }
00050
00051 if (m_MultiThreader.IsNotNull() && (m_ThreadID != -1))
00052 {
00053 m_MultiThreader->TerminateThread(m_ThreadID);
00054 m_MultiThreader = NULL;
00055 }
00056 m_AllTools.clear();
00057 }
00058
00059
00060 mitk::TrackingTool* mitk::VirtualTrackingDevice::AddTool(const char* toolName)
00061 {
00062
00063
00064
00065
00066 mitk::VirtualTrackingTool::Pointer t = mitk::VirtualTrackingTool::New();
00067 t->SetToolName(toolName);
00068 t->SetVelocity(0.1);
00069 this->InitializeSpline(t);
00070 MutexLockHolder lock(*m_ToolsMutex);
00071 m_AllTools.push_back(t);
00072 return t;
00073 }
00074
00075
00076 bool mitk::VirtualTrackingDevice::StartTracking()
00077 {
00078 if (this->GetState() != Ready)
00079 return false;
00080 this->SetState(Tracking);
00081 this->m_StopTrackingMutex->Lock();
00082 this->m_StopTracking = false;
00083 this->m_StopTrackingMutex->Unlock();
00084
00085 m_TrackingFinishedMutex->Unlock();
00086
00087 mitk::TimeStamp::GetInstance()->Start(this);
00088
00089 if (m_MultiThreader.IsNotNull() && (m_ThreadID != -1))
00090 m_MultiThreader->TerminateThread(m_ThreadID);
00091 if (m_MultiThreader.IsNull())
00092 m_MultiThreader = itk::MultiThreader::New();
00093
00094 m_ThreadID = m_MultiThreader->SpawnThread(this->ThreadStartTracking, this);
00095 return true;
00096 }
00097
00098
00099 bool mitk::VirtualTrackingDevice::StopTracking()
00100 {
00101 if (this->GetState() == Tracking)
00102 {
00103 m_StopTrackingMutex->Lock();
00104 m_StopTracking = true;
00105 m_StopTrackingMutex->Unlock();
00106 this->SetState(Ready);
00107 }
00108
00109 mitk::TimeStamp::GetInstance()->Stop(this);
00110 m_TrackingFinishedMutex->Lock();
00111
00112 return true;
00113 }
00114
00115
00116 unsigned int mitk::VirtualTrackingDevice::GetToolCount() const
00117 {
00118 MutexLockHolder lock(*m_ToolsMutex);
00119 return static_cast<unsigned int>(this->m_AllTools.size());
00120 }
00121
00122
00123 mitk::TrackingTool* mitk::VirtualTrackingDevice::GetTool(unsigned int toolNumber) const
00124 {
00125 MutexLockHolder lock(*m_ToolsMutex);
00126 if ( toolNumber < m_AllTools.size())
00127 return this->m_AllTools.at(toolNumber);
00128 return NULL;
00129 }
00130
00131
00132 bool mitk::VirtualTrackingDevice::OpenConnection()
00133 {
00134 if (m_NumberOfControlPoints < 1)
00135 {
00136 this->SetErrorMessage("to few control points for spline interpolation");
00137 return false;
00138 }
00139 srand(time(NULL));
00140
00141 this->SetState(Ready);
00142 return true;
00143 }
00144
00145
00146 void mitk::VirtualTrackingDevice::InitializeSpline( mitk::VirtualTrackingTool* t )
00147 {
00148 if (t == NULL)
00149 return;
00150
00151 typedef mitk::VirtualTrackingTool::SplineType SplineType;
00152
00153 SplineType::ControlPointListType controlPoints;
00154 controlPoints.reserve(m_NumberOfControlPoints + 1);
00155
00156 controlPoints.push_back(this->GetRandomPoint());
00157 double length = 0.0;
00158 for (unsigned int i = 1; i < m_NumberOfControlPoints - 1; ++i)
00159 {
00160 SplineType::ControlPointType pos;
00161 pos = this->GetRandomPoint();
00162 length += controlPoints.at(i - 1).EuclideanDistanceTo(pos);
00163 controlPoints.push_back(pos);
00164 }
00165 controlPoints.push_back(controlPoints.at(0));
00166 length += controlPoints.at(controlPoints.size() - 2).EuclideanDistanceTo(controlPoints.at(controlPoints.size() - 1));
00167
00168
00169 SplineType::KnotListType knotList;
00170 knotList.push_back(0.0);
00171 for (unsigned int i = 1; i < controlPoints.size() + t->GetSpline()->GetSplineOrder() + 1; ++i)
00172 knotList.push_back(i);
00173 knotList.push_back(controlPoints.size() + t->GetSpline()->GetSplineOrder() + 1);
00174
00175 t->GetSpline()->SetControlPoints(controlPoints);
00176 t->GetSpline()->SetKnots(knotList);
00177 t->SetSplineLength(length);
00178 }
00179
00180
00181 bool mitk::VirtualTrackingDevice::CloseConnection()
00182 {
00183 bool returnValue = true;
00184 if(this->GetState() == Setup)
00185 return true;
00186
00187 this->SetState(Setup);
00188 return returnValue;
00189 }
00190
00191
00192 mitk::ScalarType mitk::VirtualTrackingDevice::GetSplineChordLength(unsigned int idx)
00193 {
00194 mitk::VirtualTrackingTool* t = this->GetInternalTool(idx);
00195 if (t != NULL)
00196 return t->GetSplineLength();
00197 else
00198 throw std::invalid_argument("invalid index");
00199 }
00200
00201
00202 void mitk::VirtualTrackingDevice::SetToolSpeed(unsigned int idx, mitk::ScalarType roundsPerSecond)
00203 {
00204 if (roundsPerSecond < 0.0001)
00205 throw std::invalid_argument("Minimum tool speed is 0.0001 rounds per second");
00206
00207 mitk::VirtualTrackingTool* t = this->GetInternalTool(idx);
00208 if (t != NULL)
00209 t->SetVelocity(roundsPerSecond);
00210 else
00211 throw std::invalid_argument("invalid index");
00212 }
00213
00214
00215 mitk::VirtualTrackingTool* mitk::VirtualTrackingDevice::GetInternalTool(unsigned int idx)
00216 {
00217 MutexLockHolder toolsMutexLockHolder(*m_ToolsMutex);
00218 if (idx < m_AllTools.size())
00219 return m_AllTools.at(idx);
00220 else
00221 return NULL;
00222 }
00223
00224
00225 void mitk::VirtualTrackingDevice::TrackTools()
00226 {
00227 try
00228 {
00229 bool localStopTracking;
00230
00231 this->m_StopTrackingMutex->Lock();
00232 localStopTracking = this->m_StopTracking;
00233
00234
00235 if (!localStopTracking) MutexLockHolder trackingFinishedLockHolder(*m_TrackingFinishedMutex);
00236 this->m_StopTrackingMutex->Unlock();
00237
00238 mitk::ScalarType t = 0.0;
00239 while ((this->GetState() == Tracking) && (localStopTracking == false))
00240 {
00241
00242 for (unsigned int i = 0; i < this->GetToolCount(); ++i)
00243 {
00244 mitk::VirtualTrackingTool::Pointer currentTool = this->GetInternalTool(i);
00245 mitk::VirtualTrackingTool::SplineType::PointType pos;
00246
00247 pos = currentTool->GetSpline()->EvaluateSpline(t);
00248 mitk::Point3D mp;
00249 mitk::itk2vtk(pos, mp);
00250 currentTool->SetPosition(mp);
00251
00252 t += 0.001;
00253 if (t >= 1.0)
00254 t = 0.0;
00255
00256 mitk::Quaternion quat;
00257
00258 quat.x() = 1.0;
00259 quat.y() = 1.0;
00260 quat.z() = 1.0;
00261 quat.r() = 1.0;
00262 currentTool->SetOrientation(quat);
00263
00264
00265 currentTool->SetTrackingError( 2 * (rand() / (RAND_MAX + 1.0)));
00266 currentTool->SetDataValid(true);
00267 }
00268 itksys::SystemTools::Delay(m_RefreshRate);
00269
00270 this->m_StopTrackingMutex->Lock();
00271 localStopTracking = m_StopTracking;
00272 this->m_StopTrackingMutex->Unlock();
00273 }
00274
00275 m_TrackingFinishedMutex->Unlock();
00276 }
00277 catch(...)
00278 {
00279 m_TrackingFinishedMutex->Unlock();
00280 this->StopTracking();
00281 this->SetErrorMessage("Error while trying to track tools. Thread stopped.");
00282 }
00283 }
00284
00285
00286 ITK_THREAD_RETURN_TYPE mitk::VirtualTrackingDevice::ThreadStartTracking(void* pInfoStruct)
00287 {
00288
00289 struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct;
00290 if (pInfo == NULL)
00291 {
00292 return ITK_THREAD_RETURN_VALUE;
00293 }
00294 if (pInfo->UserData == NULL)
00295 {
00296 return ITK_THREAD_RETURN_VALUE;
00297 }
00298 VirtualTrackingDevice *trackingDevice = static_cast<VirtualTrackingDevice*>(pInfo->UserData);
00299
00300 if (trackingDevice != NULL)
00301 trackingDevice->TrackTools();
00302
00303 trackingDevice->m_ThreadID = -1;
00304 return ITK_THREAD_RETURN_VALUE;
00305 }
00306
00307
00308 mitk::VirtualTrackingDevice::ControlPointType mitk::VirtualTrackingDevice::GetRandomPoint()
00309 {
00310 ControlPointType pos;
00311 pos[0] = m_Bounds[0] + (m_Bounds[1] - m_Bounds[0]) * (rand() / (RAND_MAX + 1.0));
00312 pos[1] = m_Bounds[2] + (m_Bounds[3] - m_Bounds[2]) * (rand() / (RAND_MAX + 1.0));
00313 pos[2] = m_Bounds[4] + (m_Bounds[5] - m_Bounds[4]) * (rand() / (RAND_MAX + 1.0));
00314 return pos;
00315 }