1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2024-12-14 04:00:34 +00:00

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 ### 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 - Check satellites' health status. If a satellite is marked as not healthy in
its navigation message, the corresponding observables are not used for its navigation message, the corresponding observables are not used for
navigation. navigation.

View File

@ -581,6 +581,11 @@ void galileo_telemetry_decoder_gs::set_satellite(const Gnss_Satellite &satellite
void galileo_telemetry_decoder_gs::reset() void galileo_telemetry_decoder_gs::reset()
{ {
gr::thread::scoped_lock lock(d_setlock); 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_last_valid_preamble = d_sample_counter;
d_sent_tlm_failed_msg = false; d_sent_tlm_failed_msg = false;
d_stat = 0; 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_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); 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 else
{ {
// this page has no timing information // 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) 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; 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. // 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 // 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) 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 case 3: // we have a new set of ephemeris data for the current SV
if (d_nav.satellite_validation() == true) 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) if (abs(corr_value) >= d_samples_per_preamble)
{ {
d_preamble_index = d_sample_counter; // record the preamble sample stamp 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; DLOG(INFO) << "Preamble detection for GPS L1 satellite " << this->d_satellite;
decode_subframe(); if (decode_subframe())
d_stat = 1; // enter into frame pre-detection status {
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; d_flag_TOW_set = false;
break; break;
} }
case 1: // possible preamble lock case 1: // preamble acquired
{
// 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
{ {
if (d_sample_counter >= d_preamble_index + static_cast<uint64_t>(d_preamble_period_symbols)) 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)), 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))) gr::io_signature::make(1, 1, sizeof(Gnss_Synchro)))
{ {
//debug_action1 = false;
// prevent telemetry symbols accumulation in output buffers // prevent telemetry symbols accumulation in output buffers
this->set_max_noutput_items(1); this->set_max_noutput_items(1);
d_trk_parameters = conf_; 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); consume_each(d_current_prn_length_samples);
d_sample_counter += static_cast<uint64_t>(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) if (current_synchro_data.Flag_valid_symbol_output || loss_of_lock)

View File

@ -198,6 +198,8 @@ private:
bool d_dump_mat; bool d_dump_mat;
bool d_acc_carrier_phase_initialized; bool d_acc_carrier_phase_initialized;
bool d_enable_extended_integration; 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_pull_in = false;
enable_fll_steady_state = false; enable_fll_steady_state = false;
pull_in_time_s = 10; 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; fll_filter_order = 1;
pll_filter_order = 3; pll_filter_order = 3;
dll_filter_order = 2; 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); 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); 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); 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_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); 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); 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)); WN_0 = static_cast<int32_t>(read_navigation_unsigned(data_jk_bits, WN_0_BIT));
DLOG(INFO) << "WN_0= " << WN_0; DLOG(INFO) << "WN_0= " << WN_0;
TOW_0 = static_cast<int32_t>(read_navigation_unsigned(data_jk_bits, TOW_0_BIT)); 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) << "TOW_0= " << TOW_0;
DLOG(INFO) << "flag_tow_set" << flag_TOW_set; DLOG(INFO) << "flag_tow_set" << flag_TOW_set;
} }

View File

@ -164,6 +164,21 @@ public:
flag_TOW_6 = flag_tow6; 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 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); 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_iono_and_GST{}; // Flag indicating that ionospheric and GST parameters (word 5) have been received
bool flag_TOW_5{}; bool flag_TOW_5{};
bool flag_TOW_6{}; bool flag_TOW_6{};
bool flag_TOW_0{};
bool flag_TOW_set{}; // it is true when page 5 or page 6 arrives 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 bool flag_utc_model{}; // Flag indicating that utc model parameters (word 6) have been received