Commit Graph
245 Commits
Author SHA1 Message Date
Carles Fernandez 95c72618f8 Fix Galileo telemetry decoder races during reset and satellite changes 2026-09-28 13:19:07 +02:00
Carles Fernandez fd70179392 Fix Galileo preamble confirmation with intervening payload matches
Preserve the candidate anchor until its expected confirmation point.
Replace it only after confirmation is missed, preventing payload
correlations from repeatedly displacing a valid preamble.
2026-09-28 10:56:34 +02:00
Carles Fernandez 044aee9bc2 Keep a separate logfile for each run with Abseil logging, as google-glog did 2026-09-27 18:26:57 +02:00
Carles Fernandez 20a0a69780 Fix acquisition code phase handed to tracking in GPS L1 C/A tests, restore Doppler search range in GLONASS L1 C/A acquisition test 2026-09-27 13:22:23 +02:00
Carles Fernandez b37cc311d0 Fix race in acquisition tests 2026-09-26 12:02:38 +02:00
Carles Fernandez 28acfb7d9d Fix QuickSync acquisition 2026-09-26 11:38:18 +02:00
Carles Fernandez b2d117018c Split run_tests into per-category translation units
test_main.cc #included every unit test into a single translation unit, which made GCC exceed its variable tracking limit and required several GB of RAM to compile on small machines.
2026-09-25 19:05:01 +02:00
Carles Fernandez 4ddddd1d50 Fix C++11/C++14 compatibility in FPGA acquisition tests 2026-09-24 10:24:38 +02:00
Carles Fernandez fb9d405022 Make clang-tidy happy 2026-09-24 10:00:28 +02:00
Carles Fernandez e24868424f Fix satellite visibility test 2026-09-24 09:17:20 +02:00
Carles Fernandez fcc770c1fa Fix BeiDou Doppler prediction and reject stale acquisition assistance
Use radian angles and the correct GEO inclination for BeiDou almanacs,
and convert GPST to BDT before propagating BeiDou navigation data.

Require a sample-clock-anchored PVT fix no older than one second for
Doppler prediction. Clear previous assistance when retrying acquisition
after tracking loss.
2026-09-23 19:09:23 +02:00
Carles Fernandez fd274fb891 Make acquisition dump readers skip noise-reference columns
With set_doppler_num_bins(), acq_grid holds the Doppler candidate columns
followed by 0, 1 or 2 noise-reference columns placed at doppler_center
+/- the configured doppler_max, outside the linear Doppler axis. Nothing
in the dump said how many columns were candidates, so the readers either
rejected the file (Acquisition_Dump_Reader) or plotted the reference
columns on a wrong Doppler axis (plot_acq_grid.py, plot_acq_grid.m).

Write a new doppler_num_candidates variable to the dump and use it in
the readers to keep only the candidate columns. Dumps without it are
read as before, except that the reference column of older narrowed
dumps is also skipped. The Python and MATLAB scripts plot a
single-candidate (narrowed) grid as a code-delay line instead of an
empty surface.

Add a regression test that reads back a full-grid dump with two
reference columns and a narrowed N = 5 dump.
2026-09-23 12:46:37 +02:00
Carles Fernandez 5dd293ed0e Fix heap overflow in set_doppler_num_bins() for N = full grid - 1
A narrowed search of N < d_num_doppler_bins candidates adds up to two
noise-reference rows, so N = d_num_doppler_bins - 1 needs
d_num_doppler_bins + 1 rows. The step-1 grid buffers were sized to the
full grid's own row count, which has no reference rows when the
peak-ratio statistic is used or the CFAR wraparound distance suffices,
so that request wrote one row past the end of d_grid_doppler_wipeoffs
and d_magnitude_grid.

