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

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)

System1 min2 min5 min
ArduPilot alone8661,2342,366
Pathfinder without MLno number after the fixes yet: both morning flights failed in the test harness
Pathfinder with ML (stayed in AUTO, no failsafe, both flights)3585

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)

System1 min2 min5 min
ArduPilot alone, all 121,4352,0533,821
ML speedometer alone (Velocity Predictor, no estimator), all 122985901,653
ArduPilot alone, trained frames (n = 8)1,4432,0593,852
ML speedometer alone, trained frames (n = 8)2825801,630
ArduPilot alone, unseen frame (n = 4)5748141,498
ML speedometer alone, unseen frame (n = 4)111204787

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 flights1 min2 min5 min
100
Already 3x better than ArduPilot alone
3947181,777
200
Best of the curve; the gain stops here
3336101,613
400
Same as 200
3396131,795
800
Same as 200
3266151,673
1,600
Same as 200, within noise
3667081,908
1,200 newer flights only (shipped v3)
A different mix, not more data; one run
3055471,541
ArduPilot alone, for comparison
No ML
1,4432,0593,852
Speedometer error against training flightsMedian position error in metres, log scale, 1, 2 and 5 minutes after GPS loss, ML speedometer alone, for 100, 200, 400, 800 and 1,600 training flights, 8 held-out quad and octa flights, measured in the simulator. ArduPilot alone at 2 minutes, 2,059 m, is drawn as a dotted reference.m2005001,0002,0001002004008001,600training flights (log scale)ArduPilot alone, 2 min1 min2 min5 min
Median error (m, log scale) after GPS loss on the 8 held-out quad and octa flights, measured (sim). Dotted: ArduPilot alone at 2 minutes.

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

Flight paths, whole viewTrue path and the two position estimates after GPS was lost, all on one scale. Pathfinder without ML has no flight after the fixes, so it is not drawn.startGPS lost (jam)1 kmnorth up, east right
Whole view. Flight 2 of the morning proof (8:47, 12 Oct), measured (sim).
Flight paths, zoomedSame flight zoomed to the true path: Pathfinder with ML stays close to it.startGPS lost (jam)1 kmnorth up, east right
Zoomed to the true path. Estimates are drawn from the moment GPS was lost.
Position error over time after GPS lossError in metres on a log scale against seconds after GPS loss for ArduPilot alone and Pathfinder with ML, flight heldout-jam-1000, measured in the simulator.1101001,00010,0000100200300400500600seconds after GPS was losterror, metres (log)
Error against time since GPS was lost, log scale (each gridline is ten times the one below). ArduPilot alone climbs past 1,000 m; Pathfinder with ML stays under 100 m for the first five minutes.

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.

Back to the index · Full method (appendix)