diff --git a/docs/changelog.md b/docs/changelog.md index 6353d23ba..c958a70d0 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -70,6 +70,7 @@ SPDX-FileCopyrightText: 2011-2020 Carles Fernandez-Prades = 1 && eph.d_N_T <= 366) + { + J = 1; + } + else if (eph.d_N_T >= 367 && eph.d_N_T <= 731) + { + J = 2; + } + else if (eph.d_N_T >= 732 && eph.d_N_T <= 1096) + { + J = 3; + } + else if (eph.d_N_T >= 1097 && eph.d_N_T <= 1461) + { + J = 4; + } // Get observation time in nearly GLONASS time. Correction for leap seconds done at the end obs_time_glot = obs_time + glot2utc; @@ -11991,7 +12008,7 @@ boost::posix_time::ptime Rinex_Printer::compute_UTC_time(const Glonass_Gnav_Ephe // Form date and time duration types const boost::posix_time::time_duration t1(0, 0, tod); - const boost::gregorian::date d1(eph.d_yr, 1, 1); + const boost::gregorian::date d1(eph.d_yr - J + 1.0, 1, 1); const boost::gregorian::days d2(eph.d_N_T - 1); const boost::posix_time::ptime glo_time(d1 + d2, t1); @@ -12024,6 +12041,23 @@ double Rinex_Printer::get_leap_second(const Glonass_Gnav_Ephemeris& eph, const d double obs_time_glot = 0.0; int32_t i = 0; double leap_second = 0; + int J = 0; + if (eph.d_N_T >= 1 && eph.d_N_T <= 366) + { + J = 1; + } + else if (eph.d_N_T >= 367 && eph.d_N_T <= 731) + { + J = 2; + } + else if (eph.d_N_T >= 732 && eph.d_N_T <= 1096) + { + J = 3; + } + else if (eph.d_N_T >= 1097 && eph.d_N_T <= 1461) + { + J = 4; + } // Get observation time in nearly GLONASS time. Correction for leap seconds done at the end obs_time_glot = gps_obs_time + glot2utc; @@ -12033,7 +12067,7 @@ double Rinex_Printer::get_leap_second(const Glonass_Gnav_Ephemeris& eph, const d // Form date and time duration types const boost::posix_time::time_duration t1(0, 0, tod); - const boost::gregorian::date d1(eph.d_yr, 1, 1); + const boost::gregorian::date d1(eph.d_yr - J + 1.0, 1, 1); const boost::gregorian::days d2(eph.d_N_T - 1); const boost::posix_time::ptime glo_time(d1 + d2, t1); diff --git a/src/core/system_parameters/glonass_gnav_ephemeris.cc b/src/core/system_parameters/glonass_gnav_ephemeris.cc index ee92c4c1f..c26d60128 100644 --- a/src/core/system_parameters/glonass_gnav_ephemeris.cc +++ b/src/core/system_parameters/glonass_gnav_ephemeris.cc @@ -27,11 +27,29 @@ #include -boost::posix_time::ptime Glonass_Gnav_Ephemeris::compute_GLONASS_time(const double offset_time) const +boost::posix_time::ptime Glonass_Gnav_Ephemeris::compute_GLONASS_time(double offset_time) const { - boost::posix_time::time_duration t(0, 0, offset_time + d_tau_c + d_tau_n); - boost::gregorian::date d1(d_yr, 1, 1); - boost::gregorian::days d2(d_N_T - 1); + int J = 0; + if (d_N_T >= 1 && d_N_T <= 366) + { + J = 1; + } + else if (d_N_T >= 367 && d_N_T <= 731) + { + J = 2; + } + else if (d_N_T >= 732 && d_N_T <= 1096) + { + J = 3; + } + else if (d_N_T >= 1097 && d_N_T <= 1461) + { + J = 4; + } + + const boost::posix_time::time_duration t(0, 0, offset_time + d_tau_c + d_tau_n); + const boost::gregorian::date d1(d_yr - J + 1.0, 1, 1); + const boost::gregorian::days d2(d_N_T - 1); boost::posix_time::ptime glonass_time(d1 + d2, t); return glonass_time; @@ -40,13 +58,29 @@ boost::posix_time::ptime Glonass_Gnav_Ephemeris::compute_GLONASS_time(const doub boost::posix_time::ptime Glonass_Gnav_Ephemeris::glot_to_utc(const double offset_time, const double glot2utc_corr) const { - double tod = 0.0; - double glot2utc = 3 * 3600; + const double glot2utc = 3 * 3600; + int J = 0; + if (d_N_T >= 1 && d_N_T <= 366) + { + J = 1; + } + else if (d_N_T >= 367 && d_N_T <= 731) + { + J = 2; + } + else if (d_N_T >= 732 && d_N_T <= 1096) + { + J = 3; + } + else if (d_N_T >= 1097 && d_N_T <= 1461) + { + J = 4; + } - tod = offset_time - glot2utc + glot2utc_corr + d_tau_n; - 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); + const double tod = offset_time - glot2utc + glot2utc_corr + d_tau_n; + const boost::posix_time::time_duration t(0, 0, tod); + const boost::gregorian::date d1(d_yr - J + 1.0, 1, 1); + const boost::gregorian::days d2(d_N_T - 1); boost::posix_time::ptime utc_time(d1 + d2, t); return utc_time; @@ -55,32 +89,48 @@ boost::posix_time::ptime Glonass_Gnav_Ephemeris::glot_to_utc(const double offset void Glonass_Gnav_Ephemeris::glot_to_gpst(double tod_offset, double glot2utc_corr, double glot2gpst_corr, int32_t* wn, double* tow) const { - double tod = 0.0; - double glot2utc = 3 * 3600; + const double glot2utc = 3 * 3600; double days = 0.0; double total_sec = 0.0; double sec_of_day = 0.0; int i = 0; + int J = 0; + if (d_N_T >= 1 && d_N_T <= 366) + { + J = 1; + } + else if (d_N_T >= 367 && d_N_T <= 731) + { + J = 2; + } + else if (d_N_T >= 732 && d_N_T <= 1096) + { + J = 3; + } + else if (d_N_T >= 1097 && d_N_T <= 1461) + { + J = 4; + } - boost::gregorian::date gps_epoch{1980, 1, 6}; + const boost::gregorian::date gps_epoch{1980, 1, 6}; // tk is relative to UTC(SU) + 3.00 hrs, so we need to convert to utc and add corrections // tk plus 10 sec is the true tod since get_TOW is called when in str5 - tod = tod_offset - glot2utc; + const double tod = tod_offset - glot2utc; - 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 utc_time(d1 + d2, t); - boost::gregorian::date utc_date = utc_time.date(); + const boost::posix_time::time_duration t(0, 0, tod); + const boost::gregorian::date d1(d_yr - J + 1.0, 1, 1); + const boost::gregorian::days d2(d_N_T - 1); + const boost::posix_time::ptime utc_time(d1 + d2, t); + const 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); + const boost::posix_time::time_duration t3(GLONASS_LEAP_SECONDS[i][3], GLONASS_LEAP_SECONDS[i][4], GLONASS_LEAP_SECONDS[i][5]); + const boost::gregorian::date d3(GLONASS_LEAP_SECONDS[i][0], GLONASS_LEAP_SECONDS[i][1], GLONASS_LEAP_SECONDS[i][2]); + const boost::posix_time::ptime ls_time(d3, t3); if (utc_time >= ls_time) { // We add the leap second when going from utc to gpst @@ -90,7 +140,6 @@ void Glonass_Gnav_Ephemeris::glot_to_gpst(double tod_offset, double glot2utc_cor } // Total number of days - std::string fdat = boost::posix_time::to_simple_string(gps_time); days = static_cast((utc_date - gps_epoch).days()); // Total number of seconds @@ -109,9 +158,8 @@ void Glonass_Gnav_Ephemeris::glot_to_gpst(double tod_offset, double glot2utc_cor double Glonass_Gnav_Ephemeris::check_t(double time) { - double corrTime; - double half_day = 43200.0; // seconds - corrTime = time; + const double half_day = 43200.0; // seconds + double corrTime = time; if (time > half_day) { corrTime = time - 2.0 * half_day; @@ -128,8 +176,7 @@ double Glonass_Gnav_Ephemeris::check_t(double time) // 20.3.3.3.3.1 User Algorithm for SV Clock Correction. double Glonass_Gnav_Ephemeris::sv_clock_drift(double transmitTime, double timeCorrUTC) { - double dt; - dt = check_t(transmitTime - d_t_b); + const double dt = check_t(transmitTime - d_t_b); d_satClkDrift = -(d_tau_n + timeCorrUTC - d_gamma_n * dt); // Correct satellite group delay and missing relativistic term here // d_satClkDrift-=d_TGD; diff --git a/src/core/system_parameters/glonass_gnav_ephemeris.h b/src/core/system_parameters/glonass_gnav_ephemeris.h index cf85e4351..07cfd780b 100644 --- a/src/core/system_parameters/glonass_gnav_ephemeris.h +++ b/src/core/system_parameters/glonass_gnav_ephemeris.h @@ -24,6 +24,7 @@ #define GNSS_SDR_GLONASS_GNAV_EPHEMERIS_H +#include "glonass_gnav_utc_model.h" #include // for ptime #include #include @@ -94,7 +95,7 @@ public: * \brief Computes the GLONASS System Time and returns a boost::posix_time::ptime object * \ param offset_time Is the start of day offset to compute the time */ - boost::posix_time::ptime compute_GLONASS_time(const double offset_time) const; + boost::posix_time::ptime compute_GLONASS_time(double offset_time) const; /*! * \brief Converts from GLONASST to UTC 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 aae70cf81..a62b3a924 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 @@ -51,6 +51,60 @@ TEST(GlonassGnavEphemerisTest, ComputeGlonassTime) } +TEST(GlonassGnavEphemerisTest, ComputeGlonassTime2019) +{ + Glonass_Gnav_Ephemeris gnav_eph; + gnav_eph.d_yr = 2019; + gnav_eph.d_N_T = 1366; + boost::posix_time::time_duration t(0, 0, 7560); + boost::gregorian::date d(gnav_eph.d_yr, 1, 1); + boost::gregorian::days d2(gnav_eph.d_N_T); + d = d + d2; + + boost::gregorian::date expected_gdate; + boost::posix_time::time_duration expected_gtime; + + boost::posix_time::ptime gtime = gnav_eph.compute_GLONASS_time(7560); + expected_gdate = gtime.date(); + expected_gtime = gtime.time_of_day(); + + // Perform assertions of decoded fields + ASSERT_TRUE(expected_gdate.year() - d.year() < FLT_EPSILON); + ASSERT_TRUE(expected_gdate.month() - d.month() < FLT_EPSILON); + ASSERT_TRUE(expected_gdate.day() - d.day() < FLT_EPSILON); + ASSERT_TRUE(expected_gtime.hours() - t.hours() < FLT_EPSILON); + ASSERT_TRUE(expected_gtime.minutes() - t.minutes() < FLT_EPSILON); + ASSERT_TRUE(expected_gtime.seconds() - t.seconds() < FLT_EPSILON); +} + + +TEST(GlonassGnavEphemerisTest, ComputeGlonassTime2020) +{ + Glonass_Gnav_Ephemeris gnav_eph; + gnav_eph.d_yr = 2020; + gnav_eph.d_N_T = 62; + boost::posix_time::time_duration t(0, 0, 7560); + boost::gregorian::date d(gnav_eph.d_yr, 1, 1); + boost::gregorian::days d2(gnav_eph.d_N_T); + d = d + d2; + + boost::gregorian::date expected_gdate; + boost::posix_time::time_duration expected_gtime; + + boost::posix_time::ptime gtime = gnav_eph.compute_GLONASS_time(7560); + expected_gdate = gtime.date(); + expected_gtime = gtime.time_of_day(); + + // Perform assertions of decoded fields + ASSERT_TRUE(expected_gdate.year() - d.year() < FLT_EPSILON); + ASSERT_TRUE(expected_gdate.month() - d.month() < FLT_EPSILON); + ASSERT_TRUE(expected_gdate.day() - d.day() < FLT_EPSILON); + ASSERT_TRUE(expected_gtime.hours() - t.hours() < FLT_EPSILON); + ASSERT_TRUE(expected_gtime.minutes() - t.minutes() < FLT_EPSILON); + ASSERT_TRUE(expected_gtime.seconds() - t.seconds() < FLT_EPSILON); +} + + /*! * \brief Testing conversion from GLONASST to GPST * \test Tests scenario for N_T when greater than 365 days. Possible values here from 1 to 365*4 @@ -127,3 +181,47 @@ TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT3) ASSERT_TRUE(week - true_week < FLT_EPSILON); ASSERT_TRUE(tow - true_tow < FLT_EPSILON); } + + +TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT4) +{ + Glonass_Gnav_Ephemeris gnav_eph; + gnav_eph.d_yr = 2019; + gnav_eph.d_N_T = 1366; + + double glo2utc = 3600 * 3; + double tod = 7560; + int week = 0.0; + double tow = 0.0; + double true_leap_sec = 18; + double true_week = 2072; + double true_tow = 447120 + true_leap_sec + tod; + + gnav_eph.glot_to_gpst(tod + glo2utc, 0.0, 0.0, &week, &tow); + + // Perform assertions of decoded fields + ASSERT_TRUE(week - true_week < FLT_EPSILON); + ASSERT_TRUE(tow - true_tow < FLT_EPSILON); +} + + +TEST(GlonassGnavEphemerisTest, ConvertGlonassT2GpsT5) +{ + Glonass_Gnav_Ephemeris gnav_eph; + gnav_eph.d_yr = 2020; + gnav_eph.d_N_T = 62; + + double glo2utc = 3600 * 3; + double tod = 7560; + int week = 0.0; + double tow = 0.0; + double true_leap_sec = 18; + double true_week = 2095; + double true_tow = 259200 + true_leap_sec + tod; + + gnav_eph.glot_to_gpst(tod + glo2utc, 0.0, 0.0, &week, &tow); + + // Perform assertions of decoded fields + ASSERT_TRUE(week - true_week < FLT_EPSILON); + ASSERT_TRUE(tow - true_tow < FLT_EPSILON); +}