Skip to main content

Systemd Services

The agent runs as a collection of systemd services. Each service handles one responsibility: MAVLink, video, cloud, health, and so on. The supervisor service manages the lifecycle of all child services. This architecture gives you per-service restart, resource isolation via cgroups, and clean dependency ordering.

Service list

Core services (all profiles)

ServiceDescriptionTier
ados-supervisorParent service, starts and monitors childrenAll
ados-mavlinkFC serial connection and MAVLink proxy1+
ados-apiFastAPI REST server on port 80802+
ados-healthCPU, RAM, disk, temperature monitoring2+
ados-discoverymDNS advertisement (_ados._tcp.local.)2+
ados-videoCamera detection, encoding, MediaMTX3+
ados-wfbWFB-ng video transmitter3+
ados-cloudMQTT and Convex cloud relay3+
ados-scriptingPython script executor and text commands3+
ados-peripheralsUSB hot-plug, sensor manager3+
ados-otaGitHub release polling, upgrade, rollback3+

Ground station services (ground_station profile only)

ServiceDescription
ados-wfb-rxWFB-ng video receiver
ados-mediamtx-gsMediaMTX for ground-side video relay
ados-hostapdWiFi hotspot (access point)
ados-dnsmasq-gsDHCP and DNS for the hotspot
ados-setup-captiveCaptive portal DNS responder
ados-usb-gadgetUSB CDC-NCM/RNDIS gadget for laptop tether
ados-usb-gadget-setupOne-shot USB gadget configuration
ados-oledOLED display driver (SSD1306 I2C)
ados-buttonsGPIO button handler
ados-inputBluetooth and USB gamepad input manager
ados-kioskHDMI kiosk mode (Chromium + cage Wayland)
ados-picPriority Input Controller arbiter
ados-uplink-routerInternet uplink priority and data cap
ados-cloud-relayCloud relay bridge for ground station
ados-wifi-clientWiFi client connection manager
ados-modemCellular modem manager
ados-ethernetEthernet connection manager

Startup order

The supervisor starts first and brings up child services in dependency order:
ados-supervisor

  ├── ados-mavlink        (starts immediately)
  ├── ados-api            (starts immediately)
  ├── ados-health         (starts immediately)
  ├── ados-discovery      (starts immediately)

  ├── ados-video          (after camera detected)
  ├── ados-wfb            (after ados-video)
  ├── ados-cloud          (after ados-api)
  ├── ados-scripting      (after ados-api)
  ├── ados-peripherals    (after ados-api)
  └── ados-ota            (after ados-api)
Hardware-dependent services (video, wfb, modem) only start when the relevant hardware is detected.

Resource limits

Each service runs with cgroup resource limits to prevent any single service from consuming all system resources:
# Example from ados-video.service
[Service]
MemoryMax=512M
CPUQuota=80%
Typical memory allocation on a 2 GB board:
ServiceMemoryMaxTypical usage
ados-mavlink64M~20 MB
ados-api128M~40 MB
ados-video512M~100-200 MB
ados-cloud128M~30 MB
ados-health64M~15 MB
ados-scripting256M~30-100 MB
Total core~1.2 GB cap~250-400 MB actual
This leaves headroom for the OS, ffmpeg, MediaMTX, and any scripts you run.

Circuit breaker

The supervisor implements a circuit breaker: if a service fails 5 times within 60 seconds, the circuit breaker opens and stops restarting it. This prevents crash loops from consuming all system resources. The circuit breaker state is visible through the REST API:
curl http://localhost:8080/api/services \
  -H "X-ADOS-Key: $KEY"

Managing services

Check service status

# All services
sudo systemctl list-units "ados-*" --all

# Specific service
sudo systemctl status ados-video

Restart a service

sudo systemctl restart ados-video

View service logs

# Last 50 lines from a specific service
sudo journalctl -u ados-video -n 50

# Follow live
sudo journalctl -u ados-video -f

# All agent logs combined
sudo journalctl -u "ados-*" -f

# Since a specific time
sudo journalctl -u ados-mavlink --since "10 minutes ago"

Stop everything

sudo systemctl stop ados-supervisor
This stops the supervisor and all child services.

Start everything

sudo systemctl start ados-supervisor

Service dependencies

Ground station services have explicit dependency ordering:
ados-kiosk
  └── After=ados-mediamtx-gs.service
       └── After=ados-wfb-rx.service

ados-uplink-router
  └── After=ados-hostapd.service
       └── After=ados-dnsmasq-gs.service
This ensures the WiFi hotspot is up before the uplink router starts, and the video relay is ready before the kiosk opens the HUD page.

Automatic restart

All services are configured with automatic restart on failure:
[Service]
Restart=on-failure
RestartSec=3
The supervisor detects when a child service restarts and logs the event. Combined with the circuit breaker, this means transient failures self-heal while persistent failures are contained.

Viewing all service files

The systemd unit files are installed at:
/etc/systemd/system/ados-*.service
To see the contents of a specific service file:
cat /etc/systemd/system/ados-video.service
Do not edit the service files directly. They are overwritten on each upgrade. If you need to customize a service (e.g., add environment variables or change resource limits), use a systemd override:
sudo systemctl edit ados-video
This creates a drop-in override file that persists across upgrades.