Skip to main content
The driver base classes and data types ship in both SDKs (ados.sdk.drivers in Python, ados_sdk::drivers in Rust), and the method contracts on these pages match them. The agent does not route drivers. It never calls discover(), open() or the iterators. register_*_driver calls return not_implemented, and the sensor.*.register capabilities are refused at grant time. A driver plugin opens and runs its own device from its lifecycle hooks, as the first-party Gimbal v2 plugin does. No Mission Control panel renders driver output.
A PayloadActuatorDriver controls a non-imaging payload: a sprayer, dropper, claw, sampler, winch, or any other actuator your plugin triggers.

The interface

In Rust, actuate returns DriverError::InvalidParam when command.action_id is not in PayloadCapabilities::actions, and args and metadata are msgpack value maps.

Capabilities

actions is the tuple of action_id strings the driver accepts in PayloadCommand. metadata holds driver-specific values (maximum payload mass, refill volume, firmware version).

Commands

action_id is mandatory. args is a free-form dict the driver validates; raise ValueError on unknown keys.

State

busy=True while an action is in flight. Your plugin calls actuate itself; serialise calls per session in your plugin. A driver that sees a sustained fault reports it under metadata["error"] and raises DriverError on the next actuate call.

Opening the driver from your plugin

Your plugin opens the driver in on_start and calls actuate when its GCS half or a mission action asks for it. The pattern is on Driver layer. A GPIO-driven actuator needs hardware.gpio_out; a serial one needs hardware.uart. Risk levels are on Permissions.
A payload that moves or releases mass in flight is a flight-safety action. Read Safety before you fly it.

Next steps

Driver layer

The shared contract and the manifest table.

Permissions

The capability catalog and risk levels.

Hardware testing

Test with a mock backend before the bench.
Last modified on October 11, 2026