Commit Graph
553 Commits
Author SHA1 Message Date
Carles Fernandez 96b4921f8c Merge branch 'joebre-freq-error-reduction' into next 2026-09-16 15:21:49 +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 199e943b8e Extend the healthy field to more signals 2026-09-16 11:24:37 +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
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 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
Carles Fernandez d84069121a Let PVT.iono_model decide band combination in the single point solution 2026-09-10 12:20:38 +02:00
Carles Fernandez 2622d2666e 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-10 12:20:38 +02:00
joebreandClaude Sonnet 5 5f5152e936 Fix CHANGELOG.md prose-wrap to match CI's prettier invocation
CI runs prettier with --prose-wrap always, which reflows Markdown
prose to the print-width regardless of existing line breaks; the
local default (preserve) had left the added bullet's original
wrapping untouched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jb6oqf5UHnLP1yQoMdpb3S
2026-09-10 12:20:37 +02:00
joebre a77536ed05 Add an opt-in EVK1029_Signal_Source for the SAPHYRION EVK1029
EVK1029 is an Evaluation Kit for SAPHYRION SAGL space-grade ASICs: the
SY1009 RF Front-End and the SY1019 ADC/DSP. The kit includes a USB 3.0
device connected to a dual-band (E1/E5a) or triple-band (E1/E5a/E6) GNSS
front-end board, a Linux application for controlling/monitoring the
EVK1029 USB device and the SY10x9 ASICs and for saving the real-time
captured GNSS data stream to a binary file, and an EVK1029-enabled
version of GNSS-SDR.

This adds a signal source that reads the EVK1029 host application's raw
capture files directly: a continuous, header-less stream of OBA-encoded
4-bit samples (two per byte, 16 samples per little-endian 64-bit word),
with no periodic block header -- distinct enough from the generic
XML-metadata-driven ION_GSMS_Signal_Source path to warrant a dedicated
reader rather than a configuration of it.

Evk1029Source (the GNU Radio block) supports emitting multiple identical
output streams from a single read/file, so a dual-band capture (e.g. two
Freq_Xlating_Fir_Filter instances tuned to different IFs from the same
raw stream) stays sample-locked between bands: GNU Radio computes
noutput_items as the minimum available space across all declared output
ports, so backpressure from whichever downstream chain is slower stalls
production for every port together, instead of two independently-read
SignalSource instances that can silently drift apart over a long run.
The scheduler's output-multiple quantum is derived from the configured
sampling_frequency (targeting ~0.7 ms of data, rounded to the nearest
power of two) rather than hardcoded, since this block runs at the raw,
pre-decimation sample rate (up to ~180 Msps) where call-frequency
overhead measurably affects both this block and downstream readers.

Disabled by default, matching this project's convention for new
optional signal sources: build with -DENABLE_EVK1029=ON to enable it
(mirrors ENABLE_ION's wiring exactly -- CMake option, compile
definition on core_receiver, conditional registration in
gnss_block_factory.cc). Verified: clean build with the option off
(zero EVK1029 code compiled in) and with it on.

EVK1029 is being developed under an ESA contract and is expected to
become commercially available within 6-12 months.
2026-09-10 12:20:36 +02:00
joebre 6bee062e8f Rename UsedSatellite message to TrackedSatellite
A field named "used" inside a message called UsedSatellite read
oddly, especially since the message reports every tracked satellite
(used or excluded), not only used ones. Renamed the message and its
repeated field (tracked_satellites), plus the matching C++/protobuf
serialization types (Monitor_Pvt::TrackedSatelliteInfo,
tracked_satellites), so "used" now reads sensibly as a per-satellite
flag on a TrackedSatellite rather than inside a UsedSatellite.
2026-09-09 17:56:39 +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
joebre 7c8dfbbb79 Report az/el for satellites excluded from the PVT fix, not just used ones
rescode() (rtklib_pntpos.cc) computes each satellite's azimuth/elevation via
satazel() before checking it against PVT.elevation_mask, and pntpos() copies
that azel into ssat[] unconditionally -- only ssat[].vs is gated by the mask
(the same applies to a satellite dropped by RAIM FDE). The used_satellites
loop in rtklib_solver.cc was keying its entire per-satellite entry on vs, so
a tracked satellite excluded from the fix (below the elevation mask, or by
RAIM) disappeared from MonitorPvt entirely -- indistinguishable from a
genuine tracking problem.

Key entries on whether azel was actually computed this epoch instead, and
add a separate `used` flag (default true) reflecting vs. A satellite that
is tracked but excluded from the fix now still reports its real az/el, with
used = false.
2026-09-07 18:11:12 +02:00
joebreandClaude Sonnet 5 dff90d5f73 Fix CHANGELOG.md prose-wrap to match CI's prettier invocation
CI runs prettier with --prose-wrap always, which reflows Markdown
prose to the print-width regardless of existing line breaks; the
local default (preserve) had left the added bullet's original
wrapping untouched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jb6oqf5UHnLP1yQoMdpb3S
2026-09-07 17:20:15 +02:00
joebre 0849172803 Add an opt-in EVK1029_Signal_Source for the SAPHYRION EVK1029
EVK1029 is an Evaluation Kit for SAPHYRION SAGL space-grade ASICs: the
SY1009 RF Front-End and the SY1019 ADC/DSP. The kit includes a USB 3.0
device connected to a dual-band (E1/E5a) or triple-band (E1/E5a/E6) GNSS
front-end board, a Linux application for controlling/monitoring the
EVK1029 USB device and the SY10x9 ASICs and for saving the real-time
captured GNSS data stream to a binary file, and an EVK1029-enabled
version of GNSS-SDR.

