Skip to content

nav-trust-c2

Human-on-the-loop mission control for a small team of simulated drones: navigation trust per vehicle (GREEN, AMBER, RED, with a reason and a measured position error) and recommendations that wait for an operator's approval.

One minute, captioned: the replay demo from a trusted fleet to an approved, gated command. Map tiles are left out of this recording. The three-minute demo shows the live map.

In 60 seconds

Problem. A drone that loses GNSS, or whose position has frozen, keeps flying on a position that is wrong. A person supervising several drones has to learn which one, how wrong, and what to do, and no vehicle may be commanded without that person's approval.

What it does. Two independent detectors watch each simulated vehicle (GNSS availability, and agreement with the vehicle's own sensors). The console shows per vehicle a trust state (GREEN, AMBER, RED), the reason, and a position error with its measured coverage. It recommends landing, re-tasking a lost vehicle's sector, and nothing else. Nothing executes without a recorded operator approval; one gate is the only path to a command, and a test enforces it.

Evidence, all in simulation (PX4 SITL and Gazebo, ground truth from the simulator).

  • GNSS loss was detected in 1.0 to 1.4 s in 12 runs; a frozen position in 3.0 to 4.5 s. No alert in 9 nominal runs.
  • The displayed bound, within 3 m, held in 100% of 4,040 reports on the data it was tuned on and in 99.72% of 5,308 reports on an independent set. The first version, taken from the estimator's own accuracy figure, held in 30.8%.
  • A frozen GPS position does not stall the vehicle, it flies away (5.3 km in one run). Only LAND ended the flight in a controlled stop, so that is what is recommended.
  • With one of three vehicles lost, the area covered was 100% when the operator approved the re-task and 87% when the operator denied it (3 runs each, scripted operator).
  • Held-out validation: 7 of 8 pre-declared expectations met. The one that was not is reported, not excluded: docs/validation/heldout-report.md.

What is not shown. Real hardware, real interference, or a usability result: two people did not act on the decision unaided, the console was then redesigned, and that has not been re-tested (findings). Targets in the documents are proposals.

Demo video (about 3 minutes): https://youtu.be/L7DrhOYMQ5A. A one-minute captioned version is on the project page.

How it was built, including the mistakes: docs/how-this-was-built.md.

How it works

flowchart TB
    V["Survey drones<br/>PX4 SITL and Gazebo"] -- "GNSS fix and estimator status" --> T["Trust engine, one per drone<br/>two separate detectors"]
    T -- "GREEN / AMBER / RED, reason, position bound" --> H["C2 backend"]
    H --> R["Recommender: land, or re-task a sector"]
    R --> C["Operator console"]
    C -- "approve or deny, name recorded" --> H
    H --> L[("Append-only audit log")]
    H --> G{"Policy gate:<br/>the only path to a command"}
    G -- "approved, once" --> X["Executor"]
    X -- "MAVSDK command" --> V
  1. Detect. Each drone's navigation is checked twice a second by two separate detectors (ADR 0001): is GNSS available, and does the GNSS position agree with the drone's own sensors.
  2. Explain. The console shows a trust state, the reason in plain words and how far off the position may be.
  3. Recommend, then wait. The backend proposes one action and lists exactly what approving will do. A person approves or denies; the decision and the name go to an append-only log.
  4. Execute through one gate. Only an approved recommendation, and only once, reaches a vehicle. PX4's own failsafes stay outside the C2 and act on their own.

The decision loop in the replay demo: uav2 is flagged, the operator approves, uav2 lands and uav1 takes over its sector

Replay demo at double speed; map tiles left out of this recording.

Source, tests and the results tables are in the repository. The measured results are regenerated and checked by CI: development set, held-out set, fleet runs.