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 "mitkNavigationDataPlayer.h"
00019
00020
00021 #include <itksys/SystemTools.hxx>
00022
00023 #include <mitkTimeStamp.h>
00024 #include <fstream>
00025
00026 mitk::NavigationDataPlayer::NavigationDataPlayer()
00027 {
00028 m_NumberOfOutputs = 0;
00029 m_Pause = false;
00030 m_Playing = false;
00031 m_Stream = NULL;
00032 m_PlayerMode = NormalFile;
00033 m_FileName = "";
00034 m_FileVersion = 1;
00035 m_Playing = false;
00036 m_Pause = false;
00037 m_NumberOfOutputs = 0;
00038 m_StartPlayingTimeStamp = 0.0;
00039 m_PauseTimeStamp = 0.0;
00040 m_parentElement = NULL;
00041 m_currentNode = NULL;
00042
00043
00044 mitk::TimeStamp::GetInstance()->Start(this);
00045
00046
00047 }
00048
00049
00050 mitk::NavigationDataPlayer::~NavigationDataPlayer()
00051 {
00052 StopPlaying();
00053 delete m_parentElement;
00054 }
00055
00056
00057 void mitk::NavigationDataPlayer::GenerateData()
00058 {
00059
00060 if (!m_Playing)
00061 {
00062
00063 for (unsigned int index = 0; index < m_NumberOfOutputs; index++)
00064 {
00065 mitk::NavigationData* output = this->GetOutput(index);
00066 assert(output);
00067
00068 mitk::NavigationData::Pointer nd = mitk::NavigationData::New();
00069 mitk::NavigationData::PositionType position;
00070 mitk::NavigationData::OrientationType orientation(0.0,0.0,0.0,0.0);
00071 position.Fill(0.0);
00072
00073 nd->SetPosition(position);
00074 nd->SetOrientation(orientation);
00075 nd->SetDataValid(false);
00076
00077 output->Graft(nd);
00078 }
00079 return;
00080 }
00081
00082
00083 TimeStampType now = mitk::TimeStamp::GetInstance()->GetElapsed();
00084
00085
00086
00087 TimeStampType timeSinceStart = now - m_StartPlayingTimeStamp;
00088
00089
00090 std::vector< NavigationData::Pointer > nextCandidates;
00091 std::vector< NavigationData::Pointer > lastCandidates;
00092 std::vector< NavigationData::TimeStampType > currentTimeOfData;
00093
00094 for (unsigned int index=0; index < m_NumberOfOutputs; index++)
00095 {
00096 nextCandidates.push_back(m_NextToPlayNavigationData.at(index));
00097 lastCandidates.push_back(m_NextToPlayNavigationData.at(index));
00098
00099 currentTimeOfData.push_back(timeSinceStart + m_StartTimeOfData.at(index));
00100 }
00101
00102 if (m_NextToPlayNavigationData.size() != m_NumberOfOutputs)
00103 {
00104 std::cout << "Mismatch in data" << std::endl;
00105 return;
00106 }
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 while(nextCandidates[0]->GetTimeStamp() < currentTimeOfData[0])
00119 {
00120 for (unsigned int index=0; index < m_NumberOfOutputs; index++)
00121 {
00122 lastCandidates[index] = nextCandidates.at(index);
00123
00124 switch(m_FileVersion)
00125 {
00126 case 1:
00127 nextCandidates[index] = ReadVersion1();
00128 break;
00129 default:
00130 return;
00131 break;
00132 }
00133
00134
00135 for (unsigned int i = 0; i < m_NumberOfOutputs; i++)
00136 {
00137 if (nextCandidates.at(index).IsNull())
00138 {
00139 StopPlaying();
00140 return;
00141 }
00142 }
00143 }
00144
00145 }
00146
00147
00148 for (unsigned int index = 0; index < m_NumberOfOutputs; index++)
00149 {
00150 mitk::NavigationData* output = this->GetOutput(index);
00151 assert(output);
00152
00153 output->Graft(lastCandidates.at(index));
00154 m_NextToPlayNavigationData[index] = nextCandidates.at(index);
00155 }
00156
00157 }
00158
00159
00160 void mitk::NavigationDataPlayer::UpdateOutputInformation()
00161 {
00162 this->Modified();
00163 Superclass::UpdateOutputInformation();
00164 }
00165
00166
00167 void mitk::NavigationDataPlayer::InitPlayer()
00168 {
00169 if (m_Stream == NULL)
00170 {
00171 StopPlaying();
00172 std::cout << "Playing not possible. Wrong file name or path? " << std::endl;
00173 return;
00174 }
00175 if (!m_Stream->good())
00176 {
00177 StopPlaying();
00178 std::cout << "Playing not possible. Stream is not good!" << std::endl;
00179 return;
00180 }
00181
00182 m_FileVersion = GetFileVersion(m_Stream);
00183
00184
00185 if (m_FileVersion < 1)
00186 {
00187 StopPlaying();
00188 std::cout << "Playing not possible. Stream is not good!" << std::endl;
00189 return;
00190 }
00191 if(m_NumberOfOutputs == 0){
00192 m_NumberOfOutputs = GetNumberOfNavigationDatas(m_Stream);
00193 }
00194
00195
00196 if (m_NumberOfOutputs > 0)
00197 {
00198
00199
00200 if (this->GetNumberOfOutputs() != m_NumberOfOutputs)
00201 {
00202 this->SetNumberOfOutputs(m_NumberOfOutputs);
00203 }
00204
00205 GetFirstData();
00206 }
00207 else
00208 {
00209 std::cout << "The input stream seems to have NavigationData incompatible format" << std::endl;
00210 StopPlaying();
00211 }
00212
00213 }
00214
00215 unsigned int mitk::NavigationDataPlayer::GetFileVersion(std::istream* stream)
00216 {
00217 if (stream==NULL)
00218 {
00219 std::cout << "No input stream set!" << std::endl;
00220 return 0;
00221 }
00222 if (!stream->good())
00223 {
00224 std::cout << "Stream not good!" << std::endl;
00225 return 0;
00226 }
00227 int version = 1;
00228
00229 TiXmlDeclaration* dec = new TiXmlDeclaration();
00230 *stream >> *dec;
00231 if(strcmp(dec->Version(),"") == 0){
00232 std::cout << "The input stream seems to have XML incompatible format" << std::endl;
00233 return 0;
00234 }
00235
00236 m_parentElement = new TiXmlElement("");
00237 *stream >> *m_parentElement;
00238
00239 std::string tempValue = m_parentElement->Value();
00240 if(tempValue != "Version")
00241 {
00242 if(tempValue == "Data"){
00243 m_parentElement->QueryIntAttribute("version",&version);
00244 }
00245 }
00246 else
00247 {
00248 m_parentElement->QueryIntAttribute("Ver",&version);
00249 }
00250
00251 if (version > 0)
00252 return version;
00253 else
00254 return 0;
00255
00256 }
00257
00258
00259 unsigned int mitk::NavigationDataPlayer::GetNumberOfNavigationDatas(std::istream* stream)
00260 {
00261 if (stream == NULL)
00262 {
00263 std::cout << "No input stream set!" << std::endl;
00264 return 0;
00265 }
00266 if (!stream->good())
00267 {
00268 std::cout << "Stream not good!" << std::endl;
00269 return 0;
00270 }
00271
00272
00273
00274
00275 int numberOfTools = 0;
00276
00277 std::string tempValue = m_parentElement->Value();
00278 if(tempValue == "Version"){
00279 *stream >> *m_parentElement;
00280 }
00281 m_parentElement->QueryIntAttribute("ToolCount",&numberOfTools);
00282
00283 if (numberOfTools > 0)
00284 return numberOfTools;
00285
00286 return 0;
00287
00288 }
00289
00290
00291 mitk::NavigationData::Pointer mitk::NavigationDataPlayer::ReadVersion1()
00292 {
00293 if (m_Stream == NULL)
00294 {
00295 m_Playing = false;
00296 std::cout << "Playing not possible. Wrong file name or path? " << std::endl;
00297 return NULL;
00298 }
00299 if (!m_Stream->good())
00300 {
00301 m_Playing = false;
00302 std::cout << "Playing not possible. Stream is not good!" << std::endl;
00303 return NULL;
00304 }
00305
00306 mitk::NavigationData::Pointer nd = mitk::NavigationData::New();
00307 mitk::NavigationData::PositionType position;
00308 mitk::NavigationData::OrientationType orientation(0.0,0.0,0.0,0.0);
00309 mitk::NavigationData::TimeStampType timestamp = -1;
00310 mitk::NavigationData::CovarianceMatrixType matrix;
00311
00312 bool hasPosition = true;
00313 bool hasOrientation = true;
00314 bool dataValid = false;
00315
00316 position.Fill(0.0);
00317 matrix.SetIdentity();
00318
00319 TiXmlElement* elem = new TiXmlElement("");
00320 m_currentNode = m_parentElement->IterateChildren(m_currentNode);
00321 if(m_currentNode){
00322 elem = m_currentNode->ToElement();
00323 }
00324
00325
00326 elem->QueryDoubleAttribute("Time",×tamp);
00327 if (timestamp == -1)
00328 {
00329 return NULL;
00330 }
00331
00332 elem->QueryFloatAttribute("X", &position[0]);
00333 elem->QueryFloatAttribute("Y", &position[1]);
00334 elem->QueryFloatAttribute("Z", &position[2]);
00335
00336 elem->QueryFloatAttribute("QX", &orientation[0]);
00337 elem->QueryFloatAttribute("QY", &orientation[1]);
00338 elem->QueryFloatAttribute("QZ", &orientation[2]);
00339 elem->QueryFloatAttribute("QR", &orientation[3]);
00340
00341 elem->QueryFloatAttribute("C00", &matrix[0][0]);
00342 elem->QueryFloatAttribute("C01", &matrix[0][1]);
00343 elem->QueryFloatAttribute("C02", &matrix[0][2]);
00344 elem->QueryFloatAttribute("C03", &matrix[0][3]);
00345 elem->QueryFloatAttribute("C04", &matrix[0][4]);
00346 elem->QueryFloatAttribute("C05", &matrix[0][5]);
00347 elem->QueryFloatAttribute("C10", &matrix[1][0]);
00348 elem->QueryFloatAttribute("C11", &matrix[1][1]);
00349 elem->QueryFloatAttribute("C12", &matrix[1][2]);
00350 elem->QueryFloatAttribute("C13", &matrix[1][3]);
00351 elem->QueryFloatAttribute("C14", &matrix[1][4]);
00352 elem->QueryFloatAttribute("C15", &matrix[1][5]);
00353
00354 int tmpval = 0;
00355 elem->QueryIntAttribute("Valid", &tmpval);
00356 if (tmpval == 0)
00357 dataValid = false;
00358 else
00359 dataValid = true;
00360
00361 tmpval = 0;
00362 elem->QueryIntAttribute("hO", &tmpval);
00363 if (tmpval == 0)
00364 hasOrientation = false;
00365 else
00366 hasOrientation = true;
00367
00368 tmpval = 0;
00369 elem->QueryIntAttribute("hP", &tmpval);
00370 if (tmpval == 0)
00371 hasPosition = false;
00372 else
00373 hasPosition = true;
00374
00375 nd->SetTimeStamp(timestamp);
00376 nd->SetPosition(position);
00377 nd->SetOrientation(orientation);
00378 nd->SetCovErrorMatrix(matrix);
00379 nd->SetDataValid(dataValid);
00380 nd->SetHasOrientation(hasOrientation);
00381 nd->SetHasPosition(hasPosition);
00382
00383
00384 return nd;
00385 }
00386
00387
00388 void mitk::NavigationDataPlayer::StartPlaying()
00389 {
00390 if (m_Stream == NULL)
00391 {
00392 m_Playing = false;
00393
00394
00395 if (m_FileName != "")
00396 {
00397
00398
00399 SetStream(m_PlayerMode);
00400 }
00401
00402
00403 if (m_Stream == NULL)
00404 {
00405 StopPlaying();
00406 std::cout << "Playing not possible. Wrong file name or path? " << std::endl;
00407 return;
00408 }
00409 }
00410
00411 if (!m_Playing && m_Stream->good())
00412 {
00413 m_Playing = true;
00414 m_StartPlayingTimeStamp = mitk::TimeStamp::GetInstance()->GetElapsed();
00415 }
00416 else
00417 {
00418 std::cout << "Player already started or stream is not good" << std::endl;
00419 StopPlaying();
00420 }
00421
00422 }
00423
00424
00425 void mitk::NavigationDataPlayer::StopPlaying()
00426 {
00427
00428
00429 m_Pause = false;
00430 m_Playing = false;
00431 m_Stream = NULL;
00432 m_FileVersion = 1;
00433 m_Playing = false;
00434 m_Pause = false;
00435 m_StartPlayingTimeStamp = 0.0;
00436 m_PauseTimeStamp = 0.0;
00437 m_NextToPlayNavigationData.clear();
00438 m_StartTimeOfData.clear();
00439 }
00440
00441
00442 void mitk::NavigationDataPlayer::GetFirstData()
00443 {
00444
00445
00446 for (unsigned int index=0; index < m_NumberOfOutputs; index++)
00447 {
00448
00449 m_NextToPlayNavigationData.push_back(NULL);
00450 m_StartTimeOfData.push_back(0.0);
00451 mitk::NavigationData::Pointer nd = this->GetOutput(index);
00452
00453 switch(m_FileVersion)
00454 {
00455 case 1:
00456 m_NextToPlayNavigationData[index] = ReadVersion1();
00457
00458
00459 if (m_NextToPlayNavigationData[index].IsNull())
00460 {
00461 StopPlaying();
00462 std::cout << "XML File is corrupt or has no NavigationData" << std::endl;
00463 return;
00464 }
00465
00466
00467 if (nd.IsNull())
00468 this->SetNthOutput(index, m_NextToPlayNavigationData[index]);
00469
00470 m_StartTimeOfData[index] = m_NextToPlayNavigationData[index]->GetTimeStamp();
00471 break;
00472 default:
00473 return;
00474 break;
00475 }
00476 }
00477 }
00478
00479
00480 void mitk::NavigationDataPlayer::Pause()
00481 {
00482
00483 if(m_Playing && !m_Pause)
00484 {
00485 m_Playing = false;
00486 m_Pause = true;
00487 m_PauseTimeStamp = mitk::TimeStamp::GetInstance()->GetElapsed();
00488 }
00489 else
00490 {
00491 std::cout << "Player is either not started or already in paused" << std::endl;
00492 }
00493
00494 }
00495
00496
00497 void mitk::NavigationDataPlayer::Resume()
00498 {
00499
00500 if(!m_Playing && m_Pause)
00501 {
00502 m_Playing = true;
00503 mitk::NavigationData::TimeStampType now = mitk::TimeStamp::GetInstance()->GetElapsed();
00504 m_StartPlayingTimeStamp = now + (m_PauseTimeStamp - m_StartPlayingTimeStamp);
00505 }
00506 else
00507 {
00508 std::cout << "Player is not paused!" << std::endl;
00509 }
00510 }
00511
00512
00513 void mitk::NavigationDataPlayer::SetStream( PlayerMode )
00514 {
00515 m_Stream = NULL;
00516
00517 if (!itksys::SystemTools::FileExists(m_FileName.c_str()))
00518 {
00519 std::cout << "File dont exist!" << std::endl;
00520 return;
00521 }
00522 switch(m_PlayerMode)
00523 {
00524 case NormalFile:
00525
00526 m_Stream = new std::ifstream(m_FileName.c_str());
00527
00528 break;
00529 case ZipFile:
00530
00531 m_Stream = NULL;
00532 std::cout << "Sorry no ZipFile support yet";
00533
00534 break;
00535 default:
00536 m_Stream = NULL;
00537 break;
00538 }
00539
00540 this->Modified();
00541 InitPlayer();
00542 }
00543
00544
00545 void mitk::NavigationDataPlayer::SetStream( std::istream* stream )
00546 {
00547 if (!stream->good())
00548 {
00549 std::cout << "The stream is not good" << std::endl;
00550 return;
00551 }
00552
00553 m_Stream = stream;
00554
00555 this->Modified();
00556 InitPlayer();
00557 }
00558