Skip to main content

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.

A PayloadActuatorDriver controls a non-imaging mission payload: sprayer, dropper, claw, sampler, winch, or any other actuator that the operator triggers from a panel or a scripted mission step.

The interface

from ados.sdk.drivers.payload_actuator import (
    PayloadActuatorDriver,
    PayloadCandidate,
    PayloadCapabilities,
    PayloadSession,
    PayloadCommand,
    PayloadState,
)

class MyPayloadDriver(PayloadActuatorDriver):
    async def discover(self) -> list[PayloadCandidate]:
        ...

    async def open(self, candidate, config) -> PayloadSession:
        ...

    async def close(self, session) -> None:
        ...

    def capabilities(self, session) -> PayloadCapabilities:
        ...

    async def actuate(self, session, command: PayloadCommand) -> None:
        ...

    def get_state(self, session) -> PayloadState:
        ...

Capabilities

PayloadCapabilities(
    actions=("arm", "trigger", "stop", "set_flow_rate"),
    has_position_feedback=False,
    has_flow_feedback=True,
    metadata={"max_payload_kg": 2.5, "update_hz": 10.0},
)
actions is the tuple of action_id strings the driver accepts in PayloadCommand. The GCS panel discovers these and renders one button per action. metadata is the open-ended bag for driver-specific knobs (max payload mass, refill volume, vendor firmware version).

Commands

PayloadCommand(
    action_id="trigger",
    args={"duration_s": 1.5, "intensity": 0.8},
)
action_id is mandatory. args is a free-form dict that the driver validates. Unknown keys should raise ValueError.

State

PayloadState(
    timestamp_ns=ns,
    last_action_id="trigger",
    busy=False,
    metadata={"flow_lpm": 0.0, "tank_pct": 65.0, "armed": True},
)
busy=True while an action is in flight; the host serialises actuate calls per session to keep the contract simple. Drivers that report sustained errors should propagate them via metadata["error"] and raise DriverError on the next actuate call so the GCS sees the failure on the user-action path.

Manifest permissions

agent:
  permissions:
    - sensor.payload.register
    - vehicle.payload.actuate    # required to call execute()
    - serial.read_write          # if the driver speaks raw serial
vehicle.payload.actuate is a high-risk capability. The host prompts per-action consent the first time a session calls actuate(...) unless the operator has pre-approved auto-confirm in the plugin’s permission detail page.

See also