00001 /*========================================================================= 00002 00003 Program: Medical Imaging & Interaction Toolkit 00004 Language: C++ 00005 Date: $Date: $ 00006 Version: $Revision: $ 00007 00008 Copyright (c) German Cancer Research Center, Division of Medical and 00009 Biological Informatics. All rights reserved. 00010 See MITKCopyright.txt or https://www.mitk.org/copyright.html for details. 00011 00012 This software is distributed WITHOUT ANY WARRANTY; without even 00013 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 00014 PURPOSE. See the above copyright notices for more information. 00015 00016 =========================================================================*/ 00017 00018 #include <mitkVirtualTrackingDevice.h> 00019 #include <mitkInternalTrackingTool.h> 00020 00021 #include <mitkNavigationData.h> 00022 #include <mitkTrackingDeviceSource.h> 00023 #include "mitkNavigationDataDisplacementFilter.h" 00024 #include <mitkNavigationDataRecorder.h> 00025 #include <mitkNavigationDataPlayer.h> 00026 00027 #include <itksys/SystemTools.hxx> 00028 00029 //##Documentation 00030 //## \brief A small console tutorial about MITK-IGT 00031 int main(int /*argc*/, char* /*argv*/[]) 00032 { 00033 00034 00035 //************************************************************************* 00036 // What we will do... 00037 //************************************************************************* 00038 //In this tutorial we build up a small navigation pipeline with a virtual tracking device 00039 //which produce random positions and orientation so no additional hardware is required. 00040 //The source of the pipeline is a TrackingDeviceSource object. This we connect to a simple 00041 //filter which just displaces the positions with an offset. After that we use a recorder 00042 //to store this new positions and other information to disc in a XML file. After that we use 00043 //another source (NavigationDataPlayer) to replay the recorded data. 00044 00045 00046 //************************************************************************* 00047 // Part I: Basic initialization of the source and tracking device 00048 //************************************************************************* 00049 //First of all create a tracking device object and two tools for this "device". 00050 00051 //Here we take the VirtualTrackingDevice. This is not a real tracking device it just delivers random 00052 //positions and orientations. You can use other/real tracking devices if you replace the following 00053 //code with different tracking devices, e.g. mitk::NDITrackingDevice. The tools represent the 00054 //sensors of the tracking device. The TrackingDevice fills the tools with data. 00055 std::cout << "Generating TrackingDevice ..." << std::endl; 00056 00057 mitk::VirtualTrackingDevice::Pointer tracker = mitk::VirtualTrackingDevice::New(); 00058 tracker->AddTool("tool1"); 00059 tracker->AddTool("tool2"); 00060 00061 //The tracking device object is used for the physical connection to the device. To use the 00062 //data inside of our tracking pipeline we need a source. This source encapsulate the tracking device 00063 //and provides objects of the type mitk::NavigationData as output. The NavigationData objects stores 00064 //position, orientation, if the data is valid or not and special error informations in a covariance 00065 //matrix. 00066 // 00067 //Typically the start of our pipeline is a TrackingDeviceSource. To work correct we have to set a 00068 //TrackingDevice object. Attention you have to set the tools before you set the whole TrackingDevice 00069 //object to the TrackingDeviceSource because the source need to know how many outputs should be 00070 //generated. 00071 00072 std::cout << "Generating Source ..." << std::endl; 00073 00074 mitk::TrackingDeviceSource::Pointer source = mitk::TrackingDeviceSource::New(); 00075 source->SetTrackingDevice(tracker); //here we set the device for the pipeline source 00076 00077 source->Connect(); //here we connect to the tracking system 00078 //Note we do not call this on the TrackingDevice object 00079 source->StartTracking(); //start the tracking 00080 //Now the source generates outputs. 00081 00082 00083 //************************************************************************* 00084 // Part II: Create a NavigationDataToNavigationDataFilter 00085 //************************************************************************* 00086 00087 //The next thing we do is using a NavigationDataToNavigationDataFilter. One of these filter is the 00088 //very simple NavigationDataDisplacementFilter. This filter just changes the positions of the input 00089 //NavigationData objects with an offset for each direction (X,Y,Z). The input of this filter is the 00090 //source and the output of this filter is the "displaced" input. 00091 00092 std::cout << "Generating DisplacementFilter ..." << std::endl; 00093 00094 mitk::NavigationDataDisplacementFilter::Pointer displacer = mitk::NavigationDataDisplacementFilter::New(); 00095 mitk::Vector3D offset; 00096 mitk::FillVector3D(offset, 10.0, 100.0, 1.0); //initialize the offset 00097 displacer->SetOffset(offset); //now set the offset in the NavigationDataDisplacementFilter object 00098 00099 //now every output of the source object is connected to the displacer object 00100 for (unsigned int i = 0; i < source->GetNumberOfOutputs(); i++) 00101 { 00102 displacer->SetInput(i, source->GetOutput(i)); //here we connect to the displacement filter 00103 } 00104 00105 00106 //************************************************************************* 00107 // Part III: Record the data with the NavigationDataRecorder 00108 //************************************************************************* 00109 00110 //The next part of our pipeline is the recorder. The recorder needs a filename. Otherwise the output 00111 //is redirected to the console. The input of the recorder is the output of the displacement filter 00112 //and the output is a XML file with the name "Test Output-0.xml". 00113 00114 std::cout << "Start Recording ..." << std::endl; 00115 00116 //we need the stringstream for building up our filename 00117 std::stringstream filename; 00118 00119 //the .xml extension and an counter is added automatically 00120 filename << itksys::SystemTools::GetCurrentWorkingDirectory() << "/Test Output"; 00121 00122 std::cout << "Record to file: " << filename.str() << "-0.xml ..." << std::endl; 00123 00124 mitk::NavigationDataRecorder::Pointer recorder = mitk::NavigationDataRecorder::New(); 00125 recorder->SetFileName(filename.str()); 00126 00127 //now every output of the displacer object is connected to the recorder object 00128 for (unsigned int i = 0; i < displacer->GetNumberOfOutputs(); i++) 00129 { 00130 recorder->AddNavigationData(displacer->GetOutput(i)); // here we connect to the recorder 00131 } 00132 00133 recorder->StartRecording(); //after finishing the settings you can start the recording mechanism 00134 //now every update of the recorder stores one line into the file for 00135 //each added NavigationData 00136 00137 00138 for (unsigned int x = 0; x < 100; x++) //write 100 datasets 00139 { 00140 recorder->Update(); //the update causes one line in the XML file for every tool 00141 //in this case two lines 00142 itksys::SystemTools::Delay(100); //sleep a little 00143 } 00144 recorder->StopRecording(); //to get proper XML files you should stop recording 00145 //if your application crashes during recording no data 00146 //will be lost it is all stored to disc 00147 00148 00149 //************************************************************************* 00150 // Part IV: Play the data with the NavigationDataPlayer 00151 //************************************************************************* 00152 00153 //The recording is finished now so now we can play the data. The NavigationDataPlayer is similar 00154 //to the TrackingDevice source. It also derives from NavigationDataSource. So you can use a player 00155 //instead of a TrackingDeviceSource. The input of this player is the filename and the output are 00156 //NavigationData object. 00157 00158 filename << "-0.xml"; 00159 std::cout << "Start playing from file: " << filename.str() << " ..." << std::endl; 00160 00161 00162 mitk::NavigationDataPlayer::Pointer player = mitk::NavigationDataPlayer::New(); 00163 //this is first part of the file name the .xml extension and an counter is added automatically 00164 player->SetFileName(filename.str()); 00165 player->StartPlaying(); //this starts the player 00166 //From now on the player provides NavigationDatas in the order and 00167 //correct time as they were recorded 00168 00169 //this connects the outputs of the player to the NavigationData objects 00170 mitk::NavigationData::Pointer nd = player->GetOutput(0); 00171 mitk::NavigationData::Pointer nd2 = player->GetOutput(1); 00172 for (unsigned int x=0; x<100; x++) 00173 { 00174 if (nd.IsNotNull()) //check if the output is not null 00175 { 00176 //With this update the NavigationData object propagates through the pipeline to get a new value. 00177 //In this case we only have a source (NavigationDataPlayer). 00178 nd->Update(); 00179 00180 std::cout << x << ": 1:" << nd->GetPosition() << std::endl; 00181 std::cout << x << ": 2:" << nd2->GetPosition() << std::endl; 00182 std::cout << x << ": 1:" << nd->GetOrientation() << std::endl; 00183 std::cout << x << ": 2:" << nd2->GetOrientation() << std::endl; 00184 00185 itksys::SystemTools::Delay(100); //sleep a little like in the recorder part 00186 } 00187 } 00188 player->StopPlaying(); //This stops the player 00189 //With another call of StartPlaying the player will start again at the beginning of the file 00190 00191 itksys::SystemTools::Delay(2000); 00192 std::cout << "finished" << std::endl; 00193 00194 } 00195 00196