A drone built for contested airspace has to keep its head when the satellites go dark and the link drops. So we asked the firmware directly — on a real ArduPilot autopilot flying in a cloud sandbox, with the GPS jammed mid-air — and asserted on the telemetry what it actually did. Three experiments, real numbers, and the honest line between what a flow sensor buys you and what it doesn't.
✓ GPS-jam safe-land · 6/6 verified ✓ optical-flow hold · 5/5 verified ⚠ absolute nav on flow · the honest limitElectronic warfare is the defining condition of modern contested airspace: GPS gets jammed or spoofed, command links get cut. A drone whose autonomy collapses the moment it loses GPS — that flies away on a diverging position estimate, or falls out of the sky — is worse than useless. The questions a test engineer has to answer are concrete and falsifiable:
This page answers all three on real firmware, with the telemetry to back each claim. It's the embedded counterpart of QualityMax's web testing pattern — discover → generate a scenario → assert on real signals → readable report — with MAVLink where HTTP usually sits.
No physical hardware. Real ArduPilot flight-control firmware runs in its built-in
headless SITL inside an E2B cloud micro-VM (no Gazebo, no GPU), exposing MAVLink on
UDP 14540. A standalone mavsdk_server bridges to the test, which drives the
firmware and reads telemetry. The whole loop runs inside the perimeter — for defence work,
the model that designs the test and the run itself never leave the boundary
(the sovereign loop).
Template qualitymax-mavlink · the same runner
that flies the nominal mission 5/5 and the geofence failsafe 7/7. GPS jamming is injected with the
firmware's own simulator knobs (SIM_GPS1_ENABLE), so the EKF's reaction is the real
firmware's, not a model's.
Hypothesis. A drone built for contested airspace should contain a lost GPS fix into a safe, bounded response — not diverge on a bad estimate.
Method. Arm, take off, fly a 40 m waypoint on GPS (the control leg), then disable the simulated GPS mid-air and watch the firmware on telemetry for 25 s: how far does it drift from the jam point, and what flight mode does it enter?
# inject the jam — the firmware's own simulator await drone.system.param.set_param_int("SIM_GPS1_ENABLE", 0) # ... 25 s later, from the sampled telemetry: max_drift = max(hypot(s.n - jam_n, s.e - jam_e) for s in post) # no-flyaway test failsafe = [m for m in modes_seen if "GUIDED" not in m] # left GUIDED for a failsafe?
Result. 6/6 assertions PASS in 77.9 s on real SITL:
[PASS] Reached takeoff altitude (~10 m) — got 9.1 m [PASS] Control (GPS on): flew to waypoint 40 m north — within 6.8 m [PASS] GPS jammed (SIM GPS disabled) — via SIM_GPS1_ENABLE [PASS] GPS jammed: no flyaway (drift bounded) — max drift 6.2 m over 25 s (bound 25 m) [PASS] GPS jammed: entered a known GPS-loss failsafe — modes: LAND, OFFBOARD OVERALL: PASS (6/6)
And the firmware's own account, from the SITL log — this is the EKF deciding, not the test:
EKF variance: position lost
EKF Failsafe: changed to Land Mode
SmartRTL deactivated: bad position
Interpretation. The autopilot detects the position estimate going bad and contains it into a controlled LAND in place — drifting only 6.2 m over 25 s. No flyaway. That's the correct, safe baseline behaviour, proven on the real failsafe path. Watch it — open the “EW: GPS jamming” tab; the distance-from-home line stays flat at 40 m through the descent.
Hypothesis. A downward optical-flow sensor + rangefinder gives the EKF a velocity source, so the firmware should keep a position estimate — and hold station — even with GPS jammed, instead of landing immediately.
Method. Boot SITL with optical flow + rangefinder and a second EKF source set; switch the EKF from GPS to optical flow with an RC aux switch while hovering, then jam GPS near home — the real discriminator: on a GPS source set the firmware would LAND at once.
# flow.parm — loaded at boot (reboot-required backends) SIM_FLOW_ENABLE 1 FLOW_TYPE 10 EK3_FLOW_USE 1 RNGFND1_TYPE 100 RNGFND1_MAX_CM 5000 RNGFND1_ORIENT 25 EK3_SRC2_VELXY 5 # source set 2 = optical-flow velocity + baro height RC6_OPTION 90 # RC aux: select EKF source set (1=GPS, 2=flow)
Result. 5/5 PASS in 80.9 s — and the headline number is striking:
[PASS] EKF accepted optical-flow source (still flying, not LAND) [PASS] Optical flow held station with sub-metre drift while GPS jammed — max drift 0.04 m over 8 samples on flow [PASS] Optical flow extended GPS-denied flight beyond the instant safe-LAND — held 9.0 s on flow, then ArduCopter's EKF failsafe still landed it OVERALL: PASS (5/5)
Interpretation. With flow, the drone holds its position to within 4 centimetres while GPS is jammed — a real, GPS-denied station-keep. But it's bounded: after ~9 s ArduCopter's EKF failsafe still trips and lands it. Flow buys time and precision over Experiment 1's immediate land — it does not make the aircraft GPS-independent. Watch it — the “EW: flow hold” tab; the drone sits dead-still inside the ring after the jam.
Hypothesis (the one we wanted). If flow holds position, maybe it can navigate — fly the full 40 m to an absolute target with GPS jammed. This is the literal "доведення дрона до цілі під РЕБ" pitch.
Method. Same flow rig, but after switching to flow and jamming GPS near home, command an
absolute goto_location 40 m north and see if it gets there.
Result. It does not. The aircraft drifts ~7 m, never tracks the absolute waypoint, and the EKF eventually lands it — 32.6 m short of the target.
[FAIL] Flew the full 40 m to the target with GPS jammed — arrived 32.6 m from target, 7 m from home, mode LAND
Why — and this is the important part. Optical flow is a velocity sensor with
no absolute fix. Source set 2 has EK3_SRC2_POSXY = 0 (none): the EKF can hold
and dead-reckon, but it doesn't know where it is in the world, so it can't fly to an
absolute coordinate. Bounded station-keeping is the ceiling of bare optical flow — by design.
“Automatically delivering the drone to its target through РЕБ” is real — but it is not bare optical flow. It needs optical navigation: matching the live camera to a known reference (terrain / scene / target image) to recover an absolute fix without GPS. That is a substantially larger system — sensors, a vision pipeline, a map — and it is exactly the kind of capability serious miltech vendors build.
What this exercise shows is the part a test platform owns: pinning down, on real firmware, precisely where the safe-land baseline ends, where flow’s station-keep ends, and where true optical navigation has to begin — each one a falsifiable assertion on telemetry, not a slide.
| Capability | What the firmware did | Verdict |
|---|---|---|
| GPS-jam safe-land no extra sensors |
Contained the lost fix into a LAND in place; drift 6.2 m / 25 s. No flyaway. | 6/6 ✓ |
| Optical-flow hold flow + rangefinder |
Held station to 0.04 m drift for 9 s with GPS jammed, then EKF failsafe landed it. | 5/5 ✓ |
| Absolute nav on flow flow only, no fix |
Could not track the absolute waypoint; landed 32.6 m short. Needs optical navigation. | honest limit |
All code is in the repo; each scenario travels as a single file and runs against the
qualitymax-mavlink E2B template.
e2b-mavlink/scenario_ew.pye2b-mavlink/scenario_ew_flow.py + flow.parmsovereign-demo/sovereign_drone_demo.py