Size the step-1 buffers (and the CUDA engine) for d_num_doppler_bins + 2
rows, which covers every row count set_doppler_num_bins() can produce,
and add a regression test.
2026-09-23 12:11:27 +02:00
Carles Fernandez 1f4ad73f6f Merge PR #1097 (pcps-doppler-num-bins-unification) into next
Conflict resolution: keep next's CUDA engine hooks, sample-buffer renames
(d_buffer_sample_count) and full_grid_search option; adopt the PR's
set_doppler_num_bins() members. CUDA capacity now uses
d_num_doppler_bins_full_grid_active and update_grid_doppler_wipeoffs()
uploads the unified grid to the GPU.
2026-09-23 09:36:12 +00:00
Marc Majoral 87b9c7235b fix FPGA acquisition unit tests 2026-09-22 20:26:51 +02:00
Carles Fernandez 360f349209 Fix building in old setups 2026-09-22 08:15:11 +02:00
Carles Fernandez 65cca85178 Fix CUDA acquisition upload ordering and validation
- Order code and carrier uploads on the compute stream and wait before
  returning so callers can safely reuse host buffers.
- Verify CUDA readiness and completed grid counts in adapter tests,
  rejecting unexpected CPU fallback.
- Exercise host-buffer reuse in engine parity tests.
- Correct the Jetson helper's test executable path.
- Use ArgsProduct for compatibility with Google Benchmark 1.9.2–1.9.5.
2026-09-21 17:18:55 +02:00
Phillip Vu 51b4f61e1b Port CUDA acquisition test to PcpsAcquisitionAdapter
Signed-off-by: Phillip Vu <36169227+phillipvu@users.noreply.github.com>
2026-09-21 06:26:41 -07:00
Phillip Vu 726cf2c455 Use American spelling and plain punctuation in CUDA docs and comments
Signed-off-by: Phillip Vu <36169227+phillipvu@users.noreply.github.com>
2026-09-21 06:26:40 -07:00
Phillip Vu 3cdc5a43a6 Fix newline escapes in two-step CUDA test output
Signed-off-by: Phillip Vu <36169227+phillipvu@users.noreply.github.com>
2026-09-21 06:26:40 -07:00
Phillip Vu b24a261d09 GpsL1CaPcpsAcquisitionCudaTest: cover make_two_steps (STEP2_GRID) vs CPU
Signed-off-by: Phillip Vu <36169227+phillipvu@users.noreply.github.com>
2026-09-21 06:26:40 -07:00
Phillip Vu 5a8e56ed02 CUDA: fix build on modern toolkits/Jetson, add GPU PCPS acquisition engine
Build system:
- Drop hardcoded sm_30 (Kepler) nvcc flags rejected by CUDA >= 11; honour
  CMAKE_CUDA_ARCHITECTURES, auto-detect Jetson SoCs from the device tree
  (Orin 87, Xavier 72, TX2 62, Nano 53) or use "native" with CMake >= 3.24.
- CUDA standard follows the host C++ standard (C++17).
- find_package(CUDAToolkit) and explicit CUDA::cudart / CUDA::cufft links.
- Define CUDA_GPU_ACCEL project-wide; keep -Wno-psabi away from nvcc.

Acquisition:
- New CudaPcpsEngine (acquisition/libs/cuda_pcps_engine.{h,cu}): batched
  cuFFT evaluation of the Doppler x code-phase grid, one stream per block.
- pcps_acquisition::doppler_grid() dispatches to the engine when
  Acquisition_XX.use_cuda=true (or GNSS-SDR.use_cuda_acquisition=true),
  falling back to the CPU loop on any failure. Peak search and statistics
  are unchanged.

Tracking (GPS_L1_CA_DLL_PLL_Tracking_GPU):
- Split the racy single-launch wipe-off + correlator kernel into two
  launches on the same stream.
- cudaHostAllocMapped || cudaHostAllocWriteCombined -> cudaHostAllocMapped.
- No cudaDeviceReset() in the per-channel teardown; do not cudaFree()
  device aliases of host-mapped buffers; const-correct GPU_Complex.

Tests/docs:
- CudaPcpsEngineTest (GPU grid vs CPU reference incl. accumulation,
  bit-transition mode, 4 ms integration) and GpsL1CaPcpsAcquisitionCudaTest
  (full adapter on a real capture, CPU vs GPU estimates).
- benchmark_pcps_grid: CPU baseline vs GPU sweep.
- docs/JETSON.md build/verify/benchmark guide; README, changelog, sample
  config updates.

