Documentation Index
Fetch the complete documentation index at: https://docs.altnautica.com/llms.txt
Use this file to discover all available pages before exploring further.
Agent Services
The ADOS Drone Agent uses a multi-process architecture where each service runs as an independent systemd unit. A supervisor service manages the lifecycle. Services communicate through Unix domain sockets and share no memory. The agent is a hybrid system. The core long-running services (the supervisor, MAVLink router, cloud relay, and video pipeline) are native Rust binaries. Python handles the FastAPI web layer, AI and vision, the scripting engine, HAL detection, device drivers, and shared libraries. Several ground-station services (the radio data plane, uplink matrix, physical UI, and display) have native Rust implementations that are opt-in today and fall back to the packaged Python service otherwise. The supervisor never spawns these processes itself: it issuessystemctl against a fixed catalog, so systemd remains the process manager and owns the cgroup, restart, and journald wiring.
Why multi-process
A single in-process design is simpler, but it has real drawbacks for a drone:- A crashed video encoder takes down the MAVLink proxy. The flight controller loses its companion link.
- No per-service resource limits. A memory leak in one service starves the others.
- No per-service restart. Fixing a video pipeline issue requires restarting everything.
ados-video gets restarted by systemd in 3 seconds. The MAVLink proxy never notices.
Service tree
Distributed-receive roles add three more ground-station units when enabled:ados-batman (mesh carrier), ados-wfb-relay (relay role), and ados-wfb-receiver (receiver role).
The supervisor starts child services based on the active profile (air or ground-station) and the hardware detected. Services that depend on hardware not present are masked, not started.
Systemd unit structure
Each service has a unit file in/etc/systemd/system/. Native Rust services run a binary from /opt/ados/bin/; the FastAPI service and the Python-backed services run through the virtual environment in /opt/ados/venv/.
- PartOf: service stops when the supervisor stops
- Restart=on-failure: automatic restart on crash
- MemoryMax / CPUQuota: cgroup limits prevent any single service from starving the system
IPC: Unix domain sockets
Services communicate through two Unix domain sockets in/run/ados/:
MAVLink socket (/run/ados/mavlink.sock)
Binary protocol. Each frame is a 4-byte little-endian length prefix followed by raw MAVLink bytes.
State socket (/run/ados/state.sock)
JSON protocol at 10 Hz. Each frame is a newline-delimited JSON object:
Circuit breaker
The supervisor implements a circuit breaker pattern for each service. If a service crashes 5 times within 60 seconds, the breaker opens and the service is not restarted until a manual reset or a supervisor restart.- Logs a CRITICAL event
- Sends a notification to Mission Control
- Continues running all other services
Profile detection
On first boot (or whenagent.profile: auto is set), the profile_detect module runs a score-based hardware fingerprint:
| Signal | Ground score | Air score |
|---|---|---|
| I2C OLED at 0x3C or 0x3D | +3 | 0 |
| 4 GPIO buttons with pull-ups | +2 | 0 |
| RTL8812EU USB device | +1 | +1 |
| MAVLink serial device (ttyACM or UART) | 0 | +3 |
| GPS serial device | 0 | +2 |
| FC heartbeat received within 10 seconds | 0 | +3 |
| Known FC carrier board profile | 0 | +2 |
- Ground score
>= 4AND air score<= 2: ground-station profile - Air score
>= 4AND ground score<= 2: air profile - Ambiguous: unconfigured, show pick-profile UI
/etc/ados/profile.conf with the full fingerprint snapshot. Explicit agent.profile: in config.yaml always overrides detection.
Service lifecycle per profile
- Air profile
- Ground station profile
Always started:
ados-supervisor,ados-mavlink,ados-api,ados-cloud,ados-health
ados-video(if camera detected)ados-wfbin TX mode (if RTL8812EU detected)ados-peripherals(if USB sensors detected)
ados-scripting(if enabled in config)ados-ota,ados-discovery
- All ground-station services (hostapd, oled, buttons, kiosk, etc.)
FastAPI REST server
Theados-api service runs a FastAPI server on port 8080. It provides:
/api/statusand/api/status/fullfor agent state/api/video/*for video pipeline status and MediaMTX integration/api/v1/ground-station/*for ground-station-specific endpoints (WiFi, pairing, OLED, buttons, uplinks)/api/commandfor drone commands (arm, disarm, mode change)/api/configfor reading and writing agent configuration
X-ADOS-Key header with a key stored in /etc/ados/config.yaml. The key is generated at install time.
Runtime boundary
The REST server exposes a stable HTTP surface, but it does not own flight controller, video, WFB-ng, script, or parameter state directly. Route modules read those domains through the API runtime facade. In main agent mode, the facade wraps the active process runtime. In standalone API service mode, it reads live telemetry from state IPC and uses public runtime handles for optional subsystems. This boundary is internal to the agent. It does not change request paths, response bodies, or OpenAPI schemas.HAL board profiles
Each supported SBC has a YAML profile insrc/ados/hal/boards/. The profile defines:
Resource budget
Total memory usage for the ground-station profile on a Pi 4B with 4 GB RAM:| Service | Typical RAM |
|---|---|
| ados-supervisor | 15 MB |
| ados-api (FastAPI) | 40 MB |
| ados-wfb-rx | 20 MB |
| ados-mediamtx-gs | 30 MB |
| ados-hostapd | 5 MB |
| ados-oled | 10 MB |
| ados-buttons | 5 MB |
| ados-health | 10 MB |
| ados-kiosk (Chromium) | 280-520 MB |
| Total (no kiosk) | ~135 MB |
| Total (with kiosk 720p) | ~415 MB |
What is next
- Video Stack for the camera-to-browser pipeline
- Cloud Infrastructure for the three relay layers
- Project Structure for the codebase layout