MOOS 0.2375
|
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 }