GNSS Filtering Pipeline¶
The projects/GNSS_Filtering scenario configures the core
LunarGnssODTSSimulation implemented under
cpp/lupnt/simulations/LunarGnssODTS. The project folder contains scenario
assets only: YAML configs, Python delay precompute, plotting scripts, and the
notebook. The workflow is organized as a staged pipeline so that expensive
environment simulations can be cached and inspected separately from the Monte
Carlo filter.
The default case is a 3 minute ELFO receiver simulation around the Moon using
GPS SP3/ANTEX data. The receiver application is scheduled in the receiver’s
local clock at receiver_app.rate_hz and each app tick is mapped to the TDB
coordinate timeline used for propagation and measurement generation.
Pipeline Stages¶
LunarGnssODTSSimulation::Precomputein C++ Builds the GNSS constellations from SP3/ANTEX data, propagates the nominal lunar receiver trajectory, solves receiver-dependent light time, applies transmitter PCO corrections through the constellation setup, and writes one row per epoch, transmitter, and frequency. Ionosphere/plasma columns are set to zero in this stage.precompute_delays.pyin Python Reads the link CSV and runs GCPM/IRI ray tracing for each saved link. This step is intentionally Python multiprocessing based because the raytrace stack is process-parallel, not OpenMP/thread-parallel.LunarGnssODTSSimulation::Runin C++ Loads the precomputed links and, when enabled, merges the delay CSV into the truth channels. It then generates noisy pseudorange, Doppler, and optional TDCP measurements and runs the UDU EKF. When TDCP is enabled, the C++ stage uses UDU stochastic cloning with state[x_k, x_{k-1}]so the time-differenced carrier range can depend on both receiver epochs. Truth and filter propagation useNBodyDynamics. The truth clock is propagated withJointOrbitClockDynamicsand OCXO process noise; relativistic clock drift is evaluated from the receiver orbit. SRP can be modeled as a fixed force or estimated as an additional filter state.Post-processing The notebook and plotting script visualize precomputed plasma delays, tracked satellite counts, RTN position/velocity errors, clock errors, SRP coefficient error when enabled, and covariance-derived 3-sigma bounds.
Run Commands¶
The full pipeline can be launched with:
pixi run run-gnss-pipeline
The GCPM delay batch can be slow. Skip it only when the configured delay table
already exists, or when the config has plasma.simulate_truth: false:
pixi run run-gnss-pipeline --skip-delays
The wrapper accepts:
--config PATH
--workers N
--serial-delays
--overwrite-delays
--skip-delays
--no-plot
The stages can also be run one at a time:
pixi run precompute-gnss-links
pixi run precompute-gnss-delays
pixi run run-gnss-monte-carlo
pixi run plot-gnss-filtering
Inputs¶
The main configuration is:
projects/GNSS_Filtering/gnss_filtering_config.yaml
Receiver hardware, tracking-loop, link-budget, measurement-noise, and filter-mismatch defaults are selected from:
projects/GNSS_Filtering/gnss_designs.yaml
Measurement selection is controlled in the measurements block. The default
uses pseudorange and Doppler. Set measurements.use_tdcp: true to add TDCP
rows after the first receiver app tick; carrier_phase_sigma_m and
tdcp_sigma_m set the carrier/TDCP noise levels in meters.
The constellation configuration can auto-select SP3 files from
constellation.sp3_directory for the configured start epoch and simulation
duration. ANTEX PCO data are read from constellation.antex_file. The
default scenario uses every GPS PRN available in the selected SP3 file; set
constellation.use_all_gps: false and list constellation.gps_prns for a
small debugging subset. Galileo can be enabled with
constellation.include_galileo: true when the selected SP3/ANTEX products
contain Galileo satellites.
Intermediate Files¶
By default, staged products are written under output/gnss_filtering:
File |
Producer |
Purpose |
|---|---|---|
|
|
Receiver-specific light-time links with zero plasma delay columns. |
|
|
GCPM/IRI delay values keyed by epoch, constellation, PRN, and frequency. |
|
|
Per-run truth, estimate, RTN errors, covariance bounds, clock errors, optional SRP error, and tracked satellite count. |
|
|
Final and RMS Monte Carlo statistics. |
Truth and Estimated Measurement Split¶
The truth measurement channels are built from interpolated SP3/ANTEX
transmitter data, receiver-dependent light-time iteration, Sun-only Shapiro
delay, and optional precomputed GCPM/IRI ionosphere/plasma delay. The filter
measurement uses the ephemeris metadata carried in each GnssChannel and
re-solves light time from the current estimated receiver state. This keeps the
truth data product and the estimated measurement function close to the way a
receiver consumes a navigation message.
The filter can either ignore plasma delay and inflate measurement noise with
plasma.filter_pseudorange_noise_inflation_m /
plasma.filter_doppler_noise_inflation_hz, or model the same delay carried
by the channel when plasma.model_in_filter is enabled.
Time and Unit Conventions¶
The receiver trajectory and app schedule are propagated on a TDB coordinate
timeline. GNSS constellation ephemeris tables are stored and interpolated in
TAI seconds. The measurement API converts receiver receive epochs from
options.receive_time_scale to options.ephemeris_time_scale before
interpolating transmitter states.
Receiver states use SI position and velocity units. Clock bias and drift can
be represented in seconds, meters, or kilometers through ClockBiasUnit; the
filter example uses seconds in its configuration, while the library supports
range-like clock units for better numerical scaling in other filters.
Outputs and Visualization¶
Open the notebook:
projects/GNSS_Filtering/plot_gnss_filtering_results.ipynb
or regenerate PNGs from the command line:
pixi run plot-gnss-filtering
The command-line script writes:
output/gnss_filtering/gnss_filtering_rtn_tracking.png
output/gnss_filtering/gnss_filtering_plasma_delays.png