Signed-off-by: Phillip Vu <36169227+phillipvu@users.noreply.github.com>
2026-09-21 06:26:39 -07:00
Carles Fernandez d247536f3d Merge branch 'joebre-joebre-fix-observables-history-capacity' into next 2026-09-20 09:55:59 +02:00
Carles Fernandez 8e512b82fd Make abseil logging sink thread-safe 2026-09-20 09:41:31 +02:00
Carles Fernandez 9f9868d86a Make the observables robust to wrong TOWs and size their history
Hybrid_Observables:
- Interpolate only between consecutive tracking samples whose TOW advanced
  as much as the receiver time: after a gap in the valid words of a
  channel, the last sample before it and the first one after it were used
  together, giving a meaningless carrier phase and, if the TOW had stepped,
  a first pseudorange off by up to hundreds of seconds. Fix the TOW
  rollover in the interpolation and in the pseudorange computation, which
  added a week to any travel time longer than 302.4 s.
- Set the receiver time from the largest group of channels agreeing on the
  TOW, and set it again when such a group contradicts it, instead of
  trusting the latest TOW of the first valid epoch. Channels contradicting
  the receiver time do not deliver valid pseudoranges. Make the clock
  correction from the PVT block safe at the TOW rollover.
- Size the tracking history from the receiver clock buffer and the
  observables interval instead of a fixed count, which was too short for
  1 ms symbols (Galileo E6) at long intervals and 4x too large at the
  default one. Find the nearest sample with a binary search.
- Use the mean Doppler of the epoch in the cycle-slip detector: the final
  value raised false slips with high Doppler rates and long intervals.
- Make the static helpers private and remove their unit test.

RTKLIB_PVT: do not count the epochs without enough satellites as solver
errors, and send the reset to the observables once per outage: each reset
emptied the tracking history of every channel every two seconds.
2026-09-19 15:40:30 +02:00
Carles Fernandez 6dc1eb2a90 Add LDPC decoder to the BeiDou B2a processing chain
Improve color consistency in console messages
2026-09-18 13:15:21 +02:00
Carles Fernandez 99ce68f07b Merge branch 'next' into joebre-freq-error-reduction 2026-09-16 13:35:48 +02:00
Carles Fernandez 66782155ec Fix clang-tidy job 2026-09-16 12:23:45 +02:00
joebre a12e086443 Merge remote-tracking branch 'upstream/next' into pcps-doppler-num-bins-unification
# Conflicts:
#	src/core/receiver/gnss_flowgraph.cc
2026-09-15 16:45:50 +02:00
Carles Fernandez e6ebb77c75 WARMSTART keeps the almanac already in memory instead of clearing it
and reloading it from the XML assistance files, which could replace a
fresher, live-decoded almanac with a stale snapshot from disk, and the
handler now uses the visible-satellite list it computed instead of
prioritizing an empty one.
2026-09-14 16:37:38 +02:00
Carles Fernandez 930c217c97 Fix CNAV2 ephemeris handling and IODE reading 2026-09-13 10:52:49 +02:00
Carles Fernandez e896e94766 Merge branch 'feat/beidou-b2a' of https://github.com/HuangChuhan-SYSU/gnss-sdr into HuangChuhan-SYSU-feat/beidou-b2a 2026-09-13 10:13:02 +02:00
Carles Fernandez 83b194c378 Fix visibility-aware acquisition scheduling and outage recovery 2026-09-13 09:02:08 +02:00
Carles Fernandez bcb5b7228b Extend visibility-aware search and fix dual-band acquisition scheduling
Visibility-aware acquisition search (GNSS-SDR.enable_visibility_aware_search):
- Classify GLONASS and QZSS satellites too. GLONASS positions come from the
  GNAV almanac (new Glonass_Gnav_Almanac::satellite_position with the
  standard perturbation model), so the search order benefits before any
  GLONASS ephemeris is decoded.
- PVT publishes a lock-free navigation snapshot (ephemeris, almanac, UTC
  models per system) that the classifier reads instead of locking the PVT
  maps on every recompute.
- Recompute on new navigation data, on position changes larger than
  visibility_recompute_position_threshold_m, every
  visibility_recompute_interval_s, and when the almanac ages out; fix the
  periodic and position-triggered recomputes that never fired, and the
  off-by-one that excluded satellites in [mask, mask+1) degrees.
- Enter the start-up standby only when the feature is enabled, so the
  default search order is untouched.

