void OrbElemRinex::adjustBeginningValidity() { if (!dataLoaded()) return; // The nominal beginning of validity is calculated from // the fit interval and the Toe. In RINEX the fit duration // in hours is stored in the file. long oneHalfInterval = ((long)fitDuration/2) * 3600; // If we assume this is the SECOND set of elements in a set // (which is an assumption of this function - see the .hpp) then // the "small offset in Toe" will actually push the Toe-oneHalfInterval // too early. For example, consider the following case. // Toe : 19:59:44 (really near 20:00:00) // first xMit : 18:00:00 (nominal) // Blindly setting beginValid top Toe - 1/2 fit interval will // result in 17:59:44. But 18:00:00 actually is the right answer // because the -16 second offset is an artifact. // // Therefore, we are FIRST going to remove that offset, // THEN determine beginValid. long sow = (long) (static_cast<GPSWeekSecond>(ctToe)).sow; short week = (static_cast<GPSWeekSecond>(ctToe)).week; sow = sow + (3600 - (sow%3600)); CommonTime adjustedToe = GPSWeekSecond(week, (double) sow); adjustedToe.setTimeSystem(TimeSystem::GPS); beginValid = adjustedToe - oneHalfInterval; return; }
CommonTime Rinex3ObsData::parseTime(const string& line, const Rinex3ObsHeader& hdr, const TimeSystem& ts) const throw(FFStreamError) { try { // check if the spaces are in the right place - an easy // way to check if there's corruption in the file if( (line[ 1] != ' ') || (line[ 6] != ' ') || (line[ 9] != ' ') || (line[12] != ' ') || (line[15] != ' ') || (line[18] != ' ') || (line[29] != ' ') || (line[30] != ' ')) { FFStreamError e("Invalid time format"); GPSTK_THROW(e); } // if there's no time, just return a bad time if(line.substr(2,27) == string(27, ' ')) return CommonTime::BEGINNING_OF_TIME; int year, month, day, hour, min; double sec; year = asInt( line.substr( 2, 4)); month = asInt( line.substr( 7, 2)); day = asInt( line.substr(10, 2)); hour = asInt( line.substr(13, 2)); min = asInt( line.substr(16, 2)); sec = asDouble(line.substr(19, 11)); // Real Rinex has epochs 'yy mm dd hr 59 60.0' surprisingly often. double ds = 0; if(sec >= 60.) { ds = sec; sec = 0.0; } CommonTime rv = CivilTime(year,month,day,hour,min,sec).convertToCommonTime(); if(ds != 0) rv += ds; rv.setTimeSystem(ts); return rv; } // string exceptions for substr are caught here catch (std::exception &e) { FFStreamError err("std::exception: " + string(e.what())); GPSTK_THROW(err); } catch (gpstk::Exception& e) { FFStreamError err(e); GPSTK_THROW(err); } } // end parseTime
void UnixTime::convertFromCommonTime( const CommonTime& ct ) throw( InvalidRequest ) { /// This is the earliest CommonTime for which UnixTimes are valid. static const CommonTime MIN_CT = UnixTime(); /// This is the latest CommonTime for which UnixTimes are valid. /// (2^31 - 1) s and 999999 us static const CommonTime MAX_CT = UnixTime(2147483647, 999999); if ( ct < MIN_CT || ct > MAX_CT ) { InvalidRequest ir("Unable to convert given CommonTime to UnixTime."); GPSTK_THROW(ir); } long jday, sod; double fsod; ct.get( jday, sod, fsod ); tv.tv_sec = (jday - MJD_JDAY - UNIX_MJD) * SEC_PER_DAY + sod; // round to the nearest microsecond tv.tv_usec = static_cast<time_t>( fsod * 1e6 + 0.5 ) ; if (tv.tv_usec >= 1000000) { tv.tv_usec -= 1000000; ++tv.tv_sec; } }
// Test will check converting to/from CommonTime. unsigned toFromCommonTimeTest() { TUDEF("IRNWeekSecond", "isValid"); IRNWeekSecond compare(0,10.0,TimeSystem::IRN); //Initialize an object CommonTime truth; long truthDay, truthSOD; double truthFSOD; truth.set(2451412, 43210,0.0,TimeSystem::IRN); //-------------------------------------------------------------------- //Is the time after the BEGINNING_OF_TIME? //-------------------------------------------------------------------- TUASSERT(compare.convertToCommonTime() > CommonTime::BEGINNING_OF_TIME); //-------------------------------------------------------------------- //Is the set object valid? //-------------------------------------------------------------------- TUASSERT(compare.isValid()); CommonTime test = compare.convertToCommonTime(); //Convert to CommonTime long testDay, testSOD; double testFSOD; test.get(testDay, testSOD, testFSOD); truth.get(truthDay, truthSOD, truthFSOD); // Currently, IRNWeekSecond does not convert to proper CommonTime // These tests will be valid and will be uncommented once issue_248 has been // resolved and merged into master. // TUASSERTE(long, truthDay, testDay); // TUASSERTE(long, truthSOD, testSOD); // TUASSERTFE(truthFSOD, testFSOD); IRNWeekSecond test2; test2.convertFromCommonTime(test); //Convert From testFramework.changeSourceMethod("CommonTimeConversion"); //-------------------------------------------------------------------- //Is the result of conversion the same? //-------------------------------------------------------------------- TUASSERTE(TimeSystem, compare.getTimeSystem(), test2.getTimeSystem()); TUASSERTE(int, compare.week, test2.week); TUASSERTFE(compare.sow, test2.sow); //TUASSERT(test2 == test); TURETURN(); }
//============================================================ // 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(); }
void JulianDate::convertFromCommonTime( const CommonTime& ct ) { long jday, sod; double fsod; ct.get( jday, sod, fsod, timeSystem ); jd = static_cast<long double>( jday ) + ( static_cast<long double>( sod ) + static_cast<long double>( fsod ) ) * DAY_PER_SEC - 0.5; }
CommonTime JulianDate::convertToCommonTime() const { try { long double temp_jd( jd + 0.5 ); long jday( static_cast<long>( temp_jd ) ); long double sod = ( temp_jd - static_cast<long double>( jday ) ) * SEC_PER_DAY; CommonTime ct; return ct.set( jday, static_cast<long>( sod ), static_cast<double>( sod - static_cast<long>( sod ) ), timeSystem ); } catch (InvalidParameter& ip) { InvalidRequest ir(ip); GPSTK_THROW(ir); } }
CommonTime WeekSecond::convertToCommonTime() const { try { //int dow = static_cast<int>( sow * DAY_PER_SEC ); // Appears to have rounding issues on 32-bit platforms int dow = static_cast<int>( sow / SEC_PER_DAY ); // NB this assumes MJDEpoch is an integer - what if epoch H:M:S != 0:0:0 ? long jday = MJD_JDAY + MJDEpoch() + (7 * week) + dow; double sod(sow - SEC_PER_DAY * dow); CommonTime ct; return ct.set( jday, static_cast<long>(sod), sod - static_cast<long>(sod), timeSystem ); } catch (InvalidParameter& ip) { GPSTK_RETHROW(ip); } }
// 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 }
void WeekSecond::convertFromCommonTime( const CommonTime& ct ) { if(static_cast<MJD>(ct).mjd < MJDEpoch()) { InvalidRequest ir("Unable to convert to Week/Second - before Epoch."); GPSTK_THROW(ir); } long jday, sod; double fsod; ct.get( jday, sod, fsod, timeSystem ); // find the number of days since the beginning of the Epoch jday -= MJD_JDAY + MJDEpoch(); // find out how many weeks that is week = static_cast<int>( jday / 7 ); // find out what the day of week is jday %= 7; sow = static_cast<double>( jday * SEC_PER_DAY + sod ) + fsod; }
//============================================================ // 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(); }
void ANSITime::convertFromCommonTime( const CommonTime& ct ) throw(InvalidRequest) { /// This is the earliest CommonTime for which ANSITimes are valid. static const CommonTime MIN_CT = ANSITime(0); /// This is the latest CommonTime for which ANSITimes are valid. /// 2^31 - 1 seconds static const CommonTime MAX_CT = ANSITime(2147483647); if ( ct < MIN_CT || ct > MAX_CT ) { InvalidRequest ir("Unable to convert given CommonTime to ANSITime."); GPSTK_THROW(ir); } long jday, sod; double fsod; ct.get( jday, sod, fsod ); time = static_cast<time_t>((jday - MJD_JDAY - UNIX_MJD) * SEC_PER_DAY + sod); }
//============================================================ // Test Suite: rolloverTest() //============================================================ // // Test to check arithmetic operations function properly when // rolling over or under the three time variables // //============================================================ int rolloverTest( void ) { TestUtil testFramework( "CommonTime", "addSeconds", __FILE__, __LINE__ ); CommonTime fsodRollover; fsodRollover.set(10 , 6789 , 0.000999); CommonTime msodRollover; msodRollover.set(10 , 86399, 0.0001 ); CommonTime dayRollunder; dayRollunder.set(10 , 2 , 0.0001 ); CommonTime msodRollunder; msodRollunder.set(10 , 10 , 0.000001); CommonTime expectedfsodROver; expectedfsodROver.set(10, 6789 , 0.001000); CommonTime expectedmsodROver; expectedmsodROver.set(11, 0 , 0.0001); CommonTime expectedDayRUnder; expectedDayRUnder.set( 9, 86399, 0.0001); CommonTime expectedmsodRUnder; expectedmsodRUnder.set(10, 9 , 0.999999); long obtainedDay, expectedDay; long obtainedMsod, expectedMsod; double obtainedFsod, expectedFsod; double diff; long incrementSecLong = 1L , decrementSecLong = -3L; double incrementSecDouble = 0.000001, decrementSecDouble = -0.000002; //-------------------------------- //Rollover Tests //-------------------------------- //fsod Rollover test fsodRollover.addSeconds(incrementSecDouble); fsodRollover.get(obtainedDay,obtainedMsod,obtainedFsod); expectedfsodROver.get(expectedDay,expectedMsod,expectedFsod); testFramework.assert(obtainedDay == expectedDay , "Rollover of fsod affected day value" , __LINE__); testFramework.assert(obtainedMsod == expectedMsod, "Rollover of fsod did not change msod", __LINE__); diff = fabs(obtainedFsod - expectedFsod); testFramework.assert(diff < eps, "fsod did not rollover properly" , __LINE__); //msod Rollover test msodRollover.addSeconds(incrementSecLong); msodRollover.get(obtainedDay,obtainedMsod,obtainedFsod); expectedmsodROver.get(expectedDay,expectedMsod,expectedFsod); testFramework.assert(obtainedDay == expectedDay , "Rollover of msod did not change day" , __LINE__); testFramework.assert(obtainedMsod == expectedMsod, "msod did not rollover properly" , __LINE__); diff = fabs(obtainedFsod - expectedFsod); testFramework.assert(diff < eps, "Rollover of msod affected fsod oddly", __LINE__); //-------------------------------- //Rollunder Tests //-------------------------------- //fsod Rollover test dayRollunder.addSeconds(decrementSecLong); dayRollunder.get(obtainedDay,obtainedMsod,obtainedFsod); expectedDayRUnder.get(expectedDay,expectedMsod,expectedFsod); testFramework.assert(obtainedDay == expectedDay , "Rollunder of msod did not change day" , __LINE__); testFramework.assert(obtainedMsod == expectedMsod, "msod did not rollunder properly" , __LINE__); diff = fabs(obtainedFsod - expectedFsod); testFramework.assert(diff < eps, "Rollunder of msod affected fsod oddly", __LINE__); //msod Rollover test msodRollunder.addSeconds(decrementSecDouble); msodRollunder.get(obtainedDay,obtainedMsod,obtainedFsod); expectedmsodRUnder.get(expectedDay,expectedMsod,expectedFsod); testFramework.assert(obtainedDay == expectedDay , "Rollunder of fsod affected day value" , __LINE__); testFramework.assert(obtainedMsod == expectedMsod, "Rollunder of fsod did not change msod", __LINE__); diff = fabs(obtainedFsod - expectedFsod); testFramework.assert(diff < eps, "fsod did not rollunder properly" , __LINE__); return testFramework.countFails(); }
//============================================================ // Test Suite: operatorTest() //============================================================ // // Test the comparison operators // //============================================================ int operatorTest( void ) { TestUtil testFramework( "CommonTime", "Differing TimeSystem, Operator ==", __FILE__, __LINE__ ); CommonTime Compare; Compare.set(1000,200,0.2); // Initialize with value CommonTime LessThanDay; LessThanDay.set(100,200,0.2); // Initialize with smaller day value CommonTime LessThanSecond; LessThanSecond.set(1000,20,0.2); // Initialize with smaller second value CommonTime LessThanFSecond; LessThanFSecond.set(1000,200,0.1); // Initialize with smaller fractional second value CommonTime CompareCopy(Compare); // Initialize with copy constructor testFramework.assert( Compare == CompareCopy, "GPSWeekZCount operator ==, Are equivalent objects equivalent?", __LINE__ ); testFramework.assert( !(Compare == LessThanDay), "GPSWeekZCount operator !=, Are non-equivalent objects equivalent?", __LINE__ ); //---------------------------------------- // Operator != //---------------------------------------- testFramework.changeSourceMethod( "Operator !=" ); testFramework.assert( Compare != LessThanDay, "GPSWeekZCount operator !=, Are non-equivalent objects not equivalent?", __LINE__ ); testFramework.assert( Compare != LessThanSecond, "GPSWeekZCount operator !=, Are non-equivalent objects not equivalent?", __LINE__ ); testFramework.assert( Compare != LessThanFSecond, "GPSWeekZCount operator !=, Are non-equivalent objects not equivalent?", __LINE__ ); testFramework.assert( !(Compare != Compare), "GPSWeekZCount operator !=, Are equivalent objects not equivalent?", __LINE__ ); //---------------------------------------- // Operator < //---------------------------------------- testFramework.changeSourceMethod( "Operator <" ); testFramework.assert( LessThanDay < Compare, "Does the < operator function when left_object < right_object?", __LINE__ ); testFramework.assert( LessThanSecond < Compare, "Does the < operator function when left_object < right_object by days?", __LINE__ ); testFramework.assert( !(Compare < LessThanSecond), "Does the < operator function when left_object > right_object by days?", __LINE__ ); testFramework.assert( LessThanFSecond < Compare, "Does the < operator function when left_object < right_object by seconds?", __LINE__ ); testFramework.assert( !(Compare < LessThanFSecond), "Does the < operator function when left_object > right_object by seconds?", __LINE__ ); testFramework.assert( !(Compare < CompareCopy), "Does the < operator function when left_object = right_object?", __LINE__ ); //---------------------------------------- // Greater than assertions //---------------------------------------- testFramework.changeSourceMethod( "Operator >" ); testFramework.assert( Compare > LessThanDay, "Does the > operator function when left_object > right_object by years?", __LINE__ ); testFramework.assert( !(LessThanDay > Compare), "Does the > operator function when left_object < right_object by years?", __LINE__ ); testFramework.assert( Compare > LessThanSecond, "Does the > operator function when left_object > right_object by days?", __LINE__ ); testFramework.assert( !(LessThanSecond > Compare), "Does the > operator function when left_object < right_object by days?", __LINE__ ); testFramework.assert( Compare > LessThanFSecond, "Does the > operator function when left_object > right_object by seconds?", __LINE__ ); testFramework.assert( !(LessThanFSecond > Compare), "Does the > operator function when left_object < right_object by seconds?", __LINE__ ); testFramework.assert( !(Compare > CompareCopy), "Does the > operator function when left_object = right_object?", __LINE__ ); //---------------------------------------- // Less than equals assertion //---------------------------------------- testFramework.changeSourceMethod( "Operator <=" ); testFramework.assert( LessThanDay <= Compare, "Does the < operator function when left_object < right_object by years?", __LINE__ ); testFramework.assert( !(Compare <= LessThanDay), "Does the <= operator function when left_object > right_object by years?", __LINE__ ); testFramework.assert( LessThanSecond <= Compare, "Does the <= operator function when left_object < right_object by days?", __LINE__ ); testFramework.assert( !(Compare <= LessThanSecond), "Does the <= operator function when left_object > right_object by days?", __LINE__ ); testFramework.assert( LessThanFSecond <= Compare, "Does the <= operator function when left_object < right_object by seconds?", __LINE__ ); testFramework.assert( !(Compare <= LessThanFSecond), "Does the <= operator function when left_object > right_object by seconds?", __LINE__ ); testFramework.assert( Compare <= CompareCopy, "Does the <= operator function when left_object = right_object?", __LINE__ ); //---------------------------------------- // Greater than equals assertion //---------------------------------------- testFramework.changeSourceMethod( "Operator >=" ); testFramework.assert( Compare >= LessThanDay, "Does the >= operator function when left_object > right_object by years?", __LINE__ ); testFramework.assert( !(LessThanDay >= Compare), "Does the >= operator function when left_object < right_object by years?", __LINE__ ); testFramework.assert( Compare >= LessThanSecond, "Does the >= operator function when left_object > right_object by days?", __LINE__ ); testFramework.assert( !(LessThanSecond >= Compare), "Does the >= operator function when left_object < right_object by days?", __LINE__ ); testFramework.assert( Compare >= LessThanFSecond, "Does the >= operator function when left_object > right_object by seconds?", __LINE__ ); testFramework.assert( !(LessThanFSecond >= Compare), "Does the >= operator function when left_object < right_object by seconds?", __LINE__ ); // typo from last guy?? testFramework.assert( !(Compare < CompareCopy), "Does the > operator function when left_object = right_object?", __LINE__ ); //---------------------------------------- // The End! //---------------------------------------- return testFramework.countFails(); }
//============================================================ // Test Suite: improperSetTest() //============================================================ // // Test to see if setting improper values induces the // correct exception handling. //============================================================ int improperSetTest( void ) { CommonTime Test; Test.set (700000, 0, 0.); TestUtil testFramework( "CommonTime", "set", __FILE__, __LINE__ ); // Break the input in various ways and make sure the proper exception is called //---------------------------------------- // Does CommonTime.set() work with negative days? //---------------------------------------- try { Test.set(-1,0,0.); testFramework.assert( false, "[testing] CommonTime.set() with negative day, [expected] exception gpstk::Exception, [actual] threw no exception", __LINE__ ); } // QUESTION: Why test for gpstk::InvalidRequest exception instead of gpstk::Exception? // ANSWER: gpstk::InvalidRequest is a child of gpstk::Exception, and depending on CommonTime.cpp // we might sometimes need to be more specific than catching gpstk::Exception // catch( gpstk::InvalidParameter e) // For now, I'm replacing gpstk::InvalidParameter with gpstk::Exception to be consistent throughout this test application catch( gpstk::Exception e) { testFramework.assert( true, "[expected] CommonTime.set() with negative day should throw a gpstk::Exception", __LINE__ ); } catch(...) { testFramework.assert( false, "[testing] CommonTime.set() with negative day, [expected] exception gpstk::Exception, [actual] threw wrong exception", __LINE__ ); } //---------------------------------------- // Does CommonTime.set() work with too many days? //---------------------------------------- try { Test.set(3442449,0,0.); testFramework.assert( false, "[testing] CommonTime.set() with too many days, [expected] exception gpstk::Exception, [actual] threw no exception", __LINE__ ); } catch(gpstk::Exception e) { testFramework.assert( true, "[expected] CommonTime.set() with too many days should throw a gpstk::Exception", __LINE__ ); } catch (...) { testFramework.assert( false, "[testing] CommonTime.set() with too many days, [expected] exception gpstk::Exception, [actual] threw wrong exception", __LINE__ ); } //---------------------------------------- // Does CommonTime.set() work with negative seconds? //---------------------------------------- try { Test.set(700000,-1,0.); testFramework.assert( false, "[testing] CommonTime.set() with negative seconds, [expected] exception gpstk::Exception, [actual] threw no exception", __LINE__ ); } catch(gpstk::Exception e) { testFramework.assert( true, "[expected] CommonTime.set() with negative seconds should throw a gpstk::Exception", __LINE__ ); } catch (...) { testFramework.assert( false, "Fail", __LINE__ ); } //---------------------------------------- // Does a set method work with too many seconds? //---------------------------------------- try { Test.set(700000,24*60*60+1,0.); testFramework.assert( false, "[testing] CommonTime.set() with too many seconds, [expected] exception gpstk::Exception, [actual] threw no exception", __LINE__ ); } catch(gpstk::Exception e) { testFramework.assert( true, "[expected] CommonTime.set() with too many seconds should throw a gpstk::Exception", __LINE__ ); } catch (...) { testFramework.assert( false, "[testing] CommonTime.set() with too many seconds, [expected] exception gpstk::Exception, [actual] threw wrong exception", __LINE__ ); } //---------------------------------------- // Does a set method work with negative fractional seconds? //---------------------------------------- try { Test.set(700000,0,-1.); testFramework.assert( false, "[testing] CommonTime.set() with negative fractional seconds, [expected] exception gpstk::Exception, [actual] threw no exception", __LINE__ ); } catch(gpstk::Exception e) { testFramework.assert( true, "[expected] CommonTime.set() with negative fractional seconds should throw a gpstk::Exception", __LINE__ ); } catch (...) { testFramework.assert( false, "[testing] CommonTime.set() with negative fractional seconds, [expected] exception gpstk::Exception, [actual] threw wrong exception", __LINE__ ); } //---------------------------------------- // Does a set method work with too many fractional seconds? //---------------------------------------- try { Test.set(700000,0,2.); testFramework.assert( false, "[testing] CommonTime.set() with too many fractional seconds, [expected] exception gpstk::Exception, [actual] threw no exception", __LINE__ ); } catch( gpstk::Exception e ) { testFramework.assert( true, "[expected] CommonTime.set() with too many fractional seconds should throw a gpstk::Exception", __LINE__ ); } catch(...) { testFramework.assert( false, "[testing] CommonTime.set() with too many fractional seconds, [expected] exception gpstk::Exception, [actual] threw wrong exception", __LINE__ ); } //---------------------------------------- // Does CommonTime.setInterval() work with negative days? //---------------------------------------- try { Test.setInternal(-1,0,0.); testFramework.assert( false, "[testing] CommonTime.setInterval() with negative days, [expected] exception gpstk::Exception, [actual] threw no exception", __LINE__ ); } catch( gpstk::Exception e ) { testFramework.assert( true, "[expected] CommonTime.set() with negative days should throw a gpstk::Exception", __LINE__ ); } catch (...) { testFramework.assert( false, "[testing] CommonTime.setInterval() with negative days, [expected] exception gpstk::Exception, [actual] threw wrong exception", __LINE__ ); } //---------------------------------------- // Does CommonTime.setInterval() work with too many days? //---------------------------------------- try { Test.setInternal(3442449,0,0.); testFramework.assert( false, "[testing] CommonTime.setInterval() with too many days, [expected] exception gpstk::Exception, [actual] threw no exception", __LINE__ ); } catch(gpstk::Exception e) { testFramework.assert( true, "[expected] CommonTime.setInterval() with too many days should throw a gpstk::Exception", __LINE__ ); } catch (...) { testFramework.assert( false, "[testing] CommonTime.setInterval() with too many days, [expected] exception gpstk::Exception, [actual] threw wrong exception", __LINE__ ); } //---------------------------------------- // Does CommonTime.setInterval() work with negative seconds? //---------------------------------------- try { Test.setInternal(700000,-1,0.); testFramework.assert( false, "[testing] CommonTime.setInterval() with negative seconds, [expected] exception gpstk::Exception, [actual] threw no exception", __LINE__ ); } catch(gpstk::Exception e) { testFramework.assert( true, "[expected] CommonTime.setInterval() with negative seconds should throw a gpstk::Exception", __LINE__ ); } catch (...) { testFramework.assert( false, "[testing] CommonTime.setInterval() with negative seconds, [expected] exception gpstk::Exception, [actual] threw wrong exception", __LINE__ ); } //---------------------------------------- // Does a set method work with too many seconds? //---------------------------------------- try { Test.setInternal(700000,24*60*60+1,0.); testFramework.assert( false, "[testing] CommonTime.setInterval() with too many seconds, [expected] exception gpstk::Exception, [actual] threw no exception", __LINE__ ); } catch(gpstk::Exception e) { testFramework.assert( true, "[expected] CommonTime.setInterval() with too many seconds should throw a gpstk::Exception", __LINE__ ); } // catch(...) // { // testFramework.assert( false, "[testing] CommonTime.setInterval() with too many seconds, [expected] exception gpstk::Exception, [actual] threw wrong exception", __LINE__ ); // } //---------------------------------------- // Does a set method work with negative fractional seconds? //---------------------------------------- try { Test.setInternal(700000,1001,-1.); testFramework.assert( false, "[testing] CommonTime.setInterval() with negative fractional seconds, [expected] exception gpstk::Exception, [actual] threw no exception", __LINE__ ); } catch(gpstk::Exception e) { testFramework.assert( true, "[expected] CommonTime.setInterval() with negative fractional seconds should throw a gpstk::Exception", __LINE__ ); } catch (...) { testFramework.assert( false, "[testing] CommonTime.setInterval() with negative fractional seconds, [expected] exception gpstk::Exception, [actual] threw wrong exception", __LINE__ ); } //---------------------------------------- // Does a set method work with too many fractional seconds? //---------------------------------------- try { Test.setInternal(700000,1001,1001.); testFramework.assert( false, "[testing] CommonTime.setInterval() with too many fractional seconds, [expected] exception gpstk::Exception, [actual] threw no exception", __LINE__ ); } catch(gpstk::Exception e) { testFramework.assert( true, "[expected] CommonTime.setInterval() with too many fractional seconds should throw a gpstk::Exception", __LINE__ ); } catch(...) { testFramework.assert( false, "[testing] CommonTime.setInterval() with too many fractional seconds, [expected] exception gpstk::Exception, [actual] threw wrong exception", __LINE__ ); } //---------------------------------------- // The End! //---------------------------------------- return testFramework.countFails(); }
//============================================================ // Test Suite: arithmeticTest() //============================================================ // // Test to check arithmetic operations function properly // //============================================================ int arithmeticTest( void ) { TestUtil testFramework( "CommonTime", "Operators", __FILE__, __LINE__ ); CommonTime Arith1; Arith1.set(700000,1,0.1); CommonTime Arith2(Arith1); //Set second time equal to the first CommonTime Result; long day, day2, sod; double fsod, sod2; testFramework.assert( fabs((Arith1-Arith2) - 0) < eps, "Does it subtract between two CommonTime objects?", __LINE__ ); //---------------------------------------- // Add seconds with + //---------------------------------------- Result = Arith2 + 1; Result.get(day,sod,fsod); testFramework.assert( day == 700000, "Does it not add to the day value?", __LINE__ ); testFramework.assert( sod == 2, "Does it add to the sod value?", __LINE__ ); testFramework.assert( fabs(fsod - 0.1) < eps, "Does it not add to the fsod value?", __LINE__ ); //---------------------------------------- // Subtract seconds with - //---------------------------------------- Result = Arith2 - 1; Result.get(day,sod,fsod); testFramework.assert( day == 700000, "Does it not subtract from the day value?", __LINE__ ); testFramework.assert( sod == 0, "Does it subtract from the sod value?", __LINE__ ); testFramework.assert( fabs(fsod - 0.1) < eps, "Does it not subtract from the fsod value?", __LINE__ ); //---------------------------------------- // Add seconds with += //---------------------------------------- Arith2 += 1; testFramework.assert( fabs((Arith2-Arith1) - 1) < eps, "Does it add to a CommonTime object?", __LINE__ ); testFramework.assert( 1 == Arith2 - Arith1, "Check that values can be compared with integer seconds", __LINE__ ); //---------------------------------------- // Subtract seconds with -= //---------------------------------------- Arith2 -= 1; testFramework.assert(fabs((Arith2-Arith1) - 0) < eps, "Does it subtract from a CommonTime object?", __LINE__ ); //---------------------------------------- // Add days with addDays //---------------------------------------- Arith2.addDays((long)1); day = Arith2.getDays(); testFramework.assert( 700001. == day, "Does the addDays method function correctly with +?", __LINE__ ); // Subtract days with addDays Arith2.addDays((long)-1); day = Arith2.getDays(); testFramework.assert( 700000. == day, "Does the addDays method function correctly with -?", __LINE__ ); // Add seconds with addSeconds(double) Arith2.addSeconds(86400000.+1000.); testFramework.assert(fabs(86401000. - (Arith2-Arith1)) < eps, "Does the addSeconds method function correctly with +?", __LINE__ ); // Subtract seconds with addSeconds(long) Arith2.addSeconds((long)-86401000); testFramework.assert( fabs(0. - (Arith2-Arith1)) < eps, "Does the addSeconds method function correctly with -?", __LINE__ ); // Check that the two parameter get method returns day2 as the proper double Arith2.get(day2, sod2); testFramework.assert( (long)700000 == day2, "Does the 2 parameter get method reuturn days as a double?", __LINE__ ); testFramework.assert( ((double)0. - sod2) < eps, "Does the 2 parameter get method reuturn days as a double?", __LINE__ ); // Check seconds using getSecondOfDay() testFramework.assert( fabs(sod2 - Arith2.getSecondOfDay()) < eps, "Check seconds using getSecondOfDay()", __LINE__ ); // Add milliseconds with addMilliseconds(long) Arith2.addMilliseconds( (long)1 ); testFramework.assert( fabs(sod2+0.001 - Arith2.getSecondOfDay()) < eps, "Does the addMilliseconds method function correctly with +?", __LINE__ ); Arith2.addMilliseconds( (long)-1 ); testFramework.assert(fabs(sod2 - Arith2.getSecondOfDay()) < eps, "Does the addMilliseconds method function correctly with -?", __LINE__ ); //---------------------------------------- // The End! //---------------------------------------- return testFramework.countFails(); }
void scanTime( 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 hmjd( false ), hsow( false ), hweek( false ), hfullweek( false ), hdow( false ), hyear( false ), hmonth( false ), hday( false ), hzcount( false ), hdoy( false ), hzcount29( false ), hzcount32( false ), hhour( false ), hmin( false ), hsec( false ), hsod( false ), hunixsec( false ), hunixusec( false ), hepoch( false ), hansi( false ), hjulian( false ), hbdsw( false ), hqzsw( false ), hgalw( false ), hbdsfw( false ), hqzsfw( false ), hgalfw( false ), hbdse( false ), hqzse( false ), hgale( false); // These are to hold data that no one parses. int idow(0); 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': hmjd = true; break; case 'Z': hzcount = true; break; case 's': hsod = true; break; case 'g': hsow = true; break; case 'w': idow = asInt( itr->second ); hdow = true; break; case 'G': hweek = true; break; case 'F': hfullweek = true; break; case 'j': hdoy = true; break; case 'b': case 'B': hmonth = true; break; case 'Y': case 'y': hyear = true; 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; else { hdow = false; } } break; case 'm': hmonth = true; break; case 'd': hday = true; break; case 'H': hhour = true; break; case 'M': hmin = true; break; case 'S': hsec = true; break; case 'f': hsec = true; // a small hack to make fractional seconds work info['S'] = info['f']; break; case 'U': hunixsec = true; break; case 'u': hunixusec = true; break; case 'c': hzcount29 = true; break; case 'C': hzcount32 = true; break; case 'J': hjulian = true; break; case 'K': hansi = true; break; case 'E': hepoch = true; break; case 'R': hepoch = hbdse = true; break; case 'T': hepoch = hgale = true; break; case 'V': hepoch = hqzse = true; 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; }; } // end loop over Id/Value pairs if( hyear ) { if( hmonth && hday ) { CivilTime tt; tt.setFromInfo( info ); if( hsod ) { convertSODtoTime( asDouble( info['s'] ), tt.hour, tt.minute, tt.second ); } t = tt.convertToCommonTime(); return; } else // use YDSTime as default { YDSTime tt; tt.setFromInfo( info ); if( hhour && hmin && hsec ) { tt.sod = convertTimeToSOD( asInt( info['H'] ), asInt( info['M'] ), asDouble( info['S'] ) ); } t = tt.convertToCommonTime(); return; } } // end of if( hyear ) if( hzcount32 || (hfullweek && hzcount) || (hepoch && (hzcount29 || (hweek && hzcount))) ) { GPSWeekZcount tt; tt.setFromInfo( info ); t = tt.convertToCommonTime(); return; } if ( (hepoch && hweek) || hfullweek ) { WeekSecond* ptt; if(hbdse || hbdsfw || hbdsw) ptt = new BDSWeekSecond(); else if(hqzse || hqzsfw || hqzsw) ptt = new QZSWeekSecond(); else if(hgale || hgalfw || hgalw) ptt = new GALWeekSecond(); else ptt = new GPSWeekSecond(); ptt->setFromInfo(info); if( hdow && !hsow ) { ptt->sow = asInt( info['w'] ) * SEC_PER_DAY; if( hsod ) { ptt->sow += asDouble( info['s'] ); } else if( hhour && hmin && hsec ) { ptt->sow += convertTimeToSOD( asInt( info['H'] ), asInt( info['M'] ), asDouble( info['S'] ) ); } } t = ptt->convertToCommonTime(); return; } if( hmjd ) { MJD tt; tt.setFromInfo( info ); t = tt.convertToCommonTime(); return; } if( hjulian ) { JulianDate tt; tt.setFromInfo( info ); t = tt.convertToCommonTime(); return; } if( hansi ) { ANSITime tt; tt.setFromInfo( info ); t = tt.convertToCommonTime(); return; } if( hunixsec || hunixusec ) { UnixTime tt; tt.setFromInfo( info ); t = tt.convertToCommonTime(); return; } InvalidRequest ir("Incomplete time specification for readTime"); GPSTK_THROW( ir ); } catch( gpstk::StringUtils::StringException& se ) { GPSTK_RETHROW( se ); } }
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 ); } }
/* 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()'
int main(int argc, char *argv[]) { string Usage( "Usage: bc2sp3 <RINEX nav file(s)> [options]\n" " Read RINEX nav file(s) and write to SP3(a or c) file.\n" " Options (defaults):\n" " --in <file> Read the input file <file> (--in is optional, repeatable) ()\n" " --out <file> Name the output file <file> (sp3.out)\n" " --tb <time> Output beginning epoch; <time> = week,sec-of-week (earliest in input)\n" " --te <time> Output ending epoch; <time> = week,sec-of-week (latest in input)\n" " --outputC Output version c (no correlation) (otherwise a)\n" " --msg \"...\" Add ... as a comment to the output header (repeatable)\n" " --verbose Output to screen: dump headers, data, etc\n" " --help Print this message and quit\n" ); if(argc < 2) { cout << Usage; return -1; } try { bool verbose=false; //char version_out='a'; SP3Header::Version version_out(SP3Header::SP3a); int i,j; size_t k,nfile; string fileout("sp3.out"); vector<string> inputFiles; vector<string> comments; map<SatID,long> IODEmap; CommonTime begTime=CommonTime::BEGINNING_OF_TIME; CommonTime endTime=CommonTime::END_OF_TIME; CommonTime tt; GPSEphemerisStore BCEph; SP3Header sp3header; SP3Data sp3data; for(i=1; i<argc; i++) { if(argv[i][0] == '-') { string arg(argv[i]); if(arg == string("--outputC")) { version_out = SP3Header::SP3c; //'c'; if(verbose) cout << " Output version c\n"; } else if(arg == string("--in")) { inputFiles.push_back(string(argv[++i])); if(verbose) cout << " Input file name " << inputFiles[inputFiles.size()-1] << endl; } else if(arg == string("--out")) { fileout = string(argv[++i]); if(verbose) cout << " Output file name " << fileout << endl; } else if(arg == string("--tb")) { arg = string(argv[++i]); int wk=StringUtils::asInt(StringUtils::stripFirstWord(arg,',')); double sow=StringUtils::asDouble(StringUtils::stripFirstWord(arg,',')); begTime=GPSWeekSecond(wk,sow); begTime.setTimeSystem(TimeSystem::GPS); if(verbose) cout << " Begin time " << printTime(begTime,"%Y/%02m/%02d %2H:%02M:%06.3f = %F/%10.3g") << endl; } else if(arg == string("--te")) { arg = string(argv[++i]); int wk=StringUtils::asInt(StringUtils::stripFirstWord(arg,',')); double sow=StringUtils::asDouble(StringUtils::stripFirstWord(arg,',')); endTime=GPSWeekSecond(wk,sow); endTime.setTimeSystem(TimeSystem::GPS); if(verbose) cout << " End time " << printTime(endTime,"%Y/%02m/%02d %2H:%02M:%06.3f = %F/%10.3g") << endl; } else if(arg == string("--msg")) { comments.push_back(string(argv[++i])); if(verbose) cout << " Add comment " << comments[comments.size()-1] << endl; } else if(arg == string("--help")) { cout << Usage; return -1; } else if(arg == string("--verbose")) verbose = true; else cout << "Ignore unknown option: " << arg << endl; } else { inputFiles.push_back(string(argv[i])); if(verbose) cout << " Input file name " << inputFiles[inputFiles.size()-1] << endl; } } if(inputFiles.size() == 0) { cout << "Error - no input filename specified. Abort.\n"; return -1; } // open the output SP3 file SP3Stream outstrm(fileout.c_str(),ios::out); outstrm.exceptions(ifstream::failbit); for(nfile=0; nfile<inputFiles.size(); nfile++) { RinexNavHeader rnh; RinexNavData rnd; RinexNavStream rns(inputFiles[nfile].c_str()); if(!rns) { cout << "Could not open input file " << inputFiles[nfile] << endl; continue; } rns.exceptions(ifstream::failbit); if(verbose) cout << "Reading file " << inputFiles[nfile] << endl; rns >> rnh; if(verbose) { cout << "Input"; rnh.dump(cout); } while(rns >> rnd) if(rnd.health == 0) BCEph.addEphemeris(rnd); } if (verbose) { cout << "Number of ephemerides loaded: " << BCEph.size() << endl; cout << " Initial time: " << printTime(BCEph.getInitialTime(),"%03j.%02H:%02M:%02S, %P") << endl; cout << " Final time: " << printTime(BCEph.getFinalTime(),"%03j.%02H:%02M:%02S, %P") << endl; } // time limits, if not given by user if(begTime == CommonTime::BEGINNING_OF_TIME) begTime = BCEph.getInitialTime(); if(endTime == CommonTime::END_OF_TIME) endTime = BCEph.getFinalTime(); // define the data version and the header info if(version_out == SP3Header::SP3c) { // data and header must have the correct version //sp3data.version = sp3header.version = SP3Header::SP3c; sp3header.system = SP3SatID(); sp3header.timeSystem = TimeSystem::GPS; sp3header.basePV = 0.0; sp3header.baseClk = 0.0; } else { //sp3data.version = sp3header.version = SP3Header::SP3a; //'a'; } // fill the header //sp3header.pvFlag = 'V'; sp3header.containsVelocity = true; sp3header.time = CommonTime::END_OF_TIME; sp3header.epochInterval = 900.0; // hardcoded here only sp3header.dataUsed = "BCE"; sp3header.coordSystem = "WGS84"; sp3header.orbitType = " "; sp3header.agency = "ARL"; // determine which SVs, with accuracy, start time, epoch interval, // number of epochs, for header // this is a pain.... sp3header.numberOfEpochs = 0; tt = begTime; while(tt < endTime) { bool foundSome = false; for(i=1; i<33; i++) { // for each PRN ... SatID sat(i,SatID::systemGPS); try { GPSEphemeris ee = BCEph.findEphemeris(sat, tt); } catch(InvalidRequest& nef) { continue; } if(sp3header.satList.find(sat) == sp3header.satList.end()) { sp3header.satList[sat] = 0; // sat accuracy = ? IODEmap[sat] = -1; } if(!foundSome) { sp3header.numberOfEpochs++; foundSome = true; if(tt < sp3header.time) sp3header.time = tt; } } tt += sp3header.epochInterval; } // add comments if(comments.size() > 0) { // try to keep existing comments for(k=0; k<comments.size(); k++) { if(k > 3) { cout << "Warning - only 4 comments are allowed in SP3 header.\n"; break; } sp3header.comments.push_back(comments[i]); } } // dump the SP3 header if(verbose) sp3header.dump(cout); // write the header outstrm << sp3header; // sigmas to output (version c) for(j=0; j<4; j++) sp3data.sig[j]=0; // sigma = ? tt = begTime; tt.setTimeSystem(TimeSystem::Any); while(tt < endTime) { bool epochOut=false; for(i=1; i<33; i++) { long iode; SatID sat(i,SatID::systemGPS); Xvt xvt; GPSEphemeris ee; try { ee = BCEph.findEphemeris(sat, tt); } catch(InvalidRequest& nef) { continue; } sp3data.sat = sat; xvt = BCEph.getXvt(sat, tt); // epoch if(!epochOut) { sp3data.time = tt; sp3data.RecType = '*'; outstrm << sp3data; if(verbose) sp3data.dump(cout); epochOut = true; } // Position sp3data.RecType = 'P'; for(j=0; j<3; j++) sp3data.x[j] = xvt.x[j]/1000.0; // km // must remove the relativity correction from Xvt::clkbias // see EngEphemeris::svXvt() - also convert to microsec sp3data.clk = (xvt.clkdrift - ee.svRelativity(tt)) * 1000000.0; //if(version_out == 'c') for(j=0; j<4; j++) sp3data.sig[j]=... iode = ee.IODE; if(IODEmap[sat] == -1) IODEmap[sat] = iode; if(IODEmap[sat] != iode) { sp3data.orbitManeuverFlag = true; IODEmap[sat] = iode; } else sp3data.orbitManeuverFlag = false; outstrm << sp3data; if(verbose) sp3data.dump(cout); // Velocity sp3data.RecType = 'V'; for(j=0; j<3; j++) sp3data.x[j] = xvt.v[j]/10.0; // dm/s sp3data.clk = xvt.clkdrift; // s/s //if(version_out == 'c') for(j=0; j<4; j++) sp3data.sig[j]=... outstrm << sp3data; if(verbose) sp3data.dump(cout); } tt += sp3header.epochInterval; } // don't forget this outstrm << "EOF" << endl; outstrm.close(); if(verbose) cout << "Wrote " << sp3header.numberOfEpochs << " records" << endl; } catch (Exception& e) { cout << e; return -1; } catch (...) { cout << "Caught an unknown exception" << endl; return -1; } return 0; }
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; }