diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 15f6850ee..ed0c1055b 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -62,6 +62,15 @@ All notable changes to GNSS-SDR will be documented in this file. ### Improvements in Availability: +- Added `Acquisition_XX.full_grid_search` (default: `false`) for acquisition + implementations using the CPU PCPS block. When enabled, each search stage + accumulates all `max_dwells` non-coherent integrations before accepting or + rejecting the strongest peak. This also applies to both stages of + `make_two_steps` and to the reduced grid used by `enable_doppler_narrowing`. + The default preserves early acceptance; `max_dwells=1` is unchanged. + `bit_transition_flag=true` takes precedence and still uses a single + double-length dwell. Waiting for all dwells increases acquisition latency. + Contributed by @joebre. - Improved TOW rollover handling in Telemetry Decoder blocks. - Galileo F/NAV and I/NAV ephemerides are now retained independently instead of overwriting each other when they have the same PRN. PVT automatically uses the diff --git a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc index 7af293ba7..3bb84413e 100644 --- a/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc +++ b/src/algorithms/acquisition/gnuradio_blocks/pcps_acquisition.cc @@ -819,19 +819,47 @@ void pcps_acquisition::acquisition_core(uint64_t sample_count) if (!d_acq_parameters.bit_transition_flag) { - if (result.test_statistics > get_threshold()) + if (d_acq_parameters.full_grid_search) { - handle_threshold_reached(result); + // Search the entire acquisition grid (accumulate through the full max_dwells) + // before deciding accept/reject, instead of exiting as soon as any single dwell's + // (possibly still noisy, partially non-coherently accumulated) grid crosses + // threshold -- a later dwell's fuller integration can reveal a different, genuinely + // stronger peak elsewhere in the same grid that an early exit never gets the chance + // to compare against. + if (d_num_noncoherent_integrations_counter == d_acq_parameters.max_dwells) + { + if (result.test_statistics > get_threshold()) + { + handle_threshold_reached(result); + } + else + { + handle_integration_done(result); + } + } + else + { + d_buffer_sample_count = 0; + d_state = 1; + } } else { - d_buffer_sample_count = 0; - d_state = 1; - } + if (result.test_statistics > get_threshold()) + { + handle_threshold_reached(result); + } + else + { + d_buffer_sample_count = 0; + d_state = 1; + } - if (d_num_noncoherent_integrations_counter == d_acq_parameters.max_dwells) - { - handle_integration_done(result); + if (d_num_noncoherent_integrations_counter == d_acq_parameters.max_dwells) + { + handle_integration_done(result); + } } } else diff --git a/src/algorithms/acquisition/libs/acq_conf.cc b/src/algorithms/acquisition/libs/acq_conf.cc index aeaa11b49..30adaa17c 100644 --- a/src/algorithms/acquisition/libs/acq_conf.cc +++ b/src/algorithms/acquisition/libs/acq_conf.cc @@ -83,6 +83,7 @@ void Acq_Conf::SetFromConfiguration(const ConfigurationInterface *configuration, make_2_steps = configuration->property(role + ".make_two_steps", make_2_steps); blocking_on_standby = configuration->property(role + ".blocking_on_standby", blocking_on_standby); enable_doppler_narrowing = configuration->property(role + ".enable_doppler_narrowing", enable_doppler_narrowing); + full_grid_search = configuration->property(role + ".full_grid_search", full_grid_search); if (pfa <= 0.0) { diff --git a/src/algorithms/acquisition/libs/acq_conf.h b/src/algorithms/acquisition/libs/acq_conf.h index 62d100809..b54a9a771 100644 --- a/src/algorithms/acquisition/libs/acq_conf.h +++ b/src/algorithms/acquisition/libs/acq_conf.h @@ -92,6 +92,14 @@ public: // flag has no effect and the full configured Doppler grid is always searched. bool enable_doppler_narrowing{false}; + // Accumulate through the full max_dwells before deciding accept/reject, instead + // of exiting as soon as any single dwell's (possibly still noisy, partially + // accumulated) grid crosses threshold -- a later dwell's fuller integration can + // reveal a different, genuinely stronger peak elsewhere in the grid that an early + // exit never gets the chance to compare against. Opt-in: off by default, enable + // per-implementation in the .conf (e.g. Acquisition_1B.full_grid_search = true). + bool full_grid_search{false}; + // Specific to some implementations bool acquire_pilot{false}; bool acquire_iq{false};