diff --git a/Modules/IGT/Documentation/doxygen/IGTModule.dox b/Modules/IGT/Documentation/doxygen/IGTModule.dox index 14a175c1bd..a7f8491f05 100644 --- a/Modules/IGT/Documentation/doxygen/IGTModule.dox +++ b/Modules/IGT/Documentation/doxygen/IGTModule.dox @@ -1,22 +1,29 @@ /** \page IGTGeneralModulePage The IGT Modules \section IGTGeneralModulePageOverview Overview The module IGT integrates image guided therapy (IGT) functionality to MITK. The main features of MITK-IGT are: MITK-IGT consists of two layers for hardware control (Tracking Layer) and processing of tracking data (Navigation Layer). Additionally it offers components for rapid development of graphical user interfaces (GUIs) of navigation applications. To seperate UI functionality from the rest of the code UI classes are encapsulated in the seperate module IGT-UI. +\section IGTTutorial IGT Code Tutorial + +If you want to learn more about IGT you can have a look +on the IGT code tutorial, which can be found here: + + \li \subpage IGTCodeTutorialPage + \section IGTGeneralModulePageModuleList List of IGT Plugins There are also a few ready-to-use sample applications available as MITK-Plugins: \li \subpage org_mitk_gui_qt_igtexample \li \subpage org_mitk_gui_qt_igttracking */ \ No newline at end of file diff --git a/Modules/IGT/Documentation/doxygen/IGTTutorialStep1-2.png b/Modules/IGT/Documentation/doxygen/IGTTutorialStep1-2.png new file mode 100644 index 0000000000..f4f678d5a3 Binary files /dev/null and b/Modules/IGT/Documentation/doxygen/IGTTutorialStep1-2.png differ diff --git a/Modules/IGT/Documentation/doxygen/IGTTutorialStep1.dox b/Modules/IGT/Documentation/doxygen/IGTTutorialStep1.dox new file mode 100644 index 0000000000..74448ca274 --- /dev/null +++ b/Modules/IGT/Documentation/doxygen/IGTTutorialStep1.dox @@ -0,0 +1,213 @@ +/** +\page IGTCodeTutorialPage The IGT Code Tutorial + +The IGT tutorial consists of four main parts for construction of a small navigation pipeline using a virtual tracking device. +The virtual tracking device produces random tool data (position and orientation) so no additional hardware is required. + +\section sec1 In Tracking Layer + +Firstly a new object "tracker" of the type mitk::VirtualTrackingDevice is created, then two tools, named "tool1" and "tool2", +are added to this "tracker". Since, the tracking device "tracker" is treated as a virtual tracking +device "tool1" and "tool2" are just added to the object by method AddTool(name). + +\section sec2 In Navigation Layer + +\image html IGTTutorialStep1.png + +Secondly, a new source of the type mitk::TrackingDeviceSource has to be created with outputs for each single tool of a tracker. +The source sets the following tracking device by using method SetTrackingDevice as shown below +\code +source->SetTrackingDevice(tracker); +\endcode +So now, the source is initialized with the virtual tracking device. Next, the source is connected and tracking is started. + +In part II, a displacemt filter (object "displacer") is constructed to change the positions of the filtered NavigationData objects +with an offset for each direction (X,Y,Z). The given filter has inputs and outputs for each tool, in this example we have 2 tools, hence there exists two inputs and outputs. Every output of the displacement filter object is connected to the recorder object in the next part. + +In part III, all the NavigationData is recorded with the NavigationDataRecorder. In order to record, we simply create +an object "recorder" of the type mitk::NavigationDataRecorder and set the appropriate file to it. Now the displacer object is connected to the +recorder object for every output by using a for-loop in the code, the method StartRecording() is called on the next line. Afterwards, +the recorder has to be updated a couple of times. In this example the recorder is updating 100 times through +the second for-loop statement in part III. This can also be seen as a simulation of a timer by using a for-loop. + +Part IV explains how the recoded file can be played for further use. After the object "player" of a type mitk::NavigationDataPlayer +is created, the required file has to be set to the player and playing has to be started. Here, there exists a new pipeline which functions by reading +the recorded file from the harddisc and plays it by using the player as source. During the play, the for-loop makes the file update as in part III. + +\image html IGTTutorialStep1-2.png + +The full code of small navigation pipeline is shown below. + +\code + +int main(int /*argc*/, char* /*argv*/[]) +{ + + + //************************************************************************* + // What we will do... + //************************************************************************* + //In this tutorial we build up a small navigation pipeline with a virtual tracking device + //which produce random positions and orientation so no additional hardware is required. + //The source of the pipeline is a TrackingDeviceSource object. This we connect to a simple + //filter which just displaces the positions with an offset. After that we use a recorder + //to store this new positions and other information to disc in a XML file. After that we use + //another source (NavigationDataPlayer) to replay the recorded data. + + + //************************************************************************* + // Part I: Basic initialization of the source and tracking device + //************************************************************************* + //First of all create a tracking device object and two tools for this "device". + + //Here we take the VirtualTrackingDevice. This is not a real tracking device it just delivers random + //positions and orientations. You can use other/real tracking devices if you replace the following + //code with different tracking devices, e.g. mitk::NDITrackingDevice. The tools represent the + //sensors of the tracking device. The TrackingDevice fills the tools with data. + std::cout << "Generating TrackingDevice ..." << std::endl; + + mitk::VirtualTrackingDevice::Pointer tracker = mitk::VirtualTrackingDevice::New(); + tracker->AddTool("tool1"); + tracker->AddTool("tool2"); + + //The tracking device object is used for the physical connection to the device. To use the + //data inside of our tracking pipeline we need a source. This source encapsulate the tracking device + //and provides objects of the type mitk::NavigationData as output. The NavigationData objects stores + //position, orientation, if the data is valid or not and special error informations in a covariance + //matrix. + // + //Typically the start of our pipeline is a TrackingDeviceSource. To work correct we have to set a + //TrackingDevice object. Attention you have to set the tools before you set the whole TrackingDevice + //object to the TrackingDeviceSource because the source need to know how many outputs should be + //generated. + + std::cout << "Generating Source ..." << std::endl; + + mitk::TrackingDeviceSource::Pointer source = mitk::TrackingDeviceSource::New(); + source->SetTrackingDevice(tracker); //here we set the device for the pipeline source + + source->Connect(); //here we connect to the tracking system + //Note we do not call this on the TrackingDevice object + source->StartTracking(); //start the tracking + //Now the source generates outputs. + + + //************************************************************************* + // Part II: Create a NavigationDataToNavigationDataFilter + //************************************************************************* + + //The next thing we do is using a NavigationDataToNavigationDataFilter. One of these filter is the + //very simple NavigationDataDisplacementFilter. This filter just changes the positions of the input + //NavigationData objects with an offset for each direction (X,Y,Z). The input of this filter is the + //source and the output of this filter is the "displaced" input. + + std::cout << "Generating DisplacementFilter ..." << std::endl; + + mitk::NavigationDataDisplacementFilter::Pointer displacer = mitk::NavigationDataDisplacementFilter::New(); + mitk::Vector3D offset; + mitk::FillVector3D(offset, 10.0, 100.0, 1.0); //initialize the offset + displacer->SetOffset(offset); //now set the offset in the NavigationDataDisplacementFilter object + + //now every output of the source object is connected to the displacer object + for (unsigned int i = 0; i < source->GetNumberOfOutputs(); i++) + { + displacer->SetInput(i, source->GetOutput(i)); //here we connect to the displacement filter + } + + + //************************************************************************* + // Part III: Record the data with the NavigationDataRecorder + //************************************************************************* + + //The next part of our pipeline is the recorder. The recorder needs a filename. Otherwise the output + //is redirected to the console. The input of the recorder is the output of the displacement filter + //and the output is a XML file with the name "Test Output-0.xml". + + std::cout << "Start Recording ..." << std::endl; + + //we need the stringstream for building up our filename + std::stringstream filename; + + //the .xml extension and an counter is added automatically + filename << itksys::SystemTools::GetCurrentWorkingDirectory() << "/Test Output"; + + std::cout << "Record to file: " << filename.str() << "-0.xml ..." << std::endl; + + mitk::NavigationDataRecorder::Pointer recorder = mitk::NavigationDataRecorder::New(); + recorder->SetFileName(filename.str()); + + //now every output of the displacer object is connected to the recorder object + for (unsigned int i = 0; i < displacer->GetNumberOfOutputs(); i++) + { + recorder->AddNavigationData(displacer->GetOutput(i)); // here we connect to the recorder + } + + recorder->StartRecording(); //after finishing the settings you can start the recording mechanism + //now every update of the recorder stores one line into the file for + //each added NavigationData + + + for (unsigned int x = 0; x < 100; x++) //write 100 datasets + { + recorder->Update(); //the update causes one line in the XML file for every tool + //in this case two lines + itksys::SystemTools::Delay(100); //sleep a little + } + recorder->StopRecording(); //to get proper XML files you should stop recording + //if your application crashes during recording no data + //will be lost it is all stored to disc + + + //************************************************************************* + // Part IV: Play the data with the NavigationDataPlayer + //************************************************************************* + + //The recording is finished now so now we can play the data. The NavigationDataPlayer is similar + //to the TrackingDevice source. It also derives from NavigationDataSource. So you can use a player + //instead of a TrackingDeviceSource. The input of this player is the filename and the output are + //NavigationData object. + + filename << "-0.xml"; + std::cout << "Start playing from file: " << filename.str() << " ..." << std::endl; + + + mitk::NavigationDataPlayer::Pointer player = mitk::NavigationDataPlayer::New(); + //this is first part of the file name the .xml extension and an counter is added automatically + player->SetFileName(filename.str()); + player->StartPlaying(); //this starts the player + //From now on the player provides NavigationDatas in the order and + //correct time as they were recorded + + //this connects the outputs of the player to the NavigationData objects + mitk::NavigationData::Pointer nd = player->GetOutput(0); + mitk::NavigationData::Pointer nd2 = player->GetOutput(1); + for (unsigned int x=0; x<100; x++) + { + if (nd.IsNotNull()) //check if the output is not null + { + //With this update the NavigationData object propagates through the pipeline to get a new value. + //In this case we only have a source (NavigationDataPlayer). + nd->Update(); + + std::cout << x << ": 1:" << nd->GetPosition() << std::endl; + std::cout << x << ": 2:" << nd2->GetPosition() << std::endl; + std::cout << x << ": 1:" << nd->GetOrientation() << std::endl; + std::cout << x << ": 2:" << nd2->GetOrientation() << std::endl; + + itksys::SystemTools::Delay(100); //sleep a little like in the recorder part + } + } + player->StopPlaying(); //This stops the player + //With another call of StartPlaying the player will start again at the beginning of the file + + itksys::SystemTools::Delay(2000); + std::cout << "finished" << std::endl; + +} +\endcode + +*/ + + + + \ No newline at end of file diff --git a/Modules/IGT/Documentation/doxygen/IGTTutorialStep1.png b/Modules/IGT/Documentation/doxygen/IGTTutorialStep1.png new file mode 100644 index 0000000000..4fbe88081d Binary files /dev/null and b/Modules/IGT/Documentation/doxygen/IGTTutorialStep1.png differ