DNAV-1 "GPS-denied navigation" · methodology · one-page summary · 11 Oct 2026 · code at branch night/DNAV-1-pathfinder

Pathfinder method: what is physics and what is a weight

This page answers the owner's question "what is physics and what is weights" and fixes one vocabulary for the team. Each part is described in plain words first, then under its standard name, then as the equation the code runs, with every constant, its value, the file:line that holds it and the decision (D-entry in docs/01-decisions.md) that set it.

Every number carries a tag: measured (sim) came from ArduPilot SITL flights and names its source; estimate is reasoned or computed by hand, not measured; configured is a value someone chose and typed in. Nothing on this page is measured on a real drone. Paths are relative to Pathfinder/; core files are under crates/pathfinder-core/src/.

0. Standard terms DECIDED (D-NAME-1)

Decided 11 Oct 2026 (D-NAME-1 "Domain names for the six parts"): Position Estimator (mode Pathfinder without ML), Velocity Predictor, Predictor Adapter, GPS Integrity Monitor, Navigator (mode Pathfinder with ML), GPS Fix. The table below is the earlier proposal, kept as the record of what was weighed; the rest of this page uses the decided names.

The owner's feedback: the plain words used so far (physics, weight, uncertainty, fixed weight) are not precise enough. Each row below gives the word in use today, what is wrong with it, two candidate replacements (recommended first), a plain definition, and the textbook term it maps to. Every proposed term is PROPOSED until the owner picks one. The rest of this page still uses today's words, so it reads against the code and the findings page; it switches over once the owner has picked.

Word todayProblemProposed (1 = recommended)Plain definitionStandard engineering term
Pathfinder-PhysicsLearned is trained on physics too; the name hides that this is a navigation filter and that drag, compass and barometer feed it1. Pathfinder-Inertial PROPOSED
2. Pathfinder-Model
Works out position by adding up what the motion sensors feel, corrected by drag, compass and barometermodel-aided strapdown INS, error-state Kalman filter (ESKF)
Pathfinder-Learnedthe per-drone adapter also learns; "learned" does not say what it outputs1. Pathfinder-Neural PROPOSED
2. Pathfinder-NetVelocity
A neural network that guesses airspeed and direction from the last second of sensors and motor commandslearned inertial odometry (TLIO-style velocity regression)
Pathfinder-FusedPhysics already fuses four sensors, so "fused" does not set the two apart1. Pathfinder-Hybrid PROPOSED
2. Pathfinder-Full (matches run type full)
Pathfinder-Physics with the network's velocity added as one more sensorESKF with a learned pseudo-measurement
ArduPilot alonedoes not say which ArduPilot setup; "alone" is also used for "Learned alone"1. ArduPilot baseline PROPOSED
2. EKF3-only baseline
The autopilot's own navigation with no Pathfinder, failsafes off, flown through the same jamunaided EKF3 dead-reckoning baseline (run type b1)
weightthree meanings: Kalman gain, network parameters, adapter layer (section 1)1. trust share PROPOSED
2. fusion gain
How much of a sensor's disagreement the estimate accepts, from 0 (ignore) to 1 (take it whole)Kalman gain K
fixed weightthe gain is not fixed; the sensor-noise setting is1. constant noise setting PROPOSED
2. static R
The Learned sensor is always declared equally unreliable, whatever the flight is doingtime-invariant measurement noise covariance R
uncertainty (of the estimate)used for both the filter's doubt and a sensor's doubt1. estimate uncertainty PROPOSED
2. self-doubt
How wrong the filter thinks its own position, speed and heading might bestate error covariance P
uncertainty (of a sensor)same word as above1. sensor noise setting PROPOSED
2. sensor trust setting
How unreliable we declare each sensor to be; the one number we choose per sensormeasurement noise covariance R
process noise"noise" suggests a sensor; it is an allowance for an imperfect motion model1. model slack PROPOSED
2. drift allowance
How much doubt the filter adds each second because its motion equations are not perfectprocess noise covariance Q (densities σ, random walks)
driftused for position error growth and for slow bias change1. error at t+N s (e.g. "error at t+120 s") PROPOSED
2. position drift
Distance between estimated and true position, N seconds after GPS was lostunaided position error growth (horizontal error vs time)
error radius, honest radius, r95three names for one number; "honest" is the AC-3 test, not the radius1. 95% radius (r95) PROPOSED
2. confidence radius
Circle the filter claims holds the true position 95% of the time95% bound of the horizontal covariance ellipse, √(5.991·λmax); not CEP (CEP is 50%)
innovationjargon to an owner reader1. sensor surprise PROPOSED
2. disagreement
What the sensor says minus what the filter expectedinnovation y = z − h(x)
NIS gate, gateno distribution or degrees of freedom named1. surprise gate (χ²ₖ p%) PROPOSED
2. outlier gate
Throw away a sensor reading that is too surprising given both uncertaintieschi-square NIS gate
divergence (GPS guard)sounds like a rate; it is a distance1. GPS surprise distance PROPOSED
2. GPS Mahalanobis distance
How many sigmas the GPS fix is from where the filter expected itMahalanobis distance of the GPS innovation
drag model"model" collides with the neural model1. drag aiding PROPOSED
2. air-drag law
The formula for how hard the air slows the drone, used as a sensor of airspeedaerodynamic model aiding (drag-force pseudo-measurement)
adapter, drone tunertwo names; AC-7 calls it "in-flight calibration"1. in-flight calibration PROPOSED
2. per-drone tuning
While GPS is good, re-fit the network's last layer to this drone, then freeze itonline recursive least squares (RLS) last-layer adaptation
GPS guardclear; code calls it "integrity"1. GPS guard (keep) PROPOSED
2. GPS integrity monitor
Decides on every fix whether GPS is honest, and cuts it off when jammed or spoofedinnovation-based integrity monitoring with fault detection and exclusion (FDE)
hand-off "odometry"names the message, not what the autopilot does with it1. Mode A: external-nav feed PROPOSED
2. odometry feed
Pathfinder sends position and velocity; ArduPilot's own filter switches to it as a second sourceMAVLink ODOMETRY into EKF3 external navigation (source set 2)
hand-off "gps-input"names the flag, not the behaviour1. Mode B: GPS replacement PROPOSED
2. virtual GPS receiver
Pathfinder pretends to be a second GPS receiver; the autopilot switches to it when real GPS is badMAVLink GPS_INPUT as GPS2 (GPS_TYPE 14), D-65

1. The short answer

Physics is the part that predicts: the equations of motion that turn gyro and accelerometer readings into attitude, velocity and position, plus the drag formula that says how hard the air pushes back at a given airspeed. It is written by hand and runs 200 times a second.

A weight is how much one measurement is allowed to move that prediction. In Kalman-filter terms the weight is the Kalman gain K. Nobody types K in; it is computed every update from two numbers: how unsure the filter is of itself (P, the covariance) and how unsure we say the measurement is (R, the measurement noise). Large P, small R: big weight. Small P, large R: small weight.

The word "weights" has three meanings in this project, and the team keeps them apart from now on:

Say thisMeansWhereChanges when
Kalman gain (the fusion weight)how much a measurement moves the stateeskf.rs:188every update, from P and R
network parametersthe trained numbers inside the Velocity Predictor networkmodels/velocity-long.onnxonly when we retrain
adapter layerthe last layer [W|b] of the network, re-fitted per drone while GPS is goodadapter.rs:101-123first 30-180 s of a flight, then frozen

"Fixed weight" means a constant R. Today every Velocity Predictor velocity sample enters with the same R = 22.9 × 294 = 6,733 (m/s)² per axis, a one-sigma of about 82 m/s estimate, whatever the flight phase, whatever the network says about its own confidence, however long GPS has been gone. The gain K still moves a little, because P grows as Position Estimator drifts, but nothing in the code chooses to trust Velocity Predictor more or less. Section 5 shows the arithmetic.

2. How the parts connect

Sensors on the left. Position Estimator is the filter in the middle; every arrow into it is a measurement with its own R. Velocity Predictor is one more arrow. The GPS Integrity Monitor decides whether the GPS arrow is open. The hand-off sends the result to the autopilot.

Pathfinder data flow IMU drives the prediction step of the error-state Kalman filter. Drag, barometer, compass, learned velocity and GPS (through the GPS Integrity Monitor) are measurements with noise R. The filter output goes to the autopilot as odometry or GPS_INPUT. IMU 200 Hzgyro, accelerometer Barometerheight, R = 1.0² m² Compass 10 Hzyaw, R = 0.08² rad² Velocity Predictorair velocity, 10 HzR = 6,733 (m/s)², fixed GPS ~4.75 Hzpos R = h_acc², vel 0.3² GPS Integrity MonitorTRUSTED / SUSPECT /REJECTED Position Estimator error-state Kalman filter, 17 states predict: motion equationsstate x, covariance P, process noise Q drag measurement 10 Hzair pushes back, R = 0.5² (m/s²)² update: K = P Hᵀ (H P Hᵀ + R)⁻¹the weight, per measurement Navigator =this filter with the Velocity Predictor arrow on B2 / Position Estimator = same filter,Velocity Predictor arrow off Hand-offODOMETRY orGPS_INPUTto ArduPilot

Rates: IMU 200.1 Hz over MAVLink measured (sim) D-61; GPS 4.75 Hz measured (sim) models/integrity.json gps_rate_hz; compass gated to 10 Hz in crates/pathfinderd/src/daemon.rs D-61; drag every 0.1 s configured config.rs:44 D-58; Velocity Predictor every 0.1 s configured config.rs:50 D-53.

3. Position Estimator

It adds up what the motion sensors feel, 200 times a second, to know where the drone is pointing, how fast it moves and where it is. Small sensor errors pile up, so it also keeps a running estimate of how wrong it might be. A drag formula, compass and barometer pull it back toward reality without GPS.

Standard term: error-state Kalman filter (ESKF, D-38 "Fusion filter", interface D-47). Run type b2, harness name B2_FILTER_DRAG.

3.1 State

The nominal state is what the filter believes. The error state is the small correction it is unsure about; the covariance P is defined over the error state.

IndexSymbolMeaningUnitCode
0-2pposition, NED, from the first good fixmIP eskf.rs:6
3-5vground velocity, NEDm/sIV eskf.rs:7
6-8δθattitude error (small rotation, body)radITH eskf.rs:8
9-11b_ggyro biasrad/sIBG eskf.rs:9
12-14b_aaccelerometer biasm/s²IBA eskf.rs:10
15-16whorizontal wind, NEm/sIW eskf.rs:11

17 states, N at eskf.rs:5 configured. Accelerometer scale and drag coefficient states were deliberately not added (D-53).

3.2 Prediction (propagation)

Plain: turn the gyro reading into a rotation, the accelerometer reading into an acceleration in the world frame, and integrate. Standard: strapdown inertial propagation with a state-transition Jacobian F and process noise Q.

