diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 65e942829..27a32f12a 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -78,6 +78,10 @@ All notable changes to GNSS-SDR will be documented in this file. ### Improvements in Reliability +- Reduction of the TTFF in GPS L1 and Galileo E1 by improving the frame + synchronization mechanism. +- Bug fix in the Galileo E1/E5 telemetry decoder that produced incorrect timing + information if a satellite is lost and then readquired. - Check satellites' health status. If a satellite is marked as not healthy in its navigation message, the corresponding observables are not used for navigation. diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc index c91185651..95aeb5978 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/galileo_telemetry_decoder_gs.cc @@ -581,6 +581,11 @@ void galileo_telemetry_decoder_gs::set_satellite(const Gnss_Satellite &satellite void galileo_telemetry_decoder_gs::reset() { gr::thread::scoped_lock lock(d_setlock); + d_flag_frame_sync = false; + d_TOW_at_current_symbol_ms = 0; + d_TOW_at_Preamble_ms = 0; + d_fnav_nav.set_flag_TOW_set(false); + d_inav_nav.set_flag_TOW_set(false); d_last_valid_preamble = d_sample_counter; d_sent_tlm_failed_msg = false; d_stat = 0; @@ -840,6 +845,15 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__(( d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast(GALILEO_INAV_PAGE_PART_MS + (d_required_symbols + 1) * d_PRN_code_period_ms); d_inav_nav.set_TOW6_flag(false); } + //warning: type 0 frame does not contain a valid TOW in some simulated signals, thus it is not safe to activate the following code: + // else if (d_inav_nav.is_TOW0_set() == true) // page 0 arrived and decoded + // { + // // TOW_0 refers to the even preamble, but when we decode it we are in the odd part, so 1 second later plus the decoding delay + // d_TOW_at_Preamble_ms = static_cast(d_inav_nav.get_TOW0() * 1000.0); + // d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast(GALILEO_INAV_PAGE_PART_MS + (d_required_symbols + 1) * d_PRN_code_period_ms); + // d_inav_nav.set_TOW0_flag(false); + // //std::cout << "FRAME 0 current tow: " << tmp_d_TOW_at_current_symbol_ms << " vs. " << d_TOW_at_current_symbol_ms + d_PRN_code_period_ms << "\n"; + // } else { // this page has no timing information @@ -955,6 +969,7 @@ int galileo_telemetry_decoder_gs::general_work(int noutput_items __attribute__(( if (d_inav_nav.get_flag_TOW_set() == true or d_fnav_nav.get_flag_TOW_set() == true or d_cnav_nav.get_flag_CRC_test() == true) { + //std::cout << "TOW is set\n"; current_symbol.TOW_at_current_symbol_ms = d_TOW_at_current_symbol_ms; // todo: Galileo to GPS time conversion should be moved to observable block. // current_symbol.TOW_at_current_symbol_ms -= d_delta_t; // Galileo to GPS TOW diff --git a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.cc b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.cc index ca0b986ac..7a294b3f5 100644 --- a/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.cc +++ b/src/algorithms/telemetry_decoder/gnuradio_blocks/gps_l1_ca_telemetry_decoder_gs.cc @@ -294,6 +294,24 @@ bool gps_l1_ca_telemetry_decoder_gs::decode_subframe() switch (subframe_ID) { + case 1: + if (d_nav.satellite_validation() == true) + { + // get ephemeris object for this SV (mandatory) + const std::shared_ptr tmp_obj = std::make_shared(d_nav.get_ephemeris()); + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } + + break; + case 2: + if (d_nav.satellite_validation() == true) + { + // get ephemeris object for this SV (mandatory) + const std::shared_ptr tmp_obj = std::make_shared(d_nav.get_ephemeris()); + this->message_port_pub(pmt::mp("telemetry"), pmt::make_any(tmp_obj)); + } + + break; case 3: // we have a new set of ephemeris data for the current SV if (d_nav.satellite_validation() == true) { @@ -389,63 +407,33 @@ int gps_l1_ca_telemetry_decoder_gs::general_work(int noutput_items __attribute__ if (abs(corr_value) >= d_samples_per_preamble) { d_preamble_index = d_sample_counter; // record the preamble sample stamp + if (corr_value < 0) + { + d_flag_PLL_180_deg_phase_locked = true; + } + else + { + d_flag_PLL_180_deg_phase_locked = false; + } DLOG(INFO) << "Preamble detection for GPS L1 satellite " << this->d_satellite; - decode_subframe(); - d_stat = 1; // enter into frame pre-detection status + if (decode_subframe()) + { + d_CRC_error_counter = 0; + d_flag_preamble = true; // valid preamble indicator (initialized to false every work()) + gr::thread::scoped_lock lock(d_setlock); + d_last_valid_preamble = d_sample_counter; + if (!d_flag_frame_sync) + { + d_flag_frame_sync = true; + DLOG(INFO) << " Frame sync SAT " << this->d_satellite; + } + d_stat = 1; // preamble acquired + } } d_flag_TOW_set = false; break; } - case 1: // possible preamble lock - { - // correlate with preamble - int32_t corr_value = 0; - if (d_symbol_history.size() >= GPS_CA_PREAMBLE_LENGTH_BITS) - { - // ******* preamble correlation ******** - for (int32_t i = 0; i < GPS_CA_PREAMBLE_LENGTH_BITS; i++) - { - if (d_symbol_history[i] < 0.0) // symbols clipping - { - corr_value -= d_preamble_samples[i]; - } - else - { - corr_value += d_preamble_samples[i]; - } - } - } - if (abs(corr_value) >= d_samples_per_preamble) - { - // check preamble separation - const auto preamble_diff = static_cast(d_sample_counter - d_preamble_index); - if (abs(preamble_diff - d_preamble_period_symbols) == 0) - { - DLOG(INFO) << "Preamble confirmation for SAT " << this->d_satellite; - d_preamble_index = d_sample_counter; // record the preamble sample stamp - if (corr_value < 0) - { - d_flag_PLL_180_deg_phase_locked = true; - } - else - { - d_flag_PLL_180_deg_phase_locked = false; - } - decode_subframe(); - d_stat = 2; - } - else - { - if (preamble_diff > d_preamble_period_symbols) - { - d_stat = 0; // start again - d_flag_TOW_set = false; - } - } - } - break; - } - case 2: // preamble acquired + case 1: // preamble acquired { if (d_sample_counter >= d_preamble_index + static_cast(d_preamble_period_symbols)) { diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc index d0f9f550c..491c396dc 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.cc @@ -75,6 +75,7 @@ dll_pll_veml_tracking_sptr dll_pll_veml_make_tracking(const Dll_Pll_Conf &conf_) dll_pll_veml_tracking::dll_pll_veml_tracking(const Dll_Pll_Conf &conf_) : gr::block("dll_pll_veml_tracking", gr::io_signature::make(1, 1, sizeof(gr_complex)), gr::io_signature::make(1, 1, sizeof(Gnss_Synchro))) { + //debug_action1 = false; // prevent telemetry symbols accumulation in output buffers this->set_max_noutput_items(1); d_trk_parameters = conf_; @@ -1981,6 +1982,14 @@ int dll_pll_veml_tracking::general_work(int noutput_items __attribute__((unused) } } } + //*** debug only!! + //force tracking loss after 120 seconds + //if (debug_action1 == false and (static_cast(d_sample_counter) / d_trk_parameters.fs_in >= 120)) + // { + // d_carrier_lock_fail_counter = 200000; // force loss-of-lock condition + // debug_action1 = true; + // } + //************* consume_each(d_current_prn_length_samples); d_sample_counter += static_cast(d_current_prn_length_samples); if (current_synchro_data.Flag_valid_symbol_output || loss_of_lock) diff --git a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h index 71948e4f0..e396c69ce 100644 --- a/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h +++ b/src/algorithms/tracking/gnuradio_blocks/dll_pll_veml_tracking.h @@ -198,6 +198,8 @@ private: bool d_dump_mat; bool d_acc_carrier_phase_initialized; bool d_enable_extended_integration; + //debug only + //bool debug_action1; }; diff --git a/src/algorithms/tracking/libs/dll_pll_conf.cc b/src/algorithms/tracking/libs/dll_pll_conf.cc index 21124543e..86ede0620 100644 --- a/src/algorithms/tracking/libs/dll_pll_conf.cc +++ b/src/algorithms/tracking/libs/dll_pll_conf.cc @@ -34,7 +34,7 @@ Dll_Pll_Conf::Dll_Pll_Conf() enable_fll_pull_in = false; enable_fll_steady_state = false; pull_in_time_s = 10; - bit_synchronization_time_limit_s = pull_in_time_s + 60; + bit_synchronization_time_limit_s = pull_in_time_s + 10; fll_filter_order = 1; pll_filter_order = 3; dll_filter_order = 2; @@ -138,7 +138,7 @@ void Dll_Pll_Conf::SetFromConfiguration(const ConfigurationInterface *configurat enable_fll_steady_state = configuration->property(role + ".enable_fll_steady_state", enable_fll_steady_state); fll_bw_hz = configuration->property(role + ".fll_bw_hz", fll_bw_hz); pull_in_time_s = configuration->property(role + ".pull_in_time_s", pull_in_time_s); - bit_synchronization_time_limit_s = pull_in_time_s + 60; + bit_synchronization_time_limit_s = configuration->property(role + ".bit_synchronization_time_limit_s", bit_synchronization_time_limit_s); early_late_space_chips = configuration->property(role + ".early_late_space_chips", early_late_space_chips); early_late_space_narrow_chips = configuration->property(role + ".early_late_space_narrow_chips", early_late_space_narrow_chips); very_early_late_space_chips = configuration->property(role + ".very_early_late_space_chips", very_early_late_space_chips); diff --git a/src/core/system_parameters/galileo_inav_message.cc b/src/core/system_parameters/galileo_inav_message.cc index 6ede44d85..5d4b09413 100644 --- a/src/core/system_parameters/galileo_inav_message.cc +++ b/src/core/system_parameters/galileo_inav_message.cc @@ -1337,6 +1337,8 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk) WN_0 = static_cast(read_navigation_unsigned(data_jk_bits, WN_0_BIT)); DLOG(INFO) << "WN_0= " << WN_0; TOW_0 = static_cast(read_navigation_unsigned(data_jk_bits, TOW_0_BIT)); + flag_TOW_set = true; // set to false externally + flag_TOW_0 = true; // set to false externally DLOG(INFO) << "TOW_0= " << TOW_0; DLOG(INFO) << "flag_tow_set" << flag_TOW_set; } diff --git a/src/core/system_parameters/galileo_inav_message.h b/src/core/system_parameters/galileo_inav_message.h index eed796dc6..baddaf0b2 100644 --- a/src/core/system_parameters/galileo_inav_message.h +++ b/src/core/system_parameters/galileo_inav_message.h @@ -164,6 +164,21 @@ public: flag_TOW_6 = flag_tow6; } + inline int32_t get_TOW0() const + { + return TOW_0; + } + + inline bool is_TOW0_set() const + { + return flag_TOW_0; + } + + inline void set_TOW0_flag(bool flag_tow0) + { + flag_TOW_0 = flag_tow0; + } + inline bool get_flag_GGTO() const { return (flag_GGTO_1 == true and flag_GGTO_2 == true and flag_GGTO_3 == true and flag_GGTO_4 == true); @@ -395,6 +410,7 @@ private: bool flag_iono_and_GST{}; // Flag indicating that ionospheric and GST parameters (word 5) have been received bool flag_TOW_5{}; bool flag_TOW_6{}; + bool flag_TOW_0{}; bool flag_TOW_set{}; // it is true when page 5 or page 6 arrives bool flag_utc_model{}; // Flag indicating that utc model parameters (word 6) have been received