This adds a signal source that reads the EVK1029 host application's raw
capture files directly: a continuous, header-less stream of OBA-encoded
4-bit samples (two per byte, 16 samples per little-endian 64-bit word),
with no periodic block header -- distinct enough from the generic
XML-metadata-driven ION_GSMS_Signal_Source path to warrant a dedicated
reader rather than a configuration of it.

Evk1029Source (the GNU Radio block) supports emitting multiple identical
output streams from a single read/file, so a dual-band capture (e.g. two
Freq_Xlating_Fir_Filter instances tuned to different IFs from the same
raw stream) stays sample-locked between bands: GNU Radio computes
noutput_items as the minimum available space across all declared output
ports, so backpressure from whichever downstream chain is slower stalls
production for every port together, instead of two independently-read
SignalSource instances that can silently drift apart over a long run.
The scheduler's output-multiple quantum is derived from the configured
sampling_frequency (targeting ~0.7 ms of data, rounded to the nearest
power of two) rather than hardcoded, since this block runs at the raw,
pre-decimation sample rate (up to ~180 Msps) where call-frequency
overhead measurably affects both this block and downstream readers.

Disabled by default, matching this project's convention for new
optional signal sources: build with -DENABLE_EVK1029=ON to enable it
(mirrors ENABLE_ION's wiring exactly -- CMake option, compile
definition on core_receiver, conditional registration in
gnss_block_factory.cc). Verified: clean build with the option off
(zero EVK1029 code compiled in) and with it on.

EVK1029 is being developed under an ESA contract and is expected to
become commercially available within 6-12 months.
2026-09-07 16:47:55 +02:00
Carles Fernandez 1ba1f37d3b Polish the gnss_synchro_monitor decimation fix 2026-09-05 12:46:30 +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
Carles Fernandez a87bbdd09a Update CHANGELOG.md 2026-08-29 12:58:10 +02:00
joebre a78865b555 Add per-satellite azimuth/elevation and used signals to MonitorPvt
An application monitoring gnss-sdr (e.g. for a sky plot or a per-satellite
status view) typically needs to know which satellites and signals actually
contributed to the current PVT solution, and their azimuth/elevation --
none of that is currently exposed on the MonitorPvt UDP interface, only the
scalar solution.

Adds a repeated UsedSatellite field to MonitorPvt (proto field 37), one
entry per satellite/signal used in the fix: PRN, constellation, signal ID,
azimuth, elevation, and whether that satellite's signals were combined
(e.g. Galileo E1+E5a iono-free). Signals are kept as separate entries
rather than merged into one per-satellite record, since a receiver may
track more than one signal of the same satellite independently and a
consumer may care which ones specifically contributed.

Populated in Rtklib_Solver::get_PVT() from RTKLIB's per-satellite azel
solution (pvt_ssat[]) intersected with the observables actually used in
that epoch.

Signed-off-by: joebre <joel.brenner@saphyrion.ch>
2026-08-28 11:03:35 +02:00
Carles Fernandez 4fdd65b1e6 Update XML schemas 2026-08-28 09:01:52 +02:00
Carles Fernandez df001f4dc7 Add Oleksandr Suvorov to the list of contributors 2026-08-27 11:33:31 +02:00
Oleksandr Suvorov a5a6b9359b signal_source: add native BladeRF support via libbladeRF
Add a Bladerf_Signal_Source that streams RX samples directly from
bladeRF front-ends (bladeRF x40, x115, and bladeRF 2.0 Micro xA4/xA9)
through libbladeRF, instead of going through the generic gr-osmosdr
wrapper. gr-osmosdr's bladerf backend does not expose usable per-stage
gain control on bladeRF2 hardware and has no support for the RX bias
tee used to power an active antenna on the 2.0 Micro.

The new gr::sync_block (bladerf_source) talks to libbladeRF's
synchronous streaming API directly; the adapter (BladerfSignalSource)
follows the existing SignalSourceBase pattern used by the other signal
sources, with valve and dump support wired the same way. Building it
is gated behind -DENABLE_BLADERF=ON, degrades gracefully when
libbladeRF is absent, and requires libbladeRF v2.6.0 or newer,
enforced at configure time.

Verified against a physical bladeRF 2.0 Micro: the receiver opens the
device, streams live samples, and acquires and tracks real GPS
satellites end to end using the new sample configuration file.

Only single-channel (SISO) reception is supported for now; the second
RX channel is not yet exposed.

