Skip to main content

Node Profiles

Every box running the ADOS Drone Agent is a node, and every node has a profile. The profile is not a separate build: one install script, one upgrade path, one binary set. It decides which services start and which surfaces the agent serves. The profile is chosen at install time and persisted to /etc/ados/profile.conf.

The four profiles

The installer accepts ground-station and ground_station as the same value and normalizes to the underscore form; every other value passes through unchanged.

What each profile starts

The supervisor holds one service registry with a profile gate per entry. A service with no gate runs everywhere; a gated one runs only on the profiles it names.

Cross-profile

drone and ground_station

drone only

ground_station only

workstation and compute

ados-compute runs on the operator’s workstation (a GPU box, a Mac, or any spare box that also carries the UI) and on a headless compute worker. It never runs on a drone or a ground station.

The lean headless set

A node that boots headless runs only the Rust core. That set is exactly: ados-mavlink, ados-swarmbus, ados-logd, ados-video, ados-wfb, ados-control. Everything else, including the Python surface, the cloud service, health and every ground-station unit, is blocked by the headless gate.

How the profile is chosen

Resolution order, identical on both the Python and the Rust halves:
  1. agent.profile in /etc/ados/config.yaml, when it is an explicit value.
  2. /etc/ados/profile.conf, when the config field is auto, empty or absent. The installer writes this file, and ados profile set flips it.
  3. drone as the final fallback.
Pin the profile at install time:
There is no --board flag. The board auto-detects.

macOS defaults to workstation

On macOS the bootstrap runs the installer from source and passes --profile workstation unless you pinned a profile yourself. It refuses to run under sudo: a Mac node installs as per-user LaunchAgents under $HOME/.ados, not into /opt and /etc.

Inspect and change it

ados profile set accepts drone, ground_station and ground-station only. It writes both /etc/ados/profile.conf and agent.profile in /etc/ados/config.yaml, then restarts ados-wfb, ados-wfb-rx and ados-supervisor so the new gate takes effect. Pass --no-restart to skip that and restart yourself:
workstation and compute are install-time values. ados profile set will not set them; re-run the installer with --profile to move a node onto one of those two.

What a workstation node does not have

A macOS workstation node is rootless and Rust-only. The control surface serves the native routes (/api/status, /api/pairing/*) but not the proxied setup facade, because there is no Python upstream there: /api/v1/setup/status has nothing to answer it. The ados CLI reads the native routes on macOS for exactly that reason. So on a workstation node there is no setup wizard, no captive portal, no Wi-Fi AP, no radio and no flight controller link. What you get is the compute engine, the pairing surface and the status surface. A compute node is the same minus the UI: the engine, headless.

Profiles on the wire, and in Mission Control

The agent reports its profile on the wire in the hyphenated form. The Rust resolver passes workstation and compute through unchanged and maps ground_station to ground-station; anything unrecognised reports drone. Mission Control resolves three profiles for its node surfaces: drone, ground-station and workstation. A node reporting a profile outside that set, compute included, resolves to the Agent page alone: it appears in the fleet and you can administer it, but no profile-specific surfaces are registered for it. Ground-station role (direct, relay, receiver) is read from /etc/ados/mesh/role and defaults to direct. It is null on every other profile.

Profiles in an extension manifest

An extension declares which node kinds it installs on:
The validator accepts drone, ground-station and workstation, and requires at least one. See the manifest reference.