Skip to content

System architecture

Two repositories, one flight loop

The solution deliberately separates the reusable AI block from its test environment. They share network contracts, not source code or a filesystem.

flowchart TB
    subgraph SIM["Companion simulator"]
      direction LR
      C["4 Gazebo cameras"]
      D["PX4 X500"]
      F["Flight control"] --> D
    end
    subgraph EDGE["DroneVision on Arm"]
      direction LR
      S["Frame sync"] --> P["Perception"] --> A["Association"] --> T["3D triangulation"] --> E["State estimate"]
    end
    C -- "ZeroMQ · JPEG · :5555" --> S
    E -- "UDP · JSON · :5601" --> F

Repository boundaries

Responsibility dronevision-ai Hackathon_ARM_Simulator
Portable localization library ✓ —
Recorded corpus and benchmarks ✓ —
Gazebo world and fixed cameras — ✓
PX4 SITL and external-vision injection — ✓
Model training and synthetic data generation — ✓
Live frame/state services Protocol consumer Protocol provider

The central design rule is enforced by tests: nothing under dronevision/ imports Gazebo, ROS, PX4 or MAVLink. This keeps the install small enough for a bare Raspberry Pi or embedded Linux board.

The package is the diagram

The directories carry their processing order so code navigation matches the data flow:

dronevision/
├── l1_image_sync/      frame sets, freshness and camera selection
├── l2_perception/      colour, motion, hybrid and YOLO detectors
├── l3_association/     per-camera tracking and observation selection
├── l4_triangulation/   calibrated multi-view DLT and consensus
├── l5_estimation/      temporal smoothing and estimate freshness
├── io/                 replay, network sources and output schema
├── pipeline.py         the five-stage composition root
└── service.py          long-running process boundary

tests/test_boundary.py verifies the declared layers, rejects a hidden sixth stage and prevents an earlier layer from importing a later one.

Interfaces at the boundary

Frames in

The simulator publishes four JPEG images and synchronized metadata over ZeroMQ. The production representation uses JPEG quality 90: the recorded evidence shows approximately 6 Mbit/s instead of 442 Mbit/s raw, with no meaningful loss in localization accuracy on the corpus.

State out

DroneVision emits a transport-neutral JSON state estimate over UDP. The companion project converts it to VISION_POSITION_ESTIMATE for PX4 EKF2. Real hardware can replace either service without modifying the five AI layers.

Where estimation belongs

Layer 5 currently uses an exponential moving average. An EKF3D scaffold exists but is intentionally not wired into the live path: PX4 already fuses external position with inertial data in EKF2. The edge block owes the controller a smooth, outlier-free and freshness-aware position—not a duplicate flight estimator.