Skip to content

feat(dialect)!: add the generic payload service - #18

Open
mrpollo wants to merge 6 commits into
mainfrom
mrpollo/generic-payload
Open

mrpollo wants to merge 6 commits into
mainfrom
mrpollo/generic-payload

Conversation

@mrpollo

@mrpollo mrpollo commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

Add a service that lets any MAVLink component, whether a ground station, an onboard mission computer, the autopilot or a gateway, discover, monitor and operate any payload through one set of messages, instead of a private message set per payload type.

Common MAVLink covers cameras, gimbals, grippers, winches and parachutes. Anything else has no standard way to be discovered, report its state, or be operated, so each integration defines messages that no other system can interpret.

A payload manager describes each payload as functions and reports their availability, health, resources, inhibitions and measurements. One request, status and cancel exchange carries the common lifecycle operations (arm, disarm, activate, deactivate, reset, self-test) and any action or property a payload declares in a versioned capability profile. Names, inventories and profiles come from a catalogue served through Component Metadata, with JSON schemas and examples in component_metadata/. Payloads that already have a MAVLink service keep using it, and the catalogue binds them to it.

A few choices aren't obvious from the XML:

  • Safety-relevant enums use values at least four bits apart, so a single corrupted bit cannot turn one state into another.
  • Instance epochs only increase, so a client discards late reports from a replaced or restarted payload.
  • A disarm or deactivate needs neither the current description nor a clock, so it works over a one-way link.

The Generic Payload Protocol and Payload Catalogue Metadata pages on the site cover the full rules. One question is left open: how a payload manager addresses the component that executes an operation when it relays the request. It only matters once those come from different implementers.

Wire impact: breaking. Removing <version> and <dialect> from military.xml changes the generated MAVLINK_VERSION from 1 to 2. No existing message changes.

Tested locally with the pinned mavlink and pymavlink: every job in validate_dialect, generate_c_lib, docs, workflow_lint and commit_checks passes.

Assisted-by: Claude-Code:claude-opus-5-5

sreedy-riis and others added 6 commits October 9, 2026 15:31
A payload outside the dedicated MAVLink services has no standard way
to be discovered, to report whether it is available, healthy,
inhibited or exhausted, or to be operated, so each integration
defines private messages that ground stations cannot interpret. Add
PAYLOAD_INFO, PAYLOAD_STATE, PAYLOAD_RESOURCE, PAYLOAD_INHIBIT,
PAYLOAD_MEASUREMENT, PAYLOAD_OPERATION_REQUEST, PAYLOAD_OPERATION_STATUS
and PAYLOAD_CATALOGUE_STATUS (53100-53107), their enums, and the
COMP_METADATA_TYPE_PAYLOAD_CATALOGUE metadata type, and record the
allocation in IDMAPPING.md.

Breaking: <version> and <dialect> are removed from military.xml, so
the version comes from the included files. With the pinned upstream
definitions the generated MAVLINK_VERSION changes from 1 to 2;
anything that checks that value must be updated when it regenerates.

Assisted-by: Claude-Code:claude-opus-5-5
Signed-off-by: Stephen Reedy <sreedy@riis.com>
Generic operations cover the lifecycle every payload shares, but a
payload's own actions and properties need a way to be invoked through
the same correlated exchange. Add profile actions and property reads
and writes to PAYLOAD_OPERATION_REQUEST, add PAYLOAD_OPERATION_CANCEL
(53108) so an outstanding operation can be stopped, and define how
stops, repeats and outcomes are answered so a lost reply never runs
an operation twice.

Assisted-by: Claude-Code:claude-opus-5-5
Signed-off-by: Stephen Reedy <sreedy@riis.com>
Names, service bindings, inventories, events and capability profiles
are too large and too static for runtime messages, so they are
published as a payload catalogue through Component Metadata. Add the
JSON schemas for the catalogue and its definition manifest, fictitious
examples of a catalogue, capability profiles and events whose digests
match the current definitions, and a README entry for the folder.

Assisted-by: Claude-Code:claude-opus-5-5
Signed-off-by: Stephen Reedy <sreedy@riis.com>
The XML defines each message, but not how they are used together.
Add a protocol guide for the generic payload service, covering roles,
who sends what and when, stops, operator control and sequences, and a
guide to the payload metadata formats. Add both to the site's sidebar
and services index, and give the README the final ID ranges.

Assisted-by: Claude-Code:claude-opus-5-5
Signed-off-by: Stephen Reedy <sreedy@riis.com>
Nothing recomputed the example digests when military.xml changed, so
an example could declare a stale value without anything failing. The
check recomputes every sha256 the metadata examples declare over the
bytes of the file it covers, fetching upstream files at the commit
their URI pins, and fails on any mismatch.

Assisted-by: Claude-Code:claude-opus-5-5
Signed-off-by: Stephen Reedy <sreedy@riis.com>
The example-digests job checks that each digest the metadata examples
declare matches the file it names, but nothing checks the examples
themselves: an example could stop conforming to payloads.schema.json or
definition-manifest.schema.json and every job would stay green. The
schemas also state rules their structure cannot enforce, such as unique
payloadId, functionId and instanceKey values, or catalogue constraint
members that name a bound instance and a key its profile declares, and
the payload metadata guide makes a client check them.

check_example_schemas.py validates the catalogue and manifest examples
against their schemas and each capability-profile example against the
capabilityProfileDocument definition, rejects repeated JSON keys, and
checks the uniqueness, composition, constraint-member, owner and
inhibition prevents rules. events.example.json and general.example.json
are upstream Component Metadata types and are skipped; any other example
with no schema here fails, so none goes unchecked. A new example-schemas
job runs it. jsonschema is pinned in requirements.txt beside the script,
which that job and script-tests install.

Validation: every example passes; 25 tests, run by script-tests, break
one rule each on a copy of component_metadata/ and cover the checker at
100% of lines and branches; the whole validate_dialect suite passes on
Linux with requirements.txt; actionlint 1.7.12 and zizmor 1.30.1 report
nothing.

Assisted-by: Claude-Code:claude-opus-5-5
Signed-off-by: Ramon Roche <mrpollo@gmail.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants