Deep-dive · Electronic-warfare resilience

What does autonomous firmware do when GPS is jammed?

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 limit

Why this matters

Electronic 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.

The test rig

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).

test scenario (Python) ↕ MAVSDK 3.15 mavsdk_server ↕ MAVLink / UDP 14540 ArduPilot SITL E2B micro-VM

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.

● Experiment 1 · verified 6/6

GPS jamming → does it fail safe, or fly away?

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.

● Experiment 2 · verified 5/5

Optical flow → can it keep flying with no GPS?

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.

● Experiment 3 · the honest negative

Optical flow → can it fly to the target under jamming?

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.

The honest line

“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.

The three results, side by side

CapabilityWhat the firmware didVerdict
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

What this proves about the platform

Reproduce it

All code is in the repo; each scenario travels as a single file and runs against the qualitymax-mavlink E2B template.

Safe-land test
e2b-mavlink/scenario_ew.py
Flow hold test
e2b-mavlink/scenario_ew_flow.py + flow.parm
Sovereign loop
sovereign-demo/sovereign_drone_demo.py
Replays
top-down · 3D · over-time — “EW: GPS jamming” & “EW: flow hold” tabs