// Casts Rinex3NavData to a QZSEphemeris object. Rinex3NavData::operator QZSEphemeris() const throw() { QZSEphemeris qzse; // fill the OrbitEph parts castTo(dynamic_cast<OrbitEph*>(&qzse)); // is it right? if(qzse.satID.system != SatID::systemQZSS) qzse.dataLoadedFlag = false; if(!qzse.dataLoadedFlag) return qzse; // throw? // get the epochs right CommonTime ct = time; unsigned int year = static_cast<CivilTime>(ct).year; // Get week for clock, to build Toc double dt = Toc - HOWtime; int week = weeknum; if(dt < -HALFWEEK) week++; else if(dt > HALFWEEK) week--; QZSWeekSecond qzsws = QZSWeekSecond(week, Toc, TimeSystem::QZS); qzsws.adjustToYear(year); qzse.ctToc = CommonTime(qzsws); //MGEX NB MGEX data has GPS week numbers in all systems except BeiDou, //MGEX so must implement temporary fixes: use GPS Toc for QZS and QZSS CommonTime gpstoc = GPSWeekSecond(week, Toc, TimeSystem::GPS); //MGEX qzse.ctToc = gpstoc; //MGEX qzse.ctToc.setTimeSystem(TimeSystem::QZS); // now load the QZSS-specific parts qzse.satID = SatID(qzse.satID.id + 192, SatID::systemQZSS); qzse.IODC = IODC; qzse.IODE = IODE; qzse.health = health; qzse.accuracy = accuracy; qzse.Tgd = Tgd; qzse.HOWtime = HOWtime; week = static_cast<QZSWeekSecond>(qzse.ctToe).getWeek(); qzse.transmitTime = QZSWeekSecond(week, static_cast<double>(HOWtime), TimeSystem::QZS); qzse.codeflags = codeflgs; qzse.L2Pdata = L2Pdata; // NB IODC must be set first... qzse.fitint = fitint; qzse.setFitIntervalFlag(int(fitint)); // calls adjustValidity(); return qzse; }
// Casts Rinex3NavData to a GalEphemeris object. Rinex3NavData::operator GalEphemeris() const throw() { GalEphemeris gale; // fill the OrbitEph parts OrbitEph *ptr = dynamic_cast<OrbitEph*>(&gale); castTo(ptr); // sets dataLoadedFlag // is it right? if(gale.satID.system != SatID::systemGalileo) gale.dataLoadedFlag = false; if(!gale.dataLoadedFlag) return gale; // throw? // get the epochs right CommonTime ct = time; //unsigned int year = static_cast<CivilTime>(ct).year; // Get week for clock, to build Toc double dt = Toc - HOWtime; int week = weeknum; if(dt < -HALFWEEK) week++; else if(dt > HALFWEEK) week--; //MGEX NB MGEX data has GPS week numbers in all systems except BeiDou, //MGEX so must implement temporary fixes: use GPS Toc for GAL and QZSS //MGEX GALWeekSecond galws = GALWeekSecond(week, Toc, TimeSystem::GAL); //MGEX galws.adjustToYear(year); //MGEX gale.ctToc = CommonTime(galws); CommonTime gpstoc = GPSWeekSecond(week, Toc, TimeSystem::GPS); //MGEX gale.ctToc = gpstoc; //MGEX gale.ctToc.setTimeSystem(TimeSystem::GAL); // now load the Galileo-specific parts gale.IODnav = IODnav; gale.health = health; gale.accuracy = accuracy; gale.Tgda = Tgd; gale.Tgdb = Tgd2; gale.datasources = datasources; gale.fitDuration = 4; gale.HOWtime = HOWtime; week = static_cast<GALWeekSecond>(gale.ctToe).getWeek(); gale.transmitTime = GALWeekSecond(week, static_cast<double>(HOWtime), TimeSystem::GAL); gale.adjustValidity(); return gale; }
// adjustBeginningValidity determines the beginValid and endValid times. // @throw Invalid Request if the required data has not been stored. void GPSEphemeris::adjustValidity(void) { try { OrbitEph::adjustValidity(); // for dataLoaded check // Beginning of Validity // New concept. Admit the following. // (a.) The collection system may not capture the data at earliest transmit. // (b.) The collection system may not capture the three SFs consecutively. // Consider a couple of IS-GPS-200 promises, // (c.) By definition, beginning of validity == beginning of transmission. // (d.) Except for uploads, cutovers will only happen on hour boundaries // (e.) Cutovers can be detected by non-even Toc. // (f.) Even uploads will cutover on a frame (30s) boundary. // Therefore, // 1.) If Toc is NOT even two hour interval, pick lowest HOW time, // round back to even 30s. That's the earliest Xmit time we can prove. // NOTE: For the case where this is the SECOND SF 1/2/3 after an upload, // this may yield a later time as such a SF 1/2/3 will be on a even // hour boundary. Unfortunately, we have no way of knowing whether // this item is first or second after upload without additional information // 2.) If Toc IS even two hour interval, pick time from SF 1, // round back to nearest EVEN two hour boundary. This assumes collection // SOMETIME in first hour of transmission. Could be more // complete by looking at fit interval and IODC to more accurately // determine earliest transmission time. long longToc = static_cast<GPSWeekSecond>(ctToc).getSOW(); long XmitWeek = static_cast<GPSWeekSecond>(transmitTime).getWeek(); double XmitSOW = 0.0; if ( (longToc % 7200) != 0) // NOT an even two hour change { long Xmit = HOWtime - (HOWtime % 30); XmitSOW = (double) Xmit; } else { long Xmit = HOWtime - HOWtime % 7200; XmitSOW = (double) Xmit; } beginValid = GPSWeekSecond( XmitWeek, XmitSOW, TimeSystem::GPS ); // End of Validity. // The end of validity is calculated from the fit interval // and the Toe. The fit interval is either trivial // (if fit interval flag==0, fit interval is 4 hours) // or a look-up table based on the IODC. // Round the Toe value to the hour to elminate confusion // due to possible "small offsets" indicating uploads long epochWeek = static_cast<GPSWeekSecond>(ctToe).getWeek(); double Toe = static_cast<GPSWeekSecond>(ctToe).getSOW(); long ToeOffset = (long) Toe % 3600; double adjToe = Toe; // Default case if (ToeOffset) { adjToe += 3600.0 - (double)ToeOffset; // If offset, then adjust to remove } long endFitSOW = adjToe + (fitDuration/2)*3600; short endFitWk = epochWeek; if (endFitSOW >= FULLWEEK) { endFitSOW -= FULLWEEK; endFitWk++; } endValid = GPSWeekSecond(endFitWk, endFitSOW, TimeSystem::GPS); } catch(Exception& e) { GPSTK_RETHROW(e); } }
// BDS is different in that some satellites are in GEO orbits. // According to the ICD, the // SV position derivation for MEO and IGSO is identical to // that for other kepler+perturbation systems (e.g. GPS); however, // the position derivation for the GEO SVs is different. // According to the ICD, the GEO SVs are those with PRNs 1-5. // The following method overrides OrbitEph.svXvt( ). It uses // OrbitEph::svXvt( ) for PRNs above 5, but implements a different // algorithm for PRNs 1-5. Xvt BDSEphemeris::svXvt(const CommonTime& t) const { if(!dataLoadedFlag) GPSTK_THROW(InvalidRequest("Data not loaded")); // If the PRN ID is greatet than 5, assume this // is a MEO or IGSO SV and use the standard OrbitEph // version of svXvt if (satID.id>5) return(OrbitEph::svXvt(t)); // If PRN ID is in the range 1-5, treat this as a GEO // // The initial calculations are identical to the standard // Kepler+preturbation model Xvt sv; double ea; // eccentric anomaly double delea; // delta eccentric anomaly during iteration double elapte; // elapsed time since Toe //double elaptc; // elapsed time since Toc //double dtc,dtr; double q,sinea,cosea; double GSTA,GCTA; double amm; double meana; // mean anomaly double F,G; // temporary real variables double alat,talat,c2al,s2al,du,dr,di,U,R,truea,AINC; double ANLON,cosu,sinu,xip,yip,can,san,cinc,sinc; double dek,dlk,div,duv,drv; double dxp,dyp; double xGK,yGK,zGK; WGS84Ellipsoid ell; double sqrtgm = SQRT(ell.gm()); double twoPI = 2.0e0 * PI; double lecc; // eccentricity double tdrinc; // dt inclination double Ahalf = SQRT(A); // A is semi-major axis of orbit double ToeSOW = GPSWeekSecond(ctToe).sow; // SOW is time-system-independent lecc = ecc; tdrinc = idot; // Compute time since ephemeris & clock epochs elapte = t - ctToe; // Compute mean motion amm = (sqrtgm / (A*Ahalf)) + dn; // In-plane angles // meana - Mean anomaly // ea - Eccentric anomaly // truea - True anomaly meana = M0 + elapte * amm; meana = fmod(meana, twoPI); ea = meana + lecc * ::sin(meana); int loop_cnt = 1; do { F = meana - (ea - lecc * ::sin(ea)); G = 1.0 - lecc * ::cos(ea); delea = F/G; ea = ea + delea; loop_cnt++; } while ((fabs(delea) > 1.0e-11) && (loop_cnt <= 20)); // Compute clock corrections sv.relcorr = svRelativity(t); sv.clkbias = svClockBias(t); sv.clkdrift = svClockDrift(t); sv.frame = ReferenceFrame::WGS84; // Compute true anomaly q = SQRT(1.0e0 - lecc*lecc); sinea = ::sin(ea); cosea = ::cos(ea); G = 1.0e0 - lecc * cosea; // G*SIN(TA) AND G*COS(TA) GSTA = q * sinea; GCTA = cosea - lecc; // True anomaly truea = atan2 (GSTA, GCTA); // Argument of lat and correction terms (2nd harmonic) alat = truea + w; talat = 2.0e0 * alat; c2al = ::cos(talat); s2al = ::sin(talat); du = c2al * Cuc + s2al * Cus; dr = c2al * Crc + s2al * Crs; di = c2al * Cic + s2al * Cis; // U = updated argument of lat, R = radius, AINC = inclination U = alat + du; R = A*G + dr; AINC = i0 + tdrinc * elapte + di; // At this point, the ICD formulation diverges to something // different. // Longitude of ascending node (ANLON) ANLON = OMEGA0 + OMEGAdot * elapte - ell.angVelocity() * ToeSOW; // In plane location cosu = ::cos(U); sinu = ::sin(U); xip = R * cosu; yip = R * sinu; // Angles for rotation can = ::cos(ANLON); san = ::sin(ANLON); cinc = ::cos(AINC); sinc = ::sin(AINC); // GEO satellite coordinates in user-defined inertial system xGK = xip*can - yip*cinc*san; yGK = xip*san + yip*cinc*can; zGK = yip*sinc; // Rz matrix double angleZ = ell.angVelocity() * elapte; double cosZ = ::cos(angleZ); double sinZ = ::sin(angleZ); // Initiailize 3X3 with all 0.0 gpstk::Matrix<double> matZ(3,3); // Row,Col matZ(0,0) = cosZ; matZ(0,1) = sinZ; matZ(0,2) = 0.0; matZ(1,0) = -sinZ; matZ(1,1) = cosZ; matZ(1,2) = 0.0; matZ(2,0) = 0.0; matZ(2,1) = 0.0; matZ(2,2) = 1.0; // Rx matrix double angleX = -5.0 * PI/180.0; /// This is a constant. Should set it once double cosX = ::cos(angleX); double sinX = ::sin(angleX); gpstk::Matrix<double> matX(3,3); matX(0,0) = 1.0; matX(0,1) = 0.0; matX(0,2) = 0.0; matX(1,0) = 0.0; matX(1,1) = cosX; matX(1,2) = sinX; matX(2,0) = 0.0; matX(2,1) = -sinX; matX(2,2) = cosX; // Matrix (single column) of xGK, yGK, zGK gpstk::Matrix<double> inertialPos(3,1); inertialPos(0,0) = xGK; inertialPos(1,0) = yGK; inertialPos(2,0) = zGK; gpstk::Matrix<double> result(3,1); result = matZ * matX * inertialPos; sv.x[0] = result(0,0); sv.x[1] = result(1,0); sv.x[2] = result(2,0); // derivatives of true anamoly and arg of latitude dek = amm / G; dlk = Ahalf * q * sqrtgm / (R*R); // in-plane, cross-plane, and radial derivatives div = tdrinc - 2.0e0 * dlk * (Cis * c2al - Cic * s2al); duv = dlk*(1.e0+ 2.e0 * (Cus*c2al - Cuc*s2al)); drv = A * lecc * dek * sinea + 2.e0 * dlk * (Crs * c2al - Crc * s2al); // dxp = drv*cosu - R*sinu*duv; dyp = drv*sinu + R*cosu*duv; // Time-derivative of Rz matrix gpstk::Matrix<double> dmatZ(3,3); // Row,Col dmatZ(0,0) = sinZ * -ell.angVelocity(); dmatZ(0,1) = -cosZ * -ell.angVelocity(); dmatZ(0,2) = 0.0; dmatZ(1,0) = cosZ * -ell.angVelocity(); dmatZ(1,1) = sinZ * -ell.angVelocity(); dmatZ(1,2) = 0.0; dmatZ(2,0) = 0.0; dmatZ(2,1) = 0.0; dmatZ(2,2) = 0.0; // Time-derivative of X,Y,Z in interial form gpstk::Matrix<double> dIntPos(3,1); dIntPos(0,0) = - xip * san * OMEGAdot + dxp * can - yip * (cinc * can * OMEGAdot -sinc * san * div ) - dyp * cinc * san; dIntPos(1,0) = xip * can * OMEGAdot + dxp * san - yip * (cinc * san * OMEGAdot +sinc * can * div ) + dyp * cinc * can; dIntPos(2,0) = yip * cinc * div + dyp * sinc; /* cout << "dIntPos : " << dIntPos(0,0) << ", " << dIntPos(1,0) << ", " << dIntPos(2,0) << endl; double vMag = ::sqrt(dIntPos(0,0)*dIntPos(0,0) + dIntPos(1,0)*dIntPos(1,0) + dIntPos(2,0)*dIntPos(2,0) ); cout << " dIntPos Mag: " << vMag << endl; cout << "dmatZ : " << dmatZ(0,0) << ", " << dmatZ(0,1) << ", " << dmatZ(0,2) << endl; cout << "dmatZ : " << dmatZ(1,0) << ", " << dmatZ(1,1) << ", " << dmatZ(1,2) << endl; cout << "dmatZ : " << dmatZ(2,0) << ", " << dmatZ(2,1) << ", " << dmatZ(2,2) << endl; */ gpstk::Matrix<double> vresult(3,1); vresult = matZ * matX * dIntPos + dmatZ * matX * inertialPos; /* debug gpstk::Matrix<double> firstHalf(3,1); firstHalf = matZ * matX * dIntPos; gpstk::Matrix<double> secondHalf(3,1); secondHalf = dmatZ * matX * inertialPos; cout << "firstHalf: " << firstHalf(0,0) << ", " << firstHalf(1,0) << ", " << firstHalf(2,0) << endl; cout << "secondHalf: " << secondHalf(0,0) << ", " << secondHalf(1,0) << ", " << secondHalf(2,0) << endl; end debug */ // Move results into output variables sv.v[0] = vresult(0,0); sv.v[1] = vresult(1,0); sv.v[2] = vresult(2,0); return sv; }
// Casts Rinex3NavData to a GPSEphemeris object. Rinex3NavData::operator GPSEphemeris() const throw() { GPSEphemeris gpse; // fill the OrbitEph parts OrbitEph* ptr = dynamic_cast<OrbitEph*>(&gpse); castTo(ptr); //sets dataLoadedFlag // is it right? if(gpse.satID.system != SatID::systemGPS) gpse.dataLoadedFlag = false; if(!gpse.dataLoadedFlag) return gpse; // throw? // Special case to address common problem in IGS aggregate brdc // files. In some cases (typ. beginning of week) the last // SF 1/2/3 for the previous day is being output with a HOWtime of // zero. This leaves it in conflict with the first SF 1/2/3 of // the new day (which typically has a HOW of zero) long adjHOWtime = HOWtime; short adjWeeknum = weeknum; long lToc = (long) Toc; if ((HOWtime%SEC_PER_DAY)==0 && ((lToc)%SEC_PER_DAY)==0 && HOWtime == lToc) { adjHOWtime = HOWtime - 30; if (adjHOWtime<0) { adjHOWtime += FULLWEEK; adjWeeknum--; } } // end special case adjustment (except for use of adjHOWtime below) // get the epochs right CommonTime ct = time; //unsigned int year = static_cast<CivilTime>(ct).year; // Get week for clock, to build Toc double dt = Toc - adjHOWtime; int week = adjWeeknum; if(dt < -HALFWEEK) week++; else if(dt > HALFWEEK) week--; gpse.ctToc = GPSWeekSecond(week, Toc, TimeSystem::GPS); gpse.ctToc.setTimeSystem(TimeSystem::GPS); // now load the GPS-specific parts gpse.IODC = IODC; gpse.IODE = IODE; gpse.health = health; gpse.accuracyFlag = accuracy; gpse.Tgd = Tgd; gpse.HOWtime = HOWtime; week = static_cast<GPSWeekSecond>(gpse.ctToe).getWeek(); gpse.transmitTime = GPSWeekSecond(adjWeeknum, static_cast<double>(adjHOWtime), TimeSystem::GPS); gpse.codeflags = codeflgs; gpse.L2Pdata = L2Pdata; // NB IODC must be set first... gpse.fitint = fitint; gpse.setFitIntervalFlag(int(fitint)); // calls adjustValidity(); return gpse; }
// Deprecated; use GPSEphemeris. // Converts this Rinex3NavData to an EngEphemeris object. Rinex3NavData::operator EngEphemeris() const throw() { EngEphemeris ee; // There's no TLM word in Rinex3NavData, so it's set to 0. // Likewise, there's no AS alert or tracker. // Also, in RINEX, the accuracy is in meters, and setSF1 expects // the accuracy flag. We'll give it zero and pass the accuracy // separately via the setAccuracy() method. ee.tlm_message[0] = 0; ee.tlm_message[1] = 0; ee.tlm_message[2] = 0; ee.HOWtime[0] = HOWtime; // RINEX does not actually specify ee.HOWtime[1] = HOWtime; // how the transmit time is derived. Therefore, ee.HOWtime[2] = HOWtime; // These values may be misleading. ee.ASalert[0] = 1; //AS and alert flags set to 1 (default) ee.ASalert[1] = 1; ee.ASalert[2] = 1; ee.weeknum = weeknum; ee.codeflags = codeflgs; ee.health = health; ee.IODC = short(IODC); ee.L2Pdata = L2Pdata; ee.Tgd = Tgd; ee.tracker = 0; ee.PRNID = PRNID; ee.satSys = satSys; bool healthy = false; if (health == 0) healthy = true; short accFlag = 0; //will be set later. //BrcClockCorrection takes a flag, while EngEphemeris takes a double. double toc = Toc; double timeDiff =toc - ee.HOWtime[0]; short epochWeek = ee.weeknum; if (timeDiff < -HALFWEEK) epochWeek++; else if (timeDiff > HALFWEEK) epochWeek--; CommonTime tocCT = GPSWeekSecond(epochWeek, Toc, TimeSystem::GPS); // The observation ID has a type of navigation, but the // carrier and code types are undefined. They could be // L1/L2 C/A, P, Y,..... ObsID obsID(ObsID::otNavMsg, ObsID::cbUndefined, ObsID::tcUndefined); ee.bcClock.loadData( satSys, obsID, PRNID, tocCT, accFlag, healthy, af0, af1, af2); ee.IODE = short(IODE); ee.fitint = (fitint > 4) ? 1 : 0; //double toe = Toe; //????? //Needed for modernized nav quatities double A = Ahalf * Ahalf; double dndot = 0.0; double Adot = 0.0; short fitHours = getLegacyFitInterval(ee.IODC, ee.fitint); long beginFitSOW = Toe - (fitHours/2)*3600.0; long endFitSOW = Toe + (fitHours/2)*3600.0; short beginFitWk = ee.weeknum; short endFitWk = ee.weeknum; if (beginFitSOW < 0) { beginFitSOW += FULLWEEK; beginFitWk--; } CommonTime beginFit = GPSWeekSecond(beginFitWk, beginFitSOW, TimeSystem::GPS); if (endFitSOW >= FULLWEEK) { endFitSOW += FULLWEEK; endFitWk++; } CommonTime endFit = GPSWeekSecond(endFitWk, endFitSOW, TimeSystem::GPS); CommonTime toeCT = GPSWeekSecond(epochWeek, Toe, TimeSystem::GPS); ee.orbit.loadData( satSys, obsID, PRNID, beginFit, endFit, toeCT, accFlag, healthy, Cuc, Cus, Crc, Crs, Cic, Cis, M0, dn, dndot, ecc, A, Ahalf, Adot, OMEGA0, i0, w, OMEGAdot, idot); ee.haveSubframe[0] = true; // need to be true to perform certain EngEphemeris functions ee.haveSubframe[1] = true; // examples: ee.dump(), ee.setAccuracy() ee.haveSubframe[2] = true; ee.setAccuracy(accuracy); return ee; } // End of 'Rinex3NavData::operator EngEphemeris()'
/** * Get the ephemeris reference time as a GPSWeekSecond object. */ GPSWeekSecond getToeWS() const { return GPSWeekSecond(toeWeek, Toe, TimeSystem::GPS); }
double TimeSystemCorrection :: Correction(const CommonTime& ct) const { double corr(0.0), dt; TimeSystem fromTS(ct.getTimeSystem()); GPSWeekSecond gpsws; CommonTime refTime; Exception e("Unable to compute correction - wrong TimeSystem"); Exception eSBAS("TimeSystemCorrection SBAS <=> UTC has not been implemented"); switch(type) { case GPUT: if(fromTS != TimeSystem::GPS && fromTS != TimeSystem::UTC) { GPSTK_THROW(e); } // dt = fromTime - refTime gpsws = GPSWeekSecond(refWeek,refSOW); refTime = gpsws.convertToCommonTime(); refTime.setTimeSystem(fromTS); dt = ct - refTime; if(fromTS == TimeSystem::GPS) // GPS => UTC corr = -A0-A1*dt; else // UTC => GPS corr = A0+A1*dt; break; case GAUT: if(fromTS != TimeSystem::GAL && fromTS != TimeSystem::UTC) { GPSTK_THROW(e); } // dt = fromTime - refTime gpsws = GPSWeekSecond(refWeek,refSOW); refTime = gpsws.convertToCommonTime(); refTime.setTimeSystem(fromTS); dt = ct - refTime; if(fromTS == TimeSystem::GAL) // GAL => UTC corr = A0+A1*dt; else // UTC => GAL corr = -A0-A1*dt; break; case SBUT: GPSTK_THROW(eSBAS); break; case GLUT: if(fromTS != TimeSystem::GLO && fromTS != TimeSystem::UTC) { GPSTK_THROW(e); } if(fromTS == TimeSystem::GLO) // GLO => UTC corr = A0; else // UTC => GLO corr = -A0; break; case GPGA: if(fromTS != TimeSystem::GPS && fromTS != TimeSystem::GAL) { GPSTK_THROW(e); } // dt = fromTime - refTime gpsws = GPSWeekSecond(refWeek,refSOW); refTime = gpsws.convertToCommonTime(); refTime.setTimeSystem(fromTS); dt = ct - refTime; if(fromTS == TimeSystem::GPS) // GPS => GAL corr = A0+A1*dt; else // GAL => GPS corr = -A0-A1*dt; break; case GLGP: if(fromTS != TimeSystem::GLO && fromTS != TimeSystem::GPS) { GPSTK_THROW(e); } if(fromTS == TimeSystem::GLO) // GLO => GPS corr = A0; else // GPS => GLO corr = -A0; break; case QZGP: if(fromTS != TimeSystem::QZS && fromTS != TimeSystem::GPS) { GPSTK_THROW(e); } if(fromTS == TimeSystem::QZS) // QZS => GPS corr = 0.0; // TD? else // GPS => QZS corr = 0.0; // TD? break; case QZUT: if(fromTS != TimeSystem::QZS && fromTS != TimeSystem::UTC) { GPSTK_THROW(e); } // dt = fromTime - refTime gpsws = GPSWeekSecond(refWeek,refSOW); refTime = gpsws.convertToCommonTime(); refTime.setTimeSystem(fromTS); dt = ct - refTime; if(fromTS == TimeSystem::QZS) // QZS => UTC corr = A0+A1*dt; else // UTC => QZS corr = -A0-A1*dt; break; case BDUT: if(fromTS != TimeSystem::BDT && fromTS != TimeSystem::UTC) { GPSTK_THROW(e); } // dt = fromTime - refTime gpsws = GPSWeekSecond(refWeek,refSOW); refTime = gpsws.convertToCommonTime(); refTime.setTimeSystem(fromTS); dt = ct - refTime; if(fromTS == TimeSystem::BDT) // BDT => UTC corr = A0+A1*dt; else // UTC => BDT corr = -A0-A1*dt; break; case BDGP: if(fromTS != TimeSystem::BDT && fromTS != TimeSystem::GPS) { GPSTK_THROW(e); } // dt = fromTime - refTime gpsws = GPSWeekSecond(refWeek,refSOW); refTime = gpsws.convertToCommonTime(); refTime.setTimeSystem(fromTS); dt = ct - refTime; if(fromTS == TimeSystem::BDT) // BDT => GPS corr = A0; else // GPS => BDT corr = -A0; break; default: Exception e("TimeSystemCorrection is not defined."); GPSTK_THROW(e); break; } return corr; }
// Convert this RinexNavData to a GPSEphemeris object. // for backward compatibility only - use Rinex3NavData RinexNavData::operator GPSEphemeris() const { GPSEphemeris gpse; try { // Overhead gpse.satID = SatID(PRNID, SatID::systemGPS); gpse.ctToe = time; // clock model gpse.af0 = af0; gpse.af1 = af1; gpse.af2 = af2; // Major orbit parameters gpse.M0 = M0; gpse.dn = dn; gpse.ecc = ecc; gpse.A = Ahalf * Ahalf; gpse.OMEGA0 = OMEGA0; gpse.i0 = i0; gpse.w = w; gpse.OMEGAdot = OMEGAdot; gpse.idot = idot; // modern nav msg gpse.dndot = 0.; gpse.Adot = 0.; // Harmonic perturbations gpse.Cuc = Cuc; gpse.Cus = Cus; gpse.Crc = Crc; gpse.Crs = Crs; gpse.Cic = Cic; gpse.Cis = Cis; gpse.dataLoadedFlag = true; // get the epochs right CommonTime ct = time; //unsigned int year = static_cast<CivilTime>(ct).year; // Get week for clock, to build Toc double dt = Toc - HOWtime; int week = weeknum; if(dt < -HALFWEEK) week++; else if(dt > HALFWEEK) week--; gpse.ctToc = GPSWeekSecond(week, Toc, TimeSystem::GPS); gpse.ctToc.setTimeSystem(TimeSystem::GPS); // now load the GPS-specific parts gpse.IODC = IODC; gpse.IODE = IODE; gpse.health = health; gpse.accuracyFlag = accuracy; gpse.Tgd = Tgd; gpse.HOWtime = HOWtime; week = static_cast<GPSWeekSecond>(gpse.ctToe).getWeek(); gpse.transmitTime = GPSWeekSecond(week, static_cast<double>(HOWtime), TimeSystem::GPS); gpse.codeflags = codeflgs; gpse.L2Pdata = L2Pdata; // NB IODC must be set first... gpse.fitint = fitint; gpse.setFitIntervalFlag(int(fitint)); // calls adjustValidity(); } catch(Exception& e) { GPSTK_RETHROW(e); } return gpse; }