MOOS 0.2375
/home/toby/moos-ivp/MOOS-2375-Oct0611/Tools/Graphical/uPlayBack/MOOSPlayBackV2.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 CMOOSPlayBackV2 class.
00031 //
00033 #if (_MSC_VER == 1200)
00034 #pragma warning(disable: 4786)
00035 #pragma warning(disable: 4503)
00036 #endif
00037 
00038 #include "MOOSPlayBackV2.h"
00039 #include <algorithm>
00040 
00041 #ifdef _DEBUG
00042 #undef THIS_FILE
00043 static char THIS_FILE[]=__FILE__;
00044 #define new DEBUG_NEW
00045 #endif
00046 
00047 
00048 #define MAX_CHOKE_TIME 2.0
00049 
00051 // Construction/Destruction
00053 
00054 CMOOSPlayBackV2::CMOOSPlayBackV2()
00055 {
00056     m_dfLastMessageTime = 0;
00057     m_nCurrentLine = 0;
00058     m_dfTickTime = 0.01;
00059     m_dfLastClientProcessedTime = -1;
00060     m_bWaitingForClientCatchup = false;
00061 }
00062 
00063 CMOOSPlayBackV2::~CMOOSPlayBackV2()
00064 {
00065 
00066 }
00067 
00068 bool CMOOSPlayBackV2::Initialise(const string &sFileName)
00069 {
00070 
00071     if(m_ALog.IsOpen())
00072         m_ALog.Close();
00073 
00074 
00075     m_nCurrentLine = 0;
00076     m_dfLastClientProcessedTime = -1;
00077     m_sFileName = sFileName;
00078 
00079     m_ALog.Open(sFileName);
00080     
00081     return m_ALog.IsOpen();
00082 
00083 }
00084 
00085 bool CMOOSPlayBackV2::IsOpen()
00086 {
00087     return m_ALog.IsOpen();
00088 }
00089 
00090 
00091 int CMOOSPlayBackV2::GetSize()
00092 {
00093     return m_ALog.GetLineCount();
00094 }
00095 
00096 double CMOOSPlayBackV2::GetTimeNow()
00097 {
00098     return m_dfLastMessageTime-m_dfLogStart;
00099 }
00100 
00101 int CMOOSPlayBackV2::GetCurrentLine()
00102 {
00103     return m_nLastLine;
00104 }
00105 
00106 double CMOOSPlayBackV2::GetStartTime()
00107 {
00108     if(!m_ALog.IsOpen() || m_ALog.GetLineCount()<0)
00109         return 0;
00110 
00111     return m_ALog.GetEntryTime(0);
00112 
00113 }
00114 
00115 double CMOOSPlayBackV2::GetFinishTime()
00116 {
00117     if(!m_ALog.IsOpen() || m_ALog.GetLineCount()<0)
00118         return 0;
00119     
00120     return m_ALog.GetEntryTime(GetSize()-1);
00121 
00122 }
00123 
00124 bool CMOOSPlayBackV2::IsEOF()
00125 {
00126     if(!m_ALog.IsOpen())
00127         return true;
00128 
00129     return m_nCurrentLine >= m_ALog.GetLineCount();
00130 }
00131 
00132 
00133 bool CMOOSPlayBackV2::Iterate(MOOSMSG_LIST &Output)
00134 {
00135     if(IsEOF())
00136         return false;
00137 
00138     double dfStartTime = m_dfLastMessageTime+1e-6;
00139     double dfStopTime = m_dfLastMessageTime+m_dfTickTime;
00140     
00141     bool bDone = false;
00142     
00143     while(!bDone && !IsEOF() )    
00144     {
00145         CMOOSMsg NewMsg;
00146         double dfTNext = m_ALog.GetEntryTime(m_nCurrentLine);
00147 
00148 
00149         //are we in a mode in which we are slaved to a client
00150         //via its publishing of MOOS_CHOKE?
00151         m_dfClientLagTime = MOOSTime() - m_dfLastClientProcessedTime;
00152         if (m_dfLastClientProcessedTime != -1 &&
00153              m_dfClientLagTime > MAX_CHOKE_TIME)
00154         {
00155             m_bWaitingForClientCatchup = true;    
00156             bDone = true;
00157             dfStopTime = dfTNext;
00158             continue;
00159         } 
00160         else
00161         {
00162             //normal sequential processing under our own steam
00163             m_bWaitingForClientCatchup = false;
00164 
00165             if(dfTNext<=dfStopTime)
00166             {
00167                 
00168                 if(MessageFromLine(m_ALog.GetLine(m_nCurrentLine),NewMsg))
00169                 {
00170                     if(!IsFiltered(NewMsg.GetSource()))
00171                     {
00172                         Output.push_front(NewMsg);
00173                     }
00174                 }                             
00175 
00176                                 
00177                                 // arh moved this out of the loop above, because a failed
00178                                 // call to MessageFromLine would make uPlayback hang in
00179                                 // an infinite loop
00180                                 m_nCurrentLine++;
00181             }
00182             else
00183             {
00184                 bDone = true;
00185             }
00186 
00187         }                         
00188     }
00189 
00190     //post a playback time
00191     if(!Output.empty())
00192     {
00193         CMOOSMsg timeMsg( MOOS_NOTIFY, "PLAYBACK_DB_TIME", dfStopTime );
00194         timeMsg.m_sSrc = "uPlayback";
00195         Output.push_front( timeMsg );
00196     }
00197 
00198 
00199     m_dfLastMessageTime = dfStopTime;
00200 
00201 
00202 
00203     return true;
00204 }
00205 
00206 
00207 bool CMOOSPlayBackV2::Reset()
00208 {
00209     if(!m_ALog.IsOpen())
00210         return false;
00211     
00212     m_nCurrentLine = 0;
00213     m_dfLastMessageTime = m_ALog.GetEntryTime(0)-1e-6;
00214     
00215     return true;
00216 }
00217 
00218 bool CMOOSPlayBackV2::SetTickInterval(double dfInterval)
00219 {
00220     m_dfTickTime = dfInterval;
00221     return true;
00222 }
00223 
00224 bool CMOOSPlayBackV2::IsFiltered(const std::string & sSrc)
00225 {
00226     return m_SourceFilter.find(sSrc)!=m_SourceFilter.end();
00227 }
00228 
00229 bool CMOOSPlayBackV2::Filter(const std::string & sSrc, bool bWanted)
00230 {
00231     if(bWanted)
00232     {
00233         //remove from our filter things that are wanted
00234         STRING_SET::iterator p = m_SourceFilter.find(sSrc);
00235 
00236         if(p!=m_SourceFilter.end())
00237         {
00238             m_SourceFilter.erase(p);
00239         }
00240     }
00241     else
00242     {
00243         //we don;t want this type of message (from thsinclient)
00244         //so add it to our filter
00245         m_SourceFilter.insert(sSrc);
00246         MOOSTrace("Filtering messages from %s\n",sSrc.c_str());
00247     }
00248     return true;
00249 }
00250 
00251 bool CMOOSPlayBackV2::ClearFilter()
00252 {
00253     m_SourceFilter.clear();
00254     return true;
00255 }
00256 
00257 bool CMOOSPlayBackV2::MessageFromLine(const std::string & sLine, CMOOSMsg &Msg)
00258 {
00259     int n = 0;
00260     std::string sTime,sKey,sSrc;
00261     
00262     m_ALog.GetNextToken(sLine,n,sTime);
00263     m_ALog.GetNextToken(sLine,n,sKey);
00264     m_ALog.GetNextToken(sLine,n,sSrc);
00265 
00266     size_t nData = sLine.find_first_not_of(" \t",n);
00267     if(nData==string::npos)
00268         return false;
00269 
00270     std::string sData = sLine.substr(nData,sLine.size()-nData);
00271 
00272 
00273     Msg.m_dfTime = MOOSTime();
00274 
00275     if(MOOSIsNumeric(sData))
00276     {
00277         Msg.m_dfVal = atof(sData.c_str());
00278         Msg.m_cDataType  = MOOS_DOUBLE;
00279         Msg.m_sVal = "";
00280     }
00281     else
00282     {
00283         Msg.m_dfVal = 0.0;
00284 
00285 
00286         if(sData.find("<MOOS_BINARY>") !=std::string::npos)
00287         {
00288             //Msg.MarkAsBinary();
00289             long long nOffset;
00290             if(!MOOSValFromString(nOffset,sData,"Offset"))
00291                 return MOOSFail("badly formed MOOS_BINARY indicator - missing \"Offset=xyz\"");
00292 
00293             std::string sFile;
00294             if(!MOOSValFromString(sFile,sData,"File"))
00295                 return MOOSFail("badly formed MOOS_BINARY indicator - missing \"File=XYZ\"");
00296 
00297             int nBytes;
00298             if(!MOOSValFromString(nBytes,sData,"Bytes"))
00299                 return MOOSFail("badly formed MOOS_BINARY indicator - missing \"Bytes=xyz\"");
00300 
00301 
00302             //corner case of binary file changing half way through a log....(Why this might happen
00303             //I don't know but catch it anyway....
00304             if(sFile != m_sBinaryFileName && m_BinaryFile.is_open() )
00305             {
00306                 m_BinaryFile.close();
00307             }
00308             m_sBinaryFileName = sFile;
00309 
00310             if(!m_BinaryFile.is_open())
00311             {
00312                 //open the file with the correct name
00313                 //here we need to point the file towards the full path - the blog file should be sitting next
00314                 //to teh alog being played
00315 
00317                 std::string sPath,sFileName,sExtension;
00318 
00319                 if(!MOOSFileParts(m_ALog.GetFileName(),sPath,sFileName,sExtension))
00320                     return MOOSFail("failed to parse alog file into file parts %s",MOOSHERE);
00321 
00322                 std::string sFullBinaryLogPath = sPath+"/"+m_sBinaryFileName;
00323 
00324                 MOOSTrace("opening binary file %s\n",sFullBinaryLogPath.c_str());
00325 
00326                 m_BinaryFile.open(sFullBinaryLogPath.c_str(),std::ios::binary);
00327                 if(!m_BinaryFile)
00328                 {
00329                     return MOOSFail("unable to open binary file called %s", m_sBinaryFileName.c_str());
00330                 }
00331 
00332             }
00333 
00334 
00335             //move to the right place in the file
00336             m_BinaryFile.seekg(nOffset);
00337 
00338             //make space
00339             char * pBD = new char[nBytes];
00340 
00341             //read the right number of bytes
00342             m_BinaryFile.read(pBD,nBytes);
00343 
00344             //copy data
00345             Msg.m_sVal.assign(pBD,nBytes);
00346 
00347             //delete temporary space
00348             delete [] pBD;
00349 
00350             Msg.MarkAsBinary();
00351 
00352 
00353 
00354         }
00355         else
00356         {
00357             Msg.m_dfVal = 0.0;
00358             Msg.m_cDataType  = MOOS_STRING;
00359             Msg.m_sVal = sData;
00360 
00361         }
00362 
00363     }
00364 
00365     //fill in standard aspects
00366     Msg.m_sSrc = sSrc;
00367     Msg.m_sKey = sKey;
00368     Msg.m_cMsgType = MOOS_NOTIFY;
00369 
00370 
00371     return true;
00372 }
00373 
00374 double CMOOSPlayBackV2::GetLastMessageTime()
00375 {
00376     return m_dfLastMessageTime;
00377 }
00378 
00379 bool CMOOSPlayBackV2::SetLastTimeProcessed(double dfTime)
00380 {
00381     m_dfLastClientProcessedTime = dfTime;
00382     double diff = MOOSTime() - dfTime;
00383     return true;
00384 }
00385 
00386 bool CMOOSPlayBackV2::IsWaitingForClient()
00387 {
00388     return m_bWaitingForClientCatchup;
00389 }
00390 
00391 string CMOOSPlayBackV2::GetStatusString()
00392 {
00393     return MOOSFormat("%s Client Lag %g",
00394         m_bWaitingForClientCatchup ? "Waiting for Client CATCHUP":"Playing just fine", 
00395         m_dfClientLagTime);
00396 }
00397 
00398 bool CMOOSPlayBackV2::GotoTime(double dfT)
00399 {
00400     int n =  m_ALog.SeekToFindTime(dfT);
00401 
00402     if(n!=-1)
00403     {
00404         m_nCurrentLine = n;
00405         m_dfLastClientProcessedTime = -1;
00406         m_bWaitingForClientCatchup = false;
00407         m_dfLastMessageTime = m_ALog.GetEntryTime(m_nCurrentLine)-1e-6;    
00408         return true;
00409     }
00410     else
00411     {
00412         return false;
00413     }
00414 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines