DNAV-1 "GPS-denied navigation" · method, one page · 12 Oct 2026 · numbers are measured (sim)
How Pathfinder works out where the drone is
Full version with every constant traced to its file and line: METHOD.html (the appendix). Words in italics are defined in Terms.
The problem
When the satellite signal is jammed or faked, the drone's autopilot (ArduPilot alone) keeps guessing its position from its own sensors and the guess runs away: a median 2,059 m off two minutes after the loss, on 8 held-out simulated flights.
The idea: a navigator and a speedometer
Think of a navigator who knows the starting point, the compass heading and the speed, and adds up the legs of the trip. The Position Estimator is that navigator. Its motion sensors tell it how the drone tilts and accelerates, so it can add up its movement 200 times a second. Small errors pile up, so after a few minutes it drifts.
The Velocity Predictor is the speedometer: a trained program that looks at the last second of sensor readings and motor commands and guesses how fast the drone moves through the air, and how sure it is. Its guesses are rough (a few metres per second off) but they do not pile up, because errors go up and down instead of adding.
The estimator takes the raw sensor inputs and the speedometer reading. It does not simply add them: it believes each one in proportion to how sure that input is.
The six parts, in the order a reading travels
1. GPS Fix
- What it is: the position message from the drone's satellite receiver (latitude, longitude, altitude, speed).
- Goes in: radio signals from satellites. Comes out: one position per update.
- Rule or ML: neither, it is raw data. It is what we replace when it cannot be believed.
2. GPS Integrity Monitor
- What it is: a block of checking code that looks at every GPS Fix.
- Goes in: the GPS Fix and what the drone's own sensors say it did. Comes out: Trusted, Suspect or Rejected, with a reason.
- Rule or ML: fixed rules today; a learned version is planned. File:
integrity.rs.
3. Velocity Predictor
- What it is: a small neural network saved as a file, trained on 400 simulated flights.
- Goes in: the last second of motion-sensor readings and motor commands. Comes out: air velocity in m/s and how sure it is, never a coordinate.
- Rule or ML: ML. Files:
models/velocity-long.onnx,learned.rs,onnx.rs.
4. Predictor Adapter
- What it is: a small fitting routine that nudges the Velocity Predictor's last layer to suit this drone.
- Goes in: predicted speed and GPS speed, only while GPS is Trusted. Comes out: a corrected predictor, frozen once GPS is lost.
- Rule or ML: a fixed formula (recursive least squares), no new training. File:
adapter.rs.
5. Position Estimator
- What it is: a filter built from the laws of motion that adds up the drone's movement 200 times a second.
- Goes in: motion sensors, compass, barometer, a drag formula, GPS while trusted, and (in "with ML" mode) the Velocity Predictor's speed. Comes out: position, velocity, heading and an uncertainty radius.
- Rule or ML: rules; the ML is only an optional input. Files:
eskf.rs,drag.rs.
6. Navigator
- What it is: the switch between the satellite position and Pathfinder's own.
- Goes in: the GPS Fix, its verdict and the Position Estimator's output. Comes out: a position handed to the autopilot as latitude, longitude and altitude.
- Rule or ML: rules. File:
navigator.rs.
What "weight" means here
A weight is how far one input is allowed to move the estimate. It is not typed in: each update works it out from two doubts, the estimator's own doubt about its position and the doubt we declare for that input. Today every speedometer reading is declared equally doubtful (a one-sigma of about 82 m/s after allowing for correlated errors, a fixed setting), whatever the flight is doing. Making that doubt change over time is the "shifting trust" experiment; it was measured, did worse, and is off by default (D-68). See the appendix.
What we measured (sim)
Two ways of running Pathfinder are compared with the autopilot: Pathfinder without ML (Position Estimator on its own sensors and drag rule) and Pathfinder with ML (the same, also given the Velocity Predictor's speed). Position error in metres after GPS was lost, measured (sim).
One flight, flown twice after the fixes (heldout-jam-1000, quadcopter, 12 Oct 2026, 8:30 and 8:47)
| System | 1 min | 2 min | 5 min |
|---|---|---|---|
| ArduPilot alone | 866 | 1,234 | 2,366 |
| Pathfinder without ML | no number after the fixes yet: both morning flights failed in the test harness | ||
| Pathfinder with ML (stayed in AUTO, no failsafe, both flights) | 3 | 5 | 85 |
Measured (sim), n = 2 flights of one scenario and one seed; the second flight gave the same numbers to within 1 m. Source: docs/night/2026-10-12-morning-proof.md. Pathfinder without ML failed in the harness twice (a half-written last line of the log, now fixed, and a connection reset that is not yet diagnosed). Its numbers from before the fixes (4 / 6 / 127 m) are no longer quoted here.
Why earlier numbers differed
Earlier runs of this same flight gave two different results for the same system, for example 4 m or 47 m after one minute. Two causes were found and fixed. First, a false GPS alarm: the receiver sometimes re-sent an old position with a new timestamp, so Pathfinder judged the GPS bad before the jam had even started and began guessing early (fixed, D-67 "Ignore a re-sent GPS fix"). Second, the drag fix: the model of air resistance used one curve for both directions of travel, and its error came back as a large jump at the first turn (fixed with a separate curve per direction, D-69 "Per-axis drag model" and D-71 "Quad drag uses the reproducible per-axis fit"). The "shifting trust" idea was measured and switched off, because it landed the drone on an autopilot failsafe in 2 of 2 flights (D-68).
Median over 12 held-out flights (n = 12: 8 on frames it trained on, 4 on an unseen hexacopter)
| System | 1 min | 2 min | 5 min |
|---|---|---|---|
| ArduPilot alone, all 12 | 1,435 | 2,053 | 3,821 |
| ML speedometer alone (Velocity Predictor, no estimator), all 12 | 298 | 590 | 1,653 |
| ArduPilot alone, trained frames (n = 8) | 1,443 | 2,059 | 3,852 |
| ML speedometer alone, trained frames (n = 8) | 282 | 580 | 1,630 |
| ArduPilot alone, unseen frame (n = 4) | 574 | 814 | 1,498 |
| ML speedometer alone, unseen frame (n = 4) | 111 | 204 | 787 |
Not measured: Pathfinder without ML and Pathfinder with ML over these 12 flights, so nothing is claimed for them beyond the one flight above. The all-12 medians are computed from the per-flight rows in measurements/2026-10-learned-v2-heldout.md; the 8 and 4 rows are copied from it. All numbers are from the simulator.
Does more training data help? Measured (sim)
More flights helped up to about 200 (2-minute error 718 m → 610 m) and changed nothing after that (610–708 m from 200 to 1,600 flights), so the next gains need better inputs or a better model, not more flights of the same kind.
| Training flights | 1 min | 2 min | 5 min |
|---|---|---|---|
| 100 Already 3x better than ArduPilot alone | 394 | 718 | 1,777 |
| 200 Best of the curve; the gain stops here | 333 | 610 | 1,613 |
| 400 Same as 200 | 339 | 613 | 1,795 |
| 800 Same as 200 | 326 | 615 | 1,673 |
| 1,600 Same as 200, within noise | 366 | 708 | 1,908 |
| 1,200 newer flights only (shipped v3) A different mix, not more data; one run | 305 | 547 | 1,541 |
| ArduPilot alone, for comparison No ML | 1,443 | 2,059 | 3,852 |
Median position error in metres, ML speedometer alone, GPS lost at 2 minutes into the flight, 8 held-out quad and octa flights, all from the simulator. Each point is one training run with one seed: the same held-out flight’s 2-minute error moves up to 4x between runs (flight 1011: 121 to 492 m), so the 610–708 m spread past 200 flights is noise, not a trend. “100 flights” trains on 67 (70/15/15 split). Source: measurements/2026-10-learning-curve.md.
The same flight, drawn (flight 2 of 2 after the fixes, measured (sim), n = 1)
The true path and where each system thought the drone was after GPS was lost at 120 s. The autopilot's guess runs off the map's scale; the Pathfinder with ML line stays near the true path. The second map is zoomed to the true path. Pathfinder without ML is not drawn: it has no flight after the fixes.
True pathArduPilot alonePathfinder with ML
Data: lab page lab-heldout-jam-1000-71d65f (flight of 8:47, 12 Oct), thinned to one sample per 5 s. The viewer pages are not in git.
What we do not claim
A speedometer alone cannot hold 1 m for 15 minutes. The target is far better than ArduPilot alone, stated with an honest error radius (95% of the time the drone is inside the radius we report). All numbers are from the simulator, not a real aircraft.