Commit Graph
11044 Commits
Author SHA1 Message Date
Mathieu Favreau 058aeab9c3 Retrigger CI 2026-09-18 10:02:22 +02:00
Mathieu Favreau 4b6ccdb347 Fix warning 2026-09-18 10:02:22 +02:00
Vladislav P a7ec48b46f channel_fsm: fix rare deadlock
A deadlock may occur when ChannelFsm receives Event_stop_channel when
the non-blocking acquisition is in progress.

The control flow will be the following:

ChannelFsm::Event_stop_channel locks the mutex mx_
ChannelFsm::Event_stop_channel calls stop_acquisition
ChannelFsm::stop_acquisition calls PcpsAcquisitionAdapter::stop_acquisition
PcpsAcquisitionAdapter::stop_acquisition calls pcps_acquisition::set_active
pcps_acquisition::set_active calls pcps_acquisition::wait_if_active
pcps_acquisition::wait_if_active blocks waiting for the background
acquisition thread to finish processing
pcps_acquisition::acquisition_core calls pcps_acquisition::handle_threshold_reached
pcps_acquisition::handle_threshold_reached calls pcps_acquisition::send_positive_acquisition
pcps_acquisition::send_positive_acquisition calls ChannelFsm::Event_valid_acquisition
ChannelFsm::Event_valid_acquisition tries to lock the mutex mx_ for one
more time
Deadlock.

This commit does three things:
 - removes "magic numbers" used to mark different channel states as "magic numbers"
made the first attempt to fix the deadlock fail in a really strange way.
 - Implements a new state FSM_STATE_TERMINATING, used to prevent
unintended effects during FSM transition from tracking/acquisition to
FSM_STATE_IDLE.
 - Unlocks the mutex mx_ during actual attempt to stop
tracking/acquisition.

Signed-off-by: Vladislav P <vladisslav2011@gmail.com>
2026-09-18 02:31:50 +03:00
Carles Fernandez 96b4921f8c Merge branch 'joebre-freq-error-reduction' into next 2026-09-16 15:21:49 +02:00
Carles Fernandez d6c752d450 Merge branch 'joebre-full-grid-search-standalone' into next 2026-09-16 15:19:10 +02:00
Carles Fernandez f2a19005fd Merge branch 'full-grid-search-standalone' of https://github.com/joebre/gnss-sdr into joebre-full-grid-search-standalone 2026-09-16 14:18:14 +02:00
Carles Fernandez 99ce68f07b Merge branch 'next' into joebre-freq-error-reduction 2026-09-16 13:35:48 +02:00
Carles Fernandez 1f91e48e1f Merge commit '5efbfd16c9eed710211f5532d30a0681cc67add2' into joebre-freq-error-reduction 2026-09-16 13:35:35 +02:00
Carles Fernandez e451bd110f Fix compiler warning 2026-09-16 12:39:49 +02:00
Carles Fernandez 66782155ec Fix clang-tidy job 2026-09-16 12:23:45 +02:00
Carles Fernandez 6fa2670af3 Fix Galileo almanac health fallback for E5b and E5a signals 2026-09-16 11:41:37 +02:00
Carles Fernandez dd913fe6f9 Merge branch 'joebre-tracked-satellite-healthy-flag' into next 2026-09-16 11:26:39 +02:00
Carles Fernandez 199e943b8e Extend the healthy field to more signals 2026-09-16 11:24:37 +02:00
Carles Fernandez 9f5f3b9427 Merge branch 'tracked-satellite-healthy-flag' of https://github.com/joebre/gnss-sdr into joebre-tracked-satellite-healthy-flag 2026-09-16 10:07:43 +02:00
Carles Fernandez 13cf5494ea Merge branch 'MathieuFavreau-optimization/improve-acq-sample-copy' into next 2026-09-16 10:04:04 +02:00
Carles Fernandez c1aa1a24b8 Merge branch 'optimization/improve-acq-sample-copy' of https://github.com/MathieuFavreau/gnss-sdr into MathieuFavreau-optimization/improve-acq-sample-copy 2026-09-16 10:01:23 +02:00
Carles Fernandez bea5a0907a Merge branch 'vladisslav2011-fix_positive_acquisition_logging' into next 2026-09-16 09:53:47 +02:00
Carles Fernandez 3c81028976 Merge branch 'fix_positive_acquisition_logging' of https://github.com/vladisslav2011/gnss-sdr into vladisslav2011-fix_positive_acquisition_logging 2026-09-16 09:53:28 +02:00
Carles Fernandez 2971a8d98f Merge branch 'joebre-galileo-health-fixes' into next 2026-09-16 09:51:33 +02:00
Carles Fernandez d3d236026f Read missing health flag in galileo almanac, remove wrong check 2026-09-16 09:49:52 +02:00
Carles Fernandez 5f83fbead2 Merge branch 'galileo-health-fixes' of https://github.com/joebre/gnss-sdr into joebre-galileo-health-fixes 2026-09-16 09:42:51 +02:00
Carles Fernandez 75ae5ce4e4 Allow BeiDou B2a signals in multi-band configurations 2026-09-16 07:47:19 +02:00
Vladislav P 7a5d6ed589 PCPS acquisition: Fix positive acquisition logging
Set result.positive_acq to true before sending positive acquisition.
This makes positive acquisitions being logged as positive instead of
negative.

