From cd0d65ecc056f2def7f0c8bd0aaeb92e3661aabb Mon Sep 17 00:00:00 2001 From: Damian Miralles Date: Fri, 22 Sep 2017 12:16:26 -0600 Subject: [PATCH] bugfix: Fix computation of TOW value for GLONASS GNAV Fixes the TOW computation mapping from GLONASS Time to UTC time and then conversion to TOW and WN. The logic of the conversion considers time offsets but may need to be reviewed. --- conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf | 12 +- .../PVT/gnuradio_blocks/rtklib_pvt_cc.cc | 6 +- src/core/receiver/gnss_flowgraph.cc | 2 +- src/core/system_parameters/GLONASS_L1_CA.h | 3 +- .../glonass_gnav_navigation_message.cc | 138 ++++++++++++++---- .../glonass_gnav_navigation_message.h | 10 +- 6 files changed, 132 insertions(+), 39 deletions(-) diff --git a/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf b/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf index a5bb1572f..9bec04bd9 100644 --- a/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf +++ b/conf/gnss-sdr_GLONASS_L1_CA_ibyte.conf @@ -5,7 +5,7 @@ GNSS-SDR.internal_fs_sps=6625000 ;######### SIGNAL_SOURCE CONFIG ############ SignalSource.implementation=File_Signal_Source -SignalSource.filename=/archive/NT1065_GLONASS_L1_20160831_fs6625e6_if0e3_schar_1m.bin ; <- PUT YOUR FILE HERE +SignalSource.filename=/archive/NT1065_GLONASS_L1_20160923_fs6625e6_if0e3_schar.bin ; <- PUT YOUR FILE HERE SignalSource.item_type=ibyte SignalSource.sampling_frequency=6625000 ;SignalSource.freq=0 @@ -29,11 +29,11 @@ Channel.signal=1G Channels.in_acquisition=1 Channels_1G.count=5 -Channel0.satellite=11 -Channel1.satellite=2 -Channel2.satellite=18 -Channel3.satellite=12 -Channel4.satellite=21 +Channel0.satellite=24 ; k= +Channel1.satellite=1 ; k=1 +Channel2.satellite=2 ; k=-4 +Channel3.satellite=20 ; k=-5 +Channel4.satellite=21 ; k=4 ;######### ACQUISITION GLOBAL CONFIG ############ Acquisition_1G.implementation=GLONASS_L1_CA_PCPS_Acquisition diff --git a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc index f5bf5e503..85e6bba5e 100644 --- a/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc +++ b/src/algorithms/PVT/gnuradio_blocks/rtklib_pvt_cc.cc @@ -191,7 +191,8 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg) // insert new ephemeris record DLOG(INFO) << "GLONASS GNAV New Ephemeris record inserted in global map with TOW =" << glonass_gnav_eph->d_TOW << ", GLONASS GNAV Week Number =" << glonass_gnav_eph->d_WN - << " and Ephemeris IOD = " << glonass_gnav_eph->compute_GLONASS_time(glonass_gnav_eph->d_t_b); + << " and Ephemeris IOD = " << glonass_gnav_eph->compute_GLONASS_time(glonass_gnav_eph->d_t_b) + << " from SV = " << glonass_gnav_eph->i_satellite_slot_number; // update/insert new ephemeris record to the global ephemeris map d_ls_pvt->glonass_gnav_ephemeris_map[glonass_gnav_eph->i_satellite_PRN] = *glonass_gnav_eph; } @@ -209,7 +210,8 @@ void rtklib_pvt_cc::msg_handler_telemetry(pmt::pmt_t msg) std::shared_ptr glonass_gnav_almanac; glonass_gnav_almanac = boost::any_cast>(pmt::any_ref(msg)); d_ls_pvt->glonass_gnav_almanac = *glonass_gnav_almanac; - DLOG(INFO) << "New GLONASS GNAV Almanac has arrived "; + DLOG(INFO) << "New GLONASS GNAV Almanac has arrived " + << ", GLONASS GNAV Slot Number =" << glonass_gnav_almanac->d_n_A; } else { diff --git a/src/core/receiver/gnss_flowgraph.cc b/src/core/receiver/gnss_flowgraph.cc index c83bf1e92..388eb5dce 100644 --- a/src/core/receiver/gnss_flowgraph.cc +++ b/src/core/receiver/gnss_flowgraph.cc @@ -598,7 +598,7 @@ void GNSSFlowgraph::set_signals_list() 29, 30, 31, 32, 33, 34, 35, 36}; // Removing satellites sharing same frequency number(1 and 5, 2 and 6, 3 and 7, 4 and 6, 11 and 15, 12 and 16, 14 and 18, 17 and 21 - std::set available_glonass_prn = { 1, 2, 3, 4, 9, 10, 11, 12, 18, 19, 20, 21 }; + std::set available_glonass_prn = { 1, 2, 3, 4, 9, 10, 11, 12, 18, 19, 20, 21, 24 }; std::string sv_list = configuration_->property("Galileo.prns", std::string("") ); diff --git a/src/core/system_parameters/GLONASS_L1_CA.h b/src/core/system_parameters/GLONASS_L1_CA.h index 79e43cc10..83a768c93 100644 --- a/src/core/system_parameters/GLONASS_L1_CA.h +++ b/src/core/system_parameters/GLONASS_L1_CA.h @@ -87,6 +87,7 @@ const double GLONASS_L1_CA_CODE_LENGTH_CHIPS = 511.0; //!< GLONASS L1 C/ const double GLONASS_L1_CA_CODE_PERIOD = 0.001; //!< GLONASS L1 C/A code period [seconds] const double GLONASS_L1_CA_CHIP_PERIOD = 1.9569e-06; //!< GLONASS L1 C/A chip period [seconds] 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) */ @@ -135,7 +136,7 @@ const std::map GLONASS_PRN = {17, 4,}, //Plane 3 {18,-3,}, //Plane 3 {19, 3,}, //Plane 3 - {20, 2,}, //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_navigation_message.cc b/src/core/system_parameters/glonass_gnav_navigation_message.cc index ca5b4a9d0..5bec42b38 100644 --- a/src/core/system_parameters/glonass_gnav_navigation_message.cc +++ b/src/core/system_parameters/glonass_gnav_navigation_message.cc @@ -89,6 +89,11 @@ void Glonass_Gnav_Navigation_Message::reset() d_dtr = 0.0; d_satClkDrift = 0.0; + // Data update information + d_previous_tb = 0.0; + for(unsigned int i = 0; i < GLONASS_L1_CA_NBR_SATS; i++) + d_previous_Na[i] = 0.0; + std::map satelliteBlock; //!< Map that stores to which block the PRN belongs http://www.navcen.uscg.gov/?Do=constellationStatus @@ -314,23 +319,74 @@ unsigned int Glonass_Gnav_Navigation_Message::get_frame_number(unsigned int sate return frame_ID; } +double Glonass_Gnav_Navigation_Message::get_WN() +{ + double WN = 0.0; + double days = 0.0; + double total_sec = 0.0; + int i = 0; + + boost::gregorian::date gps_epoch { 1980, 1, 6 }; + // Map to UTC + boost::gregorian::date glo_date(gnav_ephemeris.d_yr, 1, 1); + boost::gregorian::days d2(gnav_ephemeris.d_N_T); + glo_date = glo_date + d2; + + + boost::posix_time::time_duration t(-6, 0, 0); + boost::posix_time::ptime glo_time(glo_date, t); + boost::gregorian::date utc_date = glo_time.date(); + + days = static_cast((utc_date - gps_epoch).days()); + total_sec = days*86400; + + for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) + { + if (GLONASS_LEAP_SECONDS[i][0] == gnav_ephemeris.d_yr) + { + // We add the leap second when going from utc to gpst + total_sec += GLONASS_LEAP_SECONDS[i][6]; + } + } + + + WN = floor(total_sec/604800); + + return WN; +} + double Glonass_Gnav_Navigation_Message::get_TOW() { + double TOD = 0.0; double TOW = 0.0; + double dayofweek = 0.0; double utcsu2utc = 3*3600; double glot2utcsu = 3*3600; int i = 0; - TOW = gnav_ephemeris.d_t_k + glot2utcsu + utcsu2utc + gnav_utc_model.d_tau_c + gnav_utc_model.d_tau_gps; + // tk is relative to UTC(SU) + 3.00 hrs, so we need to convert to utc and add corrections + TOD = gnav_ephemeris.d_t_k - glot2utcsu - utcsu2utc + gnav_utc_model.d_tau_c + gnav_utc_model.d_tau_gps; + + + boost::gregorian::date glo_date(gnav_ephemeris.d_yr, 1, 1); + boost::gregorian::days d2(gnav_ephemeris.d_N_T); + glo_date = glo_date + d2; + + dayofweek = static_cast(glo_date.day_of_week()); + TOW = TOD + dayofweek*86400; for (i = 0; GLONASS_LEAP_SECONDS[i][0]>0; i++) { if (GLONASS_LEAP_SECONDS[i][0] == gnav_ephemeris.d_yr) { - TOW -= GLONASS_LEAP_SECONDS[i][6]; + // We add the leap second when going from utc to gpst + TOW += GLONASS_LEAP_SECONDS[i][6]; } } + // Compute the arithmetic modules to wrap around range + TOW = TOW - 604800*floor(TOW/604800); + return TOW; } @@ -342,13 +398,14 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) d_frame_ID = 0; // Unpack bytes to bits - std::bitset string_bits = std::bitset((frame_string)); + std::bitset string_bits (frame_string); // Perform data verification and exit code if error in bit sequence flag_CRC_test = CRC_test(string_bits); if(flag_CRC_test == false) return 0; + // Decode all 15 string messages d_string_ID = static_cast(read_navigation_unsigned(string_bits, STRING_ID)); switch (d_string_ID) { @@ -461,6 +518,8 @@ int Glonass_Gnav_Navigation_Message::string_decoder(std::string frame_string) if (flag_ephemeris_str_1 == true) { d_TOW = get_TOW(); + gnav_ephemeris.d_TOW = d_TOW; + gnav_ephemeris.d_WN = get_WN(); flag_TOW_set = true; } @@ -730,20 +789,29 @@ Glonass_Gnav_Almanac Glonass_Gnav_Navigation_Message::get_almanac(unsigned int s bool Glonass_Gnav_Navigation_Message::have_new_ephemeris() //Check if we have a new ephemeris stored in the galileo navigation class { + bool new_eph = false; // We need to make sure we have received the ephemeris info plus the time info if ((flag_ephemeris_str_1 == true) and (flag_ephemeris_str_2 == true) and (flag_ephemeris_str_3 == true) and (flag_ephemeris_str_4 == true) and (flag_utc_model_str_5 == true)) { - flag_ephemeris_str_1 = false;// clear the flag - flag_ephemeris_str_2 = false;// clear the flag - flag_ephemeris_str_3 = false;// clear the flag - flag_ephemeris_str_4 = false;// clear the flag - flag_all_ephemeris = true; - DLOG(INFO) << "GLONASS GNAV Ephemeris (1, 2, 3, 4) have been received and belong to the same batch" << std::endl; + if(d_previous_tb != gnav_ephemeris.d_t_b) + { + flag_ephemeris_str_1 = false;// clear the flag + flag_ephemeris_str_2 = false;// clear the flag + flag_ephemeris_str_3 = false;// clear the flag + flag_ephemeris_str_4 = false;// clear the flag + flag_all_ephemeris = true; + // Update the time of ephemeris information + d_previous_tb = gnav_ephemeris.d_t_b; + DLOG(INFO) << "GLONASS GNAV Ephemeris (1, 2, 3, 4) have been received and belong to the same batch" << std::endl; + new_eph = true; + } + } - else - return false; + + + return new_eph; } @@ -764,34 +832,50 @@ bool Glonass_Gnav_Navigation_Message::have_new_almanac() //Check if we have a ne bool new_alm = false; if ((flag_almanac_str_6 == true) and (flag_almanac_str_7 == true)) { - //All almanac have been received for this satellite - flag_almanac_str_6 = false; - flag_almanac_str_7 = false; - new_alm = true; + if (d_previous_Na[i_alm_satellite_slot_number] != gnav_utc_model.d_N_A) + { + //All almanac have been received for this satellite + flag_almanac_str_6 = false; + flag_almanac_str_7 = false; + new_alm = true; + } + } if ((flag_almanac_str_8 == true) and (flag_almanac_str_9 == true)) { - flag_almanac_str_8 = false; - flag_almanac_str_9 = false; - new_alm = true; + if (d_previous_Na[i_alm_satellite_slot_number] != gnav_utc_model.d_N_A) + { + flag_almanac_str_8 = false; + flag_almanac_str_9 = false; + new_alm = true; + } } if((flag_almanac_str_10 == true) and (flag_almanac_str_11 == true)) { - flag_almanac_str_10 = false; - flag_almanac_str_11 = false; - new_alm = true; + if (d_previous_Na[i_alm_satellite_slot_number] != gnav_utc_model.d_N_A) + { + flag_almanac_str_10 = false; + flag_almanac_str_11 = false; + new_alm = true; + } } if((flag_almanac_str_12 == true) and (flag_almanac_str_13 == true)) { - flag_almanac_str_12 = false; - flag_almanac_str_13 = false; - new_alm = true; + if (d_previous_Na[i_alm_satellite_slot_number] != gnav_utc_model.d_N_A) + { + flag_almanac_str_12 = false; + flag_almanac_str_13 = false; + new_alm = true; + } } if((flag_almanac_str_14 == true) and (flag_almanac_str_15 == true)) { - flag_almanac_str_14 = false; - flag_almanac_str_15 = false; - new_alm = true; + if (d_previous_Na[i_alm_satellite_slot_number] != gnav_utc_model.d_N_A) + { + flag_almanac_str_14 = false; + flag_almanac_str_15 = false; + new_alm = true; + } } return new_alm; diff --git a/src/core/system_parameters/glonass_gnav_navigation_message.h b/src/core/system_parameters/glonass_gnav_navigation_message.h index 0ebe59d74..cf2ac3750 100644 --- a/src/core/system_parameters/glonass_gnav_navigation_message.h +++ b/src/core/system_parameters/glonass_gnav_navigation_message.h @@ -67,9 +67,9 @@ public: Glonass_Gnav_Ephemeris gnav_ephemeris; //!< Ephemeris information decoded Glonass_Gnav_Utc_Model gnav_utc_model; //!< UTC model information - Glonass_Gnav_Almanac gnav_almanac[24]; //!< Almanac information for all 24 satellites + Glonass_Gnav_Almanac gnav_almanac[GLONASS_L1_CA_NBR_SATS]; //!< Almanac information for all 24 satellites - //!< Ephmeris Flags + //!< Ephmeris Flags and control variables bool flag_all_ephemeris; //!< Flag indicating that all strings containing ephemeris have been received bool flag_ephemeris_str_1; //!< Flag indicating that ephemeris 1/4 (string 1) have been received bool flag_ephemeris_str_2; //!< Flag indicating that ephemeris 2/4 (string 2) have been received @@ -108,6 +108,10 @@ public: double d_dtr; // Relativistic clock correction term double d_satClkDrift; // Satellite clock drift + // Data update parameters + double d_previous_tb; + double d_previous_Na[GLONASS_L1_CA_NBR_SATS]; + bool CRC_test(std::bitset bits); unsigned int get_frame_number(unsigned int satellite_slot_number); @@ -159,6 +163,8 @@ public: */ double get_TOW(); + double get_WN(); + /*! * \brief Computes the Coordinated Universal Time (UTC) and returns it in [s] */