Galileo receiver baseband model
This repository is a modular Python reference model for a Galileo receiver
baseband and a starting point for bit-true/RTL verification. It currently
implements E1B data and E1C pilot processing with selectable BOC(1,1) or
full-band CBOC(6,1,1/11) local replicas,
streaming real-IF or complex-IQ front ends, FFT PCPS acquisition, independent
tracking channels, fixed-point boundary models, and hardware sizing models.
The floating reference uses numpy.float64/numpy.complex128 throughout;
single-precision formats are accepted only when explicitly reading legacy files.
The repository intentionally contains no fabricated Galileo PRN sequences.
SyntheticCodeProvider creates deterministic non-ICD codes for closed-loop
verification. These codes cannot receive a live Galileo signal. Validated
official tables can be installed under data/ and loaded through
FileCodeProvider without changing acquisition or tracking APIs.
An external globsky/SignalSim checkout is now validated as a second code and
sample source. SignalSimCodeProvider parses that checkout at run time without
copying its tables. The installed commit generates combined E1B/E1C BOC(1,1)
complex IQ; both acquisition and tracking pass on its IQ8 output. See the
measured SignalSim integration report.
Status and limitations
- E1 profile: 1.023 Mcps, 4092 chips, 4 ms, 1575.42 MHz.
- BOC(1,1) remains the default regression mode. Full-band CBOC is enabled explicitly per acquisition/tracking configuration. Unambiguous BOC remains an API extension point.
- E1B bit-transition hypotheses and E1C secondary wipeoff/search are available for acquisition. E1C tracking jointly searches the 25-symbol phase and residual carrier frequency before continuous secondary-code wipeoff.
- The code-table provider, not the DSP engine, determines whether codes are synthetic or official.
- The floating-point model is executable. The fixed PCPS model is bit-true at I/O, FFT output, product, power, and accumulator boundaries; an FFT vendor/butterfly schedule must be selected before claiming bit identity with a particular RTL FFT core.
- Channel impairments include Doppler rate, sampling-clock offset, carrier offset, AWGN, clipping, and quantization. Multipath, jerk, oscillator phase noise, and interference are future channel-model plug-ins.
- The default navigation architecture acquires E1C, synchronizes/wipes its 25-symbol secondary code, and drives shared carrier/code states, C/N0, and BOC-aware lock monitoring from E1C. A phase-coherent E1B branch supplies only Prompt I/Q to I/NAV decoding. E1B-only tracking remains a regression mode.
- Code lock is derived from smoothed VE/E/P/L/VL BOC-shape powers with explicit metric validity, hysteresis, and side-peak/signal-loss tests; the legacy instantaneous Prompt/Early/Late ratio is diagnostic-only.
- E1B I/NAV word types 1–6 are decoded from tracked RF prompts. Almanac parsing, OSNMA authentication, and PVT are deliberately not implemented yet.
Install and test
Python 3.11 or newer is required.
python -m pip install -e '.[test]'
python -m pytest
All automated tests use deterministic seeds and run headlessly. Plots import Matplotlib only when explicitly requested.
Configuration and CLI
YAML keys map to strict dataclasses in galileo_rx.config; unknown keys and
unsafe long integrations raise descriptive errors. Physical quantities carry
unit suffixes. See configuration details.
python -m galileo_rx.cli generate --config configs/acquisition_example.yaml --output samples.bin
python -m galileo_rx.cli acquire --config configs/acquisition_example.yaml --input samples.bin --output acquisition.json
python -m galileo_rx.cli track --config configs/tracking_example.yaml --input samples.bin --acquisition-result acquisition.json --output tracking.csv
python -m galileo_rx.cli run --config configs/acquisition_example.yaml --input samples.bin
python -m galileo_rx.cli compare-fixed --config configs/acquisition_example.yaml --input samples.bin
python -m galileo_rx.cli validate-signalsim --signalsim-path signalsim/SignalSim --config configs/signalsim_validation.yaml --output-dir reports/signalsim_validation
python -m galileo_rx.cli collect-navigation --config configs/navigation_collection.yaml --output-dir reports/navigation_run
python -m galileo_rx.cli collect-navigation --config configs/navigation_collection.yaml --output-dir reports/navigation_e1b --tracking-mode e1b_only
python tools/compare_e1_tracking_modes.py --config configs/navigation_collection.yaml --output-dir reports/e1_tracking_mode_comparison
python tools/run_cboc_validation.py --output-dir reports --duration-s 0.30
python -m galileo_rx.cli prompts-to-symbols --input verification/navigation/signalsim_navigation_multisat_e1c_pilot_aided_e1b/prn_01/prompt_epochs.npz --prn 1 --output-dir reports/navigation_replay/prn_01
python -m galileo_rx.cli decode-inav --input verification/navigation/signalsim_navigation_multisat_e1c_pilot_aided_e1b/prn_01/prompt_epochs.npz --prn 1 --output-dir reports/navigation_replay/prn_01
python -m galileo_rx.cli inspect-navigation --input verification/navigation/signalsim_navigation_multisat_e1c_pilot_aided_e1b/prn_01
The CLI uses synthetic codes by design. Replace the provider with
FileCodeProvider after installing independently validated tables for live
signal work.
validate-signalsim is the exception: it explicitly uses the detected external
SignalSim table and IQ conventions and writes quantitative JSON/Markdown/plot
artifacts. Its quick regression is:
MPLBACKEND=Agg pytest -m signalsim -v
Runnable source examples are in examples/:
python examples/generate_e1_signal.py
python examples/run_acquisition.py
python examples/run_tracking.py
python examples/run_complete_receiver.py
Architecture
The generic acquisition and tracking engines depend on SignalProfile and
CodeProvider, not E1 constants. Adding E5a/E5b therefore means defining a
profile, modulation replica, and validated code provider; engine interfaces do
not change.
sample source -> streaming front end -> sample buffer -> PCPS acquisition
| |
+---- tracking manager
+-- E1C pilot master
+-- shared NCO phases
+-- E1B navigation branch
float blocks <-> fixed block boundaries <-> cycle transactions <-> RTL
The floating algorithms and equations are in algorithms.md,
fixed-point assumptions and starting widths in
fixed_point_plan.md, and the two acquisition plus two
tracking hardware options in rtl_mapping.md. The
module-level contract is duplicated close to the code in
src/galileo_rx/rtl_model/architecture.md.
Exact phase-gate test and example commands are recorded in development_phases.md.
E1B navigation decoding
The I/NAV pipeline preserves 4 ms Prompt I/Q epochs and their sample timestamps, recovers confidence-bearing symbols, resolves page polarity explicitly, applies the official 30×8 deinterleaver and soft Viterbi decoder, validates CRC-24Q, and parses typed word 1–6 data. Ephemerides are committed atomically only when words 1–4 have matching IODnav; the previous valid set survives incomplete updates.
The post-CBOC 32.2 s raw-IQ SignalSim regression decoded 75/75 CRC-valid pages. All five tracked satellites produced complete ephemerides, clocks, healthy status, and GST. Post-decode comparison against SignalSim's RINEX source passed at the broadcast quantization resolution. No simulator truth is accepted by the normal decoder API.
See ICD mapping, the
hardware/software partition,
BOC-aware lock design,
pilot-aided tracking architecture,
the collection report, and
the readiness gate. Saved artifacts
under verification/navigation/ can replay navigation decoding without RF
acquisition or tracking.
Phase completion record
- Profiles, typed configuration, code providers, BOC, generator, and I/O.
- Streaming front end, FFT PCPS, detector metrics, long integration, plots.
- Stateful EPL/VEVL tracking, FLL/PLL/DLL, locks, C/N0.
- Multi-channel manager and separate E1B/E1C handling.
- Fixed formats, NCO, mixer/correlator, PCPS boundary model, comparison/sweep.
- Cycle transaction types, scheduler/resource equations, RTL documentation.
Assumptions and unresolved implementation choices are called out in the linked documents rather than hidden in constants.