00001 #pragma ident "$Id: EngEphemeris.cpp 2972 2011-11-10 12:10:39Z yanweignss $"
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 "icd_200_constants.hpp"
00053 #include "GPSGeoid.hpp"
00054 #include "EngEphemeris.hpp"
00055
00056 #include <cmath>
00057
00058 namespace gpstk
00059 {
00060 using namespace std;
00061 using namespace gpstk;
00062
00063 EngEphemeris::EngEphemeris()
00064 throw()
00065 {
00066 haveSubframe[0] = haveSubframe[1] = haveSubframe[2] = false;
00067
00068 tlm_message[0] = tlm_message[1] = tlm_message[2] = 0;
00069
00070 PRNID = tracker = ASalert[0] = ASalert[1] = ASalert[2] = weeknum =
00071 codeflags = accFlag = health = L2Pdata = 0;
00072
00073 HOWtime[0] = HOWtime[1] = HOWtime[2] = 0;
00074
00075 IODC = IODE = 0;
00076 Toc = af0 = af1 = af2 = Tgd = Cuc = Cus = Crc = Crs =
00077 Cic = Cis = Toe = M0 = dn = ecc = Ahalf = OMEGA0 = i0 = w =
00078 OMEGAdot = idot = accuracy = 0.0;
00079
00080 fitint = 0;
00081 }
00082
00083 bool EngEphemeris::addSubframe(const long subframe[10], const int gpsWeek,
00084 short PRN, short track)
00085 throw(InvalidParameter)
00086 {
00087 double ficked[60];
00088
00089 if (!subframeConvert(subframe, gpsWeek, ficked))
00090 return false;
00091
00092 int sfnum = static_cast<int>( ficked[4] );
00093 InvalidParameter exc("Subframe "+StringUtils::asString(sfnum)+
00094 " not ephemeris subframe.");
00095
00096 switch (sfnum)
00097 {
00098 case 1:
00099 tlm_message[0] = (subframe[0] >> 8) & 0x3fff;
00100 HOWtime[0] = static_cast<long>( ficked[2] );
00101 ASalert[0] = static_cast<short>( ficked[3] );
00102 weeknum = static_cast<short>( ficked[5] );
00103 codeflags = static_cast<short>( ficked[6] );
00104 accFlag = static_cast<short>( ficked[7] );
00105 health = static_cast<short>( ficked[8] );
00106 IODC = static_cast<short>( ldexp( ficked[9], -11 ) );
00107 L2Pdata = static_cast<short>( ficked[10] );
00108 Tgd = ficked[11];
00109 Toc = ficked[12];
00110 af2 = ficked[13];
00111 af1 = ficked[14];
00112 af0 = ficked[15];
00113 tracker = track;
00114 PRNID = PRN;
00115 haveSubframe[0] = true;
00116
00117 accuracy = gpstk::ura2accuracy(accFlag);
00118 break;
00119
00120 case 2:
00121 tlm_message[1] = (subframe[0] >> 8) & 0x3fff;
00122 HOWtime[1] = static_cast<long>( ficked[2] );
00123 ASalert[1] = static_cast<short>( ficked[3] );
00124 IODE = static_cast<short>( ldexp( ficked[5], -11 ) );
00125 Crs = ficked[6];
00126 dn = ficked[7];
00127 M0 = ficked[8];
00128 Cuc = ficked[9];
00129 ecc = ficked[10];
00130 Cus = ficked[11];
00131 Ahalf = ficked[12];
00132 Toe = ficked[13];
00133 fitint = static_cast<short>( ficked[14] );
00134 AODO = static_cast<long>( ficked[15] );
00135 haveSubframe[1] = true;
00136 break;
00137
00138 case 3:
00139 tlm_message[2] = (subframe[0] >> 8) & 0x3fff;
00140 HOWtime[2] = static_cast<long>( ficked[2] );
00141 ASalert[2] = static_cast<short>( ficked[3] );
00142 Cic = ficked[5];
00143 OMEGA0 = ficked[6];
00144 Cis = ficked[7];
00145 i0 = ficked[8];
00146 Crc = ficked[9];
00147 w = ficked[10];
00148 OMEGAdot = ficked[11];
00149 idot = ficked[13];
00150 haveSubframe[2] = true;
00151 break;
00152
00153 default:
00154 GPSTK_THROW(exc);
00155 break;
00156 }
00157
00158 return true;
00159 }
00160
00161 bool EngEphemeris::addSubframeNoParity(const long subframe[10],
00162 const long gpsWeek,
00163 const short PRN,
00164 const short track)
00165 throw(InvalidParameter)
00166 {
00167 long paddedSF[10];
00168 short PRNArg;
00169 short trackArg;
00170
00171 for (int i=0;i<10;++i)
00172 {
00173 paddedSF[i] = subframe[i];
00174 paddedSF[i] <<= 6;
00175 paddedSF[i] &= 0x3FFFFFC0;
00176 }
00177 PRNArg = PRN;
00178 trackArg = track;
00179 return( addSubframe( paddedSF, gpsWeek, PRNArg, trackArg ));
00180 }
00181
00182 bool EngEphemeris::addIncompleteSF1Thru3(
00183 const long sf1[8], const long sf2[8], const long sf3[8],
00184 const long sf1TransmitSOW, const int gpsWeek,
00185 const short PRN, const short track)
00186 {
00187 double ficked[60];
00188
00189
00190
00191
00192
00193 const long sf1Lead[2] = { 0x00000000, 0x00000900 };
00194 const long sf2Lead[2] = { 0x00000000, 0x00000A00 };
00195 const long sf3Lead[2] = { 0x00000000, 0x00000B00 };
00196 long subframe[10];
00197
00198
00199
00200
00201
00202
00203
00204
00205 long frameCount = sf1TransmitSOW / 30;
00206 long SF1HOWTime = (frameCount * 30) + 6;
00207
00208
00209 subframe[0] = sf1Lead[0];
00210 subframe[1] = sf1Lead[1];
00211 int i;
00212 for (i=0; i<8; ++i) subframe[i+2] = sf1[i];
00213
00214 if (!subframeConvert(subframe, gpsWeek, ficked))
00215 return false;
00216
00217 tlm_message[0] = 0;
00218 HOWtime[0] = SF1HOWTime;
00219 ASalert[0] = (short)ficked[3];
00220 weeknum = (short)ficked[5];
00221 codeflags = (short)ficked[6];
00222 accFlag = (short)ficked[7];
00223 health = (short)ficked[8];
00224 IODC = (short)ldexp(ficked[9],-11);
00225 L2Pdata = (short)ficked[10];
00226 Tgd = ficked[11];
00227 Toc = ficked[12];
00228 af2 = ficked[13];
00229 af1 = ficked[14];
00230 af0 = ficked[15];
00231 tracker = track;
00232 PRNID = PRN;
00233 haveSubframe[0] = true;
00234
00235 accuracy = gpstk::ura2accuracy(accFlag);
00236
00237
00238
00239 subframe[0] = sf2Lead[0];
00240 subframe[1] = sf2Lead[1];
00241 for (i=0; i<8; ++i) subframe[i+2] = sf2[i];
00242
00243 if (!subframeConvert(subframe, gpsWeek, ficked))
00244 return false;
00245
00246 tlm_message[1] = 0;
00247 HOWtime[1] = SF1HOWTime + 6;
00248 ASalert[1] = (short)ficked[3];
00249 IODE = (short)ldexp(ficked[5],-11);
00250 Crs = ficked[6];
00251 dn = ficked[7];
00252 M0 = ficked[8];
00253 Cuc = ficked[9];
00254 ecc = ficked[10];
00255 Cus = ficked[11];
00256 Ahalf = ficked[12];
00257 Toe = ficked[13];
00258 fitint = (short)ficked[14];
00259 haveSubframe[1] = true;
00260
00261
00262 subframe[0] = sf3Lead[0];
00263 subframe[1] = sf3Lead[1];
00264 for (i=0; i<8; ++i) subframe[i+2] = sf3[i];
00265
00266 if (!subframeConvert(subframe, gpsWeek, ficked))
00267 return false;
00268
00269 tlm_message[2] = 0;
00270 HOWtime[2] = SF1HOWTime + 12;
00271 ASalert[2] = (short)ficked[3];
00272 Cic = ficked[5];
00273 OMEGA0 = ficked[6];
00274 Cis = ficked[7];
00275 i0 = ficked[8];
00276 Crc = ficked[9];
00277 w = ficked[10];
00278 OMEGAdot = ficked[11];
00279 idot = ficked[13];
00280 haveSubframe[2] = true;
00281
00282 return true;
00283 }
00284
00285 bool EngEphemeris :: isData(short subframe) const
00286 throw(gpstk::InvalidRequest)
00287 {
00288 if ((subframe < 1) || (subframe > 3))
00289 {
00290 InvalidRequest exc("Subframe "+StringUtils::asString(subframe)+
00291 " is not a valid ephemeris subframe.");
00292 GPSTK_THROW(exc);
00293 }
00294
00295 return haveSubframe[subframe-1];
00296 }
00297
00298 void EngEphemeris :: setAccuracy(const double& acc)
00299 throw(gpstk::InvalidParameter)
00300 {
00301 if( acc < 0 )
00302 {
00303 InvalidParameter exc("SV Accuracy of " + StringUtils::asString(acc) +
00304 " meters is invalid.");
00305 GPSTK_THROW(exc);
00306 }
00307 accuracy = acc;
00308 accFlag = gpstk::accuracy2ura(acc);
00309 }
00310
00311 Xvt EngEphemeris :: svXvt(const DayTime& t) const
00312 throw(InvalidRequest)
00313 {
00314 Xvt sv;
00315
00316 double ea;
00317 double delea;
00318 double elapte;
00319 double elaptc;
00320 double dtc,dtr,q,sinea,cosea;
00321 double GSTA,GCTA;
00322 double A;
00323 double amm;
00324 double meana;
00325 double F,G;
00326 double alat,talat,c2al,s2al,du,dr,di,U,R,truea,AINC;
00327 double ANLON,cosu,sinu,xip,yip,can,san,cinc,sinc;
00328 double xef,yef,zef,dek,dlk,div,domk,duv,drv;
00329 double dxp,dyp,vxef,vyef,vzef;
00330 GPSGeoid geoid;
00331
00332 double sqrtgm = ::sqrt(geoid.gm());
00333
00334
00335 double twoPI = 2.0e0 * PI;
00336 bool igtran;
00337 double lecc;
00338 double tdrinc;
00339 if (getAhalf() < 2550.0e0 )
00340 {
00341 igtran = true;
00342 lecc = 0.0e0;
00343 tdrinc = 0.0e0;
00344 }
00345 else
00346 {
00347 igtran = false;
00348 lecc = getEcc();
00349 tdrinc = getIDot();
00350 }
00351
00352
00353 elapte = t - getEphemerisEpoch();
00354 elaptc = t - getEpochTime();
00355
00356
00357
00358 A = getA();
00359 amm = (sqrtgm / (A*getAhalf())) + getDn();
00360
00361
00362
00363
00364
00365
00366 if (!igtran)
00367 meana = getM0() + elapte * amm;
00368 else
00369 meana = getM0();
00370 meana = fmod(meana, twoPI);
00371
00372 ea = meana + lecc * ::sin(meana);
00373
00374 int loop_cnt = 1;
00375 do {
00376 F = meana - ( ea - lecc * ::sin(ea));
00377 G = 1.0 - lecc * ::cos(ea);
00378 delea = F/G;
00379 ea = ea + delea;
00380 loop_cnt++;
00381 } while ( (::fabs(delea) > 1.0e-11 ) && (loop_cnt <= 20) );
00382
00383
00384 sv.ddtime = getAf1() + elaptc * getAf2();
00385 dtc = getAf0() + elaptc * ( sv.ddtime );
00386 dtr = REL_CONST * lecc * getAhalf() * ::sin(ea);
00387 sv.dtime = dtc + dtr;
00388
00389
00390 q = ::sqrt ( 1.0e0 - lecc*lecc);
00391 sinea = ::sin(ea);
00392 cosea = ::cos(ea);
00393 G = 1.0e0 - lecc * cosea;
00394
00395
00396 GSTA = q * sinea;
00397 GCTA = cosea - lecc;
00398
00399
00400 truea = ::atan2 ( GSTA, GCTA );
00401
00402
00403 alat = truea + getW();
00404 talat = 2.0e0 * alat;
00405 c2al = ::cos( talat );
00406 s2al = ::sin( talat );
00407
00408 du = c2al * getCuc() + s2al * getCus();
00409 dr = c2al * getCrc() + s2al * getCrs();
00410 di = c2al * getCic() + s2al * getCis();
00411
00412
00413 U = alat + du;
00414 R = getA()*G + dr;
00415 AINC = getI0() + tdrinc * elapte + di;
00416
00417
00418 if (!igtran)
00419 ANLON = getOmega0() + (getOmegaDot() - geoid.angVelocity()) *
00420 elapte - geoid.angVelocity() * getToe();
00421 else
00422 ANLON = getOmega0() - getOmegaDot() * getToe();
00423
00424
00425 cosu = ::cos( U );
00426 sinu = ::sin( U );
00427
00428 xip = R * cosu;
00429 yip = R * sinu;
00430
00431
00432 can = ::cos( ANLON );
00433 san = ::sin( ANLON );
00434 cinc = ::cos( AINC );
00435 sinc = ::sin( AINC );
00436
00437
00438 xef = xip*can - yip*cinc*san;
00439 yef = xip*san + yip*cinc*can;
00440 zef = yip*sinc;
00441
00442 sv.x[0] = xef;
00443 sv.x[1] = yef;
00444 sv.x[2] = zef;
00445
00446
00447 dek = amm * A / R;
00448 dlk = getAhalf() * q * sqrtgm / (R*R);
00449 div = tdrinc - 2.0e0 * dlk *
00450 ( getCic() * s2al - getCis() * c2al );
00451 domk = getOmegaDot() - geoid.angVelocity();
00452 duv = dlk*(1.e0+ 2.e0 * (getCus()*c2al - getCuc()*s2al) );
00453 drv = A * lecc * dek * sinea - 2.e0 * dlk *
00454 ( getCrc() * s2al - getCrs() * c2al );
00455
00456 dxp = drv*cosu - R*sinu*duv;
00457 dyp = drv*sinu + R*cosu*duv;
00458
00459
00460 vxef = dxp*can - xip*san*domk - dyp*cinc*san
00461 + yip*( sinc*san*div - cinc*can*domk);
00462 vyef = dxp*san + xip*can*domk + dyp*cinc*can
00463 - yip*( sinc*can*div + cinc*san*domk);
00464 vzef = dyp*sinc + yip*cinc*div;
00465
00466
00467 sv.v[0] = vxef;
00468 sv.v[1] = vyef;
00469 sv.v[2] = vzef;
00470
00471 return sv;
00472 }
00473
00474 double EngEphemeris::svRelativity(const DayTime& t) const
00475 throw(gpstk::InvalidRequest)
00476 {
00477 GPSGeoid geoid;
00478 double twoPI = 2.0e0 * PI;
00479 double sqrtgm = ::sqrt(geoid.gm());
00480 double elapte = t - getEphemerisEpoch();
00481 double elaptc = t - getEpochTime();
00482 double A = getA();
00483 double amm = (sqrtgm / (A*getAhalf())) + getDn();
00484 double meana,lecc,F,G,delea;
00485
00486 if (getAhalf() < 2550.0e0 ) { lecc = 0.0e0; meana = getM0(); }
00487 else { lecc = getEcc(); meana = getM0() + elapte * amm; }
00488 meana = ::fmod(meana, twoPI);
00489 double ea = meana + lecc * ::sin(meana);
00490
00491 int loop_cnt = 1;
00492 do {
00493 F = meana - ( ea - lecc * ::sin(ea));
00494 G = 1.0 - lecc * ::cos(ea);
00495 delea = F/G;
00496 ea = ea + delea;
00497 loop_cnt++;
00498 } while ( (::fabs(delea) > 1.0e-11 ) && (loop_cnt <= 20) );
00499 double dtr = REL_CONST * lecc * getAhalf() * ::sin(ea);
00500 return dtr;
00501 }
00502
00503 double EngEphemeris::svClockBias(const DayTime& t) const
00504 throw(gpstk::InvalidRequest)
00505 {
00506 double dtc,elaptc;
00507 elaptc = t - getEpochTime();
00508 dtc = getAf0() + elaptc * ( getAf1() + elaptc * getAf2() );
00509
00510 return dtc;
00511 }
00512
00513 double EngEphemeris::svClockDrift(const DayTime& t) const
00514 throw(gpstk::InvalidRequest)
00515 {
00516 double drift,elaptc;
00517 elaptc = t - getEpochTime();
00518 drift = getAf1() + elaptc * getAf2();
00519 return drift;
00520 }
00521
00522 short EngEphemeris :: getFitInterval() const
00523 throw(InvalidRequest)
00524 {
00525 short iodc = getIODC();
00526 short fiti = getFitInt();
00527
00528
00529 if (iodc < 0 || iodc > 1023)
00530 {
00531
00532 return 4;
00533 }
00534
00535 if (((fiti == 0) &&
00536 (iodc & 0xFF) < 240 || (iodc & 0xFF) > 255 ))
00537 {
00538
00539 return 4;
00540 }
00541 else if (fiti == 1)
00542 {
00543 if( ((iodc & 0xFF) < 240 || (iodc & 0xFF) > 255))
00544 {
00545
00546 return 6;
00547 }
00548 else if(iodc >=240 && iodc <=247)
00549 {
00550
00551 return 8;
00552 }
00553 else if(iodc >= 248 && iodc <= 255 || iodc == 496)
00554 {
00555
00556 return 14;
00557 }
00558
00559 else if(iodc >= 497 && iodc <=503 || iodc >= 1021 && iodc <= 1023)
00560 {
00561
00562 return 26;
00563 }
00564 else if(iodc >= 504 && iodc <=510)
00565 {
00566
00567 return 50;
00568 }
00569 else if(iodc == 511 || iodc >= 752 && iodc <= 756)
00570 {
00571
00572 return 74;
00573 }
00574
00575
00576
00577
00578
00579
00580
00581 else if(iodc >= 757 && iodc <= 763)
00582 {
00583
00584 return 98;
00585 }
00586 else if(iodc >= 764 && iodc <=767 || iodc >=1008 && iodc <=1010)
00587 {
00588
00589 return 122;
00590 }
00591 else if(iodc >= 1011 && iodc <=1020)
00592 {
00593
00594 return 146;
00595 }
00596 else
00597 {
00598
00599
00600 return 4;
00601 }
00602 }
00603 else
00604 {
00605
00606 return 4;
00607 }
00608
00609 return 0;
00610 }
00611
00612 unsigned EngEphemeris::getTLMMessage(short subframe) const
00613 throw(InvalidRequest)
00614 {
00615 if (!haveSubframe[subframe-1])
00616 {
00617 InvalidRequest exc("Subframe "+StringUtils::asString(subframe)+
00618 " not stored.");
00619 GPSTK_THROW(exc);
00620 }
00621 return tlm_message[subframe-1];
00622 }
00623
00624 DayTime EngEphemeris::getTransmitTime() const
00625 throw(InvalidRequest)
00626 {
00627 DayTime toReturn(0.L);
00628 toReturn.setGPSfullweek(getFullWeek(), (double)getTot());
00629 return toReturn;
00630 }
00631
00632 DayTime EngEphemeris::getEpochTime() const
00633 throw(InvalidRequest)
00634 {
00635 DayTime toReturn(0.L);
00636 if ( (getToc() - getHOWTime(1)) < -DayTime::HALFWEEK)
00637 toReturn.setGPSfullweek(getFullWeek() + 1, getToc());
00638 else if ( (getToc() - getHOWTime(1)) > DayTime::HALFWEEK)
00639 toReturn.setGPSfullweek(getFullWeek() - 1, getToc());
00640 else
00641 toReturn.setGPSfullweek(getFullWeek(), getToc());
00642 return toReturn;
00643 }
00644
00645 DayTime EngEphemeris::getEphemerisEpoch() const
00646 throw(InvalidRequest)
00647 {
00648 DayTime toReturn(0.L);
00649 if ( (getToe() - getHOWTime(1)) < -DayTime::HALFWEEK)
00650 toReturn.setGPSfullweek(getFullWeek() + 1, getToe());
00651 else if ( (getToe() - getHOWTime(1)) > DayTime::HALFWEEK)
00652 toReturn.setGPSfullweek(getFullWeek() - 1, getToe());
00653 else
00654 toReturn.setGPSfullweek(getFullWeek(), getToe());
00655 return toReturn;
00656 }
00657
00658 short EngEphemeris::getPRNID() const
00659 throw(InvalidRequest)
00660 {
00661 if(!haveSubframe[0])
00662 {
00663 InvalidRequest exc("Required subframe 1 not stored.");
00664 GPSTK_THROW(exc);
00665 }
00666 return PRNID;
00667 }
00668
00669 short EngEphemeris::getTracker() const
00670 throw(InvalidRequest)
00671 {
00672 if(!haveSubframe[0])
00673 {
00674 InvalidRequest exc("Required subframe 1 not stored.");
00675 GPSTK_THROW(exc);
00676 }
00677 return tracker;
00678 }
00679
00680 double EngEphemeris::getHOWTime(short subframe) const
00681 throw(InvalidRequest)
00682 {
00683 if (!haveSubframe[subframe-1])
00684 {
00685 InvalidRequest exc("Subframe "+StringUtils::asString(subframe)+
00686 " not stored.");
00687 GPSTK_THROW(exc);
00688 }
00689
00690
00691 return (double) HOWtime[subframe-1];
00692 }
00693
00694 short EngEphemeris::getASAlert(short subframe) const
00695 throw(InvalidRequest)
00696 {
00697 if (!haveSubframe[subframe-1])
00698 {
00699 InvalidRequest exc("Subframe "+StringUtils::asString(subframe)+
00700 " not stored.");
00701 GPSTK_THROW(exc);
00702 }
00703 return ASalert[subframe-1];
00704 }
00705
00706 short EngEphemeris::getFullWeek() const
00707 throw(InvalidRequest)
00708 {
00709 if (!haveSubframe[0])
00710 {
00711 InvalidRequest exc("Required subframe 1 not stored.");
00712 GPSTK_THROW(exc);
00713 }
00714 return weeknum;
00715 }
00716
00717 short EngEphemeris::getCodeFlags() const
00718 throw(InvalidRequest)
00719 {
00720 if (!haveSubframe[0])
00721 {
00722 InvalidRequest exc("Required subframe 1 not stored.");
00723 GPSTK_THROW(exc);
00724 }
00725 return codeflags;
00726 }
00727
00728 double EngEphemeris::getAccuracy() const
00729 throw(InvalidRequest)
00730 {
00731 if (!haveSubframe[0])
00732 {
00733 InvalidRequest exc("Required subframe 1 not stored.");
00734 GPSTK_THROW(exc);
00735 }
00736 return accuracy;
00737 }
00738
00739 short EngEphemeris::getAccFlag() const
00740 throw(InvalidRequest)
00741 {
00742 if (!haveSubframe[0])
00743 {
00744 InvalidRequest exc("Required subframe 1 not stored.");
00745 GPSTK_THROW(exc);
00746 }
00747 return accFlag;
00748 }
00749
00750 short EngEphemeris::getHealth() const
00751 throw(InvalidRequest)
00752 {
00753 if (!haveSubframe[0])
00754 {
00755 InvalidRequest exc("Required subframe 1 not stored.");
00756 GPSTK_THROW(exc);
00757 }
00758 return health;
00759 }
00760
00761 short EngEphemeris::getL2Pdata() const
00762 throw(InvalidRequest)
00763 {
00764 if (!haveSubframe[0])
00765 {
00766 InvalidRequest exc("Required subframe 1 not stored.");
00767 GPSTK_THROW(exc);
00768 }
00769 return L2Pdata;
00770 }
00771
00772 short EngEphemeris::getIODC() const
00773 throw(InvalidRequest)
00774 {
00775 if (!haveSubframe[0])
00776 {
00777 InvalidRequest exc("Required subframe 1 not stored.");
00778 GPSTK_THROW(exc);
00779 }
00780 return (short)IODC;
00781 }
00782
00783 short EngEphemeris::getIODE() const
00784 throw(InvalidRequest)
00785 {
00786 if (!haveSubframe[1])
00787 {
00788 InvalidRequest exc("Required subframe 2 not stored.");
00789 GPSTK_THROW(exc);
00790 }
00791 return (short)IODE;
00792 }
00793
00794 long EngEphemeris::getAODO() const
00795 throw(InvalidRequest)
00796 {
00797 if (!haveSubframe[1])
00798 {
00799 InvalidRequest exc("Required subframe 2 not stored.");
00800 GPSTK_THROW(exc);
00801 }
00802 return AODO;
00803 }
00804
00805 double EngEphemeris::getToc() const
00806 throw(InvalidRequest)
00807 {
00808 if (!haveSubframe[0])
00809 {
00810 InvalidRequest exc("Required subframe 1 not stored.");
00811 GPSTK_THROW(exc);
00812 }
00813 return Toc;
00814 }
00815
00816 double EngEphemeris::getAf0() const
00817 throw(InvalidRequest)
00818 {
00819 if (!haveSubframe[0])
00820 {
00821 InvalidRequest exc("Required subframe 1 not stored.");
00822 GPSTK_THROW(exc);
00823 }
00824 return af0;
00825 }
00826
00827 double EngEphemeris::getAf1() const
00828 throw(InvalidRequest)
00829 {
00830 if (!haveSubframe[0])
00831 {
00832 InvalidRequest exc("Required subframe 1 not stored.");
00833 GPSTK_THROW(exc);
00834 }
00835 return af1;
00836 }
00837
00838 double EngEphemeris::getAf2() const
00839 throw(InvalidRequest)
00840 {
00841 if (!haveSubframe[0])
00842 {
00843 InvalidRequest exc("Required subframe 1 not stored.");
00844 GPSTK_THROW(exc);
00845 }
00846 return af2;
00847 }
00848
00849 double EngEphemeris::getTgd() const
00850 throw(InvalidRequest)
00851 {
00852 if (!haveSubframe[0])
00853 {
00854 InvalidRequest exc("Required subframe 1 not stored.");
00855 GPSTK_THROW(exc);
00856 }
00857 return Tgd;
00858 }
00859
00860 double EngEphemeris::getCus() const
00861 throw(InvalidRequest)
00862 {
00863 if (!haveSubframe[1])
00864 {
00865 InvalidRequest exc("Required subframe 2 not stored.");
00866 GPSTK_THROW(exc);
00867 }
00868 return Cus;
00869 }
00870
00871 double EngEphemeris::getCrs() const
00872 throw(InvalidRequest)
00873 {
00874 if (!haveSubframe[1])
00875 {
00876 InvalidRequest exc("Required subframe 2 not stored.");
00877 GPSTK_THROW(exc);
00878 }
00879 return Crs;
00880 }
00881
00882 double EngEphemeris::getCis() const
00883 throw(InvalidRequest)
00884 {
00885 if (!haveSubframe[2])
00886 {
00887 InvalidRequest exc("Required subframe 3 not stored.");
00888 GPSTK_THROW(exc);
00889 }
00890 return Cis;
00891 }
00892
00893 double EngEphemeris::getCrc() const
00894 throw(InvalidRequest)
00895 {
00896 if (!haveSubframe[2])
00897 {
00898 InvalidRequest exc("Required subframe 3 not stored.");
00899 GPSTK_THROW(exc);
00900 }
00901 return Crc;
00902 }
00903
00904 double EngEphemeris::getCuc() const
00905 throw(InvalidRequest)
00906 {
00907 if (!haveSubframe[1])
00908 {
00909 InvalidRequest exc("Required subframe 2 not stored.");
00910 GPSTK_THROW(exc);
00911 }
00912 return Cuc;
00913 }
00914
00915 double EngEphemeris::getCic() const
00916 throw(InvalidRequest)
00917 {
00918 if (!haveSubframe[2])
00919 {
00920 InvalidRequest exc("Required subframe 3 not stored.");
00921 GPSTK_THROW(exc);
00922 }
00923 return Cic;
00924 }
00925
00926 double EngEphemeris::getToe() const
00927 throw(InvalidRequest)
00928 {
00929 if (!haveSubframe[1])
00930 {
00931 InvalidRequest exc("Required subframe 2 not stored.");
00932 GPSTK_THROW(exc);
00933 }
00934 return Toe;
00935 }
00936
00937 double EngEphemeris::getM0() const
00938 throw(InvalidRequest)
00939 {
00940 if (!haveSubframe[1])
00941 {
00942 InvalidRequest exc("Required subframe 2 not stored.");
00943 GPSTK_THROW(exc);
00944 }
00945 return M0;
00946 }
00947
00948 double EngEphemeris::getDn() const
00949 throw(InvalidRequest)
00950 {
00951 if (!haveSubframe[1])
00952 {
00953 InvalidRequest exc("Required subframe 2 not stored.");
00954 GPSTK_THROW(exc);
00955 }
00956 return dn;
00957 }
00958
00959 double EngEphemeris::getEcc() const
00960 throw(InvalidRequest)
00961 {
00962 if (!haveSubframe[1])
00963 {
00964 InvalidRequest exc("Required subframe 2 not stored.");
00965 GPSTK_THROW(exc);
00966 }
00967 return ecc;
00968 }
00969
00970 double EngEphemeris::getAhalf() const
00971 throw(InvalidRequest)
00972 {
00973 if (!haveSubframe[1])
00974 {
00975 InvalidRequest exc("Required subframe 2 not stored.");
00976 GPSTK_THROW(exc);
00977 }
00978 return Ahalf;
00979 }
00980
00981 double EngEphemeris::getA() const
00982 throw(InvalidRequest)
00983 {
00984 if (!haveSubframe[1])
00985 {
00986 InvalidRequest exc("Required subframe 2 not stored.");
00987 GPSTK_THROW(exc);
00988 }
00989 return Ahalf * Ahalf;
00990 }
00991
00992 double EngEphemeris::getOmega0() const
00993 throw(InvalidRequest)
00994 {
00995 if (!haveSubframe[2])
00996 {
00997 InvalidRequest exc("Required subframe 3 not stored.");
00998 GPSTK_THROW(exc);
00999 }
01000 return OMEGA0;
01001 }
01002
01003 double EngEphemeris::getI0() const
01004 throw(InvalidRequest)
01005 {
01006 if (!haveSubframe[2])
01007 {
01008 InvalidRequest exc("Required subframe 3 not stored.");
01009 GPSTK_THROW(exc);
01010 }
01011 return i0;
01012 }
01013
01014 double EngEphemeris::getW() const
01015 throw(InvalidRequest)
01016 {
01017 if (!haveSubframe[2])
01018 {
01019 InvalidRequest exc("Required subframe 3 not stored.");
01020 GPSTK_THROW(exc);
01021 }
01022 return w;
01023 }
01024
01025 double EngEphemeris::getOmegaDot() const
01026 throw(InvalidRequest)
01027 {
01028 if (!haveSubframe[2])
01029 {
01030 InvalidRequest exc("Required subframe 3 not stored.");
01031 GPSTK_THROW(exc);
01032 }
01033 return OMEGAdot;
01034 }
01035
01036 double EngEphemeris::getIDot() const
01037 throw(InvalidRequest)
01038 {
01039 if (!haveSubframe[2])
01040 {
01041 InvalidRequest exc("Required subframe 3 not stored.");
01042 GPSTK_THROW(exc);
01043 }
01044 return idot;
01045 }
01046
01047 short EngEphemeris::getFitInt() const
01048 throw(InvalidRequest)
01049 {
01050 if (!haveSubframe[1])
01051 {
01052 InvalidRequest exc("Required subframe 2 not stored.");
01053 GPSTK_THROW(exc);
01054 }
01055 return fitint;
01056 }
01057
01058 long EngEphemeris::getTot() const
01059 throw(InvalidRequest)
01060 {
01061 if(!haveSubframe[0])
01062 {
01063 InvalidRequest exc("Required subframe 1 not stored.");
01064 GPSTK_THROW(exc);
01065 }
01066 if(!haveSubframe[1])
01067 {
01068 InvalidRequest exc("Required subframe 2 not stored.");
01069 GPSTK_THROW(exc);
01070 }
01071 if(!haveSubframe[2])
01072 {
01073 InvalidRequest exc("Required subframe 3 not stored.");
01074 GPSTK_THROW(exc);
01075 }
01076
01077
01078 #ifdef _MSC_VER
01079 long foo = static_cast<long>( getHOWTime(1) < getHOWTime(2) ) ? getHOWTime(1) : getHOWTime(2);
01080 foo = ( foo < getHOWTime(3) ) ? foo : getHOWTime(3) ;
01081 #else
01082 long foo =
01083 static_cast<long>( std::min( getHOWTime(1),
01084 std::min( getHOWTime(2), getHOWTime(3) ) ) );
01085 #endif
01086
01087 foo/=30;
01088 foo*=30;
01089 return foo;
01090 }
01091
01092 EngEphemeris& EngEphemeris::setSF1( unsigned tlm, double how, short asalert,
01093 short fullweek, short cflags, short acc,
01094 short svhealth, short iodc, short l2pdata,
01095 double tgd, double toc, double Af2,
01096 double Af1, double Af0, short Tracker,
01097 short prn )
01098 throw()
01099 {
01100
01101 tlm_message[0] = tlm;
01102 HOWtime[0] = static_cast<long>( how );
01103 ASalert[0] = asalert;
01104 weeknum = fullweek;
01105 codeflags = cflags;
01106 accFlag = acc;
01107 health = svhealth;
01108 IODC = iodc;
01109 L2Pdata = l2pdata;
01110 Tgd = tgd;
01111 Toc = toc;
01112 af2 = Af2;
01113 af1 = Af1;
01114 af0 = Af0;
01115 tracker = Tracker;
01116 PRNID = prn;
01117 haveSubframe[0] = true;
01118
01119 accuracy = gpstk::ura2accuracy(accFlag);
01120 return *this;
01121 }
01122
01123 EngEphemeris& EngEphemeris::setSF2( unsigned tlm, double how, short asalert,
01124 short iode, double crs, double Dn,
01125 double m0, double cuc, double Ecc,
01126 double cus, double ahalf, double toe,
01127 short fitInt )
01128 throw()
01129 {
01130 tlm_message[1] = tlm;
01131 HOWtime[1] = static_cast<long>( how );
01132 ASalert[1] = asalert;
01133 IODE = iode;
01134 Crs = crs;
01135 dn = Dn;
01136 M0 = m0;
01137 Cuc = cuc;
01138 ecc = Ecc;
01139 Cus = cus;
01140 Ahalf = ahalf;
01141 Toe = toe;
01142 fitint = fitInt;
01143 haveSubframe[1] = true;
01144 return *this;
01145 }
01146
01147
01148 EngEphemeris& EngEphemeris::setSF3( unsigned tlm, double how, short asalert,
01149 double cic, double Omega0, double cis,
01150 double I0, double crc, double W,
01151 double OmegaDot, double IDot )
01152 throw()
01153 {
01154 tlm_message[2] = tlm;
01155 HOWtime[2] = static_cast<long>( how );
01156 ASalert[2] = asalert;
01157 Cic = cic;
01158 OMEGA0 = Omega0;
01159 Cis = cis;
01160 i0 = I0;
01161 Crc = crc;
01162 w = W;
01163 OMEGAdot = OmegaDot;
01164 idot = IDot;
01165 haveSubframe[2] = true;
01166 return *this;
01167 }
01168
01169 static void timeDisplay( ostream & os, const gpstk::DayTime& t)
01170 {
01171
01172 os << setw(4) << t.GPSfullweek() << "(";
01173 os << setw(4) << t.GPS10bitweek() << ") ";
01174 os << setw(6) << setfill(' ') << t.GPSsecond() << " ";
01175
01176 switch (t.GPSday())
01177 {
01178 case 0: os << "Sun-0"; break;
01179 case 1: os << "Mon-1"; break;
01180 case 2: os << "Tue-2"; break;
01181 case 3: os << "Wed-3"; break;
01182 case 4: os << "Thu-4"; break;
01183 case 5: os << "Fri-5"; break;
01184 case 6: os << "Sat-6"; break;
01185 default: break;
01186 }
01187 os << " " << t.printf("%3j %5.0s %02m/%02d/%04Y %02H:%02M:%02S");
01188 }
01189
01190
01191 static void shortcut(ostream & os, const long HOW )
01192 {
01193 short DOW, hour, min, sec;
01194 long SOD, SOW;
01195 short SOH;
01196
01197 SOW = static_cast<long>( HOW );
01198 DOW = static_cast<short>( SOW / DayTime::SEC_DAY );
01199 SOD = SOW - static_cast<long>( DOW * DayTime::SEC_DAY );
01200 hour = static_cast<short>( SOD/3600 );
01201
01202 SOH = static_cast<short>( SOD - (hour*3600) );
01203 min = SOH/60;
01204
01205 sec = SOH - min * 60;
01206 switch (DOW)
01207 {
01208 case 0: os << "Sun-0"; break;
01209 case 1: os << "Mon-1"; break;
01210 case 2: os << "Tue-2"; break;
01211 case 3: os << "Wed-3"; break;
01212 case 4: os << "Thu-4"; break;
01213 case 5: os << "Fri-5"; break;
01214 case 6: os << "Sat-6"; break;
01215 default: break;
01216 }
01217
01218 os << ":" << setfill('0')
01219 << setw(2) << hour
01220 << ":" << setw(2) << min
01221 << ":" << setw(2) << sec
01222 << setfill(' ');
01223 }
01224
01225 void EngEphemeris :: dump(ostream& s) const
01226 {
01227 ios::fmtflags oldFlags = s.flags();
01228
01229 s.setf(ios::fixed, ios::floatfield);
01230 s.setf(ios::right, ios::adjustfield);
01231 s.setf(ios::uppercase);
01232 s.precision(0);
01233 s.fill(' ');
01234
01235 s << "****************************************************************"
01236 << "************" << endl
01237 << "Broadcast Ephemeris (Engineering Units)" << endl
01238 << endl
01239 << "PRN : " << setw(2) << PRNID << endl
01240 << endl;
01241
01242
01243 s << " Week(10bt) SOW DOW UTD SOD"
01244 << " MM/DD/YYYY HH:MM:SS\n";
01245 s << "Clock Epoch: ";
01246 timeDisplay(s, getEpochTime());
01247 s << endl;
01248 s << "Eph Epoch: ";
01249 timeDisplay(s, getEphemerisEpoch());
01250 s << endl;
01251
01252 #if 0
01253
01254
01255
01256 s << "Transmit time:" << setw(4) << weeknum << ", sow=" << Tot.GPSsecond() << endl
01257 << "Fit interval flag : " << setw(2) << fitint
01258 << " (" << fitintlen << " hours)" << endl;
01259 #elsif 0
01260 s << "Transmit time:" << setw(4) << weeknum << endl
01261 << "Fit interval flag : " << setw(2) << fitint
01262 << " (" << getFitInt() << " hours)" << endl;
01263 #endif
01264
01265 s << "Transmit Week:" << setw(4) << weeknum << endl
01266 << "Fit interval flag : " << fitint << endl;
01267
01268 s << endl
01269 << " SUBFRAME OVERHEAD"
01270 << endl
01271 << endl
01272 << " SOW DOW:HH:MM:SS IOD ALERT A-S\n";
01273 for (int i=0;i<3;i++)
01274 {
01275 s << "SF" << setw(1) << (i+1)
01276 << " HOW: " << setw(7) << HOWtime[i]
01277 << " ";
01278
01279 shortcut( s, HOWtime[i]);
01280 if (i==0)
01281 s << " ";
01282 else
01283 s << " ";
01284
01285 s << "0x" << setfill('0') << hex;
01286
01287 if (i==0)
01288 s << setw(3) << IODC;
01289 else
01290 s << setw(2) << IODE;
01291
01292 s << dec << " " << setfill(' ');
01293
01294 if (ASalert[i] & 0x0002)
01295 s << "1 ";
01296 else
01297 s << "0 ";
01298
01299 if (ASalert[i] & 0x0001)
01300 s << " on";
01301 else
01302 s << "off";
01303 s << endl;
01304 }
01305
01306 s.setf(ios::scientific, ios::floatfield);
01307 s.precision(8);
01308
01309 s << endl
01310 << " CLOCK"
01311 << endl
01312 << endl
01313 << "Bias T0: " << setw(16) << af0 << " sec" << endl
01314 << "Drift: " << setw(16) << af1 << " sec/sec" << endl
01315 << "Drift rate: " << setw(16) << af2 << " sec/(sec**2)" << endl
01316 << "Group delay: " << setw(16) << Tgd << " sec" << endl;
01317
01318 s << endl
01319 << " ORBIT PARAMETERS"
01320 << endl
01321 << endl
01322 << "Semi-major axis: " << setw(16) << Ahalf << " m**.5" << endl
01323 << "Motion correction: " << setw(16) << dn << " rad/sec"
01324 << endl
01325 << "Eccentricity: " << setw(16) << ecc << endl
01326 << "Arg of perigee: " << setw(16) << w << " rad" << endl
01327 << "Mean anomaly at epoch: " << setw(16) << M0 << " rad" << endl
01328 << "Right ascension: " << setw(16) << OMEGA0 << " rad "
01329 << setw(16) << OMEGAdot << " rad/sec" << endl
01330 << "Inclination: " << setw(16) << i0 << " rad "
01331 << setw(16) << idot << " rad/sec" << endl;
01332
01333 s << endl
01334 << " HARMONIC CORRECTIONS"
01335 << endl
01336 << endl
01337 << "Radial Sine: " << setw(16) << Crs << " m Cosine: "
01338 << setw(16) << Crc << " m" << endl
01339 << "Inclination Sine: " << setw(16) << Cis << " rad Cosine: "
01340 << setw(16) << Cic << " rad" << endl
01341 << "In-track Sine: " << setw(16) << Cus << " rad Cosine: "
01342 << setw(16) << Cuc << " rad" << endl;
01343
01344 s << endl
01345 << " SV STATUS"
01346 << endl
01347 << endl
01348 << "Health bits: 0x" << setfill('0') << setw(2) << health
01349 << " URA index: " << setfill(' ') << setw(4) << accFlag << endl
01350 << "Code on L2: ";
01351
01352 switch (codeflags)
01353 {
01354 case 0:
01355 s << "reserved ";
01356 break;
01357
01358 case 1:
01359 s << " P only ";
01360 break;
01361
01362 case 2:
01363 s << " C/A only";
01364 break;
01365
01366 case 3:
01367 s << " P & C/A ";
01368 break;
01369
01370 default:
01371 break;
01372
01373 }
01374
01375 s << " L2 P Nav data: ";
01376 if (L2Pdata!=0)
01377 s << "off";
01378 else
01379 s << "on";
01380
01381 s << endl
01382 << endl;
01383 s.flags(oldFlags);
01384
01385 }
01386
01387 ostream& operator<<(ostream& s, const EngEphemeris& eph)
01388 {
01389 eph.dump(s);
01390 return s;
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404 }
01405
01406 }