RinexNavData.cpp

Go to the documentation of this file.
00001 #pragma ident "$Id: RinexNavData.cpp 2741 2011-06-22 16:37:02Z nwu $"
00002 
00003 
00004 
00005 //============================================================================
00006 //
00007 //  This file is part of GPSTk, the GPS Toolkit.
00008 //
00009 //  The GPSTk is free software; you can redistribute it and/or modify
00010 //  it under the terms of the GNU Lesser General Public License as published
00011 //  by the Free Software Foundation; either version 2.1 of the License, or
00012 //  any later version.
00013 //
00014 //  The GPSTk is distributed in the hope that it will be useful,
00015 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 //  GNU Lesser General Public License for more details.
00018 //
00019 //  You should have received a copy of the GNU Lesser General Public
00020 //  License along with GPSTk; if not, write to the Free Software Foundation,
00021 //  Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 //
00023 //  Copyright 2004, The University of Texas at Austin
00024 //
00025 //============================================================================
00026 
00027 //============================================================================
00028 //
00029 //This software developed by Applied Research Laboratories at the University of
00030 //Texas at Austin, under contract to an agency or agencies within the U.S.
00031 //Department of Defense. The U.S. Government retains all rights to use,
00032 //duplicate, distribute, disclose, or release this software.
00033 //
00034 //Pursuant to DoD Directive 523024
00035 //
00036 // DISTRIBUTION STATEMENT A: This software has been approved for public
00037 //                           release, distribution is unlimited.
00038 //
00039 //=============================================================================
00040 
00041 
00042 
00043 
00044 
00045 
00051 #include "StringUtils.hpp"
00052 #include "DayTime.hpp"
00053 #include "RinexNavData.hpp"
00054 #include "RinexNavStream.hpp"
00055 #include "icd_200_constants.hpp"
00056 
00057 namespace gpstk
00058 {
00059    using namespace gpstk::StringUtils;
00060    using namespace std;
00061 
00062    RinexNavData::RinexNavData(const EngEphemeris& ee)
00063    {
00064       time = ee.getEpochTime();
00065       PRNID = ee.getPRNID();
00066       HOWtime = long(ee.getHOWTime(1));
00067       weeknum = ee.getFullWeek();
00068       codeflgs = ee.getCodeFlags();
00069       accuracy = ee.getAccuracy();
00070       health = ee.getHealth();
00071       L2Pdata = ee.getL2Pdata();
00072       IODC = ee.getIODC();
00073       IODE = ee.getIODE();
00074 
00075       Toc = ee.getToc();
00076       af0 = ee.getAf0();
00077       af1 = ee.getAf1();
00078       af2 = ee.getAf2();
00079       Tgd = ee.getTgd();
00080 
00081       Cuc = ee.getCuc();
00082       Cus = ee.getCus();
00083       Crc = ee.getCrc();
00084       Crs = ee.getCrs();
00085       Cic = ee.getCic();
00086       Cis = ee.getCis();
00087 
00088       Toe = ee.getToe();
00089       M0 = ee.getM0();
00090       dn = ee.getDn();
00091       ecc = ee.getEcc();
00092       Ahalf = ee.getAhalf();
00093       OMEGA0 = ee.getOmega0();
00094       i0 = ee.getI0();
00095       w = ee.getW();
00096       OMEGAdot = ee.getOmegaDot();
00097       idot = ee.getIDot();
00098       fitint = ee.getFitInterval();
00099    }
00100 
00101    void RinexNavData::reallyPutRecord(FFStream& ffs) const
00102       throw(exception, FFStreamError, StringException)
00103    {
00104       RinexNavStream& strm = dynamic_cast<RinexNavStream&>(ffs);
00105 
00106       strm << putPRNEpoch() << endl;
00107       strm.lineNumber++;
00108       strm << putBroadcastOrbit1() << endl;
00109       strm.lineNumber++;
00110       strm << putBroadcastOrbit2() << endl;
00111       strm.lineNumber++;
00112       strm << putBroadcastOrbit3() << endl;
00113       strm.lineNumber++;
00114       strm << putBroadcastOrbit4() << endl;
00115       strm.lineNumber++;
00116       strm << putBroadcastOrbit5() << endl;
00117       strm.lineNumber++;
00118       strm << putBroadcastOrbit6() << endl;
00119       strm.lineNumber++;
00120       strm << putBroadcastOrbit7(strm.header.version) << endl;
00121       strm.lineNumber++;
00122    }
00123 
00124    void RinexNavData::reallyGetRecord(FFStream& ffs)
00125       throw(exception, FFStreamError, StringException)
00126    {
00127       RinexNavStream& strm = dynamic_cast<RinexNavStream&>(ffs);
00128 
00129          // If the header hasn't been read, read it...
00130       if(!strm.headerRead)
00131          strm >> strm.header;
00132 
00133       string line;
00134 
00135       strm.formattedGetLine(line, true);
00136       getPRNEpoch(line);
00137 
00138       strm.formattedGetLine(line);
00139       getBroadcastOrbit1(line);
00140 
00141       strm.formattedGetLine(line);
00142       getBroadcastOrbit2(line);
00143 
00144       strm.formattedGetLine(line);
00145       getBroadcastOrbit3(line);
00146 
00147       strm.formattedGetLine(line);
00148       getBroadcastOrbit4(line);
00149 
00150       strm.formattedGetLine(line);
00151       getBroadcastOrbit5(line);
00152 
00153       strm.formattedGetLine(line);
00154       getBroadcastOrbit6(line);
00155 
00156       strm.formattedGetLine(line);
00157       getBroadcastOrbit7(line);
00158    }
00159 
00160    void RinexNavData::dump(ostream& s) const
00161    {
00162       s << "PRN: " << setw(2) << PRNID
00163         << " TOE: " << time
00164         << " TOC: " << setw(4) << weeknum << " "
00165         << fixed << setw(10) << setprecision(3) << Toc
00166         << " IODE: " << setw(4) << int(IODE)            // IODE should be int
00167         << " HOWtime: " << setw(6) << HOWtime           // HOW should be double
00168         << endl;
00169         //<< ios::hex << IODE << " HOWtime: " << HOWtime << endl; ?? IODE is double
00170    }
00171 
00172    RinexNavData::operator EngEphemeris() const throw()
00173    {
00174       EngEphemeris ee;
00175 
00176          // there's no TLM word in RinexNavData, so it's set to 0.
00177          // likewise, there's no AS alert or tracker.
00178          // Also, in Rinex, the accuracy is in meters, and setSF1 expects
00179          // the accuracy flag.  We'll give it zero and pass the accuracy
00180          // separately via the setAccuracy() method.
00181       ee.setSF1(0, HOWtime, 0, weeknum, codeflgs, 0, health,
00182                 short(IODC), L2Pdata, Tgd, Toc, af2, af1, af0, 0, PRNID);
00183       ee.setSF2(0, HOWtime, 0, short(IODE), Crs, dn, M0, Cuc, ecc, Cus, Ahalf,
00184                 Toe, (fitint > 4) ? 1 : 0);
00185       ee.setSF3(0, HOWtime, 0, Cic, OMEGA0, Cis, i0, Crc, w, OMEGAdot,
00186                 idot);
00187 
00188       ee.setAccuracy(accuracy);
00189 
00190       return ee;
00191    }
00192 
00193    list<double> RinexNavData::toList() const
00194    {
00195       list<double> l;
00196 
00197       l.push_back(PRNID);
00198       l.push_back(HOWtime);
00199       l.push_back(weeknum);
00200       l.push_back(codeflgs);
00201       l.push_back(accuracy);
00202       l.push_back(health);
00203       l.push_back(L2Pdata);
00204       l.push_back(IODC);
00205       l.push_back(IODE);
00206       l.push_back(Toc);
00207       l.push_back(af0);
00208       l.push_back(af1);
00209       l.push_back(af2);
00210       l.push_back(Tgd);
00211       l.push_back(Cuc);
00212       l.push_back(Cus);
00213       l.push_back(Crc);
00214       l.push_back(Crs);
00215       l.push_back(Cic);
00216       l.push_back(Cis);
00217       l.push_back(Toe);
00218       l.push_back(M0);
00219       l.push_back(dn);
00220       l.push_back(ecc);
00221       l.push_back(Ahalf);
00222       l.push_back(OMEGA0);
00223       l.push_back(i0);
00224       l.push_back(w);
00225       l.push_back(OMEGAdot);
00226       l.push_back(idot);
00227       l.push_back(fitint);
00228 
00229       return l;
00230    }
00231 
00232    string RinexNavData::putPRNEpoch(void) const
00233       throw(StringException)
00234    {
00235       string line;
00236       line += rightJustify(asString(PRNID), 2);
00237       line += string(1, ' ');
00238          // year is padded with 0s but none of the rest are
00239       line += rightJustify(asString<short>(time.year()), 2, '0');
00240       line += string(1, ' ');
00241       line += rightJustify(asString<short>(time.month()), 2);
00242       line += string(1, ' ');
00243       line += rightJustify(asString<short>(time.day()), 2);
00244       line += string(1, ' ');
00245       line += rightJustify(asString<short>(time.hour()), 2);
00246       line += string(1, ' ');
00247       line += rightJustify(asString<short>(time.minute()), 2);
00248       line += rightJustify(asString(time.second(), 1), 5);
00249       line += string(1, ' ');
00250       line += doub2for(af0, 18, 2);
00251       line += string(1, ' ');
00252       line += doub2for(af1, 18, 2);
00253       line += string(1, ' ');
00254       line += doub2for(af2, 18, 2);
00255       return line;
00256    }
00257 
00258    string RinexNavData::putBroadcastOrbit1(void) const
00259       throw(StringException)
00260    {
00261       string line;
00262       line += string(3, ' ');
00263       line += string(1, ' ');
00264       line += doub2for(IODE, 18, 2);
00265       line += string(1, ' ');
00266       line += doub2for(Crs, 18, 2);
00267       line += string(1, ' ');
00268       line += doub2for(dn, 18, 2);
00269       line += string(1, ' ');
00270       line += doub2for(M0, 18, 2);
00271       return line;
00272    }
00273 
00274    string RinexNavData::putBroadcastOrbit2(void) const
00275       throw(StringException)
00276    {
00277       string line;
00278       line += string(3, ' ');
00279       line += string(1, ' ');
00280       line += doub2for(Cuc, 18, 2);
00281       line += string(1, ' ');
00282       line += doub2for(ecc, 18, 2);
00283       line += string(1, ' ');
00284       line += doub2for(Cus, 18, 2);
00285       line += string(1, ' ');
00286       line += doub2for(Ahalf, 18, 2);
00287       return line;
00288    }
00289 
00290    string RinexNavData::putBroadcastOrbit3(void) const
00291       throw(StringException)
00292    {
00293       string line;
00294       line += string(3, ' ');
00295       line += string(1, ' ');
00296       line += doub2for(Toe, 18, 2);
00297       line += string(1, ' ');
00298       line += doub2for(Cic, 18, 2);
00299       line += string(1, ' ');
00300       line += doub2for(OMEGA0, 18, 2);
00301       line += string(1, ' ');
00302       line += doub2for(Cis, 18, 2);
00303       return line;
00304    }
00305 
00306    string RinexNavData::putBroadcastOrbit4(void) const
00307       throw(StringException)
00308    {
00309       string line;
00310       line += string(3, ' ');
00311       line += string(1, ' ');
00312       line += doub2for(i0, 18, 2);
00313       line += string(1, ' ');
00314       line += doub2for(Crc, 18, 2);
00315       line += string(1, ' ');
00316       line += doub2for(w, 18, 2);
00317       line += string(1, ' ');
00318       line += doub2for(OMEGAdot, 18, 2);
00319       return line;
00320    }
00321 
00322    string RinexNavData::putBroadcastOrbit5(void) const
00323       throw(StringException)
00324    {
00325          // Internally (RinexNavData and EngEphemeris), weeknum is the week of HOW
00326          // In Rinex *files*, weeknum is the week of TOE
00327       double wk=double(weeknum);
00328       if(HOWtime - Toe > DayTime::HALFWEEK)
00329          wk++;
00330       else if(HOWtime - Toe < -(DayTime::HALFWEEK))
00331          wk--;
00332 
00333       string line;
00334       line += string(3, ' ');
00335       line += string(1, ' ');
00336       line += doub2for(idot, 18, 2);
00337       line += string(1, ' ');
00338       line += doub2for((double)codeflgs, 18, 2);
00339       line += string(1, ' ');
00340       line += doub2for(wk, 18, 2);
00341       line += string(1, ' ');
00342       line += doub2for((double)L2Pdata, 18, 2);
00343       return line;
00344    }
00345 
00346    string RinexNavData::putBroadcastOrbit6(void) const
00347       throw(StringException)
00348    {
00349       string line;
00350       line += string(3, ' ');
00351       line += string(1, ' ');
00352       line += doub2for(accuracy, 18, 2);
00353       line += string(1, ' ');
00354       line += doub2for((double)health, 18, 2);
00355       line += string(1, ' ');
00356       line += doub2for(Tgd, 18, 2);
00357       line += string(1, ' ');
00358       line += doub2for(IODC, 18, 2);
00359       return line;
00360    }
00361 
00362    string RinexNavData::putBroadcastOrbit7(const double ver) const
00363       throw(StringException)
00364    {
00365       string line;
00366       line += string(3, ' ');
00367       line += string(1, ' ');
00368       line += doub2for(HOWtime, 18, 2);
00369 
00370       if (ver >= 2.1)
00371       {
00372          line += string(1, ' ');
00373          line += doub2for(fitint, 18, 2);
00374       }
00375       return line;
00376    }
00377 
00378    void RinexNavData::getPRNEpoch(const string& currentLine)
00379       throw(StringException, FFStreamError)
00380    {
00381       try
00382       {
00383             // check for spaces in the right spots...
00384          for (int i = 2; i <= 17; i += 3)
00385             if (currentLine[i] != ' ')
00386                throw(FFStreamError("Badly formatted line"));
00387 
00388          PRNID = asInt(currentLine.substr(0,2));
00389 
00390          short yr = asInt(currentLine.substr(2,3));
00391          short mo = asInt(currentLine.substr(5,3));
00392          short day = asInt(currentLine.substr(8,3));
00393          short hr = asInt(currentLine.substr(11,3));
00394          short min = asInt(currentLine.substr(14,3));
00395          double sec = asDouble(currentLine.substr(17,5));
00396 
00397             // years 80-99 represent 1980-1999
00398          const int rolloverYear = 80;
00399          if (yr < rolloverYear)
00400             yr += 100;
00401          yr += 1900;
00402 
00403          // Real Rinex has epochs 'yy mm dd hr 59 60.0' surprisingly often....
00404          double ds=0;
00405          if(sec >= 60.) { ds=sec; sec=0.0; }
00406          time = DayTime(yr,mo,day,hr,min,sec);
00407          if(ds != 0) time += ds;
00408 
00409          Toc = time.GPSsecond();
00410          af0 = gpstk::StringUtils::for2doub(currentLine.substr(22,19));
00411          af1 = gpstk::StringUtils::for2doub(currentLine.substr(41,19));
00412          af2 = gpstk::StringUtils::for2doub(currentLine.substr(60,19));
00413       }
00414       catch (std::exception &e)
00415       {
00416          FFStreamError err("std::exception: " +
00417                            string(e.what()));
00418          GPSTK_THROW(err);
00419       }
00420    }
00421 
00422    void RinexNavData::getBroadcastOrbit1(const string& currentLine)
00423       throw(StringException, FFStreamError)
00424    {
00425       try
00426       {
00427          IODE = gpstk::StringUtils::for2doub(currentLine.substr(3,19));
00428          Crs = gpstk::StringUtils::for2doub(currentLine.substr(22,19));
00429          dn = gpstk::StringUtils::for2doub(currentLine.substr(41,19));
00430          M0 = gpstk::StringUtils::for2doub(currentLine.substr(60,19));
00431       }
00432       catch (std::exception &e)
00433       {
00434          FFStreamError err("std::exception: " +
00435                            string(e.what()));
00436          GPSTK_THROW(err);
00437       }
00438    }
00439 
00440    void RinexNavData::getBroadcastOrbit2(const string& currentLine)
00441       throw(StringException, FFStreamError)
00442    {
00443       try
00444       {
00445          Cuc = gpstk::StringUtils::for2doub(currentLine.substr(3,19));
00446          ecc = gpstk::StringUtils::for2doub(currentLine.substr(22,19));
00447          Cus = gpstk::StringUtils::for2doub(currentLine.substr(41,19));
00448          Ahalf = gpstk::StringUtils::for2doub(currentLine.substr(60,19));
00449       }
00450       catch (std::exception &e)
00451       {
00452          FFStreamError err("std::exception: " +
00453                            string(e.what()));
00454          GPSTK_THROW(err);
00455       }
00456    }
00457 
00458    void RinexNavData::getBroadcastOrbit3(const string& currentLine)
00459       throw(StringException, FFStreamError)
00460    {
00461       try
00462       {
00463          Toe = gpstk::StringUtils::for2doub(currentLine.substr(3,19));
00464          Cic = gpstk::StringUtils::for2doub(currentLine.substr(22,19));
00465          OMEGA0 = gpstk::StringUtils::for2doub(currentLine.substr(41,19));
00466          Cis = gpstk::StringUtils::for2doub(currentLine.substr(60,19));
00467       }
00468       catch (std::exception &e)
00469       {
00470          FFStreamError err("std::exception: " +
00471                            string(e.what()));
00472          GPSTK_THROW(err);
00473       }
00474    }
00475 
00476    void RinexNavData::getBroadcastOrbit4(const string& currentLine)
00477       throw(StringException, FFStreamError)
00478    {
00479       try
00480       {
00481          i0 = gpstk::StringUtils::for2doub(currentLine.substr(3,19));
00482          Crc = gpstk::StringUtils::for2doub(currentLine.substr(22,19));
00483          w = gpstk::StringUtils::for2doub(currentLine.substr(41,19));
00484          OMEGAdot = gpstk::StringUtils::for2doub(currentLine.substr(60,19));
00485       }
00486       catch (std::exception &e)
00487       {
00488          FFStreamError err("std::exception: " +
00489                            string(e.what()));
00490          GPSTK_THROW(err);
00491       }
00492    }
00493 
00494    void RinexNavData::getBroadcastOrbit5(const string& currentLine)
00495       throw(StringException, FFStreamError)
00496    {
00497       try
00498       {
00499          double codeL2, L2P, toe_wn;
00500 
00501          idot = gpstk::StringUtils::for2doub(currentLine.substr(3,19));
00502          codeL2 = gpstk::StringUtils::for2doub(currentLine.substr(22,19));
00503          toe_wn = gpstk::StringUtils::for2doub(currentLine.substr(41,19));
00504          L2P = gpstk::StringUtils::for2doub(currentLine.substr(60,19));
00505 
00506          codeflgs = (short) codeL2;
00507          L2Pdata = (short) L2P;
00508          weeknum = (short) toe_wn;
00509       }
00510       catch (std::exception &e)
00511       {
00512          FFStreamError err("std::exception: " +
00513                            string(e.what()));
00514          GPSTK_THROW(err);
00515       }
00516    }
00517 
00518    void RinexNavData::getBroadcastOrbit6(const string& currentLine)
00519       throw(StringException, FFStreamError)
00520    {
00521       try
00522       {
00523          double SV_acc, SV_health;
00524 
00525          accuracy = gpstk::StringUtils::for2doub(currentLine.substr(3,19));
00526          SV_health = gpstk::StringUtils::for2doub(currentLine.substr(22,19));
00527          Tgd = gpstk::StringUtils::for2doub(currentLine.substr(41,19));
00528          IODC = gpstk::StringUtils::for2doub(currentLine.substr(60,19));
00529 
00530 
00531          health = (short) SV_health;
00532       }
00533       catch (std::exception &e)
00534       {
00535          FFStreamError err("std::exception: " +
00536                            string(e.what()));
00537          GPSTK_THROW(err);
00538       }
00539    }
00540 
00541    void RinexNavData::getBroadcastOrbit7(const string& currentLine)
00542       throw(StringException, FFStreamError)
00543    {
00544       try
00545       {
00546          double HOW_sec;
00547 
00548          HOW_sec = gpstk::StringUtils::for2doub(currentLine.substr(3,19));
00549          fitint = gpstk::StringUtils::for2doub(currentLine.substr(22,19));
00550 
00551          HOWtime = (long) HOW_sec;
00552 
00553          // In Rinex *files*, weeknum is the week of TOE
00554          // Internally (RinexNavData and EngEphemeris), weeknum is the week of HOW
00555          if(HOWtime - Toe > DayTime::HALFWEEK)
00556             weeknum--;
00557          else if(HOWtime - Toe < -(DayTime::HALFWEEK))
00558             weeknum++;
00559 
00560          // Some Rinex files have HOW < 0
00561          while(HOWtime < 0) {
00562            HOWtime += (long) DayTime::FULLWEEK;
00563             weeknum--;
00564          }
00565 
00566       }
00567       catch (std::exception &e)
00568       {
00569          FFStreamError err("std::exception: " +
00570                            string(e.what()));
00571          GPSTK_THROW(err);
00572       }
00573    }
00574 
00575 }  // end of namespace

Generated on Thu Feb 9 03:30:59 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1