ω = gyro − b_g                 a = accel − b_a
a_ned = R(q)·a + [0, 0, g]     g = 9.80665 m/s²      (eskf.rs:12, 140)
p ← p + v·dt + ½·a_ned·dt²     v ← v + a_ned·dt      q ← q ⊗ exp(ω·dt)   (eskf.rs:141-143)
P ← F·P·Fᵀ + Q                 then P ← ½(P + Pᵀ)    (eskf.rs:166-167)

Non-zero blocks of F (eskf.rs:145-153): ∂p/∂v = I·dt, ∂v/∂δθ = −R·[a]×·dt, ∂v/∂b_a = −R·dt, ∂δθ/∂δθ = I − [ω]×·dt, ∂δθ/∂b_g = −I·dt. An IMU gap longer than max_imu_dt_s = 0.05 s configured (config.rs:45) is propagated in substeps with the newest sample (navigator.rs:102-107, D-58 item 2).

Process noise is how much the filter assumes it loses certainty every second without a measurement. Each term is a density σ and enters as σ²·dt on the diagonal (eskf.rs:157-165). Bias and wind terms are random walks: the filter assumes they wander slowly and without direction.

NameValueUnitActs onWhere · set byTag
accel_noise0.35m/s/√sveskf.rs:32 · M0/M1 plan default, EKF3-style start value (eskf.rs:15)configured
gyro_noise0.015rad/√sδθeskf.rs:33 · plan defaultconfigured
accel_bias_walk0.003m/s²/√sb_aeskf.rs:34 · plan defaultconfigured
gyro_bias_walk0.001rad/s/√sb_geskf.rs:35 · plan defaultconfigured
wind_walk0.05m/s/√sw, GPS trustedeskf.rs:36 · D-58 (was 0.2; 98.3% replay coverage at 0.05), D-63 (99.5%)measured (sim)
wind_walk_denied0.05m/s/√sw, GPS not trustedeskf.rs:37, switch navigator.rs:93-97 · D-63 (smaller values tested and refuted)measured (sim)

"Plan default" = the starting value written in docs/plans/2026-10-07-pathfinder-m0-m1.md:2047; no D-entry has tuned it. D-63 names accel_noise and the drag R as the next things to measure.

3.3 Initial uncertainty

What P starts at, as one-sigma per block (eskf.rs:57-63; navigator.rs:203-224 overrides two).

BlockσWhereTag
positionmax(GPS h_acc, 1.0) m (default 3.0 unused at start)navigator.rs:13, 219configured
velocity0.5 m/seskf.rs:58configured
roll, pitch0.05 radeskf.rs:59configured
yaw0.2 rad with compass, π withoutnavigator.rs:14, 213-217configured
gyro bias0.01 rad/seskf.rs:61configured
accel bias0.2 m/s²eskf.rs:62configured
wind5.0 m/seskf.rs:63configured

3.4 Measurement update: the one formula every sensor goes through

Plain: compare what the sensor says with what the filter expected; move the state part of the way toward the sensor; shrink the uncertainty. Standard: Kalman update, Joseph form (eskf.rs:183-197).

y = z − h(x)                  innovation: sensor minus prediction
S = H·P·Hᵀ + R                innovation covariance
K = P·Hᵀ·S⁻¹                  Kalman gain  = the weight        (eskf.rs:188)
δx = K·y                      correction, injected into x      (eskf.rs:189, 200-207)
P ← (I − K·H)·P·(I − K·H)ᵀ + K·R·Kᵀ                              (eskf.rs:194)
NIS = yᵀ·S⁻¹·y                normalised innovation squared    (eskf.rs:177-181)

For one scalar measurement this is K = P/(P + R): the share of the disagreement the filter accepts. R is the only input we choose per sensor.

3.5 Position Estimator measurements and their R

Measurementz, HR (one-sigma)Where · set byTag
Drag: the air slows the drone in proportion to airspeedmean body x,y accel over 0.1 s; predicted −k·u − k_q·u|u| + b_a, u = body air velocity = Rᵀ(v − w)0.5 m/s² per axisdrag.rs:21, law drag.rs:32-43, H drag.rs:45-66 · no D-entry; fit residual is 0.083 m/s² (drag.json), so R is about 6x the fit error estimateconfigured
Drag coefficient k0.2541 /s (quad); hexa 0.2527, octa 0.2401drag.rs:19, models/drag.json · D-58 item 1, n = 4,851 samples, rms 0.083 m/s²measured (sim)
Drag coefficient k_quad0.0341 /m (quad); hexa 0.0345, octa 0.0363drag.rs:20, models/drag.json · D-58measured (sim)
Barometerdown position, offset fixed at first sample (navigator.rs:129)1.0 mconfig.rs:42, measurements.rs:37-45 · plan defaultconfigured
Compasstilt-compensated yaw + declination (measurements.rs:48-52)0.08 rad (4.6°)config.rs:41, measurements.rs:55-66 · plan default; rate 10 Hz D-61; declination from COMPASS_DEC D-58 item 3configured
GPS position (only when the guard says TRUSTED)NED position, H = I on preceiver's own h_acc (horizontal), v_acc (vertical)measurements.rs:11-24, navigator.rs:184-187reported by receiver
GPS velocityN, E velocity0.3 m/sconfig.rs:43, measurements.rs:26-35 · plan defaultconfigured

GPS position is the only measurement whose R changes during a flight, because the receiver reports its own accuracy with every fix. Every other R on this page is a constant.

4. Velocity Predictor

