MOOS 0.2375
/home/toby/moos-ivp/MOOS-2375-Oct0611/Tools/Graphical/uPlayBack/MOOSPlayBack.cpp
Go to the documentation of this file.
00001 
00002 //
00003 //   MOOS - Mission Oriented Operating Suite 
00004 //  
00005 //   A suit of Applications and Libraries for Mobile Robotics Research 
00006 //   Copyright (C) 2001-2005 Massachusetts Institute of Technology and 
00007 //   Oxford University. 
00008 //    
00009 //   This software was written by Paul Newman at MIT 2001-2002 and Oxford 
00010 //   University 2003-2005. email: pnewman@robots.ox.ac.uk. 
00011 //      
00012 //   This file is part of a  MOOS Utility Component. 
00013 //        
00014 //   This program is free software; you can redistribute it and/or 
00015 //   modify it under the terms of the GNU General Public License as 
00016 //   published by the Free Software Foundation; either version 2 of the 
00017 //   License, or (at your option) any later version. 
00018 //          
00019 //   This program is distributed in the hope that it will be useful, 
00020 //   but WITHOUT ANY WARRANTY; without even the implied warranty of 
00021 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
00022 //   General Public License for more details. 
00023 //            
00024 //   You should have received a copy of the GNU General Public License 
00025 //   along with this program; if not, write to the Free Software 
00026 //   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 
00027 //   02111-1307, USA. 
00028 //
00030 // MOOSPlayBack.cpp: implementation of the CMOOSPlayBack class.
00031 //
00033 #ifdef _WIN32
00034     #pragma warning(disable : 4786)
00035 #endif
00036 
00037 #include "MOOSPlayBack.h"
00038 #include <algorithm>
00039 
00040 #ifdef _DEBUG
00041 #undef THIS_FILE
00042 static char THIS_FILE[]=__FILE__;
00043 #define new DEBUG_NEW
00044 #endif
00045 
00046 
00047 #define MAX_CHOKE_TIME 2.0
00048 
00050 // Construction/Destruction
00052 
00053 CMOOSPlayBack::CMOOSPlayBack()
00054 {
00055     m_dfLastMessageTime = 0;
00056     m_nLastLine = 0;
00057     m_bEOF = true;
00058     m_dfTickTime = 0.01;
00059     m_dfLastClientProcessedTime = -1;
00060     m_bWaitingForClientCatchup = false;
00061 }
00062 
00063 CMOOSPlayBack::~CMOOSPlayBack()
00064 {
00065 
00066 }
00067 
00068 bool CMOOSPlayBack::Initialise(const string &sFileName)
00069 {
00070     m_sFileName = sFileName;
00071     if(!ParseFile())
00072         return false;
00073 
00074     return true;
00075 
00076 }
00077 
00078 bool CMOOSPlayBack::IsOpen()
00079 {
00080     return m_InputFile.is_open();
00081 }
00082 
00083 bool CMOOSPlayBack::ParseFile()
00084 {
00085     
00086     m_bEOF = false;
00087 
00088     //if open then close
00089     if(m_InputFile.is_open())
00090     {
00091         m_InputFile.close();
00092         m_InputFile.clear();
00093     }
00094 
00095     //now open
00096     m_InputFile.open(m_sFileName.c_str());
00097 
00098     //check
00099     if(!m_InputFile.is_open())
00100     {
00101         //bad news
00102         return false;
00103     }
00104 
00105     m_bEOF = false;
00106 
00107     m_Sources.clear();
00108     m_PlayBackList.clear();
00109 
00110     char Tmp[10000];
00111         
00112     string sLogStart;
00113 
00114     int nLine = 0;
00115     m_dfLogStart = 0.0;
00116     while(!m_InputFile.eof())
00117     {
00118         m_InputFile.getline(Tmp,sizeof(Tmp));
00119 
00120         string sLine = string(Tmp);
00121 
00122         //if we haven't found it look for start of log file...
00123         if(m_dfLogStart==0.0 && sLine.find("LOGSTART")!=string::npos)
00124         {
00125             MOOSChomp(sLine,"LOGSTART");
00126             m_dfLogStart = atof(sLine.c_str());
00127             continue;
00128         }
00129 
00130         MOOSTrimWhiteSpace(sLine);
00131 
00132         //is it a comment? or maybe there is nothing on the line!
00133         if(sLine[0]=='%' || sLine.size()==0)
00134             continue;
00135         
00136         if(nLine==0)
00137         {
00138             sLogStart = sLine;
00139         }
00140         else
00141         {
00142             CPlaybackEntry NewEntry;
00143             
00144             NewEntry.m_dfTime = atof(MOOSChomp(sLine," ").c_str())+m_dfLogStart;
00145             MOOSTrimWhiteSpace(sLine);
00146             
00147             NewEntry.m_sWhat  = MOOSChomp(sLine," ");
00148             MOOSTrimWhiteSpace(sLine);
00149             
00150             NewEntry.m_sWho  = MOOSChomp(sLine," ");
00151             MOOSTrimWhiteSpace(sLine);
00152 
00153             string sData = sLine;
00154             MOOSTrimWhiteSpace(sData);
00155             
00156             //is this a string or not?
00157             if(MOOSIsNumeric(sData))
00158             {
00159                 NewEntry.m_dfVal = atof(sData.c_str());
00160                 NewEntry.m_sVal = "";
00161                 NewEntry.m_bNumeric = true;
00162             }
00163             else
00164             {
00165                 NewEntry.m_sVal = sData;
00166                 NewEntry.m_dfVal = 0;
00167                 NewEntry.m_bNumeric = false;
00168             }
00169 
00170             m_PlayBackList.push_back(NewEntry);
00171             //MOOSTrace("size is %d\n",m_PlayBackList.size());
00172 
00173             m_Sources.insert(NewEntry.m_sWho);
00174 
00175         }        
00176 
00177         nLine++;
00178     
00179 
00180 
00181     }
00182 
00183     sort(m_PlayBackList.begin(),m_PlayBackList.end());
00184     //m_PlayBackList.sort();
00185 
00186 
00187     return true;
00188 }
00189 
00190 int CMOOSPlayBack::GetSize()
00191 {
00192     return m_PlayBackList.size();
00193 }
00194 
00195 double CMOOSPlayBack::GetTimeNow()
00196 {
00197     return m_dfLastMessageTime-m_dfLogStart;
00198 }
00199 
00200 int CMOOSPlayBack::GetCurrentLine()
00201 {
00202     return m_nLastLine;
00203 }
00204 
00205 double CMOOSPlayBack::GetStartTime()
00206 {
00207     if(m_PlayBackList.empty())
00208         return 0;
00209 
00210     return m_PlayBackList.front().m_dfTime;
00211 }
00212 
00213 double CMOOSPlayBack::GetFinishTime()
00214 {
00215     if(m_PlayBackList.empty())
00216         return 0;
00217 
00218     return m_PlayBackList.back().m_dfTime;
00219 }
00220 
00221 bool CMOOSPlayBack::Iterate(MOOSMSG_LIST &Output)
00222 {
00223     if(m_bEOF)
00224         return false;
00225     
00226     double dfStartTime = m_dfLastMessageTime+1e-6;
00227     double dfStopTime = m_dfLastMessageTime+m_dfTickTime;
00228     
00229     bool bDone = false;
00230 
00231     while(m_pListIterator!=m_PlayBackList.end() && !bDone)
00232     {    
00233         CPlaybackEntry & rEntry = *m_pListIterator;
00234 
00235         
00236         m_dfClientLagTime = MOOSTime() - m_dfLastClientProcessedTime;
00237         if (m_dfLastClientProcessedTime != -1 &&
00238              m_dfClientLagTime > MAX_CHOKE_TIME)
00239         {
00240             m_bWaitingForClientCatchup = true;    
00241             bDone = true;
00242             dfStopTime = rEntry.m_dfTime;
00243             continue;
00244         } 
00245         else
00246         {
00247             m_bWaitingForClientCatchup = false;
00248         }
00249 
00250         if(rEntry.m_dfTime>dfStopTime)
00251         {
00252             m_pListIterator;
00253             bDone = true;
00254             continue;
00255         }
00256         else
00257         {
00258             if(rEntry.m_dfTime>=dfStartTime)
00259             {
00260                 CMOOSMsg Msg;
00261 
00262                 Entry2Message(rEntry,Msg);
00263 
00264                 if(m_SourceFilter.find(Msg.m_sSrc)==m_SourceFilter.end())
00265                 {
00266                     Output.push_front(Msg);
00267                 }
00268             }
00269             m_nLastLine++;
00270         }        
00271         m_pListIterator++;
00272     }
00273 
00274     //look for end of data..
00275     if(m_pListIterator==m_PlayBackList.end())
00276     {
00277         m_bEOF = true;
00278         return false;
00279     }
00280     
00281     m_dfLastMessageTime = dfStopTime;
00282 
00283     return true;
00284 }
00285 
00286 bool CMOOSPlayBack::IsEOF()
00287 {
00288     return m_bEOF;
00289 }
00290 
00291 bool CMOOSPlayBack::Reset()
00292 {
00293     if(m_PlayBackList.empty())
00294         return false;
00295 
00296     //reset important things..
00297     m_pListIterator = m_PlayBackList.begin();
00298     m_bEOF = false;
00299     m_nLastLine = 0;
00300     m_dfLastMessageTime = m_pListIterator->m_dfTime-1e-6;
00301 
00302     return true;
00303 }
00304 
00305 bool CMOOSPlayBack::SetTickInterval(double dfInterval)
00306 {
00307     m_dfTickTime = dfInterval;
00308     return true;
00309 }
00310 
00311 bool CMOOSPlayBack::Filter(string sSrc, bool bWanted)
00312 {
00313     if(bWanted)
00314     {
00315         //remove from our filter things that are wanted
00316         STRING_SET::iterator p = m_SourceFilter.find(sSrc);
00317 
00318         if(p!=m_SourceFilter.end())
00319         {
00320             m_SourceFilter.erase(p);
00321         }
00322     }
00323     else
00324     {
00325         //we don;t want this type of message (from thsinclient)
00326         //so add it to our filter
00327         m_SourceFilter.insert(sSrc);
00328         MOOSTrace("Filtering messages from %s\n",sSrc.c_str());
00329     }
00330     return true;
00331 }
00332 
00333 bool CMOOSPlayBack::ClearFilter()
00334 {
00335     m_SourceFilter.clear();
00336     return true;
00337 }
00338 
00339 bool CMOOSPlayBack::Entry2Message(CPlaybackEntry Entry, CMOOSMsg &Msg)
00340 {
00341     if(!CrackAndAdjustEntry(Entry))
00342         return false;
00343 
00344     Msg.m_dfTime = MOOSTime();
00345     Msg.m_dfVal = Entry.m_dfVal;
00346     Msg.m_sVal = Entry.m_sVal;
00347     Msg.m_sSrc = Entry.m_sWho;
00348     Msg.m_sKey = Entry.m_sWhat;
00349     Msg.m_cDataType = Entry.m_bNumeric ? MOOS_DOUBLE : MOOS_STRING;
00350     Msg.m_cMsgType = MOOS_NOTIFY;
00351 
00352     return true;
00353 }
00354 
00355 bool CMOOSPlayBack::CrackAndAdjustEntry(CPlaybackEntry &rEntry)
00356 {
00357     //return true; //added Jan 2005 PMN - exisiting code was intolerable!
00358     //client must fix 
00359     
00360     //this is horrible but if the original message included timing information
00361     //then we have to adjust it here....
00362     /*
00363     if(rEntry.m_sWhat=="LBL_TOF")
00364     {
00365         string sOldStart = MOOSChomp(rEntry.m_sVal,",");
00366         MOOSChomp(sOldStart,"=");
00367         double dfOldTxTime = atof(sOldStart.c_str());
00368         double dfAdjustment = MOOSTime()-rEntry.m_dfTime;
00369         string sNewStart = MOOSFormat("Tx=%.3f,",dfOldTxTime+dfAdjustment);
00370         
00371         rEntry.m_sVal = sNewStart+rEntry.m_sVal;
00372     }*/
00373 
00374     return true;
00375 }
00376 
00377 double CMOOSPlayBack::GetLastMessageTime()
00378 {
00379     return m_dfLastMessageTime;
00380 }
00381 
00382 bool CMOOSPlayBack::SetLastTimeProcessed(double dfTime)
00383 {
00384     m_dfLastClientProcessedTime = dfTime;
00385     double diff = MOOSTime() - dfTime;
00386     return true;
00387 }
00388 
00389 bool CMOOSPlayBack::IsWaitingForClient()
00390 {
00391     return m_bWaitingForClientCatchup;
00392 }
00393 
00394 string CMOOSPlayBack::GetStatusString()
00395 {
00396     return MOOSFormat("%s Client Lag %g",
00397         m_bWaitingForClientCatchup ? "Waiting for Client CATCHUP":"Playing just fine", 
00398         m_dfClientLagTime);
00399 }
00400 
00401 bool CMOOSPlayBack::GotoTime(double dfT)
00402 {
00403     int nTmp = 0;
00404 
00405     PLAYBACKLIST::iterator q = m_pListIterator;
00406     for(q=m_PlayBackList.begin();
00407         q!=m_PlayBackList.end();
00408         q++)
00409     {
00410         nTmp++;
00411         if(q->m_dfTime>dfT)
00412         {
00413             m_pListIterator=q;
00414             m_nLastLine = nTmp;
00415             m_bEOF = false;
00416             m_dfLastClientProcessedTime = -1;
00417             m_bWaitingForClientCatchup = false;
00418             m_dfLastMessageTime = m_pListIterator->m_dfTime-1e-6;    
00419             return true;
00420         }
00421     }
00422     return false;
00423 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines