GPSEphemerisStore.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: GPSEphemerisStore.cpp 2504 2011-02-13 09:31:04Z yanweignss $"
00002 
00003 //============================================================================
00004 //
00005 //  This file is part of GPSTk, the GPS Toolkit.
00006 //
00007 //  The GPSTk is free software; you can redistribute it and/or modify
00008 //  it under the terms of the GNU Lesser General Public License as published
00009 //  by the Free Software Foundation; either version 2.1 of the License, or
00010 //  any later version.
00011 //
00012 //  The GPSTk is distributed in the hope that it will be useful,
00013 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 //  GNU Lesser General Public License for more details.
00016 //
00017 //  You should have received a copy of the GNU Lesser General Public
00018 //  License along with GPSTk; if not, write to the Free Software Foundation,
00019 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //  
00021 //  Copyright 2004, The University of Texas at Austin
00022 //
00023 //============================================================================
00024 
00030 #include <iostream>
00031 #include <fstream>
00032 #include <iomanip>
00033 
00034 #include "StringUtils.hpp"
00035 #include "GPSEphemerisStore.hpp"
00036 #include "MathBase.hpp"
00037 
00038 using namespace std;
00039 using namespace gpstk;
00040 using gpstk::StringUtils::asString;
00041 
00042 namespace gpstk
00043 {
00044    //--------------------------------------------------------------------------
00045    //--------------------------------------------------------------------------
00046    Xvt GPSEphemerisStore::getXvt(const SatID sat, const DayTime& t)
00047       const throw(InvalidRequest)
00048    { 
00049       short ref;
00050       return getXvt(sat, t, ref);
00051    } // end of GPSEphemerisStore::getXvt()
00052 
00053 
00054    //--------------------------------------------------------------------------
00055    //--------------------------------------------------------------------------
00056    Xvt GPSEphemerisStore::getXvt(const SatID sat, const DayTime& t, short& ref)
00057       const throw(InvalidRequest)
00058    {
00059       try
00060       {
00061          // test for GPS satellite system in sat?
00062          const EngEphemeris& eph = findEphemeris(sat,t);
00063          ref = eph.getIODC();
00064          Xvt sv = eph.svXvt(t);
00065          return sv;
00066       }
00067       catch(InvalidRequest& ir)
00068       {
00069          GPSTK_RETHROW(ir);
00070       }
00071    } // end of GPSEphemerisStore::getXvt()
00072 
00073 
00074    //--------------------------------------------------------------------------
00075    //--------------------------------------------------------------------------
00076    const EngEphemeris&
00077    GPSEphemerisStore::findEphemeris(const SatID sat, const DayTime& t) 
00078       const throw(InvalidRequest)
00079    {
00080       try
00081       {
00082           validSatSystem(sat);
00083 
00084          return method==0 ? findUserEphemeris(sat, t) : findNearEphemeris(sat, t);
00085       }
00086       catch(InvalidRequest& ir)
00087       {
00088          GPSTK_RETHROW(ir);
00089       }
00090    }
00091 
00092 
00093    //--------------------------------------------------------------------------
00094    //--------------------------------------------------------------------------
00095    short GPSEphemerisStore::getSatHealth(const SatID sat, const DayTime& t)
00096       const throw(InvalidRequest)
00097    {
00098       try
00099       {
00100          validSatSystem(sat);
00101 
00102          // test for GPS satellite system in sat?
00103          const EngEphemeris& eph = findEphemeris(sat, t);
00104          short health = eph.getHealth();
00105          return health;
00106       }
00107       catch(InvalidRequest& ir)
00108       {
00109          GPSTK_RETHROW(ir);
00110       }
00111    } // end of GPSEphemerisStore::getHealth()
00112 
00113 
00114    //--------------------------------------------------------------------------
00115    //--------------------------------------------------------------------------
00116    void GPSEphemerisStore::dump(std::ostream& s, short detail) const
00117       throw()
00118    {
00119       UBEMap::const_iterator it;
00120 
00121       s << "Dump of GPSEphemerisStore:\n";
00122       if (detail==0)
00123       {
00124          unsigned bce_count=0;
00125          for (it = ube.begin(); it != ube.end(); it++)
00126             bce_count += it->second.size();
00127 
00128          s << " Span is " << initialTime
00129            << " to " << finalTime
00130            << " with " << bce_count << " entries."
00131            << std::endl;
00132       }
00133       else
00134       {
00135          for (it = ube.begin(); it != ube.end(); it++)
00136          {
00137             const EngEphMap& em = it->second;
00138             s << "  BCE map for satellite " << it->first
00139               << " has " << em.size() << " entries." << std::endl;
00140       
00141             EngEphMap::const_iterator ei;
00142             for (ei=em.begin(); ei != em.end(); ei++)
00143                if (detail==1)
00144                   s << "PRN " << setw(2) << it->first
00145                     << " TOE " << ei->second.getEpochTime()
00146                     << " TOC " << fixed << setw(10) << setprecision(3) << ei->second.getToc()
00147                     << " HOW " << setw(10) << ei->second.getHOWTime(2)
00148                     << " KEY " << ei->first
00149                     << std::endl;
00150                else
00151                   ei->second.dump();
00152          }
00153    
00154          s << "  End of GPSEphemerisStore data." << std::endl << std::endl;
00155       }
00156    } // end of GPSEphemerisStore::dump()
00157 
00158 
00159    //--------------------------------------------------------------------------
00160    // Only keeps one ephemeris with a given IODC/time
00161    // It should keep the one with the latest transmit time
00162    //--------------------------------------------------------------------------
00163    bool GPSEphemerisStore::addEphemeris(const EngEphemeris& eph)
00164       throw()
00165    {
00166       bool rc = false;
00167       DayTime t(0.L);
00168       t =  eph.getEphemerisEpoch();
00169       t -= 0.5*3600.0*eph.getFitInterval();
00170 
00171       DayTime endEff(0.L);
00172       endEff = eph.getEphemerisEpoch() + 0.5*3600.0*eph.getFitInterval();
00173    
00174       EngEphMap& eem = ube[eph.getPRNID()];
00175       EngEphMap::iterator sfi = eem.find(t);
00176       if ( sfi == eem.end())
00177       {
00178          eem[t] = eph;
00179          rc = true;
00180       }
00181       else
00182       {
00183          // Store the new eph only if it has a later transmit time
00184          EngEphemeris& current = sfi->second;
00185          DayTime ephTot, currentTot;
00186          ephTot = eph.getTransmitTime();
00187          currentTot = current.getTransmitTime();
00188 
00189          if (ephTot > currentTot)
00190          {
00191             //if (eph.getIODC() != current.getIODC())
00192             //cerr << "Wierd: prn:" << setw(2) << eph.getPRNID()
00193             //<< ", Toe:" << eph.getToe()
00194             //<< ", New IODC:" << eph.getIODC()
00195             //<< ", New TTx:" << eph.getTot()
00196             //<< ", Old IODC:" << current.getIODC()
00197             //<< ", Old TTx:" << current.getTot()
00198             //<< endl;
00199             
00200             current = eph;
00201             rc = true;
00202          }
00203       }
00204 
00205       // In any case, update the initial and final times
00206       if (t<initialTime)
00207          initialTime = t;
00208       else if (endEff>finalTime)
00209          finalTime = endEff;
00210 
00211       return rc;
00212    }
00213 
00214 
00215 //-----------------------------------------------------------------------------
00216 //-----------------------------------------------------------------------------
00217    void GPSEphemerisStore::edit(const DayTime& tmin, const DayTime& tmax)
00218       throw()
00219    {
00220       DayTime test;
00221       for(UBEMap::iterator i = ube.begin(); i != ube.end(); i++)
00222       {
00223          EngEphMap& eMap = i->second;
00224 
00225          EngEphMap::iterator lower = eMap.lower_bound(tmin);
00226          if (lower != eMap.begin())
00227             eMap.erase(eMap.begin(), lower);
00228 
00229          EngEphMap::iterator upper = eMap.upper_bound(tmax);
00230          if (upper != eMap.end())
00231             eMap.erase(upper, eMap.end());
00232       }
00233 
00234       initialTime = tmin;
00235       finalTime = tmax;
00236    }
00237 
00238 
00239 //-----------------------------------------------------------------------------
00240 //-----------------------------------------------------------------------------
00241    unsigned GPSEphemerisStore::ubeSize() const throw()
00242    {
00243       unsigned counter = 0;
00244       for(UBEMap::const_iterator i = ube.begin(); i != ube.end(); i++)
00245          counter += i->second.size();
00246       return counter;
00247    }
00248 
00249 
00250 //-----------------------------------------------------------------------------
00251 //-----------------------------------------------------------------------------
00252    const EngEphemeris&
00253    GPSEphemerisStore::findUserEphemeris(const SatID sat, const DayTime& t) 
00254       const throw(InvalidRequest)
00255    {
00256       validSatSystem(sat);
00257 
00258       DayTime test;
00259       UBEMap::const_iterator prn_i = ube.find(sat.id);
00260       if (prn_i == ube.end())
00261       {
00262          InvalidRequest e("No ephemeris for satellite " + asString(sat));
00263          GPSTK_THROW(e);
00264       }
00265 
00266       const EngEphMap& em = prn_i->second;
00267       DayTime t1(0.0L), t2(0.0L), Tot = DayTime::BEGINNING_OF_TIME;
00268       EngEphMap::const_iterator it = em.end();
00269 
00270       // Find eph with (Toe-(fitint/2)) > t - 4 hours
00271       // Use 4 hours b/c it's the default fit interval.
00272       // Backup one ephemeris to make sure you get the
00273       // correct one in case of fit intervals greater 
00274       // than 4 hours.
00275       EngEphMap::const_iterator ei = em.upper_bound(t - 4 * 3600); 
00276       if (!em.empty() && ei != em.begin() )
00277       {
00278          ei--;
00279       }
00280       
00281       for (; ei != em.end(); ei++)
00282       {
00283          const EngEphemeris& current = ei->second;
00284          // t1 = Toe-(fitint / 2)
00285          t1 = ei->first;
00286          // t2 = HOW time
00287          t2 = current.getTransmitTime();
00288 
00289          // Ephemeredes are ordered by fit interval.  
00290          // If the start of the fit interval is in the future, 
00291          // this and any more ephemerides are not the one you are
00292          // looking for.
00293          if( t1 > t ) 
00294          {
00295             break;
00296          }
00297          
00298          double dt1 = t - t1;
00299          double dt2 = t - t2;
00300 
00301          if (dt1 >= 0 &&                           // t is after start of fit interval
00302              dt1 < current.getFitInterval() * 3600 &&  // t is within the fit interval
00303              dt2 >= 0 &&                           // t is after Tot
00304              t2 > Tot )                            // this eph has the latest Tot
00305          {
00306             it = ei;
00307             Tot = t2;
00308          }
00309       }
00310 
00311       if (it == em.end())
00312       {
00313          string mess = "No eph found for satellite "
00314             + asString(sat) + " at " + t.printf("%03j %02H:%02M:%02S");
00315          InvalidRequest e(mess);
00316          GPSTK_THROW(e);
00317       }
00318 
00319       return it->second;
00320    } // end of GPSEphemerisStore::findEphemeris()
00321 
00322 
00323 //-----------------------------------------------------------------------------
00324 //-----------------------------------------------------------------------------
00325    const EngEphemeris&
00326    GPSEphemerisStore::findNearEphemeris(const SatID sat, const DayTime& t) 
00327       const throw(InvalidRequest)
00328    {
00329       validSatSystem(sat);
00330 
00331       DayTime test;
00332       UBEMap::const_iterator prn_i = ube.find(sat.id);
00333       if (prn_i == ube.end())
00334       {
00335          InvalidRequest e("No ephemeris for satellite " + asString(sat));
00336          GPSTK_THROW(e);
00337       }
00338 
00339       const EngEphMap& em = prn_i->second;
00340       double dt2min = -1;
00341       DayTime tstart, how;
00342       EngEphMap::const_iterator it = em.end();
00343 
00344       // Find eph with (Toe-(fitint/2)) > t - 4 hours
00345       // Use 4 hours b/c it's the default fit interval.
00346       // Backup one ephemeris to make sure you get the
00347       // correct one in case of fit intervals greater 
00348       // than 4 hours.
00349       EngEphMap::const_iterator ei = em.upper_bound(t - 4 * 3600); 
00350       if (!em.empty() && ei != em.begin() )
00351       {
00352          ei--;
00353       }
00354       
00355       for (; ei != em.end(); ei++)
00356       {
00357          const EngEphemeris& current = ei->second;
00358          // tstart = Toe-(fitint / 2)
00359          tstart = ei->first;
00360          // how = HOW time
00361          how = current.getTransmitTime();
00362 
00363          // Ephemerides are ordered by time of start of fit interval.  
00364          // If the start of the fit interval is in the future, 
00365          // this and any more ephemerides are not the one you are
00366          // looking for.
00367          if( tstart > t ) break;
00368          
00369          double dt1 = t - tstart;
00370          double dt2 = t - how;
00371 
00372          if (dt1 >= 0 &&                           // t is after start of fit interval
00373              dt1 <= current.getFitInterval()*3600 &&  // t is within the fit interval
00374              (dt2min == -1 || fabs(dt2) < dt2min))  // t is closest to HOW
00375          {
00376             it = ei;
00377             dt2min = fabs(dt2);
00378          }
00379       }
00380 
00381       if (it == em.end())
00382       {
00383          string mess = "No eph found for satellite "
00384             + asString(sat) + " at " + t.printf("%03j %02H:%02M:%02S");
00385          InvalidRequest e(mess);
00386          GPSTK_THROW(e);
00387       }
00388 
00389       return it->second;
00390    } // end of GPSEphemerisStore::findNearEphemeris()
00391 
00392 
00393 //-----------------------------------------------------------------------------
00394 //-----------------------------------------------------------------------------
00395    int GPSEphemerisStore::addToList(std::list<EngEphemeris>& v) const throw()
00396    {
00397       int n=0;
00398       UBEMap::const_iterator prn_i;
00399       for (prn_i = ube.begin(); prn_i != ube.end(); prn_i++)
00400       {
00401          const EngEphMap& em = prn_i->second;
00402          EngEphMap::const_iterator ei;
00403          for (ei=em.begin(); ei != em.end(); ei++)
00404          {
00405             v.push_back(ei->second);
00406             n++;
00407          }
00408       }
00409       return n;
00410    } // end of GPSEphemerisStore::addToList(list<EngEphemeris>&)
00411 
00412 //-----------------------------------------------------------------------------
00413 //-----------------------------------------------------------------------------
00414 //   const EngEphMap 
00415    const std::map<DayTime, EngEphemeris>& 
00416    GPSEphemerisStore::getEphMap( const SatID sat )
00417             const throw(InvalidRequest)
00418    {
00419       validSatSystem(sat);
00420 
00421       UBEMap::const_iterator prn_i = ube.find(sat.id);
00422       if (prn_i == ube.end())
00423       {
00424          InvalidRequest e("No ephemeris for satellite " + asString(sat));
00425          GPSTK_THROW(e);
00426       }
00427       return(prn_i->second);
00428    } // end of GPSEphemerisStore::getEphMap(const SatID sat)
00429    
00430 } // namespace
00431  

Generated on Tue May 22 03:30:58 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1