A small neural network looks at the last second of motion sensors, tilt and motor commands and guesses how fast the drone is moving through the air. Each guess is a few m/s off, but the errors go up and down instead of piling up. It never flies alone: on its own it is about 580 m off two minutes after GPS loss.

Standard term: learned inertial odometry (TLIO-style velocity regression) with a heteroscedastic variance head (D-35 "Model uncertainty") and an online last-layer adapter fitted by recursive least squares (D-37 "Per-drone adapter parameters").

4.1 Input and output

ItemValueWhere · set byTag
Input channels (spec v2)13: gyro 3, specific force 3 (heading frame), baro rate, baro present, AHRS roll, pitch, motor mean, spread, presentlearned.rs:13-27 · D-57 "Data spec v2: every model input exists onboard"configured
Heading framebody rotated by roll and pitch, yaw removedlearned.rs:112-114 · D-53configured
Motor normalisationu = clamp((pwm − 1000)/1000, 0, 1)learned.rs:31-32 · D-57configured
Window, rate, stride1 s, 50 Hz (50 samples), one guess every 0.1 smeta file; stride config.rs:50 · D-53configured
Networkcausal TCN, 4 residual blocks, dilation 1/2/4/8, kernel 3, 64 channelsD-53configured
Outputvelocity mean (3) + log-variance (3), clamped to [−8, 6]learned.rs:241-247 · D-53configured
Output framerotated to NED by the filter yawlearned.rs:250-255 · D-53, gap noted in D-60
Held-out error, model alone, t+120 s580 m median (quad+octa, n = 8); 204 m (hexa, n = 4)D-60, docs/measurements/2026-10-learned-v2-heldout.mdmeasured (sim)
Velocity error vs air velocity4.8 m/s RMS (vs ground velocity 5.9 m/s)models/velocity-long.calib.json · D-62measured (sim)
Residual correlation time τ14.7 scalib.json · D-62measured (sim)
Factor needed to make the model's own variance honest (95% inside χ²₂ 5.991)about 2,000 (1,963 air)calib.json q95_scale · D-62measured (sim)

That last row is why the network's own confidence is switched off today: its variance would need to be multiplied by about 2,000 to be honest, so it carries no usable signal (D-62).

4.2 Predictor Adapter (per-drone tuning while GPS is good)

Plain: during the first minutes, while GPS is still trusted, the last layer of the network is nudged so its guesses match the filter's velocity on this particular drone. Standard: recursive least squares with a forgetting factor on θ = [W|b] (3 x 65).

φ = [h; 1]                     h = 64-wide hidden vector
k = P_a·φ / (λ + φᵀ·P_a·φ)     adapter gain (not the Kalman gain)   (adapter.rs:112)
θ ← θ + (target − θ·φ)·kᵀ      target = filter air velocity, heading frame
P_a ← (P_a − k·(P_a·φ)ᵀ) / λ                                         (adapter.rs:110-115)
if ‖θ − θ₀‖_F > max_delta: pull back onto the limit                   (adapter.rs:116-120)
NameValueWhere · set byTag
forgetting λ0.999adapter.rs:25 · D-53configured
prior_var0.01adapter.rs:26 · D-53configured
max_delta2.0 (Frobenius)adapter.rs:27 · D-53configured
window300 steps = 30 sadapter.rs:28 · D-53configured
converge_rel0.02 (freeze when error falls under 2% per 30 s)adapter.rs:29 · D-53configured
min_steps, max_steps300, 1,800 (180 s cap)adapter.rs:30-31 · D-53, D-24configured

The adapted layer is used only while its error over the last 30 s is lower than the base layer's (adapter.rs:81-85). The adapter steps only while GPS is TRUSTED; its target is the air velocity v − w (D-60, D-62).

5. Navigator, and how a weight is computed today

The complete product: Position Estimator runs all the time, and every Velocity Predictor guess nudges it. How hard each guess nudges is the weight.

Standard term: Velocity Predictor velocity fused as a measurement in the same ESKF. Run type full, harness name PATHFINDER_FULL. Navigator on every stride whether GPS is trusted or not (navigator.rs:276-286, D-60).

5.1 The measurement

z = R_yaw · v̂_heading                 network output rotated to NED   (learned.rs:250-255)
h(x) = v − [w_n, w_e, 0]              air velocity, because the network learned air velocity (D-62)
H = [ I on v ,  −I on w ]             (learned.rs:296-301)
y = z − h(x)