Signed-off-by: Oleksandr Suvorov <cryosay@gmail.com>
2026-08-27 11:06:11 +03:00
Carles Fernandez 1f0be04d58 Update changelog 2026-08-23 13:22:29 +02:00
Carles Fernandez 9accccdbaa Add BeiDou B1C signals to RTK 2026-08-18 08:07:20 +02:00
Carles Fernandez e368102bfb Add single-frequency RTK 2026-08-17 20:29:25 +02:00
Carles Fernandez 032cfa8e8d Update documentation 2026-08-17 14:02:01 +02:00
Carles Fernandez a936c4d2d8 Enable usage of Virtual Reference Stations 2026-08-17 09:37:25 +02:00
Carles Fernandez 3b94087b20 Fix rtklib_tls_test building against GoogleTest < 1.10
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.¡
2026-08-16 00:32:46 +02:00
Carles Fernandez 87d8a6991e Improve carrier phase integrity in the RTK engine 2026-08-15 21:22:41 +02:00
Carles Fernandez 5470aafe85 Add RTKLIB engine improvements 2026-08-11 08:57:04 +02:00
Carles Fernandez 3a557755e4 Add NTRIP v2 and leave v1 as a fallback 2026-08-10 13:26:58 +02:00
Carles Fernandez 059e639a3a Added an opt-in fixed-base RTK path 2026-08-10 11:55:35 +02:00
Carles Fernandez 1f9afe4431 Implement SBAS/EGNOS correction path 2026-08-09 07:55:04 +02:00
Carles Fernandez f0e75ce558 Improve SBAS L1 telemetry decoder and simplify SBAS adapters
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.
2026-08-08 12:10:10 +02:00
Carles Fernandez 11bb1c44c6 Fix formatting 2026-08-08 10:21:13 +02:00
Carles Fernandez d89529b537 Document addition of the BeiDou B1C signal and add Ou Wenhao to the list of authors 2026-08-07 14:45:53 +02:00
Carles Fernandez 833bfb5dd1 Corrected RINEX 3/4 navigation and observation output 2026-08-03 11:47:34 +02:00
Carles Fernandez 5454bc22ee Complete BeiDou D1/D2 DNAV decoding 2026-07-31 19:11:58 +02:00
Carles Fernandez 3fe0226f4b Update changelog 2026-07-31 17:17:23 +02:00
Carles Fernandez 68669a361b Fix group-delay and ionospheric corrections in the RTKLIB SPP solver 2026-07-30 19:42:06 +02:00
Carles Fernandez cfc45fb8bf Store QZSS L5 CNAV UTC and iono parameters separately, log CNVX records
Extend the QZSS L1 C/A LNAV treatment to the L5 CNAV chain: the QZSS-
configured L5 telemetry decoder now publishes dedicated Qzss_CNAV_Iono
and Qzss_CNAV_Utc_Model objects instead of the shared GPS CNAV types,
and PVT keeps them in their own Rtklib_Solver members.

- RINEX 4.02 navigation files get "> STO J  CNVX" QZUT records with the
  UTC(NICT) identifier and "> ION J  CNVX WIDE" Klobuchar records. The
  WIDE subtype, compulsory for the QZSS CNVX ION message type, is
  correct because CNAV Message Type 30 broadcasts the Wide Area
  coefficient set (IS-QZSS-PNT-006; the Japan area set of Message Type
  61 is not decoded).
- QZSS CNAV parameters no longer overwrite the GPS CNAV ones in mixed
  configurations.
- The QZSS slots of the RTKLIB navigation structure take the LNAV
  values with CNAV as fallback, and QZSS-only configurations keep
  feeding the broadcast ionospheric model and the leap second count.
- The XML storage output gains qzss_cnav_utc_model.xml and
  qzss_cnav_iono.xml.
2026-07-30 12:55:28 +02:00
Carles FernandezandClaude Fable 5 4f570e7867 Store QZSS UTC and iono parameters separately and log RINEX 4 QZUT records
The Klobuchar coefficients and the UTC(NICT) offset broadcast by QZSS
satellites in LNAV subframe 4 (both the wide-area and Japan-area pages)
were stored in the shared GPS structures, overwriting the GPS-sourced
values in mixed GPS + QZSS configurations and making it impossible to
label them correctly in RINEX output.

New Qzss_Utc_Model and Qzss_Iono storage classes are now published by
the QZSS-configured L1 C/A telemetry decoder and kept in dedicated
Rtklib_Solver members. With this in place:

- RINEX 4.02 navigation files get "> STO J  LNAV" QZUT records with the
  UTC(NICT) identifier and "> ION J  LNAV" Klobuchar records, and the
  LEAP SECONDS header is updated from QZSS data in QZSS-only setups.
- QZSS-sourced parameters are no longer mislabeled as GPS corrections
  (GPUT / GPS ION or TIME SYSTEM CORR / IONOSPHERIC CORR lines).
- The QZSS slots of the RTKLIB navigation structure (utc_qzs, ion_qzs)
  are now populated; QZSS-only configurations keep feeding the broadcast
  ionospheric model and the leap second count as before.
- The XML storage output gains qzss_utc_model.xml and qzss_iono.xml.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-30 12:21:59 +02:00
Carles Fernandez b327290af1 Update changelog 2026-07-30 11:27:30 +02:00