
My drone holds 0.9% drift through a GPS jamming bubble. The code I am proud of is the line that refuses to fly.
I did not expect the most important part of this project to be the part that gives up.
I had been staring at a replay of a synthetic flight for the better part of an afternoon. A drone crosses an 80-second mission over a 245.3 m path. GPS holds for the first 18 seconds, then dies as the aircraft crosses into a simulated electronic-warfare bubble. On the screen, three tracks fan out from that moment. One of them, a bright pink line, peels off toward the corner of the map and keeps going, confident and completely wrong, while a little readout next to it insists everything is fine.
That pink line is stock visual-inertial odometry, and watching it lie to me is what changed the whole shape of what I was building. I had assumed the hard problem in GPS-denied navigation was staying accurate. It is not. The hard problem is knowing, in the one moment it matters, that you are not.
In GPS-denied airspace, a confident-but-wrong position is more dangerous than an honest "I don't know."
This is the story of building Lodestar, our navigation-integrity engine, and of the week I spent solving the wrong problem before I understood the right one.
I chased accuracy for a week before I understood the real problem
I started where most people start, which is with the estimator. Electronic warfare has made GPS unreliable in exactly the places autonomous drones now matter: contested airspace, mining pits, tunnels, urban canyons. Jamming and spoofing in contested airspace are now widely reported, common enough that GPS-denied navigation has stopped being a research curiosity and become a hard requirement. The obvious fix is to bolt on visual-inertial odometry, fuse the camera with the inertial sensors, and hope the drift stays small.
So I built a real tightly-coupled VIO EKF and spent my first week making it accurate. Same filter, three honest configurations: a dead-reckoning IMU baseline with no vision at all, a stock VIO that fuses every visual feature it sees, and an integrity-aware version that is more careful about which features it believes. I ran them all against a ground truth the simulator generates independently of every estimator, so nothing could grade its own homework. The whole mission is seeded, byte-for-byte reproducible, which mattered more than I realized at the time.
The accuracy numbers were genuinely good. Through the jamming bubble, the integrity-aware estimator holds 0.92% drift, 2.26 m of final error over that 245.3 m path. Dead-reckoning, by comparison, blows out to 30.95% drift and 75.92 m of final error, which is the difference between landing on the pad and landing in the next county. I was pleased with myself for about a day.
Then I ran the convoy.
What a jamming bubble does to a drone that trusts its own eyes
I want to be honest about how ordinary the GPS handoff looks, because that is the part that works. When GPS drops at t=18 s, the filter reweights onto the visual-inertial source with no mode change, no alarm, no operator-visible seam. The estimate just stays continuous. If you were flying the mission you would not feel the floor disappear.

Here is what I underestimated. A drone running vision does not fail by slowly getting worse. It fails by locking onto the wrong thing and reporting a clean, confident position that is simply garbage. The estimator does not know it has been fooled, because the machinery that computes the position is the same machinery that would have to notice the position is wrong. I had built a system that was accurate right up until the moment it was catastrophically, silently mistaken, and I had no way to tell the two apart from the inside.
That is not a tuning problem. You cannot tune your way out of a system that is confident about being wrong. I needed something that sat outside the estimator entirely.
The convoy that taught a good estimator to lie
I built the convoy scenario specifically to break my own work, and it did. Between t=30 and t=43 a column of vehicles crosses a low-texture clearing, spraying spurious features that look, to a hungry VIO front-end, exactly like the stable landmarks it wants to track. This is the documented ORB-SLAM3 failure, the one where the algorithm tracks the truck and concludes the drone is standing still.
Stock VIO fell for it completely. In the same seeded run, it locks onto the moving vehicles and flies off, ending at 28.79% drift and 70.61 m of final error, with an ATE of 32.95 m that is actually worse than doing no vision at all. That was the pink line I had been watching. The ugly detail is that while it was failing, its internal confidence looked healthy. The estimator was sure of itself. It was sure of a position that was drifting toward the edge of the map.