R = (s · Σ_model + f · I) · c         (learned.rs:305)
c = max(2·τ / Δt, 1)                  correlation inflation          (navigator.rs:299)
SymbolConfig nameValueWhere · set byTag
s variance scalelearned_var_scale0 (model's own variance ignored)config.rs:48 · D-62configured from a measured (sim) finding
f variance floorlearned_var_floor22.9 (m/s)² = 4.8² (was 1.0 in D-60)config.rs:47 · D-62measured (sim)
τ correlation timelearned_corr_time_s14.7 sconfig.rs:49 · D-62measured (sim)
Δt stridelearned_stride_s0.1 sconfig.rs:50 · D-53configured
NIS gatelearned_gate_nis11.34 (χ²₃ at 99%)config.rs:51, applied learned.rs:328-335 · D-62configured
air-relativelearned_air_relativetrueconfig.rs:52 · D-62configured

5.2 The arithmetic, step by step

  1. c = 2 × 14.7 / 0.1 = 294. Errors 0.1 s apart are almost the same error (they stay correlated for about 15 s), so 294 consecutive samples are treated as carrying the information of one independent sample. D-62 writes "295x"; the code gives 294 estimate.
  2. R = (0 + 22.9) × 294 = 6,733 (m/s)² per axis, one-sigma about 82 m/s, the same for every sample estimate.
  3. The gain per sample, per axis, is roughly K ≈ P_air / (P_air + 6,733), where P_air is the filter's variance of its own air velocity. With P_air = 0.25 (m/s)² that is K ≈ 0.00004; with 4 (m/s)² it is 0.0006 estimate, illustrative P_air values, not logged ones.
  4. Summed over 29.4 s (= 2τ) of samples, that is about the pull of one 4.8 m/s-accurate velocity reading. D-62 describes it as "one sample every 15 s"; by the code's formula it is one per 29.4 s estimate.
  5. The gate rejects a sample only when NIS > 11.34. With S ≈ R = 6,733 per axis, an innovation would need to be around √(11.34 × 6,733) ≈ 276 m/s to be rejected, so the gate does not fire in normal flight estimate.

5.3 What "fixed weight" means, exactly

6. GPS Integrity Monitor

Decides, on every GPS fix, whether GPS is honest. If the fix is far from where Position Estimator says the drone is, or jumps too fast, or its position and velocity disagree, GPS is cut off and Pathfinder takes over. It lets GPS back in only after 10 s of consistent fixes.

Standard term: innovation-based integrity monitor (fault detection on the GPS innovation, a Mahalanobis distance test) driving a three-state machine TRUSTED / SUSPECT / REJECTED (integrity.rs:69-218, D-21).

d = √( Δpᵀ · (P_pp + h_acc²·I)⁻¹ · Δp )     "divergence" in code; horizontal, before the update
                                             (measurements.rs:69-76)
rate = (d − d_prev) / Δt                     (integrity.rs:130-133)
posvel = EMA of |Δp_gps/Δt − v_gps|, α = min(Δt/2.0, 1)   (navigator.rs:190-201)
r95 = √(5.991 · λ_max(P_ne))                 95% horizontal radius   (navigator.rs:11, 17-20)

Thresholds in flight come from models/integrity.json, which the harness passes as --config (tests/harness/runner.py:38, 64-65). The code defaults are the plan's pre-fit values and apply only when no config is passed.

NameIn flightCode defaultWhere · set byTag
suspect_divergence12.223.0integrity.json:4, integrity.rs:26 · D-55measured (sim)
reject_divergence24.456.0integrity.json:3, integrity.rs:27 · D-55measured (sim)
reject_rate_per_s57.4 /s4.0integrity.json:5, integrity.rs:28 · D-55measured (sim)
posvel_mismatch_mps0.7 m/s0.7integrity.json:6, integrity.rs:29 · D-55 (fitted 0.44, kept at default)measured (sim)
suspect_timeout_us2 sintegrity.rs:30 · plan defaultconfigured
dropout_timeout_us1 sintegrity.rs:31 · plan defaultconfigured
min_sats, max_h_acc_m, fix6, 5.0 m, 3Dintegrity.rs:32-33, 113-118 · plan defaultconfigured
retrust_window_us10 sintegrity.rs:34 · plan defaultconfigured
reanchor_r95_m200 mintegrity.rs:35 · plan defaultconfigured
spoof_clear_fraction0.5integrity.rs:36 · D-58configured
posvel_tau_s2.0 sconfig.rs:46 · plan defaultconfigured

Fit: 22 logs, 0.52 h of healthy SITL; rule suspect = max(healthy ceiling × 1.25, default), reject = 2 × suspect; 0 false alarms per hour on the fit set (D-55). 0.52 h cannot show the 0.1/h target (needs about 30 alarm-free hours), and one live clean flight still left TRUSTED once at 34.9 s with no cause found (D-55).

The guard's d is the square root of a 2-DOF NIS. Thresholds of 12 and 24 are far above the χ²₂ 95% point (√5.991 = 2.45): they were set from SITL noise, not from a probability.

7. Hand-off to the autopilot

Pathfinder's answer is sent to ArduPilot, which keeps flying the mission with it.

ModeWhat is sentConstantsSet by
--output odometry (default)MAVLink ODOMETRY, body-FRD velocity, pose covariance; EKF3 switches to source set 2 (external nav)z variance 1 m², angle 0.01 rad² configured; set 2 acked 0.57 s after loss measured (sim)D-52, D-55
--output gps-inputMAVLink GPS_INPUT as a second GPS receiver at 10 Hz; pathfinderd writes GPS_PRIMARY 1 when it stops trusting GPShoriz_accuracy = r95 / 2.4477 (= √5.991, so one-sigma); vert 1 m, speed 1 m/s, 6 sats placeholder configured; switch 0.5 s after loss measured (sim)D-65, R-3

8. ArduPilot alone

The drone's own autopilot with no Pathfinder: the baseline to beat. ArduPilot's EKF3 left to continue without GPS.

Run type b1, harness name B1_EKF3_FAILSAFES_OFF. On heldout-jam-1000: 865 / 1,233 / 2,365 m at 1 / 2 / 5 min measured (sim), n = 1 (findings page).

9. Every constant, one table

Sorted by what it changes. "Weight input" marks the numbers that feed K through R or Q.

ConstantValueUnitKindfile:lineD-entryTag
gravity9.80665m/s²physicseskf.rs:12standardconfigured
drag k (quad)0.25411/sphysicsdrag.rs:19D-58measured (sim)
drag k_quad (quad)0.03411/mphysicsdrag.rs:20D-58measured (sim)
accel_noise0.35m/s/√sweight input (Q)eskf.rs:32none (plan)configured
gyro_noise0.015rad/√sweight input (Q)eskf.rs:33none (plan)configured
accel_bias_walk0.003m/s²/√sweight input (Q)eskf.rs:34none (plan)configured
gyro_bias_walk0.001rad/s/√sweight input (Q)eskf.rs:35none (plan)configured
wind_walk0.05m/s/√sweight input (Q)eskf.rs:36D-58, D-63measured (sim)
wind_walk_denied0.05m/s/√sweight input (Q)eskf.rs:37D-63measured (sim)
drag sigma_mss0.5m/s²weight input (R)drag.rs:21noneconfigured
baro_sigma_m1.0mweight input (R)config.rs:42none (plan)configured
mag_sigma_rad0.08radweight input (R)config.rs:41none (plan)configured
gps_vel_sigma_mps0.3m/sweight input (R)config.rs:43none (plan)configured
learned_var_floor22.9(m/s)²weight input (R)config.rs:47D-62 (D-60 had 1.0)measured (sim)
learned_var_scale0–weight input (R)config.rs:48D-62configured
learned_corr_time_s14.7sweight input (R)config.rs:49D-62measured (sim)
learned_stride_s0.1srateconfig.rs:50D-53configured
learned_gate_nis11.34χ²₃gateconfig.rs:51D-62configured
drag_period_s0.1srateconfig.rs:44D-58configured
max_imu_dt_s0.05sintegration stepconfig.rs:45D-58configured
χ²₂ 95%5.991–r95 radiusnavigator.rs:11standardconfigured
guard thresholdssee section 6
initial sigmassee section 3.3
adapter constantssee section 4.2

Count: of the 15 weight inputs above, 4 are measured (sim) and 11 are typed-in starting values that no D-entry has tuned estimate, by this table. Those 11 are where "standardize the weights" has real work to do.

10. Standard naming and units (use from now on)

10.1 System names

SayNever sayRun type · harness
Position Estimator"the filter", "B2" in prose for ownersb2 · B2_FILTER_DRAG
Velocity Predictor"the model", "ML", "the head" without the namemodels/velocity-long.onnx · learned.rs
Navigator"full", "Pathfinder" alonefull · PATHFINDER_FULL
ArduPilot alone"stock", "EKF3" in prose for ownersb1 · B1_EKF3_FAILSAFES_OFF
GPS Integrity Monitor"integrity", "the checker"integrity.rs · GpsIntegrity
hand-off"output", "feed" alone--output odometry | gps-input

10.2 Filter vocabulary

ConceptSymbolName in docsCode todayUnit
what the filter believesxstateEskf.{p,v,q,bg,ba,wind}per state
how unsure it isPcovariancecovunit²
uncertainty added per secondQ, σprocess noise (density)NoiseConfigunit/√s
how unsure a sensor isR, σmeasurement noiseMeas.r, *_sigma_*sensor unit (σ), unit² (R)
sensor minus predictionyinnovationMeas.ysensor unit
the fusion weightKKalman gaink in applystate unit / sensor unit
surprise of one sampleNISnormalised innovation squarednis, learned_gate_nisχ², with its DOF
GPS surprise distancedGPS Mahalanobis distancedivergenceσ (dimensionless)
95% error radiusr95r95r95_mm
correlated-error factorccorrelation inflationinflation–

10.3 Rules

  1. SI units, unit in the name. _m, _mps, _mss, _rad, _rads, _s, _us (integer microseconds for timestamps), _hz. A variance says so: _var with unit² in the doc comment.
  2. One-sigma by default. A number called sigma is one standard deviation. A 95% number is called r95 or carries 95 in its name.
  3. Noise densities are written per √s and enter Q as σ²·dt. Random walks (bias, wind) use the suffix _walk.
  4. Frames are named: NED (world, north-east-down), body FRD (forward-right-down), heading (body with roll and pitch removed). Vectors carry the frame: vel_ned, accel_body, mean_heading.
  5. "Weight" without a qualifier is banned in docs. Write Kalman gain, network parameters, or adapter layer (section 1).
  6. Every new constant lands with a tag (measured (sim) / estimate / configured) in its doc comment and a D-entry, and this page's table gets a row.
  7. A gate names its distribution and DOF: "NIS gate χ²₃ 99% = 11.34", never a bare "gate 11".

Code renames are not part of this page (read-only on code). Two names to change when the files are next touched: divergence → gps_mahalanobis (it is a distance, not a rate), and learned_var_floor → learned_var_base (with scale 0 it is the whole R, not a floor).

11. Glossary, A-Z

Every term, acronym and code name used in docs/ (swept 11 Oct 2026 across the .md and .html files). Terms marked PROPOSED are candidates from section 0, not yet chosen.

AC, acceptance test
A locked pass/fail test the owner approved. AC-1 "Mission continues", AC-2 "Less drift" (Navigator beats B2), AC-3 "Honest radius", AC-4 "Spoofing rejected", AC-5 "GPS return", AC-6 "Vehicle profile", AC-7 "In-flight calibration helps", AC-8 cross-platform build on four targets, AC-9 "Deterministic".
Predictor Adapter
The per-drone re-fit of the network's last layer by RLS while GPS is trusted (D-37, D-53). Proposed: in-flight calibration PROPOSED.
AHRS
Attitude and heading reference system: the autopilot's own roll, pitch and yaw estimate, sent as MAVLink ATTITUDE. Velocity Predictor's input attitude (D-57).
Air velocity
Ground velocity minus wind. What Velocity Predictor predicts (D-62).
ArduPilot, ArduCopter
The open-source autopilot Pathfinder targets; version Copter-4.6.3 in SITL.
ArduPilot alone
Run type b1: EKF3 continuing without GPS, failsafes off. Proposed: ArduPilot baseline PROPOSED.
AUTO, LAND, RTL, LOITER, GUIDED
ArduCopter flight modes: fly the mission, land, return to launch, hold position, follow commands. "Stayed AUTO" means no failsafe interrupted the mission.
B0
Baseline run type b0_raw_imu: raw IMU integration after loss with no corrections.
B1
See ArduPilot alone (B1_EKF3_FAILSAFES_OFF).
B2
See Position Estimator (B2_FILTER_DRAG).
Barometer (baro)
Air-pressure altimeter; gives height, σ 1.0 m in the filter.
Bias
A slowly changing offset in a sensor reading (gyro bias, accelerometer bias), estimated as a state.
BIN log, DataFlash
ArduPilot's onboard binary log. Message names used here: IMU, BARO, MAG, GPS, GPA, SIM, SIM2, POS, MODE, PARM, ERR, CMD, ATT, RCOU, XKF1, ORGN.
Canonical log
A flight converted to the repo's parquet tables (imu, gps, truth, ekf, events, att, rcou); the input to replay, training and scoring.
CEP
Circular error probable, the 50% radius. Not used here; r95 is the 95% radius.
χ² (chi-square)
The distribution of NIS for an honest filter; its percentiles set gates. χ²₂ 95% = 5.991, χ²₃ 99% = 11.34.
CNN, TCN
Convolutional network; temporal convolutional network, the causal 1-D CNN that Velocity Predictor uses (D-27, D-53).
COMMAND_ACK, HEARTBEAT, PARAM_VALUE, PARAM_SET, PARAM_REQUEST_READ
MAVLink control messages: command acknowledgement, keep-alive, parameter read and write.
Compass (mag)
Magnetometer; gives heading after tilt compensation and declination, σ 0.08 rad, fused at 10 Hz (D-61).
Correlation time (τ)
How long an error persists. Velocity Predictor's: 14.7 s (D-62).
Covariance (P)
The filter's estimate of its own error. Proposed: estimate uncertainty PROPOSED.
Coverage
Share of samples whose true error was inside r95. Honest is about 95%; AC-3 checks it.
D-entry
A numbered decision in docs/01-decisions.md, with what was asked, chosen and measured.
Dead reckoning
Navigating from known speed, heading and time with no position fix.
Declination
Angle between magnetic and true north; from COMPASS_DEC (D-58).
Divergence
Code name for the GPS Mahalanobis distance. Proposed: GPS surprise distance PROPOSED.
DNAV-n
Task ids of this project: DNAV-1 "GPS-denied navigation", DNAV-4 "Team brief", DNAV-6 "Pitch deck", DNAV-8 "Production phases and future upgrades".
DOF
Degrees of freedom: the number of components in a measurement, which picks the χ² row.
Domain randomisation
Training on simulated flights with randomised drone, wind and sensor settings so the network does not overfit one simulator setup (D-36).
Drag model
Body-axis law −k·u − k_quad·u|u| fused as a measurement of airspeed (D-58). Proposed: drag aiding PROPOSED.
Drift
Growth of position error after GPS loss. Proposed: error at t+N s PROPOSED.
EKF, EKF3
Extended Kalman filter; EKF3 is ArduPilot's navigation filter, run as several cores ("lanes").
Error state
The small correction the ESKF estimates on top of its believed (nominal) state.
ESC, RPM
Electronic speed controller of each motor; its telemetry can report motor RPM (not a model input yet, D-57).
ESKF
Error-state Kalman filter; the engine of Position Estimator (D-38).
EUDIS
EUDIS Defence Hackathon 2026, Cyprus Edition, 15-17 Oct 2026, Nicosia: the event this work is built for.
External nav (ExtNav), source set
EKF3's input for an outside position source; source set 2 is switched to when GPS is lost in hand-off Mode A.
Failsafe
An autopilot reaction to a fault (e.g. "EKF variance" LAND). B1 runs with failsafes off so it keeps flying.
FDE
Fault detection and exclusion: spotting a bad sensor and cutting it out. What the GPS Integrity Monitor does.
FRAME_CLASS
ArduCopter parameter for quad, hexa or octa; read for the vehicle profile (D-64).
FRD, NED
Frames: body forward-right-down; world north-east-down.
GCS
Ground control station.
GNSS, GPS
Satellite positioning in general; GPS is the US system and the word used throughout.
GPS Integrity Monitor
TRUSTED / SUSPECT / REJECTED state machine on every GPS fix (integrity.rs). Keep, or GPS integrity monitor PROPOSED.
GPS_INPUT, GPS2, GPS_PRIMARY, GPS_TYPE 14
Hand-off Mode B: Pathfinder as a second GPS receiver, and the parameter that tells ArduPilot which receiver to use (D-65).
GPS_RAW_INT
MAVLink message with the autopilot's raw GPS fix; Pathfinder's GPS source.
Hand-off
How Pathfinder's estimate reaches the autopilot: Mode A ODOMETRY, Mode B GPS_INPUT PROPOSED names.
Heading frame
Body frame with roll and pitch removed, yaw kept as the world heading; the network's frame.
Held-out flight
A SITL flight never used for training or tuning (seeds 1000-1999, D-46), e.g. heldout-jam-1000.
HIGHRES_IMU, SCALED_IMU, RAW_IMU
MAVLink IMU messages; Pathfinder reads HIGHRES_IMU at 200 Hz.
IMU
Inertial measurement unit: gyroscope plus accelerometer.
Innovation (y)
Measurement minus prediction. Proposed: sensor surprise PROPOSED.
INS
Inertial navigation system: position from integrated IMU readings.
Integrity
Code name for the GPS Integrity Monitor.
Jamming
Drowning GPS signals so the receiver loses its fix (SIM_GPS1_JAM in SITL).
Joseph form
A numerically safe way of writing the covariance update (eskf.rs:194).
Kalman gain (K)
The share of a disagreement the filter accepts. Proposed: trust share PROPOSED.
Lab, scenario lab
sim/lab.sh: flies one scenario with chosen run types and knobs (docs/LAB.md).
Last layer
The final linear layer of the network, [W|b] 3 x 65, the only part the Predictor Adapter changes.
Locked test
An AC committed red and protected; thresholds change only with the owner (D-39).
M0-M4
Original milestones in the MVP design spec, replaced by PLAN.md. M-1 is the IMU-rate measurement (D-51).
Mahalanobis distance
Distance in sigmas; √NIS.
MAVLink
The message protocol between autopilot, companion computer and ground station.
Measurement
Any reading compared against the filter's prediction.
Measurement noise (R)
How unreliable we declare a sensor. Proposed: sensor noise setting PROPOSED.
ML, RL
Machine learning; reinforcement learning (considered, not used: the Predictor Adapter is supervised).
MVP
Minimum viable product: the hackathon scope.
Night mode, night wave
Unattended overnight work in waves of agents; D-entries from those runs say "night wave n".
NIS, NIS gate
Normalised innovation squared yᵀS⁻¹y, and the rule that rejects readings above a χ² percentile. Proposed: surprise gate PROPOSED.
ODOMETRY
MAVLink message for an external position and velocity; hand-off Mode A (D-52, D-55).
ONNX, tract
The portable network file format; tract is the pure-Rust runtime that runs it onboard (D-53).
Optical flow, VIO, SLAM, TRN
Other aiding sources Pathfinder must accept later (R-2): camera ground motion, visual-inertial odometry, mapping and localisation, terrain-referenced navigation.
Parked
Work stopped on purpose with the reason written down, e.g. AC-01/03/04 parked in D-61.
Particle filter, UKF
Alternative fusion filters the estimator interface leaves room for (D-38).
Position Estimator
The ESKF with drag, compass and barometer; run type b2. Proposed: Pathfinder-Inertial PROPOSED.
Velocity Predictor
The velocity network models/velocity-long.onnx. Proposed: Pathfinder-Neural PROPOSED.
Navigator
Position Estimator plus the network's velocity; run type full, PATHFINDER_FULL. Proposed: Pathfinder-Hybrid PROPOSED.
pathfinderd, companion computer
The Pathfinder daemon, running on a computer next to the autopilot (Raspberry Pi 5 class).
Process noise (Q)
Doubt added per second for an imperfect motion model. Proposed: model slack PROPOSED.
PX4
The other major open-source autopilot; Mode B should work with it, untested (D-65).
r95
The 95% horizontal radius. Proposed: 95% radius PROPOSED.
R-n
Owner requirements: R-1 "Mission requirement, clarified by the owner", R-2 "Works with VIO, SLAM, optical flow and TRN", R-3 feed Pathfinder as a GPS replacement.
Random walk
A state assumed to drift without direction (biases, wind).
Re-anchor, re-trust
After GPS returns: re-trust = let GPS back in after 10 s of consistent fixes; re-anchor = snap position to GPS when r95 has grown past 200 m.
RLS
Recursive least squares; the Predictor Adapter's update rule.
RMS, RMSE, P50, P90, P95
Root mean square (error); the median and 90th/95th percentile of a set of errors.
RTS smoother
Rauch-Tung-Striebel smoother: corrects the past track once GPS returns (AC-5, D-64).
Run type
Which system a flight runs: b0, b1, b2, full, gps_ok, jam_no_pathfinder_stock.
Sensor profile, vehicle profile
Named sets of sensor noise for training (D-36); frame, motor count and IMU ids read from the autopilot (AC-6, D-64).
SERVO_OUTPUT_RAW, RCOU
Motor output commands (PWM), MAVLink and log names; Velocity Predictor's motor inputs.
SITL
Software in the loop: ArduPilot's simulator, the source of every "measured (sim)" number.
Speedup
SITL running faster than real time (e.g. 10x).
Spoofing
Fake GPS signals that move the reported position; the GPS Integrity Monitor rejects them (AC-4).
State
What the filter believes: 17 numbers (section 3.1).
Stride, window
Network timing: one guess every 0.1 s, from the last 1 s (50 samples).
TLIO
Tight learned inertial odometry, the published method Velocity Predictor follows.
Truth
SITL's true vehicle state, used only for scoring and labels, never onboard.
TRUSTED, SUSPECT, REJECTED
The GPS Integrity Monitor's three states.
UNVERIFIED
A fact in a plan not yet checked against source; later D-entries replace it with checked values.
USRL
The Systems Research Laboratory of the Cyprus Institute that runs the Orounda test site (full name as in 04-event-brief.md).
Variance head
The network's own error estimate (D-35); off today, about 2,000x overconfident (D-62).
Wind state, wind walk
The two wind states and their random-walk density, 0.05 m/s/√s (D-58, D-63).
WSL
Windows Subsystem for Linux, where SITL runs on the dev PC.
XKF1, ORGN, POS
DataFlash messages: EKF3 core position, its origin, and the autopilot's position; used to score B1.

12. Open points found while writing this