Secondary-frequency acquisition assistance:
- Do not start an acquisition on the PRN 0 placeholder left on assisted
  channels at connect time; it threw inside the control thread and left the
  flowgraph running headless with the secondary band never acquired.
- Match GLONASS assistance by FDMA frequency channel: the search pool keeps
  one slot per channel while tracked L1 channels report the decoded slot, so
  L2 was never picked.
- Assist from locked channels before their telemetry is decoded: the
  observables status now reports tracking-only channels and the flowgraph
  keeps a separate tracking map for the assisted search.
2026-09-12 14:15:00 +02:00
joebre f7948f4af1 Drop the config-driven widening this PR mistakenly added
set_doppler_num_bins(1) (an exactly-known Doppler, e.g. from a
dual-frequency assist) previously honored a widening exception: if
Acquisition_<Sig>.enable_assisted_doppler_narrowing was set, a
literal N == 1 request could get silently expanded into
doppler_narrowing_num_bins candidate bins instead of searched as
requested. That was never asked for and contradicts the whole point
of this unification -- N is supposed to be authoritative, full stop.
A caller that actually wants a safety margin around its own estimate
should just request that many bins directly (set_doppler_num_bins(3),
not set_doppler_num_bins(1) plus a config flag that silently changes
what "1" means).

Removes both config parameters entirely (enable_assisted_doppler_narrowing,
doppler_narrowing_num_bins) along with the widening branch in
set_doppler_num_bins(). Dual-frequency-assisted secondary acquisition
now always searches exactly 1 bin, unconditionally -- no config knob
changes that. Does not reintroduce next's original enable_doppler_narrowing
name/semantics either (a master on/off switch that could fall back an
assisted request to the full grid): under the unified API, the caller's
N is never second-guessed by a flag, matching this PR's whole premise.

Test file updated to match: init() drops both removed parameters, and
the two tests that specifically exercised the widening path
(NarrowingWithMultipleCandidateBinsRecoversOffsetEstimate,
NarrowedDumpMetadataMultipleCandidateBins) now request their multi-bin
coverage directly (set_doppler_num_bins(5)) instead of relying on
config-driven expansion from N == 1 -- same coverage, no removed
feature required to exercise it.

Verified: full local test suite (105 tests) passes against a
from-scratch build, isolated from other in-progress work.
2026-09-11 15:49:55 +02:00
joebre 2b6a1bb89c Unify pcps_acquisition's Doppler search into a single N-bin API
set_doppler_uncertainty() only ever supported two states: the full
configured grid, or a single exactly-known bin (assisted narrowing's
2-bin variant). Regular searches, primary-frequency-assisted secondary
signals, and any future partial-uncertainty search (e.g. a visibility-
aware Doppler prediction with residual error) all had to be shoehorned
into one of those two cases instead of directly stating how many
candidate bins they actually need.

Replaces it with set_doppler_num_bins(uint32_t): 0 is a sentinel for
"the full configured range" (the only value a caller can't supply
directly, since that count is otherwise private to this class); any
other value is the literal candidate bin count, from 1 (exactly known,
as when assisted by an already-tracked primary frequency) up to the
full grid. Regular and narrowed searches now go through the exact same
code path -- update_grid_doppler_wipeoffs(), compute_statistics(), the
two statistic functions -- differing only in candidate_count.

CFAR reference-bin placement is generalized the same way:
needs_extra_reference_row(candidate_bins) reproduces both today's
full-grid conditional extra-row behavior (only when the in-grid
wraparound distance can't clear reference_bin_min_sidelobes) and
narrowed mode's unconditional extra-row assumption, for any candidate
count. d_min_reference_separation_hz is derived automatically from the
new reference_bin_min_sidelobes config parameter (default 4) and
coherent_integration_time_ms, rather than needing to be set directly.

Also fixes a latent asymmetry: whenever a dedicated reference row is
needed for more than one real candidate, two rows are now computed --
at +doppler_max and -doppler_max -- and the statistic picks whichever
sits opposite the winning candidate's side of center. Previously the
reference was always fixed at +doppler_max regardless of which side
the signal landed on; a candidate near the edge of the search range
could end up right next to its own reference sample. With exactly one
real candidate (always at offset 0, no side to mirror), a single fixed
row is kept, matching prior behavior.

The detection threshold (d_threshold_active) is recalibrated by
set_doppler_num_bins() whenever the active candidate count changes,
since compute_threshold() folds the bin count into the false-alarm
probability.

Propagates the rename through AcquisitionInterface,
PcpsAcquisitionAdapter, ChannelInterface, Channel, and
GNSSFlowgraph's two assist_acquisition_doppler() call sites (0 ->
literal full-grid sentinel for the regular/unassisted case, 1 for the
dual-frequency-assisted case -- an exact inversion of the old
uncertainty-flag convention).