The integrity-aware estimator survives the convoy for a plain reason: it refuses to believe features that belong to moving objects. In the frame above, semantic masking rejected the 10 convoy features and kept only the 2 static ones, so the estimator never locks onto the column. The trajectory holds. But the part I did not anticipate is what my integrity monitor did at the same moment. It did not paint the screen green and pretend the world was fine. It flipped to AMBER, because with the convoy's features masked out there genuinely were only a handful of static landmarks left to trust. It was accurate and it was nervous, at the same time, and it said so.
That was the first time the monitor told me something the estimator could not, and it is worth more than the accuracy on its own. It also forced the question I had been avoiding.
Why can't the estimator just certify itself?
I spent an embarrassing number of hours trying to answer that with the estimator's own numbers. My first integrity check simply read the filter's reported uncertainty, its position sigma, and gated on that. If the covariance looked tight, fly. It seemed reasonable.
The convoy demolished it. When stock VIO locked onto the truck, its reported sigma stayed small. The filter was confident precisely because it had found something consistent to track. The consistency was a lie, but the covariance could not know that, because covariance is a statement the estimator makes about itself. I was asking the witness to certify its own testimony.
Trust must not depend on the thing being trusted.
That sentence became the design. The Navigation Integrity Monitor lives outside the estimator on purpose, as separate code answering a different question. Not "what is my position," which the EKF answers, but "can this position be trusted right now," which the EKF is structurally unable to answer about itself. The monitor fuses three signals into a GREEN, AMBER, or RED state with hard thresholds: usable feature count (GREEN at 8 or more, RED below 1), position sigma (GREEN under 0.6 m, RED over 1.5 m), and vision NIS, the chi-square innovation consistency that catches exactly the case where the estimator is confident and wrong (GREEN under 7.0, RED over 30.0). No single number can be gamed by the estimator, because two of the three do not come from the estimator's own self-assessment at all.
This is the thing I now believe most strongly about safety-critical autonomy. A better VIO does not fix the confident-but-wrong failure, because "is this trustworthy" is a different question than "what is this," and you cannot answer the first with the machinery that produced the second. The industry keeps racing to make the estimator smarter. The durable architecture is not a smarter estimator. It is a monitor that is willing to overrule it.
The line of code that refuses to fly
The moment I actually understood my own product was the tunnel, and I remember it because it is the moment the system does the least.
Between t=52 and t=66 the mission enters a dark tunnel and the usable visual features collapse to essentially zero. There is nothing to see. No estimator, however well tuned, can manufacture a trustworthy position from a scene it cannot observe. This is not a failure to fix. It is a fact to respect. The stock VIO, still trying, coasts off into a position it has no right to claim.
Lodestar does something else. Features die, position uncertainty crosses the threshold, and after 0.5 seconds of sustained RED the monitor latches the failsafe and commands return-to-home at t=52.5 s. It does not bluff a position. It declares the estimate untrustworthy and hands control back to a safe behavior, and it does this deterministically, with no model in the loop deciding anything.

I want to be careful about the numbers here, because honesty is the entire pitch. Across this one seeded mission, the monitor flags the genuinely unobservable tunnel 100% of the time and false-alarms on the healthy GPS-denied leg about 0.1% of the time, holding GREEN over 56.3% of the denied flight. Those are this mission's results, a physics-faithful proof of the mechanism, not an open-world flight-test guarantee. The durable claim is the structure: trust computed outside the estimator, RED sustained to a latched return-to-home, honest abstention on a scene no one could navigate. The exact metres belong to this run. The architecture belongs to every run.
The most valuable line of code in an autonomy stack is the one that refuses to fly.
What I put in the report so nobody has to take my word
I did not want anyone to have to trust my screenshots, so the last thing I built is the receipt. One click exports a Flight Integrity Report, JSON plus printable HTML, with the scoreboard, the headline metrics, the abstention correctness, the failsafe time, the event timeline, and, the part I care about most, an explicit scope disclosure of what is stubbed versus deferred.
That disclosure is not a disclaimer I bury. It is a feature. The report states plainly that the visual front-end is a stand-in, that the LiDAR fusion is a simulated range constraint rather than a real LiDAR factor, that the MAVLink interface and the Jetson throughput are not exercised here, and that the 30-45 FPS on a Jetson Orin NX 16 GB is a target-hardware spec, not a measured result. The 16,000 EKF propagation updates in the report were measured on the demo machine. The FPS was not, and the report says so in those words.

That LiDAR run is worth dwelling on because it is where a lot of demos would cheat. Toggle the simulated LiDAR on and the tunnel recovers: the range constraint anchors the solution, integrity holds, and no failsafe fires, because the scene is no longer unobservable. It would be easy to show only that run and call the problem solved. But the report also carries the cost the solution page owns up to, roughly 250 to 400 g of payload and 8 to 12 W of power. LiDAR is a real engineering trade with a real SWaP-C bill, not a free win, and a buyer deserves to see the bill next to the benefit.
There is exactly one model anywhere near this system, an optional button that drafts the technical-review narrative from the structured report. It runs entirely outside the flight loop. It writes prose. It never touches a control decision. The gate that decides whether to fly is deterministic, seeded, and offline, and it would make the identical call with the narrative button torn out. I was firm about that boundary, because the day a language model gets a vote on whether a drone trusts its own position is a day I do not want to be responsible for.
What I keep coming back to
I set out to build a drone that stays accurate when GPS dies, and I did, on this mission, to under a percent of drift. What I did not expect was to come away convinced that accuracy was the easy half.
Accuracy is a race anyone can enter. Everyone in this field is making their estimator a little tighter, their features a little denser, their backend a little smarter, and all of that is good work. But none of it answers the question that actually kills a drone in a jamming bubble, which is not "how wrong am I" but "am I in a situation where I cannot know how wrong I am." That question has to be asked from outside the estimator, by something willing to say the unglamorous thing and give up the controls.
Accuracy is a race anyone can enter. A system that knows when it is blind is the product.
You can run the whole thing yourself and watch the pink line fly off, then watch the RED state fire, at veriprajna.com/demos/gps-denied-drone-autonomy. It is seeded, so you will see exactly what I saw.
And if you would rather see it than read me describe it, here is the whole thing running end to end.
The question I have not stopped turning over is this one. If the most valuable behavior in your autonomy stack is the refusal to act, how much of your engineering budget goes into the part that gives up, and how much into the part that never learned when to?


