First-party plugins for the ADOS Drone Agent and ADOS Mission Control.
Mission Control | Drone Agent | Android GCS | Extensions | MCP | Rust crates | Docs | Website | Discord
Developer Docs · Rust SDK · Issues
ADOS is an open-source platform for software-defined drones, and extensions are how it grows. This repo holds the first-party extensions: subject following, GPS-denied vision navigation, gimbal and camera-pod drivers, and World Engine (in beta) for 3D world models and perception offload. They are built with the same SDKs and plugin system that are open to everyone, so anything here is something you can build too.
An extension adds a capability to ADOS without forking it: a new panel in Mission Control, a driver for a sensor or gimbal on the drone, or a behavior that spans both. Each one ships as a single signed .adosplug archive that an operator installs from the Plugins tab or the agent CLI, with the permissions it needs shown up front. One manifest describes both halves: the agent half runs as a supervised subprocess on the ADOS Drone Agent (Python or Rust), and the GCS half renders as React panels in a sandboxed iframe in ADOS Mission Control.
Run an extension (operator). From Mission Control, open a drone, switch to the Plugins tab, pick an extension, and approve the install. The agent downloads the signed archive, verifies the signature, and stages the plugin under its supervisor. No SSH, no rebuild.
Build an extension (developer). Scaffold a plugin with create-ados-plugin, write the GCS half in TypeScript and the agent half in Python or Rust against the SDKs, then pack and sign it into a .adosplug. The same plugin system powers both first-party and community extensions.
|
|
|
|
| Extension | Name | Kind | What it adds |
|---|---|---|---|
| follow-me | ADOS Follow-Me | Agent + GCS | Operator-designated subject follow at a fixed standoff via guided setpoints, with a lock-state safety gate |
| mavlink-gimbal-v2 | ADOS MAVLink Gimbal v2 Controller | Agent + GCS | MAVLink Gimbal v2 manager control, region-of-interest lock, and an aim-at-target visual servo with a lock-state safety gate |
| siyi-pod | ADOS SIYI Optical Pod | Agent + GCS | Native SIYI optical-pod driver with per-model capability negotiation: gimbal, zoom, thermal, and a laser rangefinder with subject geolocation |
| thermal-camera-flir-lepton-usb | ADOS Thermal Camera FLIR Lepton USB UVC | Agent + GCS | FLIR Lepton 3.5 radiometric driver, palettes and spot metering with a GCS overlay. The capture path needs a UVC backend that this repository does not include, so it reports an explicit unavailable state instead of producing readings |
| vision-nav | ADOS Vision Navigation | Agent (Rust) + GCS | GPS-denied navigation from downward optical flow, with a camera-IMU calibration check and an advisory pre-arm status |
| world-engine | ADOS World Engine | Agent (Rust) + GCS | Beta. 3D world model from drone flights, reconstructed on a LAN compute node from keyframes posed by the flight controller, visual-inertial odometry or LiDAR SLAM, plus perception offload for drones without an NPU |
These extensions are under active development and grow with every release; build on them, or start your own, with the SDKs below.
flowchart LR
subgraph air["On the drone"]
FC["Flight controller<br/>ArduPilot · PX4 · Betaflight · iNav"]
DA["ADOS Drone Agent"]
end
subgraph ground["On the ground"]
GA["ADOS Ground Agent"]
MC["ADOS Mission Control<br/>browser · desktop"]
AG["ADOS Android GCS"]
MCP["ADOS MCP<br/>AI clients"]
end
EXT["ADOS Extensions"]
FC <-- MAVLink --> DA
DA <-- "long-range radio link" --> GA
MC <-- "LAN or cloud relay" --> DA
MC <-- LAN --> GA
AG <-- "LAN or cloud" --> DA
MCP <-- "LAN or cloud" --> DA
EXT -. "agent plugins" .-> DA
EXT -. "GCS panels" .-> MC
ADOS Ground Agent is the Drone Agent running its ground-station profile.
| Repo | Runs on | What it does | Link |
|---|---|---|---|
| ADOS Mission Control | Browser, desktop (Electron) | Ground control station: FC setup, mission planning, flight, 3D simulation, fleet | ADOSMissionControl |
| ADOS Drone Agent | Companion computer on the drone, or a ground node | Onboard agent: MAVLink routing, HD video, long-range radio link, plugins, remote control | ADOSDroneAgent |
| ADOS Android GCS | Android phones and tablets | Native ground control app for agents on the LAN, direct flight controllers and the cloud | ADOSAndroidGCS |
| ADOS Extensions | Drone Agent and Mission Control | First-party signed plugins, each with an agent half and a GCS half | ADOSExtensions |
| ADOS MCP | Your machine | Model Context Protocol server that lets AI clients operate ADOS drones under scopes and a safety gate | ADOS-MCP |
| Documentation | docs.altnautica.com | Public docs for every ADOS product | Documentation |
Reusable libraries from the ADOS Drone Agent, published on crates.io. Versioning and licences: crates index.
Platform (versioned with the ADOS Drone Agent)
| Crate | What it does | Docs |
|---|---|---|
ados-protocol |
Wire contracts of the ADOS Drone Agent: IPC framing, plugin RPC envelope, capability tokens and the vision frame bus. | docs.rs |
ados-sdk |
Write Rust plugins for the ADOS Drone Agent: IPC client, plugin context, driver traits and lifecycle runner. | docs.rs |
ados-vision |
Single-object visual tracker: Kalman motion model, appearance re-identification and YOLOv8 head decoding. | docs.rs |
ados-gpio |
Drive status buzzers and LEDs on Linux GPIO lines, with bounded software-PWM beep patterns. | docs.rs |
ados-hal-probe |
Find out what a board's hardware can really do by probing it, plus bundled board profiles. | docs.rs |
Standalone
| Crate | What it does | Docs |
|---|---|---|
ados-sensorhub |
Sensor hub wire protocol: COBS framing, CRC-16 and fixed-layout IMU, baro, mag and GNSS packets. no_std. | docs.rs |
ados-offload |
Choose where perception runs (onboard, offloaded or hybrid) and hold the vehicle when results go stale. | docs.rs |
ados-macpin |
Stable MAC addresses for Linux network adapters that randomize theirs every boot. | docs.rs |
ados-lora |
LoRa transmit governor with cited regional band plans, duty cycle, dwell time and airtime accounting. | docs.rs |
ados-crsf-codec |
no_std CRSF / ExpressLRS codec for RC channels, telemetry and parameter frames. | docs.rs |
ados-positioning |
Split mixed UBX, NMEA and RTCM3 GNSS streams, configure u-blox receivers and run an RTK base survey-in. | docs.rs |
ados-rtcm |
RTCM3 framing, CRC-24Q and MAVLink GPS_RTCM_DATA fragmentation for RTK corrections. | docs.rs |
ados-clock |
Map remote clocks onto the host clock: least-squares and envelope fits, TIMESYNC and a chrony sink. | docs.rs |
ados-swarm |
Swarm control laws: separation, flocking, formations, CBBA task allocation and a point-mass simulator. | docs.rs |
ados-mavlink-tunnel |
Send large messages over MAVLink TUNNEL frames with chunking and bounded reassembly. | docs.rs |
ados-display-driver |
Small-display output on Linux: SSD1306/SH1106 OLED over I2C, pixel packers and a framebuffer writer. | docs.rs |
ados-hmi |
Front-panel input: touchscreen calibration and gestures, button presses and rotary encoders. | docs.rs |
Packages an extension author builds against:
| Package | Use |
|---|---|
create-ados-plugin |
Scaffolder. npx create-ados-plugin with GCS-only, agent-only, or hybrid templates |
plugin-sdk |
TypeScript SDK for the GCS half: telemetry hooks, postMessage RPC to the agent, and a test harness |
extension-ui |
Reusable React UI primitives that match the Mission Control theme |
ados-sdk |
Rust SDK for the agent half, on crates.io (docs.rs) |
extensions/ first-party extensions, versioned independently
follow-me/
mavlink-gimbal-v2/
siyi-pod/
thermal-camera-flir-lepton-usb/
vision-nav/
world-engine/
packages/
create-ados-plugin/ scaffolder + templates
plugin-sdk/ TypeScript GCS SDK
extension-ui/ shared React UI primitives
scripts/
pack.sh build + manifest hash + zip to .adosplug
pack-rust.sh same, for an extension whose agent half is a crate
_pack-exclude.sh shared packing helpers: archive excludes, entrypoint guard
build-rust.sh cross-compile a Rust agent half
pack-world-engine-local.sh build, pack and sign a World Engine archive for bench tests
world-engine-payloads.tsv World Engine release payloads fetched at install
lint-manifest.mjs check a manifest against the code it describes
lint-fixtures/ fixtures for the manifest linter
emit-reference.mjs write docs/reference/extensions.json from the manifests
sign.sh Ed25519-sign the archive against the publisher key
submit.sh submit a signed archive to a plugin registry
registry_submit_fields.py derive registry submission fields from a signed archive
tests/ tests for the packing, signing and submission scripts
.github/workflows/
extensions.yml per-extension build and test on pull requests and main
typecheck.yml TypeScript typecheck on pull requests and main
rust-check.yml check the Rust agent halves
reference.yml keep docs/reference/extensions.json in sync
release.yml build, sign, and release on tag push
vision-nav-release.yml Vision Navigation release pipeline
world-engine-release.yml World Engine release pipeline
world-engine-deep.yml on-demand deep World Engine test run
pnpm-workspace.yaml declares the GCS halves and root tooling (run pnpm install at the repo root). pyproject.toml declares the agent halves and shared Python utilities. Each extension carries its own CHANGELOG.md and is versioned independently through its own release tags.
cd extensions/mavlink-gimbal-v2
pnpm install
pnpm build
../../scripts/pack.sh mavlink-gimbal-v2This produces dist/com.altnautica.mavlink-gimbal-v2-<version>.adosplug. The archive layout matches the public extension spec at docs.altnautica.com/developers/manifest.
pack.sh refuses to write a half-archive: if the manifest declares a GCS entrypoint the built bundle has to be in the archive, and if it declares a Python agent.entrypoint the module that entrypoint names has to be there too. An archive with no agent source installs cleanly and verifies, then the supervisor dies importing a module that was never packed.
Check a manifest against the code it describes before you pack:
node scripts/lint-manifest.mjs extensions/mavlink-gimbal-v2/manifest.yamlIt fails on a declared permission with no call site, a declared UI slot with no implementation, and a version that disagrees across manifest.yaml, the two package.json files and the definePlugin({ version }) literal the host registers.
The Rust agent SDK is ados-sdk, published on crates.io with API docs on docs.rs. An out-of-tree plugin adds it with cargo add ados-sdk; its version tracks the agent release it targets. See the Rust SDK guide.
First-party extensions in this repo (vision-nav, world-engine) build against a sibling agent checkout instead, so the two repositories have to sit next to each other:
<root>/ADOSDroneAgent
<root>/ADOSExtensions
Cargo.toml uses a path dependency on that sibling for local development. CI clones the agent repository and checks out the revision in the repo-root ADOS_AGENT_REV file, so a release tag resolves the SDK at a fixed commit rather than whatever main happened to be. Update ADOS_AGENT_REV when a release needs a newer SDK.
Cross-compiling for a drone needs the musl target and an aarch64 musl linker. Apple's ld is not one, so a plain macOS build compiles everything and then fails at the link step; scripts/build-rust.sh documents the linker env vars, including a zig cc fallback where no musl toolchain is installed.
rustup target add aarch64-unknown-linux-musl
./scripts/pack-rust.sh vision-navpack-rust.sh asserts both halves are in the archive before it zips: the compiled binary at the manifest's agent.entrypoint and, when one is declared, the built GCS bundle.
Tagged releases run scripts/sign.sh in CI against the publisher key. The signed archive is published as a GitHub Release asset and, for first-party extensions, surfaces inside the Mission Control Plugins tab through the hosted registry.
From Mission Control: open a drone, switch to the Plugins tab, browse the registry, pick the extension, and approve the two-stage install dialog. The agent downloads the signed archive, verifies the Ed25519 signature, and stages the plugin under its supervisor.
From the agent CLI:
ados plugin install https://github.com/altnautica/ADOSExtensions/releases/download/<release>/<extension>.adosplugQuestions, ideas and show-and-tell go in Discord. Bugs and feature requests go in Issues.
First-party only at launch. Community contributions land through the hosted registry submission flow when the registry reaches v1.0. See the hosted registry developer doc for the policy, and the developer docs for the manifest, SDKs, and permission model.
GPL-3.0-or-later. Each extension is free to use, modify, and distribute under the same terms. The Rust ados-sdk crate on crates.io is MIT OR Apache-2.0.

