TTFF reduction in GPS L1 and Galileo E1

This commit is contained in:
Javier Arribas 2021-08-03 14:03:27 +02:00
parent b4b9c31182
commit 23a2d3ef89
8 changed files with 90 additions and 54 deletions

View File

@ -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.

View File

@ -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<uint32_t>(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<uint32_t>(d_inav_nav.get_TOW0() * 1000.0);
// d_TOW_at_current_symbol_ms = d_TOW_at_Preamble_ms + static_cast<uint32_t>(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

View File

@ -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<Gps_Ephemeris> tmp_obj = std::make_shared<Gps_Ephemeris>(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<Gps_Ephemeris> tmp_obj = std::make_shared<Gps_Ephemeris>(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<int32_t>(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<uint64_t>(d_preamble_period_symbols))
{

View File

@ -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<double>(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<uint64_t>(d_current_prn_length_samples);
if (current_synchro_data.Flag_valid_symbol_output || loss_of_lock)

View File

@ -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;
};

View File

@ -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);

View File

@ -1337,6 +1337,8 @@ int32_t Galileo_Inav_Message::page_jk_decoder(const char* data_jk)
WN_0 = static_cast<int32_t>(read_navigation_unsigned(data_jk_bits, WN_0_BIT));
DLOG(INFO) << "WN_0= " << WN_0;
TOW_0 = static_cast<int32_t>(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;
}

View File

@ -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