// Utility routine for getXvt and addEphemeris to convert time systems. // Convert ttag to the target time system, using the first appropriate correction // in the list, and return it. If no correction is found, ttag is unchanged and // an exception is thrown. CommonTime Rinex3EphemerisStore::correctTimeSystem(const CommonTime ttag, const TimeSystem targetSys) const { CommonTime toReturn(ttag); TimeSystem fromSys(ttag.getTimeSystem()); // is a conversion necessary? if(fromSys == targetSys) return toReturn; // first correct for leap seconds const CivilTime civt(ttag); double dt = TimeSystem::Correction(fromSys, targetSys, civt.year, civt.month, civt.day); toReturn += dt; toReturn.setTimeSystem(targetSys); // the corrected timetag: now only the system, not the value, matters toReturn.setTimeSystem(targetSys); // look up the TimeSystemCorr in list, and do the conversion map<string, TimeSystemCorrection>::const_iterator it; for(it = mapTimeCorr.begin(); it != mapTimeCorr.end(); ++it) { if(it->second.isConverterFor(fromSys, targetSys)) { dt = it->second.Correction(ttag); toReturn += dt; return toReturn; } } // failure InvalidRequest e("Unable to convert time systems from " + ttag.getTimeSystem().asString() + " to " + targetSys.asString()); GPSTK_THROW(e); return toReturn; // never reached, satisfy some compilers }
//============================================================ // Test Suite: timeSystemTest() //============================================================ // // Test will check the TimeSystem comparisons when using // the comparison operators. // //============================================================ int timeSystemTest( void ) { TestUtil testFramework( "CommonTime", "Differing TimeSystem == Operator", __FILE__, __LINE__ ); CommonTime GPS1; GPS1.set( 1000, 200, 0.2, TimeSystem(2) ); CommonTime GPS2; GPS2.set( 100, 200, 0.2, TimeSystem(2) ); CommonTime UTC1; UTC1.set( 1000, 200, 0.2, TimeSystem(5) ); CommonTime UNKNOWN; UNKNOWN.set( 1000, 200, 0.2, TimeSystem(0) ); CommonTime ANY; ANY.set( 1000, 200, 0.2, TimeSystem(1) ); //---------------------------------------- // ??? //---------------------------------------- testFramework.assert( !(GPS1 == GPS2), "Verify same Time System but different time inequality", __LINE__ ); testFramework.assert( GPS1.getTimeSystem() == GPS2.getTimeSystem(), "Verify same Time System equality", __LINE__ ); //---------------------------------------- // Differing TimeSystem != Operator //---------------------------------------- testFramework.changeSourceMethod( "Differing TimeSystem != Operator" ); testFramework.assert( GPS1 != UTC1, "Verify different Time System but same time inequality", __LINE__ ); testFramework.assert( GPS1 != UNKNOWN, "Verify different Time System but same time inequality", __LINE__ ); //---------------------------------------- // ANY TimeSystem == Operator //---------------------------------------- testFramework.changeSourceMethod( "ANY TimeSystem == Operator" ); testFramework.assert( GPS1 == ANY, "Verify TimeSystem=ANY does not matter in TimeSystem=GPS comparisons", __LINE__ ); testFramework.assert( UTC1 == ANY, "Verify TimeSystem=ANY does not matter in TimeSystem=UTC comparisons", __LINE__ ); testFramework.assert( UNKNOWN == ANY, "Verify TimeSystem=ANY does not matter in TimeSystem=UNKOWN comparisons", __LINE__ ); //---------------------------------------- // ANY TimeSystem < Operator //---------------------------------------- testFramework.changeSourceMethod( "ANY TimeSystem < Operator" ); testFramework.assert( !(GPS2 == ANY) && (GPS2 < ANY), "Verify TimeSystem=ANY does not matter in other operator comparisons", __LINE__ ); //---------------------------------------- // setTimeSystem //---------------------------------------- testFramework.changeSourceMethod( "setTimeSystem" ); UNKNOWN.setTimeSystem( TimeSystem(2) ); //Set the Unknown TimeSystem testFramework.assert( UNKNOWN.getTimeSystem()==TimeSystem(2), "Ensure resetting a Time System changes it", __LINE__ ); //---------------------------------------- // The End! //---------------------------------------- return testFramework.countFails(); }
//============================================================ // Test Suite: resetTest() //============================================================ // // Test will check the reset method. // //============================================================ int resetTest( void ) { TestUtil testFramework( "CommonTime", "reset" , __FILE__, __LINE__ ); CommonTime Compare; Compare.set(1000,200,0.2); // Initialize with value long day, sod; double fsod; Compare.reset(); // Reset it Compare.get(day,sod,fsod); testFramework.assert( TimeSystem(0) == Compare.getTimeSystem(), "Was the time system reset to expectation?", __LINE__ ); testFramework.assert( 0 == day, "Was the day value reset to expectation?", __LINE__ ); testFramework.assert( 0 == sod, "Was the sod value reset to expectation?", __LINE__ ); testFramework.assert( 0 == fsod, "Was the fsod value reset to expectation?", __LINE__ ); return testFramework.countFails(); }
/* Returns the position, velocity and clock offset of the indicated * satellite in ECEF coordinates (meters) at the indicated time, * in the PZ-90 ellipsoid. * * @param[in] sat Satellite's identifier * @param[in] epoch Time to look up * * @return the Xvt of the object at the indicated time * * @throw InvalidRequest If the request can not be completed for any * reason, this is thrown. The text may have additional information * as to why the request failed. */ Xvt GloEphemerisStore::getXvt( const SatID& sat, const CommonTime& epoch ) const { // TD is this too strict? if(epoch.getTimeSystem() != initialTime.getTimeSystem()) { InvalidRequest e(string("Requested time system is not GLONASS time")); GPSTK_THROW(e); } // Check that the given epoch is within the available time limits. // We have to add a margin of 15 minutes (900 seconds). if ( epoch < (initialTime - 900.0) || epoch > (finalTime + 900.0) ) { InvalidRequest e( "Requested time is out of boundaries for satellite " + StringUtils::asString(sat) ); GPSTK_THROW(e); } // Look for the satellite in the 'pe' (EphMap) data structure. GloEphMap::const_iterator svmap = pe.find(sat); // If satellite was not found, issue an exception if (svmap == pe.end()) { InvalidRequest e( "Ephemeris for satellite " + StringUtils::asString(sat) + " not found." ); GPSTK_THROW(e); } // Let's take the second part of the EphMap const TimeGloMap& sem = svmap->second; // Look for 'i': the first element whose key >= epoch. TimeGloMap::const_iterator i = sem.lower_bound(epoch);; // Values to be returned will be stored here Xvt sv; // If we reached the end, the requested time is beyond the last // ephemeris record, but it may still be within the allowable time // span, so we can use the last record. if ( i == sem.end() ) { i = --i; } // If key > (epoch+900), we must use the previous record if possible. if ( ( i->first > (epoch+900.0) ) && ( i != sem.begin() ) ) { i = --i; } // Check that the given epoch is within the available time limits for // this specific satellite, with a margin of 15 minutes (900 seconds). if ( epoch < (i->first - 900.0) || epoch >= (i->first + 900.0) ) { InvalidRequest e( "Requested time is out of boundaries for satellite " + StringUtils::asString(sat) ); GPSTK_THROW(e); } // We now have the proper reference data record. Let's use it GloEphemeris data( i->second ); // Compute the satellite position, velocity and clock offset sv = data.svXvt( epoch ); // We are done, let's return return sv; }; // End of method 'GloEphemerisStore::getXvt()'
void mixedScanTime( CommonTime& t, const string& str, const string& fmt ) { try { using namespace gpstk::StringUtils; // Get the mapping of character (from fmt) to value (from str). TimeTag::IdToValue info; TimeTag::getInfo( str, fmt, info ); // These indicate which information has been found. bool hsow( false ), hweek( false ), hfullweek( false ), hdow( false ), hyear( false ), hmonth( false ), hday( false ), hzcount( false ), hdoy( false ), hzcount29( false ), hhour( false ), hmin( false ), hsec( false ), hsod( false ), hepoch( false ), hunixsec( false ), hunixusec( false ), hbdsw( false ), hqzsw( false ), hgalw( false ), hbdsfw( false ), hqzsfw( false ), hgalfw( false ), hbdse( false ), hqzse( false ), hgale( false); #pragma unused(hunixsec,hunixusec) // MJD, Julian Date, ANSI time, Unix time, and 32-bit Zcounts // are treated as stand-alone types and are not mixed with others // if detected. // These variables will hold the values for use later. double isow, isod, isec; int iweek, ifullweek, idow, iyear, imonth, iday, izcount, idoy, izcount29, ihour, imin, iepoch; TimeSystem ts; for( TimeTag::IdToValue::iterator itr = info.begin(); itr != info.end(); itr++ ) { switch( itr->first ) { case 'P': ts.fromString(itr->second); t.setTimeSystem(ts); break; case 'Q': t = MJD( asLongDouble(itr->second) ); return; case 'J': t = JulianDate( asLongDouble(itr->second) ); return; case 'C': t = GPSWeekZcount().setZcount32( asInt(itr->second) ); return; case 'K': t = ANSITime( asInt(itr->second) ); return; case 'U': case 'u': { UnixTime tt; tt.setFromInfo( info ); t = tt.convertToCommonTime(); return; } break; case 'Z': hzcount = true; izcount = asInt(itr->second); break; case 's': hsod = true; isod = asDouble(itr->second); break; case 'g': hsow = true; isow = asDouble(itr->second); break; case 'w': idow = asInt(itr->second); hdow = true; break; case 'G': hweek = true; iweek = asInt(itr->second); break; case 'F': hfullweek = true; ifullweek = asInt(itr->second); break; case 'j': hdoy = true; idoy = asInt(itr->second); break; case 'b': case 'B': hmonth = true; imonth = asInt(itr->second); break; case 'Y': case 'y': hyear = true; iyear = asInt(itr->second); break; case 'a': case 'A': { hdow = true; string thisDay = firstWord( itr->second ); lowerCase(thisDay); if (isLike(thisDay, "sun.*")) idow = 0; else if (isLike(thisDay, "mon.*")) idow = 1; else if (isLike(thisDay, "tue.*")) idow = 2; else if (isLike(thisDay, "wed.*")) idow = 3; else if (isLike(thisDay, "thu.*")) idow = 4; else if (isLike(thisDay, "fri.*")) idow = 5; else if (isLike(thisDay, "sat.*")) idow = 6; } break; case 'm': hmonth = true; imonth = asInt(itr->second); break; case 'd': hday = true; iday = asInt(itr->second); break; case 'H': hhour = true; ihour = asInt(itr->second); break; case 'M': hmin = true; imin = asInt(itr->second); break; case 'S': hsec = true; isec = asDouble(itr->second); break; case 'f': hsec = true; isec = asDouble(itr->second); break; case 'c': hzcount29 = true; izcount29 = asInt(itr->second); break; case 'E': hepoch = true; iepoch = asInt(itr->second); break; case 'R': hepoch = hbdse = true; iepoch = asInt(itr->second); break; case 'T': hepoch = hgale = true; iepoch = asInt(itr->second); break; case 'V': hepoch = hqzse = true; iepoch = asInt(itr->second); break; case 'D': hfullweek = hbdsfw = true; break; case 'e': hweek = hbdsw = true; break; case 'L': hfullweek = hgalfw = true; break; case 'l': hweek = hgalw = true; break; case 'I': hfullweek = hqzsfw = true; break; case 'i': hweek = hqzsw = true; break; default: // do nothing break; }; } bool hbds(hbdse || hbdsfw || hbdsw); bool hgal(hgale || hgalfw || hgalw); bool hqzs(hqzse || hqzsfw || hqzsw); // We'll copy this time to 't' after all of the processing. CommonTime ct; ct.setTimeSystem(t.getTimeSystem()); // Go through all of the types in order of least precise to most // precise. if( hepoch ) { WeekSecond *ptt; if(hbds) ptt = new BDSWeekSecond(ct); else if(hqzs) ptt = new QZSWeekSecond(ct); else if(hgal) ptt = new GALWeekSecond(ct); else ptt = new GPSWeekSecond(ct); ptt->setEpoch( iepoch ); ct = ptt->convertToCommonTime(); } if( hyear ) { YDSTime tt(ct); tt.year = iyear; ct = tt.convertToCommonTime(); } if( hmonth ) { CivilTime tt(ct); tt.month = imonth; ct = tt.convertToCommonTime(); } if( hfullweek ) { WeekSecond *ptt; if(hbds) ptt = new BDSWeekSecond(ct); else if(hqzs) ptt = new QZSWeekSecond(ct); else if(hgal) ptt = new GALWeekSecond(ct); else ptt = new GPSWeekSecond(ct); ptt->week = ifullweek; ct = ptt->convertToCommonTime(); } if( hweek ) { WeekSecond *ptt; if(hbds) ptt = new BDSWeekSecond(ct); else if(hqzs) ptt = new QZSWeekSecond(ct); else if(hgal) ptt = new GALWeekSecond(ct); else ptt = new GPSWeekSecond(ct); ptt->setModWeek(iweek); ct = ptt->convertToCommonTime(); } if( hdow ) { WeekSecond *ptt; if(hbds) ptt = new BDSWeekSecond(ct); else if(hqzs) ptt = new QZSWeekSecond(ct); else if(hgal) ptt = new GALWeekSecond(ct); else ptt = new GPSWeekSecond(ct); ptt->sow = static_cast<double>(idow) * SEC_PER_DAY; ct = ptt->convertToCommonTime(); } if( hday ) { CivilTime tt(ct); tt.day = iday; ct = tt.convertToCommonTime(); } if( hdoy ) { YDSTime tt(ct); tt.doy = idoy; ct = tt.convertToCommonTime(); } if( hzcount29 ) { GPSWeekZcount tt(ct); tt.setZcount29( izcount29 ); ct = tt.convertToCommonTime(); } if( hzcount ) { GPSWeekZcount tt(ct); tt.zcount = izcount; ct = tt.convertToCommonTime(); } if( hhour ) { CivilTime tt(ct); tt.hour = ihour; ct = tt.convertToCommonTime(); } if( hmin ) { CivilTime tt(ct); tt.minute = imin; ct = tt.convertToCommonTime(); } if( hsow ) { WeekSecond *ptt; if(hbds) ptt = new BDSWeekSecond(ct); else if(hqzs) ptt = new QZSWeekSecond(ct); else if(hgal) ptt = new GALWeekSecond(ct); else ptt = new GPSWeekSecond(ct); ptt->sow = isow; ct = ptt->convertToCommonTime(); } if( hsod ) { YDSTime tt(ct); tt.sod = isod; ct = tt.convertToCommonTime(); } if( hsec ) { CivilTime tt(ct); tt.second = isec; ct = tt.convertToCommonTime(); } t = ct; } catch( gpstk::StringUtils::StringException& se ) { GPSTK_RETHROW( se ); } }
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; }