Follow-ups to the frequency-error-reduction merge (tracking state 5):
- Anchor Flag_PLL_180_deg_phase_locked to the sign of the last Prompt
symbol. The differential bit/secondary-code detector reconstructs bits
relative to an arbitrary first bit, so the previous corr_value sign rule
was independent of the actual carrier polarity.
- Do not feed the deliberate Doppler bin hops of the scan into the
high_dyn carrier/code phase-rate smoothers: clear the histories and
zero the rate steps while scanning.
- Start the pull_in_time_s and bit_synchronization_time_limit_s budgets
at the first sample after the scan instead of at acquisition, so long
scans no longer consume the FLL pull-in or the sync time limit. Scan
completion re-arms pull-in and resets the lock-fail counters. The
non-scan path keeps the acquisition time origin.
- Clamp f_error_accumulation to at least 1, both when parsed from the
configuration and in the block constructor, to avoid an out-of-bounds
write and a scan that never advances.
- Add unit tests for polarity, rate suppression, timers, and a full L2C
scan, and document the new options in the CHANGELOG.
Follow-up to the galileo-navtype-fallback merge. The original fallback let
E5a/E5b/E6 observations use the other service's ephemeris, but the BGD index
for those signals is fixed by frequency, so an E5a range modeled with an
I/NAV clock would be off by BGD(E1,E5a) - BGD(E1,E5b). Only E1 selects its
BGD from the ephemeris clock model, so only E1 may fall back.
Drop the per-PRN locked set: I/NAV and F/NAV carry the same IODnav/toe,
so they expire together, and an E1 switch between services costs only BGD
quantization. select_galileo_ephemeris() is const again and simply prefers
the primary service while its ephemeris is fresh.
Also normalize a legacy Unknown provenance to the primary service on the
returned ephemeris, and allow E1 Reduced CED in F/NAV-primary receivers.
Covers Dll_Pll_Conf::SetFromConfiguration() parsing of f_error_step_num
(default disabled, odd values pass through, even values round up to
odd, zero stays disabled) and f_error_accumulation/f_error_doppler_step
pass-through, plus dll_pll_veml_tracking::f_error_bin_multiplier()'s
bin-index-to-Doppler-offset mapping, including that step_num=5
reproduces the original fixed 5-bin scan order.
f_error_bin_multiplier() is made public so it can be exercised
directly from the test.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Signed-off-by: joebre <joel.brenner@saphyrion.ch>
- Rename doppler_uncertanty -> doppler_uncertainty throughout (interface,
adapter, block, comments, log message).
- Fix the out-of-bounds write and mis-detection in narrowed-mode
activation: track it with an explicit d_doppler_search_narrowed flag,
set directly in set_doppler_uncertainty() and guarded on
d_num_doppler_bins > 1, instead of inferring it from
"d_num_doppler_bins_active < d_num_doppler_bins". That inferred check
broke two ways: for a 1-bin full grid (a valid, already-accepted
config), it still forced 2 active bins, writing past the grid/wipeoff
allocations sized to d_num_doppler_bins; for a 2-bin full grid, an
actually-narrowed request computes the same active count as the full
grid (2 < 2 is false), so it silently searched the full grid's own
bin layout instead of the assisted {center, center + doppler_max}
pair. Reproduced the out-of-bounds write directly (temporarily
reverting to the inferred check crashes with "corrupted double-linked
list" under the new NarrowingEnabledOneBinGrid test) and the
mis-detection (NarrowingEnabledTwoBinGrid).
- Keep the noise-reference bin out of candidate selection: both
max_to_input_power_statistic() and first_vs_second_peak_statistic()
now take a separate candidate_count, used only for the peak-search
loop bound; the CFAR path's own num_doppler_bins (used for the
"opposite bin" reference lookup) is unchanged. In narrowed mode,
candidate_count is 1 -- the noise-reference bin can no longer win and
be reported as the acquisition result, regardless of its own power
(verified against a live signal deliberately placed in the reference
bin instead of the known/candidate bin: reverting this fix, both the
CFAR and peak-ratio statistic mistakenly report the reference bin's
Doppler as if it were the assisted center).
- Recalibrate the acceptance threshold for narrowed acquisition: adds
d_threshold_narrowed, computed like d_threshold but with
num_doppler_bins = 1 (the true candidate count in narrowed mode)
instead of the full grid's bin count, since compute_threshold() folds
the candidate count into the false-alarm probability and reusing the
full-grid threshold in narrowed mode was effectively far stricter
than the requested PFA. get_threshold() returns it whenever
d_doppler_search_narrowed is true.
- Fix narrowed dump layout/metadata: ensure_dump_grid_allocated() now
sizes acq_grid to d_num_doppler_bins_active (not the full grid width),
matching what copy_magnitude_grid_to_dump_grid() actually writes each
cycle -- this also makes narrow<->full transitions between dumps
self-correcting. dump_results() writes accurate, mode-appropriate
doppler_max/doppler_step (the same {0, doppler_max} encoding
compute_statistics() uses internally when narrowed), plus new
doppler_center and doppler_narrowed fields so offline post-processing
can tell which encoding is in effect. Verified end to end against a
live dump (NarrowedDumpMetadata).
- Strengthen Acq_Conf::enable_doppler_narrowing's doc comment (default,
which implementations it applies to, its dependency on the caller
passing doppler_uncertainty == 0) and add a commented usage example
next to GNSS-SDR.assist_dual_frequency_acq in a dual-frequency
Galileo E1B+E5a example config.
- Add tests/.../pcps_acquisition_doppler_narrowing_test.cc: 8 focused
tests (narrowing enabled/disabled, 1-bin and 2-bin full-grid
configurations, CFAR and peak-ratio statistics, a full-narrow-full
transition, two-step acquisition with step-1 narrowing, and narrowed
dump metadata), built on the same real-capture/known-ground-truth
pattern as gps_l1_ca_pcps_acquisition_test.cc. Confirmed each targeted
regression test actually fails without its corresponding fix before
finalizing them.
Signed-off-by: joebre <joel.brenner@saphyrion.ch>
GTEST_SKIP() does not exist before GoogleTest 1.10, which breaks the
build on Ubuntu 16.04 with the distro-provided GoogleTest. Wrap it in
a guarded macro that records a success and returns on older versions,
following the pattern already used in osnma_test_vectors.cc.¡
gps_l1_ca_pcps_opencl_acquisition_gsoc2013_test.cc still included
gps_l1_ca_pcps_opencl_acquisition.h, which was deleted when the old
per-variant custom acquisition adapters (OpenCL, QuickSync, Tong,
CCCWSR, 8ms) were consolidated into the generic
PcpsAcquisitionAdapterCustom. This broke any build combining
-DENABLE_UNIT_TESTING=ON with -DENABLE_OPENCL=ON, even though the
rest of the file already used the generic AcquisitionInterface /
block_factory::GetAcqBlock() pattern, matching its already-working
QuickSync/Tong siblings.
Drop the dead include. The test also called acquisition->opencl_ready(),
a method that only ever existed on the concrete GNU Radio block
(pcps_opencl_acquisition_cc), never on the generic AcquisitionInterface
returned by the factory; reach it instead via a dynamic_pointer_cast on
get_right_block(), the same pattern already used elsewhere in this
codebase to recover a concrete type from a generic block interface.
Fixes: 8f29c4f88e ("Cleanup custom acquisition adapters")
Signed-off-by: Oleksandr Suvorov <cryosay@gmail.com>
Compensate the Viterbi traceback delay when timestamping decoded SBAS
messages by carrying per-sample reception timestamps through the sample
and symbol aligners (removes a ~140 ms bias), with a deterministic unit
test covering the FIFO pairing.
Protect decoder state with d_setlock in reset(), set_satellite(),
set_channel() and general_work(), following the convention of the other
telemetry decoders.
Share per-PRN EMS dump files through a per-run dump session: the first
open in a run truncates stale data, later opens append, so channel
reassignments no longer wipe previously decoded messages.