From aa2464cc28631b40cec925eb52eba7c1c8f41e44 Mon Sep 17 00:00:00 2001 From: Damian Miralles Date: Tue, 26 Dec 2017 10:29:09 -0700 Subject: [PATCH] glonass bug fix: Adds more reliable GPST 2 UTC conversion Adds logic to check for exact epoch when performing leap second correction and also fixes unit test in code for GLONASS --- src/algorithms/PVT/libs/rinex_printer.cc | 28 ++++++++------- src/algorithms/PVT/libs/rinex_printer.h | 2 +- src/core/system_parameters/GLONASS_L1_CA.h | 12 ++++--- .../glonass_gnav_ephemeris.cc | 34 +++++++++++-------- .../pvt/rinex_printer_test.cc | 5 +-- .../glonass_gnav_ephemeris_test.cc | 2 +- .../glonass_gnav_nav_message_test.cc | 3 ++ 7 files changed, 51 insertions(+), 35 deletions(-) diff --git a/src/algorithms/PVT/libs/rinex_printer.cc b/src/algorithms/PVT/libs/rinex_printer.cc index 3e5b8fd97..0a14e63cb 100644 --- a/src/algorithms/PVT/libs/rinex_printer.cc +++ b/src/algorithms/PVT/libs/rinex_printer.cc @@ -7398,18 +7398,8 @@ boost::posix_time::ptime Rinex_Printer::compute_UTC_time(const Glonass_Gnav_Ephe double obs_time_utc = 0.0, obs_time_glot = 0.0; int i = 0; - // GLONASST already includes leap second addition or deletion - for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) - { - if (eph.d_yr >= GLONASS_LEAP_SECONDS[i][0]) - { - // We substract the leap second when going from gpst to utc - obs_time_utc = obs_time - fabs(GLONASS_LEAP_SECONDS[i][6]); - break; - } - } - // Get observation time in GLONASS time - obs_time_glot = obs_time_utc + glot2utc; + // Get observation time in nearly GLONASS time. Correction for leap seconds done at the end + obs_time_glot = obs_time + glot2utc; // Get seconds of day in glonass time tod = fmod (obs_time_glot, 86400); @@ -7424,6 +7414,20 @@ boost::posix_time::ptime Rinex_Printer::compute_UTC_time(const Glonass_Gnav_Ephe boost::posix_time::time_duration t2(0, 0, glot2utc); boost::posix_time::ptime utc_time = glo_time - t2; + // Adjust for leap second correction + for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) + { + boost::posix_time::time_duration t3(GLONASS_LEAP_SECONDS[i][3], GLONASS_LEAP_SECONDS[i][4], GLONASS_LEAP_SECONDS[i][5]); + boost::gregorian::date d3(GLONASS_LEAP_SECONDS[i][0], GLONASS_LEAP_SECONDS[i][1], GLONASS_LEAP_SECONDS[i][2]); + boost::posix_time::ptime ls_time(d3, t3); + if (utc_time >= ls_time) + { + // We subtract the leap second when going from gpst to utc + utc_time = utc_time - boost::posix_time::time_duration(0,0,fabs(GLONASS_LEAP_SECONDS[i][6])); + break; + } + } + return utc_time; } diff --git a/src/algorithms/PVT/libs/rinex_printer.h b/src/algorithms/PVT/libs/rinex_printer.h index 74f7b1262..f061a93f4 100644 --- a/src/algorithms/PVT/libs/rinex_printer.h +++ b/src/algorithms/PVT/libs/rinex_printer.h @@ -156,7 +156,7 @@ public: /*! * \brief Generates the GLONASS GNAV Observation data header. Example: bands("1C"), bands("1C 2C"), bands("2C"), ... Default: "1C". */ - void rinex_obs_header(std::fstream & out, const Glonass_Gnav_Ephemeris & eph, const double d_TOW_first_observation, const std::string bands = "1C"); + void rinex_obs_header(std::fstream & out, const Glonass_Gnav_Ephemeris & eph, const double d_TOW_first_observation, const std::string bands = "1G"); /*! * \brief Generates the Mixed (GPS L1 C/A /GLONASS) Observation data header. Example: galileo_bands("1C"), galileo_bands("1B 5X"), galileo_bands("5X"), ... Default: "1B". diff --git a/src/core/system_parameters/GLONASS_L1_CA.h b/src/core/system_parameters/GLONASS_L1_CA.h index 4e97fe121..28c634ff3 100644 --- a/src/core/system_parameters/GLONASS_L1_CA.h +++ b/src/core/system_parameters/GLONASS_L1_CA.h @@ -89,8 +89,12 @@ const double GLONASS_L1_CA_CHIP_PERIOD = 1.9569e-06; //!< GLONASS L1 C/ const double GLONASS_L1_CA_SYMBOL_RATE_BPS = 1000; const int GLONASS_L1_CA_NBR_SATS = 24; // STRING DATA WITHOUT PREAMBLE -//FIXME Probably should use leap seconds definitions of rtklib -const double GLONASS_LEAP_SECONDS[21][7] = { /* leap seconds (y,m,d,h,m,s,utc-gpst) */ +/*! + * \brief Record of leap seconds definition for GLOT to GPST conversion and vice versa + * \details Each entry is defined by an array of 7 elements consisting of yr,month,day,hr,min,sec,utc-gpst + * \note Ideally should use leap seconds definitions of rtklib + */ +const double GLONASS_LEAP_SECONDS[19][7] = { {2017, 1, 1, 0, 0, 0, -18}, {2015, 7, 1, 0, 0, 0, -17}, {2012, 7, 1, 0, 0, 0, -16}, @@ -112,7 +116,7 @@ const double GLONASS_LEAP_SECONDS[21][7] = { /* leap seconds (y,m,d,h,m,s,utc-gp {} }; -// GLONASS SV's orbital slots PRN = (orbital_slot - 1) +//!< GLONASS SV's orbital slots PRN = (orbital_slot - 1) const std::map GLONASS_PRN = {{ 0, 8,}, //For test { 1, 1,}, //Plane 1 @@ -134,7 +138,7 @@ const std::map GLONASS_PRN = {17, 4,}, //Plane 3 {18,-3,}, //Plane 3 {19, 3,}, //Plane 3 - {20, -5,}, //Plane 3 + {20,-5,}, //Plane 3 {21, 4,}, //Plane 3 {22,-3,}, //Plane 3 {23, 3,}, //Plane 3 diff --git a/src/core/system_parameters/glonass_gnav_ephemeris.cc b/src/core/system_parameters/glonass_gnav_ephemeris.cc index 2ac9294db..6cd530c59 100644 --- a/src/core/system_parameters/glonass_gnav_ephemeris.cc +++ b/src/core/system_parameters/glonass_gnav_ephemeris.cc @@ -124,28 +124,32 @@ void Glonass_Gnav_Ephemeris::glot_to_gpst(double tod_offset, double glot2utc_cor boost::posix_time::time_duration t(0, 0, tod); boost::gregorian::date d1(d_yr, 1, 1); boost::gregorian::days d2(d_N_T-1); - boost::posix_time::ptime glonass_time(d1+d2, t); - boost::gregorian::date utc_date = glonass_time.date(); + boost::posix_time::ptime utc_time(d1+d2, t); + boost::gregorian::date utc_date = utc_time.date(); + boost::posix_time::ptime gps_time; + + // Adjust for leap second correction + for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) + { + boost::posix_time::time_duration t3(GLONASS_LEAP_SECONDS[i][3], GLONASS_LEAP_SECONDS[i][4], GLONASS_LEAP_SECONDS[i][5]); + boost::gregorian::date d3(GLONASS_LEAP_SECONDS[i][0], GLONASS_LEAP_SECONDS[i][1], GLONASS_LEAP_SECONDS[i][2]); + boost::posix_time::ptime ls_time(d3, t3); + if (utc_time >= ls_time) + { + // We add the leap second when going from utc to gpst + gps_time = utc_time + boost::posix_time::time_duration(0,0,fabs(GLONASS_LEAP_SECONDS[i][6])); + break; + } + } // Total number of days - std::string fdat = boost::posix_time::to_simple_string(glonass_time); + std::string fdat = boost::posix_time::to_simple_string(gps_time); days = static_cast((utc_date - gps_epoch).days()); // Total number of seconds - sec_of_day = static_cast((glonass_time.time_of_day()).total_seconds()); + sec_of_day = static_cast((gps_time.time_of_day()).total_seconds()); total_sec = days*86400 + sec_of_day; - // GLONASST already includes leap second addition or deletion - for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) - { - if (d_yr >= GLONASS_LEAP_SECONDS[i][0]) - { - // We add the leap second when going from utc to gpst - total_sec += fabs(GLONASS_LEAP_SECONDS[i][6]); - break; - } - } - // Compute Week number *wn = floor(total_sec/604800); diff --git a/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc b/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc index 33ed3965c..ceb2d8373 100644 --- a/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc +++ b/src/tests/unit-tests/signal-processing-blocks/pvt/rinex_printer_test.cc @@ -95,8 +95,9 @@ TEST(RinexPrinterTest, GlonassObsHeader) const Glonass_Gnav_Ephemeris eph = Glonass_Gnav_Ephemeris(); std::shared_ptr rp1; - rp1 = std::make_shared(); - rp1->rinex_obs_header(rp1->obsFile, eph, 0.0); + rp1 = std::make_shared(3); + const std::string bands = "1G"; + rp1->rinex_obs_header(rp1->obsFile, eph, 0.0, bands); rp1->obsFile.seekp(0); while(!rp1->obsFile.eof()) diff --git a/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc b/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc index da5571399..7026903e2 100644 --- a/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc +++ b/src/tests/unit-tests/system-parameters/glonass_gnav_ephemeris_test.cc @@ -130,7 +130,7 @@ TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT3) double tow = 0.0; double true_leap_sec = 17; double true_week = 1886; - double true_tow = 259200+true_leap_sec; + double true_tow = 259200+true_leap_sec+tod; gnav_eph.glot_to_gpst(tod + glo2utc, 0.0, 0.0, &week, &tow); diff --git a/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc b/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc index 5fabb4676..595b1fa2f 100644 --- a/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc +++ b/src/tests/unit-tests/system-parameters/glonass_gnav_nav_message_test.cc @@ -172,6 +172,7 @@ TEST(GlonassGnavNavigationMessageTest, String3Decoder) gnav_ephemeris.d_Zn = 19929.2377929688; // Call target test method + gnav_nav_message.flag_ephemeris_str_2 = true; gnav_nav_message.string_decoder(str3); // Perform assertions of decoded fields @@ -209,6 +210,7 @@ TEST(GlonassGnavNavigationMessageTest, String4Decoder) gnav_ephemeris.d_M = 1; // Call target test method + gnav_nav_message.flag_ephemeris_str_3 = true; gnav_nav_message.string_decoder(str4); // Perform assertions of decoded fields @@ -243,6 +245,7 @@ TEST(GlonassGnavNavigationMessageTest, String5Decoder) gnav_utc_model.d_tau_gps = 9.313225746154785e-08; // Call target test method + gnav_nav_message.flag_ephemeris_str_4 = true; gnav_nav_message.string_decoder(str5); // Perform assertions of decoded fields