Fault Simulation
This chapter is the experiment-design rationale behind conf/: which GNSS conditions are
worth simulating, what the published measurements say those conditions look like, and which
knobs in GnssFaultModel correspond to which.
What jamming actually does
The dominant, repeatedly measured effect of jamming is loss of fix, not graceful degradation. At Jammertest — the open field trial run annually at Andøya by the Norwegian Public Roads Administration, Communications Authority, Defence Research Establishment, Metrology Service and Space Agency — the jamming signal was in most runs strong enough to cause complete GNSS signal loss, and a smartphone roughly ten metres from a jammer lost lock on benign signals entirely. Receivers reacquired when terrain or buildings shadowed them from the jammer and lost lock again on returning to line of sight.
That matters for how a scenario is built. A receiver inside the jammed area does not report a noisier position; it reports nothing. A model that keeps delivering fixes with more error on them describes the fringe of the jammed area, not the inside of it — and it is the inside that an inertial system, or a geophysical aid, exists to carry you through.
The scale is not marginal. IATA recorded a 220% rise in GPS signal-loss events between 2021 and 2024; European flights encountering GNSS interference rose from roughly 200 per day in Q1 2024 to around 900 per day in Q2, and EUROCONTROL logged more than 2,500 jamming events in 2024 alone.
The interference tier
| Tier | What it models | Scheduler | Fault | Configs |
|---|---|---|---|---|
| Degraded | the fringe of a jammed area | fixed_interval | degraded | conf/*_degraded.toml |
| Spoof | a deceptive signal | either | slow_bias / hijack | — |
An earlier version of this experiment matrix also carried a Denial tier
(duty_cycle/none, modeling total loss of fix inside a jammed area) as a config separate
from Degraded. It was consolidated into the single Degraded tier below: keeping one
interference profile, used identically everywhere a geo-aided run is scored, was worth more
than covering both regimes at the cost of doubling the config matrix and the pairing logic
that keeps it honest (see "Choosing a baseline" below).
Degraded
conf/*_degraded.toml: fixes every 5 s, with AR(1)-correlated error on position and velocity
and the advertised accuracies inflated.
Anchoring the magnitude to measurement rather than to a round number: smartphone GNSS is 3–5 m
under good multipath and over 10 m in harsh multipath, with semi-urban CEP95 around 10–12 m.
Under jamming the tracked satellite count falls and GDOP rises, so true error and advertised
accuracy inflate together. sigma_pos_m = 35.0 is about 14× this dataset's 2.58 m median
advertised accuracy — a receiver still producing fixes, but bad ones.
r_scale inflates the advertised 1σ, which the measurement model then squares, so R moves
by r_scale²: the standard 5.0 is a 25× R, not a 5× one.
Spoofing
slow_bias and hijack are implemented and unused in the current experiment matrix. They
differ in detectability by construction: a hijack steps the position with no matching
velocity change, so it produces a large NIS the moment it starts and a chi-squared gate
rejects it. A slow_bias moves position and velocity consistently, which is what keeps it
under the gate — that is the whole design of a soft spoof.
Correlation time and the fix interval
rho_pos and rho_vel are applied once per emitted fix, with no reference to elapsed
time. The error's correlation time is therefore -interval_s / ln(rho) — a property of the
scheduler, not of the error model. At rho_pos = 0.99, a 5 s fix interval is a 498 s
correlation time and a 30 s interval is 2985 s.
So an experiment that sweeps the fix interval is also sweeping the error timescale, and the two cannot be separated in the result.
tau_pos_s and tau_vel_s fix this. When set, the coefficient becomes exp(-dt / tau) for
the actual interval between fixes, and sigma_pos_m is reinterpreted as the steady-state
standard deviation in metres rather than the per-step innovation:
[gnss_degradation.fault]
kind = "degraded"
sigma_pos_m = 35.0 # steady-state wander, metres, whatever the schedule
tau_pos_s = 500.0 # correlation time in seconds
They are optional and additive. Omit them and the per-fix form applies exactly as before, so every configuration written earlier — and every result recorded from one — still means what it meant. Prefer them for anything that varies the schedule.
Note also that without a time constant, sigma_pos_m is the per-step innovation, not the
error you get: an AR(1) settles at sigma / sqrt(1 - rho²), so sigma_pos_m = 3.0 with
rho_pos = 0.99 is 21 m of wander, not 3 m.
Choosing a baseline to compare against
geoperf-all scores each geophysically-aided run against that filter's unaided run, so the
two must carry an identical GNSS profile. If they differ, the "improvement" reported is
the difference between two degradations and has nothing to do with the aid. The
[gnss_degradation] and [health_limits] sections of conf/{ukf,ekf,rbpf}_{grav,mag,both}.toml
are duplicated from conf/*_degraded.toml for exactly this reason, and
core/tests/example_configs.rs covers conf/ so a drift in them fails a test.
conf/*_degraded.toml carries this recalibrated 35 m profile, and it is the only
interference tier in the config matrix: conf/{ukf,ekf,rbpf}_{grav,mag,both}.toml are all
scored against their own filter's conf/{ukf,ekf,rbpf}_degraded.toml, and RBPF's geo-aided
runs are additionally scored against conf/ekf_degraded.toml as the canonical INS baseline
(just geoperf-all/geoperf-rbpf). Keeping a single profile, applied identically everywhere,
is what makes the pairing in core/tests/example_configs.rs a simple filename convention
rather than a per-tier lookup.
Sources
- Jammertest 2024 results (Septentrio)
- Navigating through interference at Jammertest (ESA)
- GNSS jamming and spoofing detection at Jammertest 2025 (u-blox)
- Using mobile phones for participatory detection and localization of a GNSS jammer
- A comparative analysis of the response of GNSS receivers under vertical and horizontal L1/E1 chirp jamming, Sensors 21(4):1446
- A comprehensive analysis of smartphone GNSS range errors in realistic environments, Sensors 23(3):1631
- Improving smartphone GNSS positioning accuracy using contextual information, Sensors 26(11):3346
- EASA and IATA plan to mitigate the risks of GNSS interference
- IATA safety risk assessment: GNSS interference
- EUROCONTROL GNSS interference testing guide v2.0
- RTCA DO-235C, Assessment of radio frequency interference relevant to the GNSS L1 frequency band
- Overbounding the effect of uncertain Gauss-Markov noise in Kalman filtering, NAVIGATION 68(2):259
- GNSS error simulator for farm machinery navigation — the first-order Gauss-Markov form
R(Δt) = σ² e^(-|Δt|/τ)these time constants implement