mirror of
https://github.com/gnss-sdr/gnss-sdr
synced 2025-01-18 21:23:02 +00:00
Fix bug in GLONASS year computation (Fixes: #347)
This commit is contained in:
parent
52980978f5
commit
4ab7690085
@ -70,6 +70,7 @@ SPDX-FileCopyrightText: 2011-2020 Carles Fernandez-Prades <carles.fernandez@cttc
|
||||
### Improvements in Reliability:
|
||||
|
||||
- Fixed a bug in GLONASS GNAV CRC computation.
|
||||
- Fixed a bug in GLONASS time year.
|
||||
- Fixed a possible buffer overflow in the generation of RTCM messages.
|
||||
- Fixed bugs which could cause a random crash on receiver stopping.
|
||||
|
||||
|
@ -11982,6 +11982,23 @@ boost::posix_time::ptime Rinex_Printer::compute_UTC_time(const Glonass_Gnav_Ephe
|
||||
const double glot2utc = 3 * 3600;
|
||||
double obs_time_glot = 0.0;
|
||||
int32_t i = 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 = 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);
|
||||
|
||||
|
@ -27,11 +27,29 @@
|
||||
#include <string>
|
||||
|
||||
|
||||
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<double>((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;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#define GNSS_SDR_GLONASS_GNAV_EPHEMERIS_H
|
||||
|
||||
|
||||
#include "glonass_gnav_utc_model.h"
|
||||
#include <boost/date_time/posix_time/ptime.hpp> // for ptime
|
||||
#include <boost/serialization/nvp.hpp>
|
||||
#include <cstdint>
|
||||
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user