MOOS 0.2375
/home/toby/moos-ivp/MOOS-2375-Oct0611/NavigationAndControl/MOOSNavLib/MOOSNavEngine.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 and others
00010 //   at MIT 2001-2002 and Oxford University 2003-2005.
00011 //   email: pnewman@robots.ox.ac.uk. 
00012 //      
00013 //   This file is part of a  MOOS Basic (Common) Application. 
00014 //        
00015 //   This program is free software; you can redistribute it and/or 
00016 //   modify it under the terms of the GNU General Public License as 
00017 //   published by the Free Software Foundation; either version 2 of the 
00018 //   License, or (at your option) any later version. 
00019 //          
00020 //   This program is distributed in the hope that it will be useful, 
00021 //   but WITHOUT ANY WARRANTY; without even the implied warranty of 
00022 //   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
00023 //   General Public License for more details. 
00024 //            
00025 //   You should have received a copy of the GNU General Public License 
00026 //   along with this program; if not, write to the Free Software 
00027 //   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 
00028 //   02111-1307, USA. 
00029 //
00031 // MOOSNavEngine.cpp: implementation of the CMOOSNavEngine class.
00032 //
00034 #ifdef _WIN32
00035 #pragma warning(disable : 4786)
00036 #endif
00037 
00038 #include <MOOSGenLib/MOOSGenLib.h>
00039 #include "MOOSNavBeacon.h"
00040 #include "MOOSNavVehicle.h"
00041 #include "MOOSNavSensor.h"
00042 #include "MOOSNavObsStore.h"    
00043 #include "MOOSNavEngine.h"
00044 #include "MOOSNavLibDefs.h"
00045 #include <sstream>
00046 #include <iomanip>
00047 #include "math.h"
00048 
00050 // Construction/Destruction
00052 
00053 //noises
00054 #define LBL_2WR_STD (2*0.0015)
00055 #define BODY_VEL_STD (0.02)
00056 
00057 #define YAW_STD 0.001
00058 #define DEPTH_STD 0.1
00059 #define XY_STD 1.0
00060 
00061 
00062 CMOOSNavEngine::CMOOSNavEngine()
00063 {
00064     m_bInitialOnline = false;
00065 
00066 
00067     m_dfSV = 1500.0;
00068 
00069     m_nNextID = 0;
00070     m_dfLastUpdate = 0;
00071 
00072     //by defualt update as often as posisble
00073     m_dfUpdatePeriod = 0;
00074 
00075     m_nIterations = 0;
00076 
00077     //by default we make static vehciles
00078      m_eVehicleType =  CMOOSNavEntity::POSE_ONLY;
00079 
00080      m_bOnline = true;
00081 
00082      m_bEnabled = true;
00083 
00084      //by default we will not map thrust to velocity measurements
00085      m_bThrust2Vel = false;
00086      m_dfThrust2VelGain = 1.0;
00087 
00088      //by default no heading bias state!
00089      m_bEstimateHeadingBias = false;
00090 
00091 
00092      //here we set the base class pointer to results mesage list to be our own 
00093      //results list (lets CMOOSNavBase::addToOutput work
00094 
00095      CMOOSNavBase::SetOutputList(&m_ResultsList);
00096 }
00097 
00098 CMOOSNavEngine::~CMOOSNavEngine()
00099 {
00100     if(m_pStore!=NULL)
00101         delete m_pStore;
00102 }
00103 
00104 bool CMOOSNavEngine::AddData(const CMOOSMsg &Msg)
00105 {
00106     //don't add data if not enabled
00107     if(!IsEnabled())
00108         return true;
00109 
00110     
00111     // 1) convert to observation
00112     // 2) store it
00113     // 3) look to processes
00114     
00115     OBSLIST NewObs;
00116                 
00117     if(DataToObservations(Msg,NewObs))
00118     {
00119         return m_pStore->Add(NewObs);            
00120     }
00121     return false;
00122 }
00123 
00124 bool CMOOSNavEngine::DataToObservations(const CMOOSMsg &Msg, OBSLIST &ObsList)
00125 {
00126     CMOOSNavSensor * pRelevantSensor = GetSensorBySource(Msg.m_sSrc,Msg.m_sKey);
00127 
00128     if(pRelevantSensor==NULL)
00129     {
00130         //no idea what to do with it...
00131         return false;
00132     }
00133 
00134     bool bSuccess = false;
00135     switch(pRelevantSensor->m_eType)
00136     {
00137     case CMOOSNavSensor::LBL:
00138         bSuccess =  MakeLBLObservations(Msg,ObsList);        
00139         break;
00140 
00141     case CMOOSNavSensor::DEPTH:
00142         bSuccess =  MakeDepthObservations(Msg,ObsList);
00143         break;
00144 
00145     case CMOOSNavSensor::XY:
00146         bSuccess =  MakeXYObservations(Msg,ObsList);
00147         break;
00148 
00149     case CMOOSNavSensor::BODY_VEL:
00150         bSuccess =  MakeBodyVelObservations(Msg,ObsList);
00151         break;
00152 
00153     case CMOOSNavSensor::CONTROL:
00154         bSuccess =  MakeControlObservations(Msg,ObsList);
00155         break;
00156         
00157 
00158     case CMOOSNavSensor::ORIENTATION:
00159         //for now we only deal with yaw
00160         if(Msg.m_sKey.find("YAW")!=string::npos)
00161         {
00162             bSuccess = MakeYawObservations(Msg,ObsList);        
00163         }
00164         break;
00165     
00166     default:
00167         break;
00168     }
00169     
00170 
00171 
00172     OBSLIST::iterator p;
00173 
00174     for(p = ObsList.begin();p!=ObsList.end();p++)
00175     {
00176         //observations may  need to know if they are
00177         // using heading bias estimation
00178         p->UsingHeadingBias(m_bEstimateHeadingBias);
00179     }
00180 
00181     return bSuccess;
00182 }
00183 
00184 
00185 CMOOSSensorChannel * CMOOSNavEngine::GetSensorChannel(const string & sKey)
00186 {
00187     SOURCE_SENSORCHANNEL_MAP::iterator q = m_SensorChannelMap.find(sKey);
00188     
00189     if(q==m_SensorChannelMap.end() || m_SensorChannelMap.empty())
00190     {
00191         //must be made from mission file
00192         return NULL;
00193     }
00194     
00195     return &(q->second);
00196 }
00197 
00198 
00199 
00200 bool CMOOSNavEngine::MakeDepthObservations(const CMOOSMsg &Msg, OBSLIST &ObsList)
00201 {
00202     CMOOSObservation NewObs;
00203     NewObs.m_dfTime = Msg.m_dfTime;
00204     NewObs.m_dfData = Msg.m_dfVal;
00205     NewObs.m_dfDataStd = DEPTH_STD;
00206 
00207     NewObs.m_eType = CMOOSObservation::DEPTH;
00208     NewObs.m_nID = GetNextID();
00209     
00210     //use the message source to figure out the sensor this
00211     //corresponds to
00212     NewObs.m_pInterrogateSensor = GetSensorBySource(Msg.m_sSrc,Msg.m_sKey);
00213 
00214     if(NewObs.m_pInterrogateSensor!=NULL)
00215     {
00216         //overload noise
00217         if(NewObs.m_pInterrogateSensor->GetNoise()>=0)
00218         {
00219             NewObs.m_dfDataStd = NewObs.m_pInterrogateSensor->GetNoise();
00220         }
00221 
00222         ObsList.push_front(NewObs);
00223     }
00224 
00225     return true;
00226 }
00227 
00228 bool CMOOSNavEngine::MakeXYObservations(const CMOOSMsg &Msg, OBSLIST &ObsList)
00229 {
00230     CMOOSObservation NewObs;
00231     NewObs.m_dfTime = Msg.m_dfTime;
00232     NewObs.m_dfData = Msg.m_dfVal;
00233     NewObs.m_dfDataStd = XY_STD;
00234 
00235     if(Msg.m_sKey.find("_X")!=string::npos)
00236     {
00237         NewObs.m_eType = CMOOSObservation::X;
00238     }
00239     if(Msg.m_sKey.find("_Y")!=string::npos)
00240     {
00241         NewObs.m_eType = CMOOSObservation::Y;
00242     }
00243 
00244     NewObs.m_nID = GetNextID();
00245 
00246     //use the message source to figure out the sensor this
00247     //corresponds to
00248     NewObs.m_pInterrogateSensor = GetSensorBySource(Msg.m_sSrc,Msg.m_sKey);
00249 
00250     if(NewObs.m_pInterrogateSensor!=NULL)
00251     {   
00252         //overload noise
00253         if(NewObs.m_pInterrogateSensor->GetNoise()>=0)
00254         {
00255             NewObs.m_dfDataStd = NewObs.m_pInterrogateSensor->GetNoise();
00256         }
00257 
00258         ObsList.push_front(NewObs);
00259     }
00260     return true;
00261 
00262 }
00263 
00264 bool CMOOSNavEngine::MakeControlObservations(const CMOOSMsg &Msg, OBSLIST &ObsList)
00265 {
00266    if(Msg.m_sKey.find("_THRUST")!=string::npos)
00267    {
00268        //do we wnat to use thrust measurements?
00269         if(!m_bThrust2Vel)
00270             return true;
00271 
00272         CMOOSMsg MappedMsg = Msg;
00273 
00274         //dilute the precision of this..
00275         double dfObsDilation = 4;
00276         //make a message for the y (forward velocity)
00277         MappedMsg.m_dfVal*= m_dfThrust2VelGain;
00278         MappedMsg.m_sKey="THRUST_DERIVED_BODY_VEL_Y";
00279         if(!MakeBodyVelObservations(MappedMsg,ObsList,dfObsDilation))
00280             return false;
00281 
00282         //make a message for the x (Lateral velocity)
00283         MappedMsg.m_dfVal= 0;
00284         MappedMsg.m_sKey="THRUST_DERIVED_BODY_VEL_X";
00285         if(!MakeBodyVelObservations(MappedMsg,ObsList,dfObsDilation))
00286             return false;
00287    }
00288  
00289    return true;
00290 
00291 }
00292 
00293 
00294 bool CMOOSNavEngine::MakeBodyVelObservations(const CMOOSMsg &Msg, OBSLIST &ObsList,double dfSF)
00295 {
00296     CMOOSObservation NewObs;
00297     NewObs.m_dfTime = Msg.m_dfTime;
00298     NewObs.m_dfData = Msg.m_dfVal;
00299     NewObs.m_dfDataStd = BODY_VEL_STD*dfSF;
00300 
00301     if(Msg.m_sKey.find("_Y")!=string::npos)
00302     {
00303         NewObs.m_eType = CMOOSObservation::BODY_VEL_Y;
00304     }
00305     else if(Msg.m_sKey.find("_X")!=string::npos)
00306     {
00307         NewObs.m_eType = CMOOSObservation::BODY_VEL_X;
00308     }
00309 
00310     NewObs.m_nID = GetNextID();
00311 
00312     //use the message source to figure out the sensor this
00313     //corresponds to
00314     NewObs.m_pInterrogateSensor = GetSensorBySource(Msg.m_sSrc,Msg.m_sKey);
00315 
00316     if(NewObs.m_pInterrogateSensor!=NULL)
00317     {
00318         //overload noise
00319         if(NewObs.m_pInterrogateSensor->GetNoise()>=0)
00320         {
00321             NewObs.m_dfDataStd = NewObs.m_pInterrogateSensor->GetNoise();
00322         }
00323 
00324         ObsList.push_front(NewObs);
00325     }
00326     return true;
00327 
00328 }
00329 
00330 
00331 bool CMOOSNavEngine::MakeYawObservations(const CMOOSMsg &Msg, OBSLIST &ObsList)
00332 {
00333     CMOOSObservation NewObs;
00334     NewObs.m_dfTime = Msg.m_dfTime;
00335     NewObs.m_dfData = Msg.m_dfVal;
00336     NewObs.m_dfDataStd = YAW_STD;
00337     NewObs.m_eType = CMOOSObservation::YAW;
00338     NewObs.m_nID = GetNextID();
00339 
00340 
00341 
00342     //use the message source to figure out the sensor this
00343     //corresponds to
00344     NewObs.m_pInterrogateSensor = GetSensorBySource(Msg.m_sSrc,Msg.m_sKey);
00345 
00346     if(NewObs.m_pInterrogateSensor!=NULL)
00347     {
00348 
00349         //overload noise
00350         if(NewObs.m_pInterrogateSensor->GetNoise()>=0)
00351         {
00352             NewObs.m_dfDataStd = NewObs.m_pInterrogateSensor->GetNoise();
00353         }
00354 
00355         ObsList.push_front(NewObs);
00356     }
00357 
00358     ObsList.push_front(NewObs);
00359 
00360     return true;
00361 }
00362 
00363 
00364 bool CMOOSNavEngine::MakeLBLObservations(const CMOOSMsg &Msg, OBSLIST &ObsList)
00365 {
00366     //this is LBL data    
00367     string sData = Msg.m_sVal;
00368     
00369     //what time was interrogation sent?
00370     MOOSChomp(sData,"Tx=");
00371     double dfTxTime = atof(MOOSChomp(sData,",").c_str());
00372     
00373     if(dfTxTime<=0)
00374     {
00375         MOOSTrace("Tx time of LBL is not positive\n");
00376         return false;
00377     }
00378     
00379     while(!sData.empty())
00380     {
00381         //for each reply...
00382         CMOOSObservation NewObs;
00383         string sChunk = MOOSChomp(sData,",");
00384 
00385         MOOSChomp(sChunk,"Ch[");
00386 
00387         int nChan = atoi(sChunk.c_str());
00388         
00389         if(nChan<=0 || nChan > 14)
00390         {
00391             MOOSTrace("Channel of LBL obs is not valid\n");
00392             continue;
00393         }
00394 
00395 
00396         NewObs.m_nChan = nChan;
00397         
00398         //figure out the beacon from the channel....
00399         CMOOSNavBeacon * pBeacon = GetBeaconByChannel(nChan);
00400         
00401         if(pBeacon==NULL)
00402         {
00403             MOOSTrace("Warning: No known Beacon with Channel[%d]\n",nChan);
00404         }
00405 
00406         
00407 
00408         //so what was the observation - the TOF?
00409         MOOSChomp(sChunk,"=");
00410         double dfTOF = atof(sChunk.c_str());
00411         if(dfTOF<=0)
00412         {
00413             MOOSTrace("TOF of LBL obs is not valid\n");
00414             return false;
00415         }
00416         NewObs.m_dfData = dfTOF;
00417         
00418 
00419         //set obs time Tx Time plus in water time
00420         NewObs.m_dfTime = dfTxTime+dfTOF;
00421 
00422 //        MOOSTrace("Making LBL Obs.dfTime = %f and now = %f\n",NewObs.m_dfTime,MOOSTime());
00423         
00424         //set obs type 
00425         NewObs.m_eType = CMOOSObservation::LBL_BEACON_2WR;
00426         
00427         //give it a unique id
00428         NewObs.m_nID = GetNextID();
00429 
00430 
00431         //use the message source to figure out the sensor this
00432         //corresponds to
00433         NewObs.m_pInterrogateSensor = GetSensorBySource(Msg.m_sSrc,Msg.m_sKey);
00434 
00435         if(NewObs.m_pInterrogateSensor==NULL)
00436         {
00437             return false;
00438         }
00439         
00440         //set observation noise
00441         NewObs.m_dfDataStd = LBL_2WR_STD;
00442         if(NewObs.m_pInterrogateSensor->GetNoise()>=0)
00443         {
00444             NewObs.m_dfDataStd = NewObs.m_pInterrogateSensor->GetNoise();
00445         }
00446         
00447         //what other responding sensor was involved?
00448         if(pBeacon!=NULL)
00449         {
00450             NewObs.m_pRespondingSensor = pBeacon->GetSensorByType(CMOOSNavSensor::LBL);
00451         }
00452         else
00453         {
00454             NewObs.m_pRespondingSensor=NULL;
00455         }
00456         
00457 
00458         //this is an acoustic obs so set the sound velocity
00459         NewObs.m_dfSV = m_dfSV;
00460         //finally add the obs to the list
00461         if(NewObs.m_pRespondingSensor!=NULL)
00462         {
00463             ObsList.push_back(NewObs);
00464         }
00465 
00466 /*        MOOSTrace("NewLBL: MOOSTime = %.3f,msgtime= %.3f,datatime = %.3f,TxTime = %.3f, cTOF= %.3f\n",
00467             MOOSTime(),
00468             Msg.m_dfTime,
00469             NewObs.m_dfTime,
00470             dfTxTime,
00471             NewObs.m_dfTime-dfTxTime);*/
00472 
00473     }
00474     
00475     return true;
00476 }
00477 
00478 CMOOSNavBeacon * CMOOSNavEngine::GetBeaconByName(const string & sName)
00479 {
00480     BEACONLIST::iterator p;
00481     
00482     for(p = m_Beacons.begin();p!=m_Beacons.end();p++)
00483     {
00484         
00485         CMOOSNavBeacon * pBcn =  *p;
00486 
00487         if(pBcn->m_sName==sName)
00488         {
00489             return pBcn;
00490         }
00491     }
00492     return NULL;
00493 }
00494 
00495 CMOOSNavBeacon * CMOOSNavEngine::GetBeaconByChannel(int nChannel)
00496 {
00497     BEACONLIST::iterator p;
00498     
00499     for(p = m_Beacons.begin();p!=m_Beacons.end();p++)
00500     {
00501         
00502         CMOOSNavBeacon * pBcn =  *p;
00503 
00504         if(pBcn->m_nChan==nChannel)
00505         {
00506             return pBcn;
00507         }
00508     }
00509     return NULL;
00510 }
00511 
00512 
00513 bool CMOOSNavEngine::Iterate(double dfTimeNow)
00514 {
00515     return false;
00516 }
00517 
00518 
00519 bool CMOOSNavEngine::Initialise(STRING_LIST  sParams)
00520 {
00521 
00522     //make a store for observations..
00523     m_pStore = new CMOOSNavObsStore;
00524 
00525     //we may be being asked to map thrust to velocity
00526     string sVal;
00527     if(MOOSGetValueFromToken(sParams,"THRUST2VELOCITY",sVal))
00528     {
00529         if(MOOSStrCmp(sVal,"TRUE"))
00530         {
00531             if(MOOSGetValueFromToken(sParams,"THRUST2VELOCITY_GAIN",sVal))
00532             {
00533                 m_bThrust2Vel = true;
00534                 m_dfThrust2VelGain = atof(sVal.c_str());
00535             }
00536         }
00537     }
00538 
00539 
00540 
00541     if(MOOSGetValueFromToken(sParams,"SV",sVal))
00542     {
00543         double dfNewSV = atof(sVal.c_str());         
00544         if(dfNewSV !=0)
00545         {
00546             m_dfSV=dfNewSV;
00547         }
00548     }
00549 
00550     //set up navigation filter logging....
00551     bool bLog = false;
00552     if(MOOSGetValueFromToken(sParams,"NAV_LOG",sVal))
00553     {
00554         bLog = MOOSStrCmp(sVal,"TRUE");
00555     }
00556     if(bLog)
00557     {
00558         string sPath="";
00559         
00560         //do we have a globally defined path?
00561         CProcessConfigReader Reader;
00562         Reader.SetFile(m_sMissionFileName);
00563 
00564         if(!Reader.GetValue("GLOBALLOGPATH",sPath))
00565         {
00566             //no..get it locally
00567             MOOSGetValueFromToken(sParams,"NAV_LOG_PATH",sPath);
00568         }
00569         bool bTimeStamp=false;
00570         if(MOOSGetValueFromToken(sParams,"NAV_LOG_TIMESTAMP",sVal))
00571         {
00572             bTimeStamp = MOOSStrCmp(sVal,"TRUE");
00573         }
00574 
00575         
00576         m_Logger.Initialise(m_sName,sPath,bTimeStamp);
00577 
00578              
00579     }
00580 
00581 
00582 
00583     //Allocate Global states..
00584     SetUpGlobalStates();
00585 
00586     AddTheVehicle(sParams);
00587 
00588     //fixed observations are attached to the COG...
00589     AddSensor("FIXED","COG", CMOOSNavSensor::FIXED,0,0,0);
00590 
00591     //set our default start up state...
00592     //set in constructor of derived classes
00593     SetOnline(m_bInitialOnline);
00594     return true;
00595 
00596 }
00597 
00598 
00599 bool CMOOSNavEngine::AddEntity(CMOOSNavEntity *pEntity,
00600                                Matrix * pCovariance,
00601                                Matrix * pCrossCovariance)
00602 {
00603     Matrix XNew;
00604 
00605     //we always give entities a pinter to the global estimate
00606     //matrices
00607 
00608     pEntity->m_pXhat = & m_Xhat;
00609     pEntity->m_pPhat = & m_Phat;
00610 
00611 
00612     //get the entity to format a state vector representing
00613     //its state
00614     if(pEntity->GetFullState(XNew,NULL,false))
00615     {
00616         //XNew will be 8x1 but what are the estimated states?
00617         int nSize = pEntity->GetStateSize();
00618 
00619         if(nSize==0)
00620         {
00621             //its not in the state vector (eg a beaon)
00622             return true;
00623         }
00624 
00625         
00626         pEntity->m_nStart = m_Xhat.Nrows()+1;
00627         pEntity->m_nEnd = pEntity->m_nStart+nSize-1;
00628 
00629         if(m_Xhat.Nrows()==0 || m_Xhat.Ncols() ==0)
00630         {
00631             m_Xhat = XNew.SubMatrix(1,nSize,1,1);
00632             m_Phat.ReSize(nSize,nSize);
00633             m_XhatTmp = m_Xhat;
00634             m_PhatTmp = m_Phat;
00635 
00636         }
00637         else
00638         {
00639             m_Xhat = m_Xhat & XNew.SubMatrix(1,nSize,1,1);
00640 
00641             //now resize P..
00642             Matrix OldP = m_Phat;
00643             m_Phat.ReSize(m_Xhat.Nrows(),m_Xhat.Nrows());
00644             m_Phat=0;
00645             m_Phat.SubMatrix(1,OldP.Nrows(),1,OldP.Ncols()) = OldP;
00646 
00647 
00648         }
00649 
00650     }
00651 
00652 
00653     return true;
00654 }
00655 
00656 bool CMOOSNavEngine::IndexObservations(int &nObsDim)
00657 {
00658 
00659     nObsDim = 0;
00660 
00661     OBSLIST::iterator p;
00662 
00663     for(p = m_Observations.begin();p!=m_Observations.end();p++)
00664     {
00665         CMOOSObservation  & rObs = *p;
00666         
00667         if(rObs.m_bIgnore || rObs.m_bGoodDA==false)
00668             continue;
00669 
00670         rObs.m_nRow = nObsDim+1;
00671 
00672         nObsDim+=rObs.GetDimension();
00673 
00674     }
00675 
00676     return true;
00677 }
00678 
00679 bool CMOOSNavEngine::TraceObservationSet()
00680 {
00681     OBSLIST::iterator p;
00682     int nIgnored=0;
00683     for(p = m_Observations.begin();p!=m_Observations.end();p++)
00684     {
00685         if(p->m_bIgnore)
00686             nIgnored++;
00687     }
00688 
00689 
00690     MOOSTrace("\n %s Working with %d observations (%d ignored):\n",
00691         m_sName.c_str(),
00692         m_Observations.size()-nIgnored,nIgnored);
00693 
00694 
00695     int i = 1;
00696     for(p = m_Observations.begin();p!=m_Observations.end();p++)
00697     {
00698         if(p->m_bIgnore)
00699             continue;
00700 
00701         MOOSTrace("%d)\t",i++);
00702         p->Trace();
00703     }
00704 
00705     return true;
00706 }
00707 
00708 bool CMOOSNavEngine::AddSensor(const string & sSource,
00709                                const string &sName,
00710                                CMOOSNavSensor::Type eType,
00711                                double dfX,
00712                                double dfY,
00713                                double dfZ,
00714                                double dfNoise)
00715 {
00717     //            add an new sensor
00718     CMOOSNavSensor * pNewSensor = new CMOOSNavSensor;
00719     pNewSensor->m_nID = GetNextID();
00720     pNewSensor->m_sName=sName;
00721     pNewSensor->m_eType = eType;
00722     pNewSensor->m_sMOOSSource = sSource;
00723     pNewSensor->SetNoise(dfNoise);
00724     if(m_pTracked!=NULL)
00725     {
00726         m_pTracked->AddSensor(pNewSensor);
00727 
00728         string sKey = sSource+":"+sName;
00729         if(m_SourceToSensorMap.find(sName)==m_SourceToSensorMap.end())
00730         {
00731             m_SourceToSensorMap[sKey] = pNewSensor;
00732             MOOSTrace("Added new sensor:\n\t\"%s\" @ %f %f %f\n",sKey.c_str(),dfX,dfY,dfZ);
00733 
00734         }
00735         else
00736         {
00737             MOOSTrace("Error Sensor \"%s\" already exists \n",sKey.c_str());
00738             return false;
00739         }
00740     }
00741     else
00742     {
00743         return false;
00744     }
00745     
00746     return true;
00747 }
00748 
00749 bool CMOOSNavEngine::AddAcousticBeacon(const string & sName,
00750                                        int nChan,
00751                                        double dfTAT,
00752                                        double dfX,
00753                                        double dfY,
00754                                        double dfZ)
00755 {
00756 
00758     //            add a beacon
00759     CMOOSNavBeacon* pBeacon = new CMOOSNavBeacon;
00760 
00761     pBeacon->m_sName = sName;
00762     pBeacon->m_nID = GetNextID();
00763     
00764     pBeacon->m_State.m_dfX = dfX;
00765     pBeacon->m_State.m_dfY = dfY;
00766     pBeacon->m_State.m_dfZ = dfZ;
00767     
00768     pBeacon->m_dfTAT = dfTAT;
00769     pBeacon->m_nChan = nChan;    
00770 
00771     if(AddEntity(pBeacon))
00772     {
00773 //        MOOSTrace("Added Beacon :\n\t");
00774 //        pBeacon->Trace();
00775         m_Beacons.push_front(pBeacon);
00776     }
00777 
00778     return true;
00779     
00780 }
00781 
00782 
00783 bool CMOOSNavEngine::AddFixedObservation(CMOOSObservation::Type eType, double dfVal, double dfStd)
00784 {
00785     CMOOSObservation NewFixedObs;
00786 
00787     NewFixedObs.m_dfData = dfVal;
00788     NewFixedObs.m_dfDataStd = dfStd;
00789     NewFixedObs.m_eType = eType;
00790     NewFixedObs.m_nID = GetNextID();
00791     NewFixedObs.m_dfTime = -1;
00792     NewFixedObs.SetFixed(true);
00793     NewFixedObs.UsingHeadingBias(m_bEstimateHeadingBias);
00794 
00795     NewFixedObs.m_pInterrogateSensor = GetSensorByName("COG");
00796 
00797     if(NewFixedObs.m_pInterrogateSensor==NULL)
00798     {
00799         return false;
00800     }
00801 
00802     m_FixedObservations.push_back(NewFixedObs);
00803 
00804     return true;
00805 
00806 }
00807 
00808 CMOOSNavSensor* CMOOSNavEngine::GetSensorByName(const string &sSensorName)
00809 {
00810     SENSOR_MAP::iterator p;
00811     for(p = m_SourceToSensorMap.begin();p!=m_SourceToSensorMap.end();p++)
00812     {
00813         CMOOSNavSensor * pSensor = p->second;
00814         if(pSensor->GetName()==sSensorName)
00815         {
00816             return pSensor;
00817         }
00818         
00819     }
00820     return NULL;
00821 
00822 }
00823 
00824 
00825 CMOOSNavSensor* CMOOSNavEngine::GetSensorBySource(const string &sMOOSSource,const string & sDataName)
00826 {
00827     SENSOR_MAP::iterator p;
00828 
00829     CMOOSNavSensor::Type eType = SensorTypeFromDataName(sDataName);
00830 
00831     if(eType==CMOOSNavSensor::INVALID)
00832         return NULL;
00833 
00834     for(p = m_SourceToSensorMap.begin();p!=m_SourceToSensorMap.end();p++)
00835     {
00836         CMOOSNavSensor * pSensor = p->second;
00837         if(pSensor->m_eType==eType && pSensor->m_sMOOSSource==sMOOSSource)
00838         {
00839             return pSensor;
00840         }        
00841     }
00842     return NULL;
00843 
00844 }
00845 
00846 // here we set aside space for global states such
00847 //as tide and heading bias estimation etc..
00848 bool CMOOSNavEngine::SetUpGlobalStates()
00849 {
00850     int nGlobalStates = 1; //tide...
00851 
00852     if(m_bEstimateHeadingBias)
00853         nGlobalStates = 2; //tide and heading bias
00854 
00855     m_Xhat.ReSize(nGlobalStates,1);
00856     m_Xhat=0;
00857     m_Phat.ReSize(nGlobalStates,nGlobalStates);
00858     m_Phat = 0;
00859 
00860     return true;
00861 }
00862 
00863 //client calls this to fetch results...
00864 bool CMOOSNavEngine::GetNextResult(CMOOSMsg &ResultMsg)
00865 {
00866     if(m_ResultsList.empty())
00867     {
00868         return false;
00869     }
00870 
00871     ResultMsg = m_ResultsList.front();
00872     m_ResultsList.pop_front();
00873 
00874     return true;
00875 }
00876 
00877 bool CMOOSNavEngine::LimitObservations(CMOOSObservation::Type eType, int nNumber)
00878 {
00879     OBSLIST::iterator p;
00880 
00881     int nFound = 0;
00882     for(p = m_Observations.begin();p!=m_Observations.end();p++)
00883     {
00884         if(p->m_eType==eType)
00885         {
00886             nFound++;
00887             if(nFound>nNumber)
00888             {
00889                 p->m_bIgnore = true;
00890             }
00891             else
00892             {
00893                 p->m_bIgnore = false;
00894             }
00895         }
00896     }
00897 
00898     return true;
00899 }
00900 
00901 bool CMOOSNavEngine::WrapAngleStates()
00902 {
00903     //wrap the state itself!
00904     int nStateNdx = m_pTracked->m_nStart+iiH;
00905     m_Xhat(nStateNdx,1) = MOOS_ANGLE_WRAP(m_Xhat(nStateNdx,1));
00906     
00907     if(m_pTracked->GetEntityType()==CMOOSNavEntity::POSE_AND_RATE)
00908     {
00909         nStateNdx = m_pTracked->m_nStart+iiHdot;
00910         m_Xhat(nStateNdx,1) = MOOS_ANGLE_WRAP(m_Xhat(nStateNdx,1));
00911     }
00912 
00913 
00914     return true;
00915 }
00916 
00917 bool CMOOSNavEngine::GuessVehicleLocation()
00918 {
00919     BEACONLIST::iterator q;
00920     double dfX=0;
00921     double dfY=0;
00922     double dfZ = 0;
00923     for(q=m_Beacons.begin();q!=m_Beacons.end();q++)
00924     {
00925         dfX+=(*q)->m_State.m_dfX;
00926         dfY+=(*q)->m_State.m_dfY;
00927         dfZ+=(*q)->m_State.m_dfZ;
00928 
00929     }
00930 
00931     dfX/=m_Beacons.size();
00932     dfY/=m_Beacons.size();
00933     dfZ/=m_Beacons.size();
00934 
00935     m_pTracked->m_State.m_dfX = dfX;
00936     m_pTracked->m_State.m_dfY = dfY;
00937     m_pTracked->m_State.m_dfZ = dfZ+10;
00938 
00939     m_pTracked->RefreshStateVector();
00940     
00941 
00942     MOOSTrace("Set Vehicle to [%7.3f %7.3f %7.3f]\n",
00943         m_pTracked->m_State.m_dfX, 
00944         m_pTracked->m_State.m_dfY,
00945         m_pTracked->m_State.m_dfZ);
00946 
00947 
00948     return true;
00949 
00950 }
00951 
00952 
00953 
00954 
00955 bool CMOOSNavEngine::GetTATByChannel(int nChannel, double &dfTAT)
00956 {
00957     CMOOSNavBeacon * pBcn = GetBeaconByChannel(nChannel);
00958 
00959     if(pBcn)
00960     {
00961         dfTAT =  pBcn->m_dfTAT;
00962         return true;
00963     }
00964     else
00965     {
00966         return false;
00967     }
00968 }
00969 
00970 bool CMOOSNavEngine::AddTheVehicle(STRING_LIST &sParams)
00971 {
00973     //        add the vehicle itself!
00974     // overide this function to make more complex vehicles
00975     m_pTracked = new CMOOSNavVehicle;
00976     m_pTracked->m_nID = GetNextID();
00977     m_pTracked->m_sName="TheAUV";
00978     m_pTracked->SetEntityType(m_eVehicleType);
00979     m_pTracked->m_State.m_dfZ = 0;
00980     return AddEntity(m_pTracked);
00981 }
00982 
00983 
00984 bool CMOOSNavEngine::MakeObsMatrices()
00985 {
00986     int nObsSize;
00987     
00988     if(!IndexObservations(nObsSize))
00989         return false;
00990     
00991     int nStateSize = m_Xhat.Nrows();
00992     
00993     if(m_jH.Nrows()!=nObsSize || m_jH.Ncols() !=  nStateSize)
00994     {
00995         m_jH.ReSize(nObsSize,nStateSize);
00996     }
00997     
00998     if(m_R.Nrows()!=nObsSize || m_R.Ncols() !=  nObsSize)
00999     {
01000         m_R.ReSize(nObsSize,nObsSize);
01001     }
01002     
01003     if(m_Innov.Nrows()!=nObsSize || m_Innov.Ncols() !=  1)
01004     {
01005         m_Innov.ReSize(nObsSize,1);
01006     }
01007     
01008     //zero all..
01009     m_jH=0;
01010     m_R=0;
01011     m_Innov = 0;
01012     
01013 
01014     OBSLIST::iterator p;
01015     
01016     for(p = m_Observations.begin();p!=m_Observations.end();p++)
01017     {
01018         CMOOSObservation  & rObs = *p;
01019 
01020         if(rObs.m_bIgnore || rObs.m_bGoodDA==false)
01021             continue;
01022         
01023         rObs.MakeMatrices(m_Innov,m_jH,m_R,m_Xhat);
01024         
01025     }
01026         
01027     
01028     return true;
01029 }
01030 
01031 bool CMOOSNavEngine::GetTrackedPosition(double &dfX, double &dfY, double &dfZ,double & dfH,double & dfLastUpdate)
01032 {
01033     m_pTracked->RefreshState();
01034     dfX = m_pTracked->m_State.m_dfX;
01035     dfY = m_pTracked->m_State.m_dfY;
01036     dfZ = m_pTracked->m_State.m_dfZ;
01037     dfH = m_pTracked->m_State.m_dfH;
01038 
01039     dfLastUpdate = m_dfLastUpdate;
01040 
01041     return true;
01042 }
01043 
01044 bool CMOOSNavEngine::GetTrackedUncertainty(double &dfPX,
01045                                            double &dfPY,
01046                                            double &dfPZ,
01047                                            double &dfPH)                                           
01048 {
01049     m_pTracked->RefreshState();
01050     dfPX = m_pTracked->m_State.m_dfPX;
01051     dfPY = m_pTracked->m_State.m_dfPY;
01052     dfPZ = m_pTracked->m_State.m_dfPZ;
01053     dfPH = m_pTracked->m_State.m_dfPH;
01054 
01055     return true;
01056 }
01057 
01058 
01059 bool CMOOSNavEngine::ForceTrackedPosition(double dfX, double dfY, double dfZ, double dfH)
01060 {
01061     m_pTracked->m_State.m_dfX = dfX;
01062     m_pTracked->m_State.m_dfY = dfY;
01063     m_pTracked->m_State.m_dfZ = dfZ;
01064     m_pTracked->m_State.m_dfH = dfH;
01065 
01066     m_pTracked->RefreshStateVector();
01067 
01068     AddToOutput("Forcing %s to [%.1f,%.1f,%.1f,%.1f]",
01069         m_sName.c_str(),
01070         dfX,
01071         dfY,
01072         dfZ,
01073         dfH);
01074 
01075     
01076 
01077 
01078     return true;
01079  
01080 }
01081 
01082 bool CMOOSNavEngine::LimitObservationTypes()
01083 {
01084 
01085     if(m_pTracked->GetEntityType()==CMOOSNavEntity::POSE_ONLY)
01086     {
01087         set<CMOOSObservation::Type> Allowed;
01088 
01089         Allowed.insert(CMOOSObservation::X);
01090         Allowed.insert(CMOOSObservation::Y);
01091         Allowed.insert(CMOOSObservation::YAW);
01092         Allowed.insert(CMOOSObservation::LBL_BEACON_2WR);
01093         Allowed.insert(CMOOSObservation::DEPTH);
01094         Allowed.insert(CMOOSObservation::TIDE);
01095 
01096         if(m_bEstimateHeadingBias)
01097         {
01098             Allowed.insert(CMOOSObservation::HEADING_BIAS);
01099         }
01100 
01101 
01102         OBSLIST::iterator p;
01103 
01104         for(p=m_Observations.begin();p!=m_Observations.end();p++)
01105         {
01106             CMOOSObservation & rObs = *p;
01107             if(Allowed.find(rObs.m_eType)==Allowed.end())
01108             {
01109                 rObs.Ignore(true);
01110             }
01111         }
01112     }
01113     
01114     return true;
01115 }
01116 
01117 bool CMOOSNavEngine::Reset()
01118 {
01119     return true;
01120 }
01121 
01122 bool CMOOSNavEngine::IsOnline()
01123 {
01124     return m_bOnline;
01125 }
01126 
01127 bool CMOOSNavEngine::SetOnline(bool bOnline)
01128 {
01129     if(m_bOnline==false && bOnline==true)
01130     {
01131         //reset cousnters when starting up
01132         m_nIterations = 0;
01133     }
01134 
01135     m_bOnline = bOnline;
01136 
01137     AddToOutput("%s is %s!",m_sName.c_str(),m_bOnline?"ONLINE":"OFFLINE");
01138 
01139     return true;
01140 }
01141 
01142 int CMOOSNavEngine::GetIterations()
01143 {
01144     return m_nIterations;
01145 }
01146 
01147 bool CMOOSNavEngine::Enable(bool bEnable)
01148 {
01149     m_bEnabled = bEnable;
01150     return true;
01151 }
01152 
01153 bool CMOOSNavEngine::IsEnabled()
01154 {
01155     return m_bEnabled;
01156 }
01157 
01158 double CMOOSNavEngine::GetYoungestDataTime()
01159 {
01160    return m_pStore->GetNewestObsTime(); 
01161 }
01162 
01163 bool CMOOSNavEngine::SetMissionFileName(const string &sFileName)
01164 {
01165     m_sMissionFileName = sFileName;
01166     return true;
01167 }
01168 
01169 bool CMOOSNavEngine::MarkObservationsDA(bool bGoodDA)
01170 {
01171     OBSLIST::iterator p;
01172     for(p = m_Observations.begin();p!=m_Observations.end();p++)
01173     {
01174         CMOOSObservation & rObs = *p;
01175 
01176         if(!rObs.m_bIgnore)
01177         {
01178             rObs.SetGoodDA(bGoodDA);
01179         }
01180     }
01181 
01182     return true;
01183 }
01184 bool CMOOSNavEngine::LogObservationSet(double dfTimeNow,                                   
01185                                        int nthUpdate)
01186 {
01187     OBSLIST::iterator p;
01188     for(p=m_Observations.begin();p!=m_Observations.end();p++)
01189     {
01190         CMOOSObservation & rObs = *p;
01191 
01192         if(!rObs.m_bIgnore)
01193         {
01194             m_Logger.LogObservation(dfTimeNow,rObs,nthUpdate);
01195         }
01196     }
01197 
01198     return true;
01199 }
01200 
01201 bool CMOOSNavEngine::RecordObsStatistics(Matrix *pInnov, Matrix *pS)
01202 {
01203     if(pInnov==NULL)
01204         return true;
01205 
01206     int nObs = pInnov->Nrows();
01207     for(int i = 1;i<=nObs;i++)
01208     {
01209         OBSLIST::iterator t;
01210         for(t = m_Observations.begin();t!=m_Observations.end();t++)
01211         {
01212             if(t->m_bIgnore==false && t->m_nRow==i)
01213             {
01214                 t->m_dfInnov = (*pInnov)(i,1);
01215                 if(pS!=NULL)
01216                 {
01217                     t->m_dfInnovStd = sqrt((*pS)(i,i));
01218                 }
01219             }
01220         }
01221     }
01222     return true;
01223 }
01224 
01225 bool CMOOSNavEngine::SetTimeStarted(double dfTime)
01226 {
01227     m_dfTimeStarted = dfTime;
01228     return true;
01229 }
01230 
01231 
01232 double CMOOSNavEngine::GetTimeStarted()
01233 {
01234     return m_dfTimeStarted;
01235 }
01236 
01237 CMOOSNavSensor::Type CMOOSNavEngine::SensorTypeFromDataName(const string &sDataName)
01238 {
01239     if(sDataName.find("_YAW")!=string ::npos)
01240         return CMOOSNavSensor::ORIENTATION;
01241 
01242     if(sDataName.find("_DEPTH")!=string ::npos)
01243         return CMOOSNavSensor::DEPTH;
01244     
01245     if(sDataName.find("_BODY_VEL")!=string ::npos )
01246         return CMOOSNavSensor::BODY_VEL;
01247 
01248     if(sDataName.find("_X")!=string ::npos)
01249         return CMOOSNavSensor::XY;
01250 
01251     if(sDataName.find("_Y")!=string ::npos)
01252         return CMOOSNavSensor::XY;
01253 
01254     if(sDataName.find("_TOF")!=string ::npos)
01255         return CMOOSNavSensor::LBL;
01256 
01257 
01258     return CMOOSNavSensor::INVALID;
01259 }
01260 
01261 bool CMOOSNavEngine::TraceDiagPhat()
01262 {
01263 
01264     ostringstream os;
01265 
01266     os.setf(ios::left);
01267 
01268     os<<endl<<"********* COVARIANCE DUMP *************"<<endl;
01269 
01270     os<<setw(15)<<"Tide Std = "<<sqrt(m_Phat(TIDE_STATE_INDEX,TIDE_STATE_INDEX))<<endl;
01271 
01272     if(m_bEstimateHeadingBias)
01273     {
01274         os<<"YawBias   Std= "<<sqrt(m_Phat(HEADING_BIAS_STATE_INDEX,HEADING_BIAS_STATE_INDEX))<<endl;
01275     }
01276 
01277     int nOffset = m_pTracked->m_nStart;
01278 
01279     os<<setw(15)<<"X   Std= "<<sqrt(m_Phat(nOffset+iiX,nOffset+iiX))<<endl;
01280     os<<setw(15)<<"Y   Std= "<<sqrt(m_Phat(nOffset+iiY,nOffset+iiY))<<endl;
01281     os<<setw(15)<<"Z   Std= "<<sqrt(m_Phat(nOffset+iiZ,nOffset+iiZ))<<endl;
01282     os<<setw(15)<<"Yaw Std= "<<sqrt(m_Phat(nOffset+iiH,nOffset+iiH))<<endl;
01283 
01284     
01285 
01286     if(m_pTracked->GetEntityType()==CMOOSNavEntity::POSE_AND_RATE)
01287     {
01288 
01289         os<<setw(15)<<"XVel   Std= "<<sqrt(m_Phat(nOffset+iiXdot,nOffset+iiXdot))<<endl;
01290         os<<setw(15)<<"YVel   Std= "<<sqrt(m_Phat(nOffset+iiYdot,nOffset+iiYdot))<<endl;
01291         os<<setw(15)<<"ZVel   Std= "<<sqrt(m_Phat(nOffset+iiZdot,nOffset+iiZdot))<<endl;
01292         os<<setw(15)<<"YawVel Std= "<<sqrt(m_Phat(nOffset+iiHdot,nOffset+iiHdot))<<endl;
01293     }
01294 
01295     os<<ends;
01296     string sOut = os.str();
01297     //os.rdbuf()->freeze(0);
01298 
01299     MOOSTrace(sOut);
01300     return true;
01301 
01302 }
01303 bool CMOOSNavEngine::SetUpSensorChannels(STRING_LIST  sParams,string sToken)
01304 {
01305 
01306        
01307     //ok we need to load up rejection settings
01308     STRING_LIST::iterator p;
01309     
01310     for(p = sParams.begin();p!=sParams.end();p++)
01311     {
01312         string sLine = *p;
01313         if(sLine.find(sToken)!=string::npos)
01314         {
01315             MOOSRemoveChars(sLine," \t");
01316             MOOSChomp(sLine,"=");
01317             //LSQ_REJECTION = TheAvtrak : Reject = 3, History = 5,Fail = 0.001           
01318             CMOOSSensorChannel NewChannel;
01319             
01320             string sSensor =    MOOSChomp(sLine,":");
01321             string sHistory =    MOOSChomp(sLine,",");
01322             string sFail =        MOOSChomp(sLine,",");
01323 
01324             MOOSChomp(sHistory,"=");
01325             MOOSChomp(sFail,"=");
01326 
01327             
01328             if(sFail.empty() ||sHistory.empty())
01329             {
01330                 MOOSTrace("error in %s line!\n",sToken.c_str());
01331                 return false;
01332             }
01333             
01334             int nDepth = atoi(sHistory.c_str());
01335             if(nDepth>0)
01336             {
01337                 NewChannel.SetHistoryDepth(nDepth);
01338             }
01339             
01340 
01341                double dfFail = atof(sFail.c_str());
01342             if(dfFail>0)
01343             {
01344                 NewChannel.SetNoiseLimit(dfFail);
01345             }
01346 
01347             NewChannel.SetName(sSensor);
01348 
01349             m_SensorChannelMap[sSensor]=NewChannel;
01350             
01351         }       
01352     }
01353 
01354     return true;
01355 }
01356 
01357 bool CMOOSNavEngine::AddToHistory(CMOOSObservation & rObs)
01358 {
01359     
01360     string sKey = rObs.GetName();
01361     
01362     //we now have a list of observations on this channel
01363     //with the most recent at the fromt of the list
01364     CMOOSSensorChannel * pChannel = GetSensorChannel(sKey);
01365     
01366     pChannel->Add(rObs);
01367     
01368 
01369     return true;
01370 }
01371 
01372 
01373 bool CMOOSNavEngine::AgreesWithHistory(CMOOSObservation &rObs)
01374 {
01375     //figure out what acoustic trajectory we are talking about
01376     string sKey = rObs.GetName();
01377     
01378     CMOOSSensorChannel * pChannel = GetSensorChannel(sKey);
01379     
01380     if(pChannel==NULL)
01381     {
01382         //we are not running trajectory filter on this sensor
01383         //so we suppose its OK - definately don't want to reject it
01384         //otherwise we are enforcing use of a sensor channel rejection
01385         //scheme!
01386         return true; 
01387     }
01388     else
01389     {
01390         //ask the channel
01391         return pChannel->Agrees(rObs);
01392     }
01393         
01394     
01395 }
01396 
01397 bool CMOOSNavEngine::PreFilterData()
01398 {
01399     OBSLIST::iterator p;
01400 
01401 //    TraceObservationSet();
01402 
01403     //firstly see if we are accpeting this kind of data
01404     LimitObservationTypes();
01405 
01406 
01407     bool bSentProgress = false;
01408     for(p = m_Observations.begin();p!=m_Observations.end();p++)
01409     {
01410         
01411         //from most recent to oldest..
01412         CMOOSObservation & rObs = *p;
01413 
01414         //if we have already been told not to use then we had better
01415         //not overide this decision
01416         if(rObs.m_bIgnore==true)
01417         {
01418             continue;
01419         }
01420         
01421         //do we have filtering set up for this kind of data?
01422         CMOOSSensorChannel * pChannel =GetSensorChannel(rObs.GetName());
01423         if(pChannel==NULL)
01424         {
01425             //no then we must use it!
01426             rObs.Ignore(false);
01427             continue;
01428         }
01429 
01430         //if the observation is fixed or already marked for ignore
01431         //then don't use it
01432         if(!rObs.IsFixed() && rObs.m_bIgnore==false)
01433         {
01434             //add it to our history
01435             AddToHistory(rObs);
01436             
01437             //does this observation line up with its own history
01438             if(!AgreesWithHistory(rObs))
01439             {
01440                 //maybe we are just starting up
01441                 if(pChannel->IsOnline())
01442                 {
01443                     //no we are online ....
01444                     MOOSTrace("SensorChannel rejecting obs[%d] %s data = %f\n",
01445                         rObs.m_nID,
01446                         rObs.GetName().c_str(),
01447                         rObs.m_dfData);
01448 
01449                     //pChannel->Trace();
01450                 }
01451                 else
01452                 {
01453                     if(!bSentProgress && !pChannel->IsBuilt())
01454                     {
01455                         SOURCE_SENSORCHANNEL_MAP::iterator q;
01456                         for(q = m_SensorChannelMap.begin();q!=m_SensorChannelMap.end();q++)
01457                         {
01458                             CMOOSSensorChannel & rLocalChannel = q->second;
01459 
01460                             if(rLocalChannel.GetPercentFull()>0)
01461                             {
01462                                 #ifdef VERBOSE
01463                                     AddToOutput("%s building history for %s, %f percent done",
01464                                         GetName().c_str(),
01465                                         rLocalChannel.GetName().c_str(),
01466                                         rLocalChannel.GetPercentFull());
01467                                 #endif
01468                             }
01469                             
01470                         }
01471                         bSentProgress = true;
01472                     }
01473                 }
01474                 //didn't agree with history or history not yet built
01475                 //set the ignore flag
01476 
01477                 rObs.m_bGoodDA = false;
01478 
01479                 //log our rejection here
01480                 m_Logger.LogObservation(m_dfTimeNow,
01481                                         rObs,
01482                                         m_nIterations,
01483                                         !pChannel->IsOnline());
01484 
01485                 rObs.m_bIgnore = true;
01486             }            
01487             else
01488             {
01489                 rObs.m_bIgnore = false;
01490                 rObs.m_bGoodDA = true;
01491             }
01492             //pChannel->Trace();
01493         }
01494     }
01495     
01496     
01497     return true;
01498 }
01499 
01500 CMOOSNavEngine::CObservationStatistic::CObservationStatistic()
01501 {
01502     m_dfRejectionRate = 0;
01503     m_nTotal = 0;
01504 }
01505 bool CMOOSNavEngine::CObservationStatistic::AddPoint(bool bAccepted)
01506 {
01507     double dfAlpha = 0.95;
01508     double dfRejected = bAccepted?0.0:1.0;
01509     m_nTotal++;
01510     m_dfRejectionRate = (100.0)*(dfAlpha*m_dfRejectionRate/100.0 + (1.0-dfAlpha)*dfRejected);
01511 
01512     return true;
01513 }
01514 
01515 
01516 bool CMOOSNavEngine::DoObservationStatistics()
01517 {
01518     
01519     OBSLIST::iterator p;
01520     for(p=m_Observations.begin();p!=m_Observations.end();p++)
01521     {
01522         CMOOSObservation & rObs = *p;
01523         
01524         OBSSTATISTIC_MAP::iterator q= m_ObsStatisticsMap.find(rObs.GetName());
01525 
01526         if(q==m_ObsStatisticsMap.end())
01527         {
01528             CObservationStatistic NewStatistic;
01529             NewStatistic.m_sType = rObs.GetName();
01530             m_ObsStatisticsMap[rObs.GetName()] = NewStatistic;
01531             q= m_ObsStatisticsMap.find(rObs.GetName());
01532         }
01533 
01534         CObservationStatistic & rStat = q->second;
01535 
01536         rStat.AddPoint(rObs.m_bGoodDA);
01537 
01538     }
01539 
01540 
01541     return true;
01542 }
01543 
01544 bool CMOOSNavEngine::DoObservationSummary()
01545 {
01546     OBSSTATISTIC_MAP::iterator q;
01547     for(q = m_ObsStatisticsMap.begin();q!=m_ObsStatisticsMap.end();q++)
01548     {
01549         CObservationStatistic & rStat = q->second;
01550         string sText = MOOSFormat("%s Rejecting %d percent of %s [%d]",
01551             GetName().c_str(),
01552             (int)rStat.m_dfRejectionRate,
01553             rStat.m_sType.c_str(),
01554             rStat.m_nTotal);
01555 
01556         AddToOutput(sText);
01557     }
01558     return true;
01559 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines