diff --git a/Modules/IGT/IGTTrackingDevices/mitkVirtualTrackingDevice.cpp b/Modules/IGT/IGTTrackingDevices/mitkVirtualTrackingDevice.cpp index 2ea629c2d0..4ff8e3cbce 100644 --- a/Modules/IGT/IGTTrackingDevices/mitkVirtualTrackingDevice.cpp +++ b/Modules/IGT/IGTTrackingDevices/mitkVirtualTrackingDevice.cpp @@ -1,315 +1,316 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: $ Version: $Revision: $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkVirtualTrackingDevice.h" #include #include #include #include #include #include typedef itk::MutexLockHolder MutexLockHolder; mitk::VirtualTrackingDevice::VirtualTrackingDevice() : mitk::TrackingDevice(), m_AllTools(), m_ToolsMutex(NULL), m_MultiThreader(NULL), m_ThreadID(-1), m_RefreshRate(100), m_NumberOfControlPoints(20) { m_Type = VirtualTracker; m_Bounds[0] = m_Bounds[2] = m_Bounds[4] = -400.0; // initialize bounds to -400 ... +400 (mm) cube m_Bounds[1] = m_Bounds[3] = m_Bounds[5] = 400.0; m_ToolsMutex = itk::FastMutexLock::New(); } mitk::VirtualTrackingDevice::~VirtualTrackingDevice() { if (this->GetState() == Tracking) { this->StopTracking(); } if (this->GetState() == Ready) { this->CloseConnection(); } /* cleanup tracking thread */ if (m_MultiThreader.IsNotNull() && (m_ThreadID != -1)) { m_MultiThreader->TerminateThread(m_ThreadID); m_MultiThreader = NULL; } m_AllTools.clear(); } mitk::TrackingTool* mitk::VirtualTrackingDevice::AddTool(const char* toolName) { //if (this->GetState() == Tracking) //{ // return NULL; //} mitk::VirtualTrackingTool::Pointer t = mitk::VirtualTrackingTool::New(); t->SetToolName(toolName); t->SetVelocity(0.1); this->InitializeSpline(t); MutexLockHolder lock(*m_ToolsMutex); // lock and unlock the mutex m_AllTools.push_back(t); return t; } bool mitk::VirtualTrackingDevice::StartTracking() { if (this->GetState() != Ready) return false; this->SetState(Tracking); // go to mode Tracking this->m_StopTrackingMutex->Lock(); this->m_StopTracking = false; this->m_StopTrackingMutex->Unlock(); m_TrackingFinishedMutex->Unlock(); // transfer the execution rights to tracking thread mitk::TimeStamp::GetInstance()->Start(this); if (m_MultiThreader.IsNotNull() && (m_ThreadID != -1)) m_MultiThreader->TerminateThread(m_ThreadID); if (m_MultiThreader.IsNull()) m_MultiThreader = itk::MultiThreader::New(); m_ThreadID = m_MultiThreader->SpawnThread(this->ThreadStartTracking, this); // start a new thread that executes the TrackTools() method return true; } bool mitk::VirtualTrackingDevice::StopTracking() { if (this->GetState() == Tracking) // Only if the object is in the correct state { m_StopTrackingMutex->Lock(); // m_StopTracking is used by two threads, so we have to ensure correct thread handling m_StopTracking = true; m_StopTrackingMutex->Unlock(); this->SetState(Ready); } mitk::TimeStamp::GetInstance()->Stop(this); m_TrackingFinishedMutex->Lock(); return true; } unsigned int mitk::VirtualTrackingDevice::GetToolCount() const { MutexLockHolder lock(*m_ToolsMutex); // lock and unlock the mutex return static_cast(this->m_AllTools.size()); } mitk::TrackingTool* mitk::VirtualTrackingDevice::GetTool(unsigned int toolNumber) const { MutexLockHolder lock(*m_ToolsMutex); // lock and unlock the mutex if ( toolNumber < m_AllTools.size()) return this->m_AllTools.at(toolNumber); return NULL; } bool mitk::VirtualTrackingDevice::OpenConnection() { if (m_NumberOfControlPoints < 1) { this->SetErrorMessage("to few control points for spline interpolation"); return false; } srand(time(NULL)); //Init random number generator this->SetState(Ready); return true; } void mitk::VirtualTrackingDevice::InitializeSpline( mitk::VirtualTrackingTool* t ) { if (t == NULL) return; typedef mitk::VirtualTrackingTool::SplineType SplineType; /* create random control points */ SplineType::ControlPointListType controlPoints; controlPoints.reserve(m_NumberOfControlPoints + 1); controlPoints.push_back(this->GetRandomPoint()); // insert point 0 double length = 0.0; // estimate spline length by calculating line segments lengths for (unsigned int i = 1; i < m_NumberOfControlPoints - 1; ++i) // set points 1..n-2 { SplineType::ControlPointType pos; pos = this->GetRandomPoint(); length += controlPoints.at(i - 1).EuclideanDistanceTo(pos); controlPoints.push_back(pos); } controlPoints.push_back(controlPoints.at(0)); // close spline --> insert point last control point with same value as first control point length += controlPoints.at(controlPoints.size() - 2).EuclideanDistanceTo(controlPoints.at(controlPoints.size() - 1)); /* Create knot list. TODO: rethink knot list values and list size. Is there a better solution? */ SplineType::KnotListType knotList; knotList.push_back(0.0); for (unsigned int i = 1; i < controlPoints.size() + t->GetSpline()->GetSplineOrder() + 1; ++i) knotList.push_back(i); knotList.push_back(controlPoints.size() + t->GetSpline()->GetSplineOrder() + 1); t->GetSpline()->SetControlPoints(controlPoints); t->GetSpline()->SetKnots(knotList); t->SetSplineLength(length); } bool mitk::VirtualTrackingDevice::CloseConnection() { bool returnValue = true; if(this->GetState() == Setup) return true; this->SetState(Setup); return returnValue; } mitk::ScalarType mitk::VirtualTrackingDevice::GetSplineChordLength(unsigned int idx) { mitk::VirtualTrackingTool* t = this->GetInternalTool(idx); if (t != NULL) return t->GetSplineLength(); else throw std::invalid_argument("invalid index"); } void mitk::VirtualTrackingDevice::SetToolSpeed(unsigned int idx, mitk::ScalarType roundsPerSecond) { if (roundsPerSecond < 0.0001) throw std::invalid_argument("Minimum tool speed is 0.0001 rounds per second"); mitk::VirtualTrackingTool* t = this->GetInternalTool(idx); if (t != NULL) t->SetVelocity(roundsPerSecond); else throw std::invalid_argument("invalid index"); } mitk::VirtualTrackingTool* mitk::VirtualTrackingDevice::GetInternalTool(unsigned int idx) { MutexLockHolder toolsMutexLockHolder(*m_ToolsMutex); // lock and unlock the mutex if (idx < m_AllTools.size()) return m_AllTools.at(idx); else return NULL; } void mitk::VirtualTrackingDevice::TrackTools() { try { 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 this->m_StopTrackingMutex->Lock(); // update the local copy of m_StopTracking localStopTracking = this->m_StopTracking; /* lock the TrackingFinishedMutex to signal that the execution rights are now transfered to the tracking thread */ if (!localStopTracking) MutexLockHolder trackingFinishedLockHolder(*m_TrackingFinishedMutex); // keep lock until end of scope this->m_StopTrackingMutex->Unlock(); mitk::ScalarType t = 0.0; while ((this->GetState() == Tracking) && (localStopTracking == false)) { //for (ToolContainer::iterator itAllTools = m_AllTools.begin(); itAllTools != m_AllTools.end(); itAllTools++) for (unsigned int i = 0; i < this->GetToolCount(); ++i) // use mutexed methods to access tool container { mitk::VirtualTrackingTool::Pointer currentTool = this->GetInternalTool(i); mitk::VirtualTrackingTool::SplineType::PointType pos; /* calculate tool position with spline interpolation */ pos = currentTool->GetSpline()->EvaluateSpline(t); mitk::Point3D mp; mitk::itk2vtk(pos, mp); // convert from SplineType::PointType to mitk::Point3D currentTool->SetPosition(mp); // Currently, a constant speed is used. TODO: use tool velocity setting t += 0.001; if (t >= 1.0) t = 0.0; mitk::Quaternion quat; /* fix quaternion rotation */ quat.x() = 1.0; quat.y() = 1.0; quat.z() = 1.0; quat.r() = 1.0; currentTool->SetOrientation(quat); // TODO: rotate once per cycle around a fixed rotation vector currentTool->SetTrackingError( 2 * (rand() / (RAND_MAX + 1.0))); // tracking error in 0 .. 2 Range currentTool->SetDataValid(true); + currentTool->Modified(); } itksys::SystemTools::Delay(m_RefreshRate); /* Update the local copy of m_StopTracking */ this->m_StopTrackingMutex->Lock(); localStopTracking = m_StopTracking; this->m_StopTrackingMutex->Unlock(); } // tracking ends if we pass this line m_TrackingFinishedMutex->Unlock(); // transfer control back to main thread } catch(...) { m_TrackingFinishedMutex->Unlock(); this->StopTracking(); this->SetErrorMessage("Error while trying to track tools. Thread stopped."); } } ITK_THREAD_RETURN_TYPE mitk::VirtualTrackingDevice::ThreadStartTracking(void* pInfoStruct) { /* extract this pointer from Thread Info structure */ struct itk::MultiThreader::ThreadInfoStruct * pInfo = (struct itk::MultiThreader::ThreadInfoStruct*)pInfoStruct; if (pInfo == NULL) { return ITK_THREAD_RETURN_VALUE; } if (pInfo->UserData == NULL) { return ITK_THREAD_RETURN_VALUE; } VirtualTrackingDevice *trackingDevice = static_cast(pInfo->UserData); if (trackingDevice != NULL) trackingDevice->TrackTools(); trackingDevice->m_ThreadID = -1; // reset thread ID because we end the thread here return ITK_THREAD_RETURN_VALUE; } mitk::VirtualTrackingDevice::ControlPointType mitk::VirtualTrackingDevice::GetRandomPoint() { ControlPointType pos; pos[0] = m_Bounds[0] + (m_Bounds[1] - m_Bounds[0]) * (rand() / (RAND_MAX + 1.0)); // X = xMin + xRange * (random number between 0 and 1) pos[1] = m_Bounds[2] + (m_Bounds[3] - m_Bounds[2]) * (rand() / (RAND_MAX + 1.0)); // Y pos[2] = m_Bounds[4] + (m_Bounds[5] - m_Bounds[4]) * (rand() / (RAND_MAX + 1.0)); // Z return pos; } diff --git a/Modules/IGT/IGTTrackingDevices/mitkVirtualTrackingDevice.h b/Modules/IGT/IGTTrackingDevices/mitkVirtualTrackingDevice.h index 86469c1e5b..ab85e72f95 100644 --- a/Modules/IGT/IGTTrackingDevices/mitkVirtualTrackingDevice.h +++ b/Modules/IGT/IGTTrackingDevices/mitkVirtualTrackingDevice.h @@ -1,188 +1,190 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-02-11 18:22:32 +0100 (Mi, 11 Feb 2009) $ Version: $Revision: 16250 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKVIRTUALTRACKINGDEVICE_H_HEADER_INCLUDED_ #define MITKVIRTUALTRACKINGDEVICE_H_HEADER_INCLUDED_ #include #include #include #include #include "itkFastMutexLock.h" #include namespace mitk { /** Documentation * \brief Class representing a tracking device which generates random positions / orientations. * No hardware is needed for tracking device. * * This TrackingDevice class does not interface with a physical tracking device. It simulates * a tracking device by moving the tools on a randomly generated spline path. * * \ingroup IGT */ class MitkIGT_EXPORT VirtualTrackingDevice : public TrackingDevice { public: mitkClassMacro(VirtualTrackingDevice, TrackingDevice); itkNewMacro(Self); /** * \brief Sets the refresh rate of the virtual tracking device in ms + * \warning This refresh rate is not guaranteed. A thread is used to refresh the positions + * of the virtual tools. However, this thread may not run at all during this refresh time period. * \return Sets the refresh rate of the virtual tracking device in ms */ itkSetMacro(RefreshRate, unsigned int) /** * \brief Returns the refresh rate in ms. * \return Returns the refresh rate in ms. */ itkGetConstMacro(RefreshRate, unsigned int) /** * \brief Starts the tracking. * * After StartTracking() is called, * the tools will move on their spline paths with a constant velocity that can be set with * SetToolSpeed(). The standard velocity is 10 seconds for one complete cycle along the spline path. * \warning tool speed is not yet used in the current version * \return Returns true if the tracking is started. Returns false if there was an error. */ virtual bool StartTracking(); /** * \brief Stops the tracking. * \return Returns true if the tracking is stopped. Returns false if there was an error. */ virtual bool StopTracking(); /** * \brief Opens the connection to the device. This have to be done before the tracking is started. * */ virtual bool OpenConnection(); /** * \brief Closes the connection and clears all resources. */ virtual bool CloseConnection(); /** * \return Returns the number of tools which have been added to the device. */ virtual unsigned int GetToolCount() const; /** * \param toolNumber The number of the tool which should be given back. * \return Returns the tool which the number "toolNumber". Returns NULL, if there is * no tool with this number. */ TrackingTool* GetTool(unsigned int toolNumber) const; /** * \brief Adds a tool to the tracking device. * * The tool will have a random path on which it will move around. The path is created with a * spline function and random control points inside the tracking volume. * * \param tool The tool which will be added. * \return Returns true if the tool has been added, false otherwise. */ TrackingTool* AddTool(const char* toolName); /** * \brief Set the tracking volume bounds * * This will set the tracking volume as an axis aligned bounding box * defined by the six bounds values xMin, xMax, yMin, yMax, zMin, zMax. * Note that the random path of existing tools will not be updated with the new * tracking volume. Tools that are created after calling SetBounds() will use the * new tracking volume */ itkSetVectorMacro(Bounds, mitk::ScalarType, 6); /** * \brief return the tracking volume bounds * * This will return the tracking volume as an axis aligned bounding box * defined by the six bounds values xMin, xMax, yMin, yMax, zMin, zMax */ const mitk::ScalarType* GetBounds() const { return m_Bounds; }; /** * \brief return the approximate length of the spline for tool with index idx in millimeter * * if the index idx is not a * valid tool index, a std::invalid_argument exception is thrown. * GetSplineChordLength() returns the distance between all control points of the * spline in millimeter. This can be used as an approximation for the length of the spline path. */ mitk::ScalarType GetSplineChordLength(unsigned int idx); /** * \brief sets the speed of the tool idx in rounds per second * * The virtual tools will travel along a closed spline path. * This method sets the speed of a tool as a factor of how many rounds per second * the tool should move. A setting of 1.0 will indicate one complete round per second. * Together with GetSplineChordLength(), the speed in millimeter per second can be estimated. * roundsPerSecond must be positive and larger than 0.0001. * \warning Tool speed is currently not used. * \TODO: use tool speed */ void SetToolSpeed(unsigned int idx, mitk::ScalarType roundsPerSecond); protected: VirtualTrackingDevice(); ~VirtualTrackingDevice(); /** * \brief This method tracks tools as long as the variable m_Mode is set to "Tracking". * Tracking tools means generating random numbers for the tool position and orientation. */ void TrackTools(); void InitializeSpline(mitk::VirtualTrackingTool* t); ///< initializes the spline path of the tool t with random control points inside the current tracking volume static ITK_THREAD_RETURN_TYPE ThreadStartTracking(void* data); ///< static start method for tracking thread typedef mitk::VirtualTrackingTool::SplineType::ControlPointType ControlPointType; ControlPointType GetRandomPoint(); ///< returns a random position inside the tracking volume (defined by m_Bounds) mitk::VirtualTrackingTool* GetInternalTool(unsigned int idx); typedef std::vector ToolContainer; ///< container type for tracking tools ToolContainer m_AllTools; ///< container for all tracking tools itk::FastMutexLock::Pointer m_ToolsMutex; ///< mutex for coordinated access of tool container itk::MultiThreader::Pointer m_MultiThreader; ///< MultiThreader that starts continuous tracking update int m_ThreadID; unsigned int m_RefreshRate; ///< refresh rate of the internal tracking thread in milliseconds (NOT refreshs per second!) unsigned int m_NumberOfControlPoints; ///< number of control points for the random path generation mitk::ScalarType m_Bounds[6]; ///< bounding box of the tracking volume stored as {xMin, xMax, yMin, yMax, zMin, zMax} }; }//mitk #endif /* MITKVIRTUALTRACKINGDEVICE_H_HEADER_INCLUDED_ */ diff --git a/Modules/IGT/IGTTrackingDevices/mitkVirtualTrackingTool.h b/Modules/IGT/IGTTrackingDevices/mitkVirtualTrackingTool.h index d2f75ed9d6..05f368d7d8 100644 --- a/Modules/IGT/IGTTrackingDevices/mitkVirtualTrackingTool.h +++ b/Modules/IGT/IGTTrackingDevices/mitkVirtualTrackingTool.h @@ -1,72 +1,73 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2009-08-11 15:15:02 +0200 (Di, 11 Aug 2009) $ Version: $Revision: 18516 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef MITKVirtualTrackingTool_H_HEADER_INCLUDED_ #define MITKVirtualTrackingTool_H_HEADER_INCLUDED_ #include #include #include #include #if ITK_VERSION_MAJOR == 3 && ITK_VERSION_MINOR == 18 && ITK_VERSION_PATCH == 0 #include // fixed version of a class that is defect in ITK 3.18 #else #include #endif namespace mitk { /**Documentation * \brief implements TrackingTool interface * * This class is a complete TrackingTool implementation. It can either be used directly by * TrackingDevices, or be subclassed for more specific implementations. * mitk::MicroBirdTrackingDevice uses this class to manage its tools. Other tracking devices * uses specialized versions of this class (e.g. mitk::NDITrackingTool) * * \ingroup IGT */ class MitkIGT_EXPORT VirtualTrackingTool : public InternalTrackingTool { public: mitkClassMacro(VirtualTrackingTool, InternalTrackingTool); friend class VirtualTrackingDevice; typedef itk::NonUniformBSpline<3> SplineType; ///< spline type used for tool path interpolation itkGetMacro(SplineLength, mitk::ScalarType); itkSetMacro(SplineLength, mitk::ScalarType); itkGetMacro(Velocity, mitk::ScalarType); itkSetMacro(Velocity, mitk::ScalarType); itkGetObjectMacro(Spline, SplineType); + protected: itkNewMacro(Self); VirtualTrackingTool(); virtual ~VirtualTrackingTool(); SplineType::Pointer m_Spline; mitk::ScalarType m_SplineLength; mitk::ScalarType m_Velocity; }; } // namespace mitk #endif /* MITKVirtualTrackingTool_H_HEADER_INCLUDED_ */ diff --git a/Modules/IGT/Testing/mitkVirtualTrackingDeviceTest.cpp b/Modules/IGT/Testing/mitkVirtualTrackingDeviceTest.cpp index be346f3afe..f88fa2d8ac 100644 --- a/Modules/IGT/Testing/mitkVirtualTrackingDeviceTest.cpp +++ b/Modules/IGT/Testing/mitkVirtualTrackingDeviceTest.cpp @@ -1,123 +1,125 @@ /*========================================================================= Program: Medical Imaging & Interaction Toolkit Language: C++ Date: $Date: 2010-02-21 19:30:44 +0100 (So, 21 Feb 2010) $ Version: $Revision: 7837 $ Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. See MITKCopyright.txt or http://www.mitk.org/copyright.html for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #include "mitkVirtualTrackingDevice.h" #include "itksys/SystemTools.hxx" #include "mitkTestingMacros.h" #include "mitkTrackingTool.h" #include int mitkVirtualTrackingDeviceTest(int /* argc */, char* /*argv*/[]) { // always start with this! MITK_TEST_BEGIN("VirtualTrackingDevice"); // let's create an object of our class mitk::VirtualTrackingDevice::Pointer tracker = mitk::VirtualTrackingDevice::New(); // first test: did this work? // using MITK_TEST_CONDITION_REQUIRED makes the test stop after failure, since // it makes no sense to continue without an object. MITK_TEST_CONDITION_REQUIRED(tracker.IsNotNull(),"Testing instantiation\n"); MITK_TEST_CONDITION_REQUIRED(tracker->GetState() == mitk::TrackingDevice::Setup ,"Checking tracking device state == setup.\n"); //CloseConnection MITK_TEST_CONDITION( (tracker->CloseConnection()), "Testing behavior of method CloseConnection()."); //StartTracking MITK_TEST_CONDITION( tracker->StartTracking() == false, "Testing behavior of method StartTracking()."); tracker->SetRefreshRate(43); MITK_TEST_CONDITION( tracker->GetRefreshRate() == 43, "Testing Set-/GetRefreshRate()"); MITK_TEST_CONDITION( tracker->GetToolCount() == 0, "Testing GetToolCount() before AddTool()"); MITK_TEST_CONDITION( tracker->AddTool("Tool0"), "Testing AddTool() for tool 0."); MITK_TEST_CONDITION( tracker->GetToolCount() == 1, "Testing GetToolCount() after AddTool()"); mitk::TrackingTool::Pointer tool = tracker->GetTool(0); MITK_TEST_CONDITION_REQUIRED( tool.IsNotNull(), "Testing GetTool() for tool 0."); MITK_TEST_CONDITION( tracker->GetToolByName("Tool0") == tool.GetPointer(), "Testing GetTool() equals GetToolByName() for tool 0."); mitk::ScalarType bounds[6] = {0.0, 10.0, 1.0, 20.0, 3.0, 30.0}; tracker->SetBounds(bounds); MITK_TEST_CONDITION( tracker->GetBounds()[0] == bounds[0] && tracker->GetBounds()[1] == bounds[1] && tracker->GetBounds()[2] == bounds[2] && tracker->GetBounds()[3] == bounds[3] && tracker->GetBounds()[4] == bounds[4] && tracker->GetBounds()[5] == bounds[5] , "Testing Set-/GetBounds()"); MITK_TEST_CONDITION( tracker->AddTool("Tool1"), "Testing AddTool() for tool 1."); MITK_TEST_CONDITION( tracker->GetToolCount() == 2, "Testing GetToolCount() after AddTool()"); tracker->SetToolSpeed(0, 0.1); // no exception expected tracker->SetToolSpeed(1, 0.1); // no exception expected MITK_TEST_FOR_EXCEPTION(std::invalid_argument, tracker->SetToolSpeed(2, 0.1)); // exception expected mitk::ScalarType lengthBefore = tracker->GetSplineChordLength(0); // no exception expected MITK_TEST_FOR_EXCEPTION(std::invalid_argument, tracker->GetSplineChordLength(2)); // exception expected MITK_TEST_CONDITION( tracker->OpenConnection() == true, "Testing OpenConnection()."); MITK_TEST_CONDITION( tracker->GetSplineChordLength(0) == lengthBefore, "Testing GetSplineChordLength() after initalization"); //StartTracking mitk::Point3D posBefore0; tool->GetPosition(posBefore0); mitk::Point3D posBefore1; tracker->GetToolByName("Tool1")->GetPosition(posBefore1); mitk::Point3D posAfter0; tool->GetPosition(posAfter0); MITK_TEST_CONDITION( mitk::Equal(posBefore0, posAfter0) == true, "Testing if position value is constant before StartTracking()"); MITK_TEST_CONDITION( tracker->StartTracking() == true, "Testing behavior of method StartTracking()."); itksys::SystemTools::Delay(500); // wait for tracking thread to start generating positions tool->GetPosition(posAfter0); MITK_TEST_CONDITION( mitk::Equal(posBefore0, posAfter0) == false, "Testing if tracking is producing new position values in tool 0."); mitk::Point3D posAfter1; tracker->GetToolByName("Tool1")->GetPosition(posAfter1); MITK_TEST_CONDITION( mitk::Equal(posBefore1, posAfter1) == false, "Testing if tracking is producing new position values in tool 1."); // add tool while tracking is in progress tracker->AddTool("while Running"); itksys::SystemTools::Delay(100); // wait for tracking thread to start generating positions tracker->GetToolByName("while Running")->GetPosition(posBefore0); + unsigned long tmpMTime = tracker->GetToolByName("while Running")->GetMTime(); itksys::SystemTools::Delay(100); // wait for tracking thread to start generating positions tracker->GetToolByName("while Running")->GetPosition(posAfter0); - bool randomNumberFail = mitk::Equal(posBefore0, posAfter0); - if(randomNumberFail) //this value should never be true because in 100ms the generator should produce 2 new values with refreshrate 43ms + if(tracker->GetToolByName("while Running")->GetMTime() == tmpMTime) //tool not modified yet { - //output for debugging purposes - MITK_INFO << std::setprecision(16) << "Value of posBefore0 " << posBefore0; - MITK_INFO << std::setprecision(16) << "Value of posAfter0 " << posAfter0; + //hence the tool was not modified, the position has to be equal + MITK_TEST_CONDITION( mitk::Equal(posBefore0, posAfter0) == true, "Testing if the position values for the 'while running' tool remain the same."); + } + else //tool was modified => position should be changed + { + MITK_TEST_CONDITION( mitk::Equal(posBefore0, posAfter0) == false, "Testing if tracking is producing new position values for 'while running' tool."); } - MITK_TEST_CONDITION( randomNumberFail == false, "Testing if tracking is producing new position values for 'while running' tool."); // always end with this! MITK_TEST_END(); }