Signed-off-by: Vladislav P <vladisslav2011@gmail.com>
2026-09-16 02:36:13 +03:00
joebre e5d7604c9f Re-trigger CI (previous run's only failure was the unrelated flaky RinexPrinterTest, not this change)
Signed-off-by: joebre <joel.brenner@saphyrion.ch>
2026-09-15 11:50:16 +02:00
joebre 0f049493eb Add a per-signal broadcast health flag to MonitorPvt's tracked satellites
TrackedSatelliteInfo.used only says whether a tracked satellite/signal
contributed to the fix, not why it didn't -- below PVT.elevation_mask,
RAIM FDE, and broadcast-unhealthy are all indistinguishable to a monitor
client. Add a `healthy` field (proto field 8, default true) alongside it.

GPS health comes from the decoded ephemeris's SV_health, falling back to
the almanac (broadcast by every satellite) when no ephemeris has been
decoded yet. Galileo health is resolved per-signal via the existing
get_galileo_signal_health(), with the same almanac fallback when no
ephemeris is available for that signal's service. Other systems default
to healthy=true.
2026-09-15 10:58:17 +02:00
joebre 10aab33302 Fix two Galileo health-check gaps that silently accept unhealthy satellites
Galileo_Ephemeris_Store::combined_view() overwrote a preferred source's
merged entry with the raw ephemeris from that source, discarding the
health/DVS fields the preferred source's message type structurally never
carries (F/NAV never decodes E1B_HS/E1B_DVS/E5b_HS/E5b_DVS, I/NAV never
decodes E5a_HS/E5a_DVS). Those fields default to 0 ("OK"), so an E1+E5a
configuration preferring F/NAV would silently present an I/NAV-flagged
unhealthy satellite as healthy. Now the merge fills in only the fields the
preferred source can't carry, from the secondary source's entry.

select_galileo_ephemeris()'s Reduced CED bootstrap fallback had no health
check at all: Galileo_Reduced_CED carries no health/DVS bits of its own, so
an unhealthy satellite with no full ephemeris decoded yet would still be
accepted via Reduced CED. Cross-check the almanac's E1B_HS instead, which
every other satellite broadcasts as part of the normal almanac rotation.
2026-09-15 10:48:29 +02:00
joebre 5efbfd16c9 Remove time-to-fix breakdown diagnostic
log_time_to_fix_breakdown() and its six supporting state variables
were left-over instrumentation from developing the frequency-error-
reduction feature, not part of its documented behavior -- strip
before this is mergeable.
2026-09-15 10:28:54 +02:00
Carles Fernandez 8ddffe821d Merge branch 'joebre-warmstart-ephemeris-fix' into next 2026-09-15 09:25:32 +02:00
Mathieu Favreau dd5e76f90d Optimize cshort type 2026-09-14 19:56:00 +00:00
Mathieu Favreau 0e8065b45d Improve acquisition sample copy 2026-09-14 18:51:09 +00: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 203deb1f1b Revert commit 10bb8e31a6. 2026-09-13 15:18:07 +02:00
Carles Fernandez a80b973fa9 Forget stalled data in GLONASS GNAV 2026-09-13 14:14:47 +02:00
Carles Fernandez ecc3e51522 Fix volk_gnsssdr sincos kernel 2026-09-13 14:13:43 +02:00
Carles Fernandez 10bb8e31a6 Fix local carrier generation in PCPS acquisition
The Doppler wipeoff replicas were generated with
volk_gnsssdr_s32f_sincos_32fc, which accumulates the phase in single
precision over the whole vector without wrapping it. With a large
frequency offset, such as the GLONASS FDMA channel bias (several rad per
sample), the accumulated phase reaches 1e5 rad over a coherent block and
its float resolution drops to 0.01-0.06 rad, so the effective frequency
of the local carrier was off by hundreds of Hz to kHz, changing at every
power-of-two boundary of the accumulator.

In GLONASS L1/L2 C/A receivers this corrupted the Doppler grid: the
noise estimate taken from the opposite Doppler row no longer represented
the grid, satellites absent from the signal passed the pfa threshold on
every dwell (tracked for ~11 s at ~30 dB-Hz with no carrier lock, then
dropped and re-acquired, periodically), and the acquisition Doppler of
the satellites actually present was biased by up to one bin, which could
push the tracking loop into a false lock.

Generate the carrier with a complex rotator instead, renormalized every
512 samples. The residual frequency error is below 0.1 Hz.
2026-09-13 13:21:29 +02:00
Carles Fernandez c943be70f5 Fix B-CNAV2 MT33 IODC bit offset 2026-09-13 11:55:48 +02:00
Carles Fernandez f697b4d242 Merge branch 'HuangChuhan-SYSU-feat/beidou-b2a' into next 2026-09-13 11:24:35 +02:00
Carles Fernandez 930c217c97 Fix CNAV2 ephemeris handling and IODE reading 2026-09-13 10:52:49 +02:00
Carles Fernandez 6d131745a2 Fix CNV2 RINEX output of ISC_B2ad placement 2026-09-13 10:35:01 +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 0b1b85f758 Merge branch 'vladisslav2011-glonass_almanac_crash_fix' into next 2026-09-13 10:05:52 +02:00
Carles Fernandez 45deff66d7 Merge branch 'glonass_almanac_crash_fix' of https://github.com/vladisslav2011/gnss-sdr into vladisslav2011-glonass_almanac_crash_fix 2026-09-13 09:45:32 +02:00
Carles Fernandez c3c0bfe2d7 Merge branch 'joebre-visibility-aware-search' into next 2026-09-13 09:41:52 +02:00
Carles Fernandez 83b194c378 Fix visibility-aware acquisition scheduling and outage recovery 2026-09-13 09:02:08 +02:00
Vladislav P 9181145999 Glonass_Gnav_Navigation_Message: fix crash in almanac decoder
Validate i_alm_satellite_slot_number before trying to access gnav_almanac
elements by index in Glonass_Gnav_Navigation_Message::string_decoder.

Signed-off-by: Vladislav P <vladisslav2011@gmail.com>
2026-09-13 04:05:59 +03: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
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
joebre a191c50008 Merge remote-tracking branch 'upstream/next' into visibility-aware-search-local 2026-09-10 18:08:37 +02:00
joebre 13f7d190a7 Fix satellites at [mask, mask+1) elevation wrongly excluded
compute_visible_satellites() correctly decides visible-vs-excluded
using the raw double elevation (`El > elevation_mask_deg`), but then
truncates the returned elevation to floor(El) for the diagnostic dump.
Tick() later re-derives the same visible/excluded decision from that
already-floored value (twice: once to separate a health-only exclusion
from an elevation one, once for the final visible_/excluded_ split).
For a satellite whose true elevation lands in [mask, mask+1) --
e.g. El=15.63 against a 15 deg mask -- floor(El) collapses to exactly
`mask`, and the strict `>` re-check then wrongly excludes a satellite
that was already correctly accepted by the untruncated comparison.

Verified live: G11 at El=15.63 (15 deg mask) stayed stuck in EXCLUDED
across a full recompute instead of promoting to VISIBLE.

Both re-derivations need `>=` instead of `>` to correctly compensate
for the floor() truncation bias (proof in the added comments); this is
exact for every fractional elevation except one landing exactly on the
integer mask value, a measure-zero case for a continuous real angle.
2026-09-10 17:50:48 +02:00
joebre 1d661e2442 Fix periodic/position-triggered full recompute never firing
last_recompute_rx_time_s_ and last_recompute_r_eb_e_ were being reset
on every Tick() that passed the early-return gate, including a
data_changed-only (targeted) recompute -- not just on an actual full
sweep, despite both being documented as tracking the last *full*
recompute. With a dozen+ satellites actively updating their ephemeris/
almanac, data_changed fires often enough to keep resetting both clocks
before visibility_recompute_interval_s (or the position-displacement
threshold) is ever reached, silently starving the periodic full
recompute -- the one mechanism that can catch a satellite rising above
the horizon with no ephemeris/almanac change of its own to trigger a
targeted recompute.

Move both assignments inside the needs_full_recompute block so they
only advance when a full sweep actually just ran.
2026-09-10 15:56:42 +02:00