MOOS 0.2375
/home/toby/moos-ivp/MOOS-2375-Oct0611/Tools/Simulation/Ocean/uMVS/MVSim.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 
00031 // SimpleAUVSim.cpp: implementation of the CMVSim class.
00032 //
00034 #include <MOOSLIB/MOOSLib.h>
00035 #include <MOOSGenLib/MOOSGenLib.h>
00036 #include "AcousticResponder.h"
00037 #include "MVSim.h"
00038 #include "math.h"
00039 #include <iostream>
00040 #include <iomanip>
00041 using namespace std;
00042 
00043 
00044 #include "AcousticIntersection.h"
00045 
00047 // Construction/Destruction
00049 
00050 
00051 
00052 
00053 CMVSim::CMVSim()
00054 {
00055     m_dfSimulatorTime = 0.0;
00056     m_dfLastMailed = 0.0;
00057     m_dfUpdateRate = 5.0;
00058     m_dfOldSimulatorTime = 0;
00059 
00060     m_dfStartTime = MOOSTime();
00061 
00062     m_bInitialised = false;
00063 
00064     m_bRealTime = true;
00065 
00066     SetAppFreq(10);
00067     SetCommsFreq(20);
00068 }
00069 
00070 CMVSim::~CMVSim()
00071 {
00072     
00073 }
00074 
00075 //this will be called for us automatically
00076 bool CMVSim::OnConnectToServer()
00077 {
00078     return DoRegistrations();
00079 }
00080 
00081 
00082 bool CMVSim::DoRegistrations()
00083 {
00084     SIM_ENTITY_LIST::iterator p;
00085 
00086     for(p = m_Entities.begin();p!=m_Entities.end();p++)
00087     {
00088         CSimEntity* pEntity = *p;
00089 
00090         CSixDOFAUV* pAUV = dynamic_cast<CSixDOFAUV*> (pEntity);
00091 
00092         if(pAUV)
00093         {
00094             m_Comms.Register(pAUV->m_sInputPrefix+"DESIRED_THRUST",0.0);
00095             m_Comms.Register(pAUV->m_sInputPrefix+"DESIRED_ELEVATOR",0.02);
00096             m_Comms.Register(pAUV->m_sInputPrefix+"DESIRED_RUDDER",0.02);
00097         }
00098     }
00099 
00100 
00101     m_Comms.Register("SIM_RESET",0.02);
00102     m_Comms.Notify("SIMULATION_MODE","TRUE");
00103 
00104     return true;
00105 }
00106 
00107 bool CMVSim::OnNewMail(MOOSMSG_LIST &NewMail)
00108 {
00109     //someone has changed one of the variable we were intersted in!
00110     MOOSMSG_LIST::iterator p;
00111 
00112  
00113 
00114     for(p=NewMail.begin();p!=NewMail.end();p++)
00115     {
00116        
00117         CMOOSMsg & rMsg = *p;
00118 
00119         CSixDOFAUV * pAUV = GetSubscriber(rMsg.m_sKey);
00120 
00121         if(pAUV)
00122         {
00123             //we now know which AUV wants this control data..
00124             if(rMsg.m_sKey.find("DESIRED_ELEVATOR")!=string::npos)
00125             {
00126                 pAUV->m_dfElevator = MOOSDeg2Rad(rMsg.m_dfVal);
00127                 continue;
00128             }
00129             else if(rMsg.m_sKey.find("DESIRED_RUDDER")!=string::npos)
00130             {
00131                 pAUV->m_dfRudder = MOOSDeg2Rad(rMsg.m_dfVal);
00132                 continue;
00133             }
00134             else if(rMsg.m_sKey.find("DESIRED_THRUST")!=string::npos)
00135             {
00136                 pAUV->m_dfThrust = rMsg.m_dfVal;
00137                 continue;
00138             }
00139         }
00140     
00141         if(MOOSStrCmp(rMsg.m_sKey,"SIM_RESET"))
00142         {
00143             Initialise();
00144         }
00145     }
00146 
00147     return true;
00148 }
00149 
00150 
00151 // who of teh AUVs want to rx this data (look at prefixes)
00152 CSixDOFAUV * CMVSim::GetSubscriber(const std::string & sName)
00153 {
00154     //index to entities...
00155     SIM_ENTITY_LIST::iterator p;
00156 
00157     for(p = m_Entities.begin();p!=m_Entities.end();p++)
00158     {
00159         CSimEntity* pEntity = *p;
00160 
00161         CSixDOFAUV* pAUV = dynamic_cast<CSixDOFAUV*> (pEntity);
00162 
00163         if(pAUV)
00164         {
00165             std::string sPrefix = pAUV->m_sInputPrefix;
00166 
00167             if(MOOSStrCmp(sName.substr(0,sPrefix.length()),sPrefix))
00168             {
00169                 return pAUV;
00170             }
00171         }
00172     }
00173 
00174     return NULL;
00175 }
00176 
00177 bool CMVSim::Iterate()
00178 {
00179     
00180   
00181     //have we initialised?
00182     if(!m_bInitialised)
00183     {
00184 
00185         Initialise();
00186     }
00187 
00188 
00190     //          sort timing out
00192     
00193     double dfDT  = 0;
00194 
00195     //here we decide what the increment in time is...
00196     if(m_bRealTime)
00197     {
00198         //we will go at real world speed.
00199         dfDT     = MOOSTime()-m_dfSimulatorTime;
00200         
00201 
00202         if(dfDT==0)
00203         {
00204             return true;
00205         }
00206     }
00207     else
00208     {
00209         //coarse DT is 0.1 seconds..good as any...
00210         dfDT = 0.1;
00211         SetAppFreq(int(1/dfDT));
00212     }
00213     
00214 
00215     //the epoch ends at:
00216     double dfEndTime    =   m_dfSimulatorTime +dfDT;    
00217 
00218 
00219     //but we want a fine granularity within this epoch of
00220     //better than 10 ms.
00221     //and within this we shall perform linear interpolation.
00222     double dfSmallDT    =   dfDT;
00223     int nDiv            =   1;
00224 
00225     do
00226     {
00227 
00228         dfSmallDT = dfDT/(nDiv++);
00229 
00230     }while(dfSmallDT>0.01);
00231 
00232 
00233 
00235     //          now propagate models.....
00237     
00238     while(m_dfSimulatorTime<=dfEndTime)
00239     {
00240 
00241         //index to entities...
00242         SIM_ENTITY_LIST::iterator p;
00243 
00244 
00245         //move all entities - Newton(1:3) still rule even in the
00246         //new millenium 
00247         for(p = m_Entities.begin();p!=m_Entities.end();p++)
00248         {
00249             CSimEntity* pEntity = *p;
00250             pEntity->Iterate(m_dfSimulatorTime,dfSmallDT);
00251         }
00252 
00253         //MOOSTrace("\n\nAbout To Solve Acoustics\n");
00254         //look for intersection with signals
00255         for(p = m_Entities.begin();p!=m_Entities.end();p++)
00256         {
00257             CSimEntity* pEntity = *p;
00258 
00259             pEntity->SolveAcoustics(m_dfSimulatorTime,dfSmallDT);
00260 
00261         }
00262 
00263         //move just a wee bit forward in time...
00264         m_dfSimulatorTime+=dfSmallDT;
00265     
00266     }//completed epoch...
00267 
00268 
00269 
00270     // housekeeping  - remove old pings in the water column..
00271     m_Environment.RemoveOldSignals(m_dfSimulatorTime);
00272 
00273 
00274 
00276     // Tell the world what has happened //
00278     
00279     //MOOSTrace("Posting @ %f\n",MOOSTime());
00280     PostResults();
00281 
00282 
00283 
00284     return true;
00285 }
00286 
00287 
00288 
00289 
00290 
00291 bool CMVSim::NeedToMail()
00292 {
00293     return m_dfSimulatorTime-m_dfLastMailed>1.0/m_dfUpdateRate;
00294 
00295 }
00296 
00297 
00298 bool CMVSim::OnStartUp()
00299 {
00300     Initialise();
00301 
00302     DoRegistrations();
00303 
00304     return true;
00305 }
00306 
00307 bool CMVSim::Initialise()
00308 {
00309 
00310 
00311 
00312     Clean();
00313 
00314     SetAppFreq(50);
00315 
00316     m_dfLastMailed = 0.0;
00317 
00318  
00319     if(m_bRealTime)
00320     {
00321         m_dfStartTime = MOOSTime();
00322         m_dfSimulatorTime = m_dfStartTime;
00323     }
00324     else
00325     {
00326         m_dfAppStartTime=0.0;
00327         m_dfStartTime = 0.0;
00328         m_dfSimulatorTime = 0.0;
00329     }
00330     m_dfOldSimulatorTime = m_dfSimulatorTime;
00331 
00332     m_Environment.SetStartTime(m_dfSimulatorTime);
00333     
00334     //now load in terrain data
00335     string sTerrainFile= "terrain.dat";
00336     m_MissionReader.GetValue("TerrainFile",sTerrainFile);
00337     
00338     if(!m_Environment.Initialise(sTerrainFile.c_str()))
00339     {
00340         MOOSTrace("warning environment failed to build\n");
00341     }
00342 
00343     // load general parameters from process config block
00344     STRING_LIST sParams;
00345     m_MissionReader.GetConfiguration(GetAppName(),sParams);
00346     m_Params.Load(sParams);
00347 
00348     //load some others in
00349     m_MissionReader.GetConfigurationParam("TideHeight",m_Environment.m_dfTideHeight);
00350     m_MissionReader.GetValue("MagneticOffset",m_Environment.m_dfMagneticOffset);
00351 
00352 
00353 
00354     //populate with vehicles and beacons
00355     STRING_LIST::iterator p;
00356     for(p = sParams.begin();p!=sParams.end();p++)
00357     {
00358         std::string sTmp = *p;
00359         std::string sTok,sVal;
00360         CMOOSFileReader::GetTokenValPair(sTmp,sTok,sVal);
00361         if(MOOSStrCmp(sTok,"ADD_AUV"))
00362         {
00363             MakeAUV(sVal);
00364         }
00365         else if(MOOSStrCmp(sTok,"ADD_TRANSPONDER"))
00366         {
00367             MakeBeacon(sVal);
00368         }
00369     }
00370 
00371 
00372     //open log file
00373     OpenLogFile();
00374 
00375     //log all entities' initial state
00376     LogStartConditions();
00377 
00378 
00379     m_bInitialised = true;
00380 
00381     return true;
00382 }
00383 
00384 
00385 
00386 
00387 void CMVSim::PostResults()
00388 {
00389     if(NeedToMail())
00390     {
00391         //index to entities...
00392         SIM_ENTITY_LIST::iterator p;
00393         
00394         for(p = m_Entities.begin();p!=m_Entities.end();p++)
00395         {
00396             CSimEntity* pEntity = *p;
00397             
00398             CSixDOFAUV* pAUV = dynamic_cast<CSixDOFAUV*> (pEntity);
00399             
00400             if(pAUV==NULL)
00401                 continue;
00402             
00403             double dfX = pAUV->GetX();
00404             if(m_Params.m_bAddNoise)
00405                 dfX+=MOOSWhiteNoise(m_Params.m_dfXYStd);
00406             
00407             double dfY = pAUV->GetY();
00408             if(m_Params.m_bAddNoise)
00409                 dfY+=MOOSWhiteNoise(m_Params.m_dfXYStd);
00410             
00411             double dfZ = pAUV->GetZ();
00412             if(m_Params.m_bAddNoise)
00413                 dfZ+=MOOSWhiteNoise(m_Params.m_dfZStd);
00414             
00415             double dfYaw = pAUV->GetYaw();
00416             if(m_Params.m_bAddNoise)
00417             {
00418                 dfYaw+=MOOSWhiteNoise(m_Params.m_dfYawStd);
00419                 dfYaw+=m_Params.m_dfYawBias;
00420             }
00421             
00422             double dfDepth = pAUV->GetDepth();
00423             if(m_Params.m_bAddNoise)
00424                 dfDepth+=MOOSWhiteNoise(m_Params.m_dfZStd);
00425             
00426             double dfBodyVelY = pAUV->GetBodyVelY();
00427             if(m_Params.m_bAddNoise)
00428                 dfBodyVelY+=MOOSWhiteNoise(m_Params.m_dfXYVelStd);
00429             
00430             double dfBodyVelX = pAUV->GetBodyVelX();
00431             if(m_Params.m_bAddNoise)
00432                 dfBodyVelX+=MOOSWhiteNoise(m_Params.m_dfXYVelStd);
00433             
00434             double dfSpeed = pAUV->GetSpeed();
00435             if(m_Params.m_bAddNoise)
00436                 dfSpeed=hypot(dfBodyVelY,dfBodyVelX);
00437             
00438             double dfHeading = pAUV->GetHeading();
00439             if(m_Params.m_bAddNoise)
00440                 dfHeading = -MOOSRad2Deg(dfYaw);
00441             
00442             std::string sP = pAUV->m_sOutputPrefix;
00443 
00444             m_Comms.Notify(sP+"X",dfX);
00445             m_Comms.Notify(sP+"Y",dfY);
00446             m_Comms.Notify(sP+"Z",dfZ);
00447             m_Comms.Notify(sP+"YAW",dfYaw);
00448             m_Comms.Notify(sP+"DEPTH",dfDepth);
00449             m_Comms.Notify(sP+"SPEED",dfSpeed);
00450             m_Comms.Notify(sP+"HEADING",dfHeading);
00451             m_Comms.Notify(sP+"BODY_VEL_Y",dfBodyVelY);
00452             m_Comms.Notify(sP+"BODY_VEL_X",dfBodyVelX);
00453             m_Comms.Notify(sP+"PITCH",pAUV->GetPitch());
00454                         
00455             
00456             if(pAUV->GetAltitude()>=0)
00457             {
00458                 m_Comms.Notify(sP+"ALTITUDE",pAUV->GetAltitude());
00459             }        
00460             
00461         }    
00462 
00463         m_Comms.Notify("TIDE_HEIGHT",m_Environment.GetTideHeight());
00464         m_dfLastMailed = m_dfSimulatorTime;
00465 
00466     }
00467 
00468         //finally get all Msg that have appeared in Environments
00469         //out box, this allows objects from anywhere to send notifications
00470         MOOSMSG_LIST::iterator q;
00471         for(q = m_Environment.m_MailOut.begin();q!=m_Environment.m_MailOut.end();q++)
00472         {
00473             //MOOSTrace("Sending Env :%s\n",q->GetString().c_str());
00474             m_Comms.Post(*q);
00475         }
00476 
00477         if(!m_Environment.m_MailOut.empty())
00478         {
00479 //            MOOSTrace("Sent %d Mesg from Environment\n",m_Environment.m_MailOut.size());
00480             m_Environment.m_MailOut.clear();
00481         }
00482 
00483 
00484         //log all entities
00485         SIM_ENTITY_LIST::iterator p;
00486         for(p = m_Entities.begin();p!=m_Entities.end();p++)
00487         {
00488             (*p)->LogState(m_dfSimulatorTime);
00489         }
00490 
00491 
00492 
00493 
00494 }
00495 
00496 
00497 bool CMVSim::Clean()
00498 {
00499     SIM_ENTITY_LIST::iterator p;
00500 
00501 
00502     //move all entities
00503     for(p = m_Entities.begin();p!=m_Entities.end();p++)
00504     {
00505         CSimEntity* pEntity = *p;
00506         delete pEntity;
00507     }
00508     m_Entities.clear();
00509     
00510     m_Environment.Clean();
00511 
00512     return true;
00513 }
00514 
00516 bool CMVSim::MakeAUV(std::string sConfig)
00517 {
00518 
00519     //ADD_AUV=  pose=[3x1]{7,3,4,5},name = AUV1,InputPrefix=AUV1,OutputPrefix=AUV1
00520     CSixDOFAUV * pAUV = new CSixDOFAUV; 
00521     try
00522     {
00523         //give it a parameter block
00524         pAUV->SetParams(&m_Params);
00525         
00526         pAUV->Initialise();
00527         
00528         //where is it?
00529         std::vector<double> T; int nR,nC;
00530         if(MOOSValFromString(T,nR,nC,sConfig,"pose"))
00531         {
00532             if(nR !=4)
00533             {
00534                 throw CMOOSException(MOOSFormat("pose must be a 4 vector %s\n",MOOSHERE));
00535             }
00536             pAUV->SetX(T[0]);
00537             pAUV->SetY(T[1]);
00538             pAUV->SetZ(T[2]);
00539             pAUV->SetYaw(T[3]);
00540             
00541         }
00542         
00543         //whats it called
00544         std::string sName;
00545         if(!MOOSValFromString(sName,sConfig,"name"))
00546             throw CMOOSException(MOOSFormat("AUV has no name! %s\n",MOOSHERE));
00547         
00548         
00549         pAUV->SetName(sName);
00550         
00551         
00552         //how will control be sent to it and positions be emmited?
00553         std::string sInputPrefix="SIM"; //this would mean it Rxs SIM_DESIRED_RUDDER
00554         std::string sOutputPrefix="SIM";//and publishes SIM_X etc...
00555         
00556         if(!MOOSValFromString(sInputPrefix,sConfig,"InputPrefix"))
00557         {
00558             throw CMOOSException(MOOSFormat("No Input prefix defined - assuming  %s\n",sInputPrefix.c_str()));
00559         }
00560         if(!MOOSValFromString(sOutputPrefix,sConfig,"OutputPrefix"))
00561         {
00562             throw CMOOSException(MOOSFormat("No OutputPrefix  defined - assuming  %s\n",sOutputPrefix.c_str()));
00563         }
00564         
00565         pAUV->SetInputPrefix(sInputPrefix);
00566         pAUV->SetOutputPrefix(sOutputPrefix);
00567         
00568         //tell it about teh world
00569         pAUV->SetEnvironment(&m_Environment);
00570 
00571         //what channel does it reply to interrogations on?
00572         std::string  sChannelResponder = "Ch2";
00573         if(!MOOSValFromString(sChannelResponder,sConfig,"ResponderChannel"))
00574         {
00575             MOOSTrace("No ResponderChannel  defined - assuming no Responder required \n");
00576 
00577             //turn it off - other parameters don't matter
00578             pAUV->ConfigureResponder(false,ACOUSTIC_CHAN_CIF,ACOUSTIC_CHAN_CIF,-1);
00579 
00580         }
00581         else
00582         {
00583             AcousticChannel eCh = CAcousticSignal::ChannelFromString(sChannelResponder);
00584                         
00585             //what is its TAT on interrogations?
00586             double dfTAT = 0.125;
00587             if(!MOOSValFromString(dfTAT,sConfig,"TAT"))
00588             {
00589                 throw CMOOSException(MOOSFormat("No TAT defined - assuming  %f\n",dfTAT));
00590             }
00591                         
00592             //turn it on..
00593             pAUV->ConfigureResponder(true,ACOUSTIC_CHAN_CIF,eCh,dfTAT);
00594         }
00595         //store it
00596         m_Entities.push_front(pAUV);
00597     }
00598     catch(CMOOSException e)
00599     {
00600         delete pAUV;
00601         return MOOSFail(e.m_sReason);
00602     }
00603 
00604     return true;
00605 
00606 
00607 }
00608 
00609 
00610 
00611 bool CMVSim::MakeBeacon(std::string sConfig)
00612 {
00613     //"ADD_TRANSPONDER = Name = B1,pose=[3x1]{23, 45, 0},TAT = 0.125,RX = CH8 | CH9 | C10,TX = CIF
00614 
00615     CAcousticBeacon * pBeacon = new CAcousticBeacon;
00616     try
00617     {
00618 
00619         std::vector<double> T; int nR,nC;
00620         if(MOOSValFromString(T,nR,nC,sConfig,"pose"))
00621         {
00622             if(nR !=3)
00623             {
00624                 return MOOSFail("pose must be a 3 vector %s\n",MOOSHERE);
00625             }
00626             pBeacon->m_Pos_e<<T[0]
00627                 <<T[1]
00628                 <<T[2]
00629                 <<0
00630                 <<0
00631                 <<0;
00632         }
00633         
00634         //whats it called
00635         std::string sName;
00636         if(!MOOSValFromString(sName,sConfig,"name"))
00637             throw CMOOSException(MOOSFormat("Beacon has no name! %s %s\n",sConfig.c_str(),MOOSHERE));
00638         pBeacon->SetName(sName);
00639         
00640         std::string sTx;
00641         if(!MOOSValFromString(sTx,sConfig,"Tx"))
00642             throw CMOOSException(MOOSFormat("Beacon has no Tx field %s %s\n",sConfig.c_str(),MOOSHERE));
00643         
00644         
00645         ACOUSTIC_NODE_LIST AcousticNodes;
00646         pBeacon->GetAcousticNodes(AcousticNodes);
00647         
00648         AcousticChannel eChan = CAcousticSignal::ChannelFromString(sTx);
00649         
00650         if( eChan==ACOUSTIC_CHAN_ERROR ||
00651             !AcousticNodes.front()->SetTxChan(eChan))
00652         {
00653             throw CMOOSException(MOOSFormat("error setting Tx Channel on beacon %s\n",sName.c_str()));
00654         }
00655         
00656         std::string sRx;
00657         if(!MOOSValFromString(sTx,sConfig,"Rx"))
00658             throw CMOOSException(MOOSFormat("Beacon has no Rx field %s %s\n",sConfig.c_str(),MOOSHERE));
00659         
00660         
00661         
00662         while(!sRx.empty())
00663         {
00664             string sChan = MOOSChomp(sRx,"|");
00665             
00666             AcousticChannel eChan = CAcousticSignal::ChannelFromString(sChan);
00667             
00668             if( eChan==ACOUSTIC_CHAN_ERROR ||
00669                 !AcousticNodes.front()->SetRxChan(eChan,true))
00670             { 
00671                 MOOSTrace("error setting Rx Channel on beacon\n");
00672             }
00673         }//for all channels
00674         
00675         
00677         //      set up TAT
00679         
00680         double dfTAT;
00681         if(!MOOSValFromString(dfTAT,sConfig,"TAT"))
00682             throw CMOOSException(MOOSFormat("Beacon has no TAT field %s %s\n",sConfig.c_str(),MOOSHERE));
00683         
00684         
00685         CAcousticResponder * pResponder = dynamic_cast<CAcousticResponder*>(AcousticNodes.front());
00686         if(pResponder!=NULL)
00687         {
00688             pResponder->SetTAT(dfTAT);
00689         }
00690         
00691         //final set up of beacon...
00692         pBeacon->SetEnvironment(&m_Environment);
00693         
00694         pBeacon->SetParams(&m_Params);
00695         
00696         m_Entities.push_front(pBeacon);
00697     }
00698     catch (CMOOSException e)
00699     {
00700         delete pBeacon;
00701         return MOOSFail(e.m_sReason);
00702     }
00703 
00704     return true;
00705 }            
00706     
00707 
00708 
00709 bool CMVSim::OpenLogFile()
00710 {
00711     //set up log file...
00712     if(!m_Params.m_sLogFileName.empty())
00713     {
00714         //open and close ..truncates file
00715         ofstream os(m_Params.m_sLogFileName.c_str());
00716         
00717         os.close();
00718     }
00719     return true;
00720 }
00721 
00722 bool CMVSim::LogStartConditions()
00723 {
00724     SIM_ENTITY_LIST::iterator p;
00725 
00726     if(!m_Params.m_sLogFileName.empty())
00727     {
00728         //open and close ..truncates file
00729         ofstream os(m_Params.m_sLogFileName.c_str(),ios::app);
00730 
00731         //start time...
00732         os.setf(ios::fixed,ios::floatfield);
00733         os<<setprecision(3);
00734         os<<"StartTime,T="<<setprecision(3)<<m_dfSimulatorTime<<endl;
00735 
00736         //entity states
00737         for(p = m_Entities.begin();p!=m_Entities.end();p++)
00738         {
00739             (*p)->CSimEntity::LogState(m_dfSimulatorTime);
00740         }
00741 
00742 
00743     }
00744 
00745     return true;
00746 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines