00001 #pragma ident "$Id: RinexNavData.cpp 2741 2011-06-22 16:37:02Z nwu $"
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
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
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)
00167 << " HOWtime: " << setw(6) << HOWtime
00168 << endl;
00169
00170 }
00171
00172 RinexNavData::operator EngEphemeris() const throw()
00173 {
00174 EngEphemeris ee;
00175
00176
00177
00178
00179
00180
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
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
00326
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
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
00398 const int rolloverYear = 80;
00399 if (yr < rolloverYear)
00400 yr += 100;
00401 yr += 1900;
00402
00403
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
00554
00555 if(HOWtime - Toe > DayTime::HALFWEEK)
00556 weeknum--;
00557 else if(HOWtime - Toe < -(DayTime::HALFWEEK))
00558 weeknum++;
00559
00560
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 }