Verified: full local test suite (acq_test, trk_test, gnss_block_test,
flowgraph_test -- 105 tests) passes against a from-scratch build off
upstream/next, isolated from other in-progress work in this tree.
2026-09-11 15:25:54 +02:00
Carles Fernandez 4d3ad83957 Fix polarity, Doppler rate, and timers after the frequency-error scan
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.
2026-09-11 09:00:01 +02:00
Carles Fernandez 379c99a9de Merge branch 'freq-error-reduction' of https://github.com/joebre/gnss-sdr into joebre-freq-error-reduction 2026-09-09 16:20:53 +02:00
Carles Fernandez 352e1e9fea Fix formatting 2026-09-09 16:00:13 +02:00
Carles Fernandez 4e0d7837e9 Let PVT.iono_model decide band combination in the single point solution 2026-09-09 15:57:41 +02:00
huangchuhan 909591f47b Address B2a first-cut review: nav consistency, storage, RINEX.
Reset CNAV2 state on channel reassignment and reject PRN-mismatched
frames. Assemble MT10/MT11/clock into a candidate set keyed by broadcast
IODE/IODC instead of sticky arrival flags. Store CNAV2 independently of
CNAV1, set the B2a wavelength on the occupied RTKLIB slot, and write
RINEX 4 CNV2 (omit CNAV2 on RINEX 3).

Signed-off-by: huangchuhan <huangchh37@mail2.sysu.edu.cn>
2026-09-09 09:40:26 +08:00
Carles Fernandez 08d24faa9d Restrict Galileo nav-service fallback to E1 and make it stateless
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.
2026-09-08 11:16:34 +02:00
huangchuhan 849c18b0e6 Add BeiDou-3 B2a RNSS single-frequency SPP (B-CNAV2).
Introduce the 5D signal chain: ICD BPSK(10) replica, PCPS acquisition,
DLL-PLL tracking (1 ms data component), and a first-cut B-CNAV2 decoder
(preamble + CRC-24Q, MT10/MT11/MT30, systematic 288 bits, no 64-ary
LDPC). GEO and BDS-2 PRNs are not assigned B2a channels. B2a-only SPP
remaps 5D onto RTKLIB slot 0 with lam[0]=c/FREQ5.

Signed-off-by: huangchuhan <huangchh37@mail2.sysu.edu.cn>
2026-09-08 15:05:32 +08:00
Carles Fernandez 1ba1f37d3b Polish the gnss_synchro_monitor decimation fix 2026-09-05 12:46:30 +02:00
joebreandClaude Sonnet 5 9f3b4a16da Add unit tests for tracking frequency-error reduction
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>
2026-09-05 10:45:16 +02:00
Carles Fernandez 3053cebd3a Merge branch 'monitor_decimation_fix' of https://github.com/vladisslav2011/gnss-sdr into vladisslav2011-monitor_decimation_fix 2026-09-04 20:22:17 +02:00
Vladslav P 0437bd8c65 Add gnss_syncro_monitor test
Test basic gnss_syncro_monitor operation.
Test decimation at different decimation factors.

Signed-off-by: Vladslav P <vladisslav2011@gmail.com>
2026-09-04 18:13:33 +03:00
Carles Fernandez 8c116a7d1e Make RinexPrinterTest more robust in CI environments 2026-09-03 21:45:37 +02:00
Carles Fernandez 1f8f688ed1 Fix test building in some environments 2026-09-01 10:09:41 +02:00
Carles Fernandez 0af508713a Fix Acquisition dump readers
Update changelog
Add Joel to the CITATION.cff file
2026-09-01 09:22:38 +02:00