Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Payload and Autonomy Microservice Support from Marine Dialect #1998

Open
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

bazfp
Copy link

@bazfp bazfp commented May 26, 2023

This has been in development for over a year and is currently operational on underwater vehicles (UUVs) like the popular Remus vehicle from Hydroid. It's stable enough now we have decided to present the changes upstream.

This is version v22.08.01

There are also matching functional implementations in MAVSDK which are also in operation on both vehicle-side and autonomy-control side.

UUVs tend to operate in very comms limited environments (no RF / limited acoustic comms). As with most robots they have an on-board "autopilot" or "front-seat" that controls low-level vehicle movement (Control Fins to set Heading, Control Motor to Set Speed etc). They also often run a generic Autonomy system on an additional "back-seat" computer, which accepts high-level commands and breaks them down for the front-seat vehicle to consume (Scan this point, Scan this area etc.)

Typically each vehicle manufacturer creates their own bespoke interface to allow external-control from an autonomy system, we are pushing to standardise this approach with an open standard.

We are using MAVLink now as our vehicle interface for this Autonomy <-> Frontseat link and have been working with vehicle manufacturers have MAVLink integrated as a "frontseat" control interface.

The things of note are:

  • Generic Vehicle Payload Registering, Status and Control
    • Ability to add/swap/remove/enable/disable/pause generic external sensors, sonar, sidescan, FLS, etc.
  • Support for External Autonomy Systems - Components, Health, State and Control
    • These autonomy systems run on a companion computer and issue MAVLINK commands to the vehicle front-seat controller.
  • Water current, DVL (Doppler Velocity Logger)
    • Domain specific environment monitoring
  • Various assorted messages for information sharing between squads.

Payload Microservice

The Payload Microservice is used to discover, configure and control Payloads<Payload> (which could be sensors, actuators or other connected components) registered on a MAVLink system.

You can use this Microservice to:

  • Retrieve a list of all Payloads on the system
  • Retrieve the status of a single Payload
  • Receive updates on newly registered Payloads
  • Control Payload state

It is expected that the AutoPilot maintains a list of registered Payloads, containing for each:

  • ID
    • Any number in the range (1 - UINT8_MAX)
    • Must be unique in reguards to the other Payload IDs
  • Type
    • Must be one of the values defined in the PAYLOAD_TYPE enum
  • States
    • The states that the Payload can be set to
    • 16 byte bitmask corresponding to the PAYLOAD_STATE enum
  • Health
    • The Payload health
    • 16 byte bitmask corresponding to the PAYLOAD_HEALTH enum
  • State
    • The the current states of the vehicle
    • 16 byte bitmask corresponding to the PAYLOAD_STATE enum
  • Name
    • Optional
    • Maximum length of 16 characters

A system can use the Payload Microservice to request details about the Payloads on the MAVLink system and to configure said Payloads.

When an external system enables a Payload it will set the Payload state to:

  • PAYLOAD_STATE_POWERED = true
  • PAYLOAD_STATE_ARMED = true
  • PAYLOAD_STATE_ACTIVE = true

When a Payload is disabled, An external system will set the Payload state to:

  • PAYLOAD_STATE_POWERED = true
  • PAYLOAD_STATE_ARMED = false
  • PAYLOAD_STATE_ACTIVE = false

In order to request a PAYLOAD_STATUS from the AutoPilot, A system will
send a MAV_CMD_REQUEST_MESSAGE with:

  • Param 1 set to 44206 (the Message
    ID of PAYLOAD_STATUS)
  • Param 2 set to the Payload ID of the
    Payload being enquired about

For a list of the enumerations used in the payload messages, please see payload-enum-summary.

The AutoPilot also needs to respect the implementation details layed out in payload-microservice-operation-exceptions.

Workflows

payload_discovery_process below shows the communication sequence external systems use to retrieve the list of registered Payloads from the AutoPilot (assuming all operations succeed).
payload_list_request

Payload Discovery Operation

In more detail, the sequence of operations is:

  1. Autonomy sends a PAYLOAD_REQUEST_LIST to start the discovery and
    download process
    • Autonomy will wait for a specific length of time for a
      PAYLOAD_COUNT response from the AutoPilot. If no response is
      received during that time, Autonomy will re-send the
      PAYLOAD_REQUEST_LIST message.
  2. The AutoPilot receives the message and responds with a
    PAYLOAD_COUNT where the count field
    is the number of registered payloads
  3. Autonomy sends a PAYLOAD_LIST_ITEM_REQUEST for the first list item
    ( list position = 0)
    • Autonomy will wait for a specific length of time for a
      PAYLOAD_LIST_ITEM_REQUEST response from the AutoPilot. If no
      response is received during that time, Autonomy will re-send the
      PAYLOAD_LIST_ITEM_REQUEST message.
  4. The AutoPilot receives the PAYLOAD_LIST_ITEM_REQUEST message and
    responds with the requested Payload details via a
    PAYLOAD_LIST_ITEM message
  5. Autonomy and AutoPilot repeat steps 3 and 4 until Autonomy has the
    deatils of all Payloads
  6. After receiving the details of the last Payload, Autonomy responds
    with a single PAYLOAD_LIST_ACK with the
    type field set to
    PAYLOAD_LIST_ACCEPTED (see the PAYLOAD_LIST_RESULT enum) to
    indicate Payload discovery success
  7. The AutoPilot receives the PAYLOAD_LIST_ACK containing
    PAYLOAD_LIST_ACCEPTED and understands the operation to be
    complete.

List request errors are considered unrecoverable see payload-microservice-errors for details on how to handle errors.

payload_status_update below shows the communication sequence that autonomy follows to request the status of a registered Payload.

Autonomy sends a MAV_CMD_REQUEST_MESSAGE message with the ID of the Payload it wants the status of (IDX) to the AutoPilot. The AutoPilot then responds with a PAYLOAD_STATUS message containing the Type, Health and Status of the Payload.

payload_status_update

Payload Status Update Operation

The diagram below shows the communication sequence Autonomy uses to change the State of a registered Payload. The MAV_CMD_PAYLOAD_SET_STATE message is used to set the State of a Payload using a bitmask corresponding to the PAYLOAD_STATE enum, where the bits are set to 1 to indicate the state is true and 0 to indicate the state is false.

As part of the Payload discovery process, the valid States that can be set for each Payload are specified in the PAYLOAD_LIST_ITEM message. If trying to set a unsupported state on a payload (e.g. setting Armed=true on a Payload that only has Powered as a valid state), then the MAV_CMD_PAYLOAD_SET_STATE command should be rejected by the AutoPilot with a COMMAND_ACK with a MAV_RESULT of MAV_RESULT_DENIED.

If the id field in the MAV_CMD_PAYLOAD_SET_STATE command sent by Autonomy is 0, the AutoPilot must apply the state change to all registered Payloads for which it is a valid option. If a Payload ID that is not registered is specified in the command, it should be rejected by sending a
COMMAND_ACK with a MAV_RESULT of MAV_RESULT_DENIED.

If AutoPilot successfully handles the command, a COMMAND_ACK message should be sent back to Autonomy with a MAV_RESULT of MAV_RESULT_ACCEPTED followed by AutoPilot sending a PAYLOAD_STATUS message containing the updated Payload State.

payload_state_control

Payload State Control Operation

When a Payload is added or removed to the AutoPilot's Payload list, a PAYLOAD_CHANGE message needs to be broadcast in order to inform all connected Companion Computers (including Autonomy) of the change, specifying the Payload ID that was affected and whether it has been added or removed.

If the update was about a new Payload, the Companion Computers may subsequently sent a
MAV_CMD_REQUEST_MESSAGE
message to obtain details of the new Payload.

payload_list_change

Autonomy Microservice

The Autonomy Microservice allows the AutoPilot to set Autonomy execution state, for control handover, and to monitor the state of Autonomy. The various MAVLink Messages used in the Autonomy Microservice are detailed in Autonomy Message Table.

Message ID Direction Description
MAV_CMD_AUTONOMY_DEMAND #44000 AutoPilot to Autonomy Send Autonomy Demand to Autonomy.
AUTONOMY_STATUS #44001 Autonomy to AutoPilot The state of Autonomy.

Messages used by the Autonomy Microservice

Central to the Autonomy Microservice is a state machine representing the autonomy system's execution state. numref:autonomy_state_diagram shows this state machine, where:

  • Each state is defined in the AUTONOMY_STATE enum (sent from
    Autonomy to the AutoPilot via the AUTONOMY_STATUS message).

  • Each transition is defined in the AUTONOMY_DEMAND enum (sent
    from the AutoPilot to Autonomy via the MAV_CMD_AUTONOMY_DEMAND
    message).

autonomy_state_diagram

The Autopilot MUST send a Stop or Pause command to Autonomy whenever it takes forcible control of the system.

In addition to providing an overall system state, the AUTONOMY_STATUS message also provides status bitmaps for a number of sub-components. Autonomy provides status for the following components:

  • AUTONOMY_COMPONENT_CORE
  • AUTONOMY_COMPONENT_ATR
  • AUTONOMY_COMPONENT_MISSION

Status bits for all other components are not used by Autonomy and set to zero.

Health Reporting

Component Health Descriptions describes in further detail what each
health flag reported by AUTONOMY_STATUS indicates.

Autonomy Component Health Description
AUTONOMY_COMPONENT_CORE When health is reported as true for this component, it indicates that Autonomy has initialized successfully.
AUTONOMY_COMPONENT_ATR When health is reported as true for this component, it indicates that Autonomy's Embedded ATR component has initialized successfully and is ready for data processing.
AUTONOMY_COMPONENT_MISSION When health is reported as true for this component, it indicates that Autonomy has a valid mission plan loaded and is ready for launch.

Autonomy Component Health

Workflows

autonomy_request_state below shows the communication sequence
AutoPilot needs to follow to get the status of Autonomy.

Autonomy responds to the
MAV_CMD_REQUEST_MESSAGE
command (see Command Types Table) sent by the AutoPilot with a AUTONOMY_STATUS message
containing the presence, state and health of the components present on
the Autonomy system, and the current execution state of the system.

autonomy_request_status

Request Autonomy State Process

autonomy_send_autonomy_demand below shows the communication sequence
when the AutoPilot sends a MAV_CMD_AUTONOMY_DEMAND containing an
AUTONOMY_DEMAND to Autonomy.

Autonomy responds with a
COMMAND_ACK
and a AUTONOMY_STATUS message as stated in
payload-microservice-errors.

autonomy_send_autonomy_demand

Send Autonomy Demand Process

Additional MAVLink Messages

In addition to the messages already detailed in the various MAVLink Microservices,

  • MESSAGE_CONTACT_SNIPPET
  • MESSAGE_AUTONOMY_MISSION_STATUS
  • SQUAD_VEHICLE_STATE

Also see the following enumerations:

  • MAV_SYS_STATUS_SENSOR_EXTENDED

External Communications

For integrations where all external communications (acoustic, RF etc.) for a vehicle are handled entirely by the AutoPilot:

  • Autonomy will forward all outgoing communication it wishes to send to
    the AutoPilot
  • The AutoPilot must send Autonomy incoming communications
Message ID Direction Description
MESSAGE_CONTACT_SNIPPET 44100 Autonomy to AutoPilot Forward message containing details of an ATR Contact Snippet.
MESSAGE_AUTONOMY_MISSION_STATUS 44101 Bidirectional Forward message containing the status of the Autonomy Mission

Autonomy will provide the following metadata to define how the AutoPilot should handle the communication:

  • destination_address - The ID of the
    external target of the communication, or 0 for broadcast
  • message_length - The length of the
    communication to be sent (32 bytes by default)
  • snippet_confidence - Only used by
    MESSAGE_CONTACT_SNIPPET, to be used by the AutoPilot to sort the
    order of the stored snippets

AutoPilot must provide the following metadata when sending a MESSAGE_AUTONOMY_MISSION_STATUS to Autonomy:

  • source_vehicle_id - The ID of the
    external source of the communication

ALL MESSAGE_CONTACT_SNIPPET messages received by the AutoPilot should be sent in the order they were received; while only the most recent MESSAGE_AUTONOMY_MISSION_STATUS should be sent.

It is expected that the AutoPilot will forward any incoming Mission Status communications to Autonomy using the MESSAGE_AUTONOMY_MISSION_STATUS message.

If sending outgoing communications over a limited medium, such as acoustic, it is expected that the AutoPilot uses the type of outgoing communication to determine the sending priority.

If the AutoPilot receives telemetry, vehicle state or fault updates from other vehicles in the squad via acoustic of other communications, these must be forwarded to Autonomy using the SQUAD_VEHICLE_STATE message.

APPENDIX 1

Messages (Marine)

MAVLink Type Enumerations

AUTONOMY_DEMAND

[Enum] Demands
that can be made to an autonomy system.

Value Field Name Description
0 AUTONOMY_DEMAND_DEFAULT Default value, ignored.
1 AUTONOMY_DEMAND_START Start Autonomy System.
2 AUTONOMY_DEMAND_STOP Stop Autonomy System.
3 AUTONOMY_DEMAND_GO_TO_RECOVERY Abort Autonomy System to the Recovery Point.
4 AUTONOMY_DEMAND_PAUSE Pause Autonomy System.
5 AUTONOMY_DEMAND_SUSPEND Suspend Autonomy System Control Temporarily.
6 AUTONOMY_DEMAND_RESUME Resume Autonomy System.

AUTONOMY_COMPONENT

[Enum] These
encode the components that can be present in an autonomy system.

Value Field Name Description
1 AUTONOMY_COMPONENT_CORE 0x01 Autonomy System Core
2 AUTONOMY_COMPONENT_ATR 0x02 Automated Target Recognition
4 AUTONOMY_COMPONENT_SAS 0x04 Synthetic Aperture Sonar
8 AUTONOMY_COMPONENT_MBES 0x08 Multi Beam Echo Sounder
16 AUTONOMY_COMPONENT_FLS 0x10 Forward Look Sonar
32 AUTONOMY_COMPONENT_CAMERA 0x20 Camera
64 AUTONOMY_COMPONENT_ACOMMS 0x40 Acomms Modem
128 AUTONOMY_COMPONENT_MISSION 0x80 Autonomy Mission

AUTONOMY_STATE

[Enum] Describes
the states an autonomy system can be in.

Value Field Name Description
0 AUTONOMY_STATE_DEFAULT Default state, ignored.
1 AUTONOMY_STATE_IDLE System has not been started.
2 AUTONOMY_STATE_EXECUTING Autonomy System Executing and in control.
3 AUTONOMY_STATE_PAUSED Autonomy System execution paused.
4 AUTONOMY_STATE_SUSPENDED Autonomy System Control Suspended Temporarily.
5 AUTONOMY_STATE_COMPLETED Autonomy System execution completed successfully.
6 AUTONOMY_STATE_STOPPED Autonomy System execution stopped early.
7 AUTONOMY_STATE_RECOVERING Autonomy System heading to recovery position.

MAV_SYS_STATUS_SENSOR_EXTENDED

[Enum] Extends the
common
MAV_SYS_STATUS_SENSOR
enum.

Value Field Name Description
1 MAV_SYS_STATUS_RECOVERY_SYSTEM 0x01 Recovery system (parachute, balloon, retracts etc)
2 MAV_SYS_STATUS_ACOUSTIC_MODEM 0x02 Acoustic Modem
4 MAV_SYS_STATUS_SAS 0x04 Single Aperture Sonar
8 MAV_SYS_STATUS_MBES 0x08 Multi Beam Echo Sounder
16 MAV_SYS_STATUS_FLS 0x10 Forward Look Sonar

PAYLOAD_TYPE

[Enum] Defines the
various types of Payloads<Payload> that can be available on the
MAVLink system.

Value Field Name Description
0 PAYLOAD_TYPE_CAMERA Generic Camera Payload
1 PAYLOAD_TYPE_LIDAR Light Detection and Ranging Payload
2 PAYLOAD_TYPE_WINCH Winch Payload
3 PAYLOAD_TYPE_ACOUSTIC_MODEM Acoustic Modem Payload
4 PAYLOAD_TYPE_SAS Single Aperture Sonar Payload
5 PAYLOAD_TYPE_MBES Multi Beam Echo Sounder Payload
6 PAYLOAD_TYPE_FLS Forward Look Sonar Payload
101 PAYLOAD_TYPE_GENERIC_1 Generic Payload 1
102 PAYLOAD_TYPE_GENERIC_2 Generic Payload 2
103 PAYLOAD_TYPE_GENERIC_3 Generic Payload 3
104 PAYLOAD_TYPE_GENERIC_4 Generic Payload 4
105 PAYLOAD_TYPE_GENERIC_5 Generic Payload 5

PAYLOAD_HEALTH

[Enum] These
define the operational health a Payload can be in.

Value Field Name Description
1 PAYLOAD_HEALTH_GENERIC 0x01 Payload Health - Generic

PAYLOAD_STATE

[Enum] These
define the states a Payload can be in.

Value Field Name Description
1 PAYLOAD_STATE_POWERED 0x01 Payload State - Powered
2 PAYLOAD_STATE_ARMED 0x02 Payload State - Armed
4 PAYLOAD_STATE_ACTIVE 0x04 Payload State - Active

PAYLOAD_LIST_RESULT

[Enum] These
define the results of a payload discovery operation.

Value Field Name Description
0 PAYLOAD_LIST_ACCEPTED Payload List downloaded OK
1 PAYLOAD_LIST_ERROR Generic error with downloading Payload List
2 PAYLOAD_LIST_REPEATED_ID Multiple entries for same Payload ID in List

VEHICLE_MODE

[Enum] Vehicle
Mode.

Value Field Name Description
0 VEHICLE_MODE_DEFAULT Default state, ignored.
1 VEHICLE_MODE_MISSION_FAULT There is a fault with the current mission.
2 VEHICLE_MODE_MISSION_ABORT The current mission has been aborted.
3 VEHICLE_MODE_BASELINE_MISSION The vehicle is executing its baseline mission.
4 VEHICLE_MODE_REMOTE_MISSION THe vehicle is executing a remote mission.

MAVLink Commands (MAV_CMD)

Note

MAVLink commands
(MAV_CMD)
and messages are different! These commands define the values of up to 7
parameters that are packaged INSIDE specific messages used in the
Mission Protocol and Command Protocol. Use commands for actions in
missions or if you need acknowledgment and/or retry logic from a
request. Otherwise use messages.

MAV_CMD_AUTONOMY_DEMAND (#44000)

[Command]
Send autonomy demands to a Companion Computer.

Parameter (:Label) Units Values Description
1: Autonomy Demand N/A AUTONOMY_DEMAND Autonomy Demand
2 N/A N/A Empty
3 N/A N/A Empty
4 N/A N/A Empty
5 N/A N/A Empty
6 N/A N/A Empty
7 N/A N/A Empty

MAV_CMD_PAYLOAD_SET_STATE (#44002)

[Command]
Set the states for the payload with the specified ID.

Command will be rejected if trying to set a state not supported by the
payload.

Note

This command should always be sent as
COMMAND_INT which has:

  • Param 5/x as int32_t rather than
    float
Parameter (:Label) Units Values Description
1: Payload ID N/A min: 0 max:999 increment:1 Payload ID, 0 to apply to all Payloads in List
2 N/A N/A Empty
3 N/A N/A Empty
4 N/A N/A Empty
5: components N/A PAYLOAD_STATE Bitmask of enabled Payload states
6 N/A N/A Empty
7 N/A N/A Empty

MAVLink Messages

AUTONOMY_STATUS (#44001)

[Message] Used
to specify the state of an autonomy system.

AUTONOMY_STATUS
Field Name Default Value Type Units Description
target_system N/A uint8_t N/A System ID
target_component N/A uint8_t N/A Component ID
autonomy_components_present N/A uint32_t MAV_AUTONOMY_COMPONENT A 32 bit bitmap corresponding to the AUTONOMY_COMPONENT<AUTONOMY_COMPONENT> enum, showing which autonomy components are present on the MAVLink system:
  • Value of 0 if not present
  • Value of 1 if present
autonomy_components_enabled N/A uint32_t MAV_AUTONOMY_COMPONENT A 32 bit bitmap corresponding to the AUTONOMY_COMPONENT<AUTONOMY_COMPONENT> enum, showing which autonomy components are enabled:
  • Value of 0 if not enabled
  • Value of 1 if enabled
autonomy_components_health N/A uint32_t MAV_AUTONOMY_COMPONENT A 32 bit bitmap corresponding to the AUTONOMY_COMPONENT<AUTONOMY_COMPONENT> enum, showing which autonomy components have an error (or are operational):
  • Value of 0 if it has an error
  • Value of 1 if it is healthy
system_state N/A uint8_t AUTONOMY_STATE<AUTONOMY_COMPONENT> The current execution state of the Autonomy system.

MESSAGE_CONTACT_SNIPPET (#44100)

[Message]
Contact snippet message to be sent to specified destination with message
priority, as well as confidence of contact snippet.

Field Name Default Value Type Units Description
target_system N/A uint8_t N/A System ID
target_component N/A uint8_t N/A Component ID
destination_address N/A uint8_t N/A Acomms message destination, 0 for broadcast.
snippet_confidence N/A uint8_t % Contact snippet confidence (0 to 100).
snippet_id N/A uint16_t N/A Contact snippet identifier. Unique for each snippet across all contacts
source_vehicle_id N/A uint8_t N/A Source Vehicle ID. UINT8_MAX: field not provided.
message_length N/A uint8_t N/A Length of the data transported in message
message N/A uint8_t[128] N/A Variable length message. The message length is defined by message_length.

MESSAGE_AUTONOMY_MISSION_STATUS (#44101)

[Message]
Autonomy System Mission Status message to be sent to specified
destination.

Field Name Default Value Type Units Description
target_system N/A uint8_t N/A System ID
target_component N/A uint8_t N/A Component ID
destination_address N/A uint8_t N/A Acomms message destination, 0 for broadcast.
source_vehicle_id N/A uint8_t N/A Source Vehicle ID. UINT8_MAX: field not provided.
message_length N/A uint8_t N/A Length of the data transported in message
message N/A uint8_t[128] N/A Variable length message. The message length is defined by message_length.

SQUAD_VEHICLE_STATE (#44102)

[Message]
Vehicle state data recieved from another vehicle in the squad.

Field Name Default Value Type Units Description
target_system N/A uint8_t N/A System ID
target_component N/A uint8_t N/A Component ID
source_vehicle_id N/A uint8_t N/A Source Vehicle ID.
vehicle_mode N/A uint8_t N/A Current vehicle mode. See VEHICLE_MODE for allowed values.
lat N/A int32_t Decimal Degrees * 1e7 Latitude, expressed
lon N/A int32_t Decimal Degrees * 1e7 Longitude, expressed
depth N/A float m Current depth in meters positive down from the surface.
altitude N/A float m Current altitude from the terrain
heading N/A float degrees Heading in degrees clockwise from North.
velocity N/A float m/s Speed in meters per second.
battery_state N/A uint8_t % Remaining battery energy. Values: [0-100], -1: AutoPilot does not estimate the remaining battery.
vehicle_faults N/A int32_t N/A Vehicle faults - defined specific to vehicle.

PAYLOAD_REQUEST_LIST (#44200)

[Message] Used
to request the list of registered Payloads from the AutoPilot.

Field Name Default Value Type Units Description
target_system N/A uint8_t N/A System ID
target_component N/A uint8_t N/A Component ID

PAYLOAD_COUNT (#44201)

[Message] This
message is emitted as response to PAYLOAD_REQUEST_LIST. The Companion Computer can then request the individual payload item based on the
knowledge of the total number of Payloads<Payload>.

Field Name Default Value Type Units Description
target_system N/A uint8_t N/A System ID
target_component N/A uint8_t N/A Component ID
count N/A uint16_t N/A Number of registered payloads

PAYLOAD_LIST_ITEM_REQUEST (#44202)

[Message]
Request the status of the Payload with the specified Payload ID.

Field Name Default Value Type Units Description
target_system N/A uint8_t N/A System ID
target_component N/A uint8_t N/A Component ID
payload_list_position N/A uint8_t N/A Payload List position

PAYLOAD_LIST_ITEM (#44203)

[Message]
Description of a single Payload.

Field Name Default Value Type Units Description
target_system N/A uint8_t N/A System ID
target_component N/A uint8_t N/A Component ID
payload_id N/A uint8_t N/A Payload ID, 1 - N
payload_name N/A char[16] N/A Payload Name
payload_type N/A PAYLOAD_TYPE N/A Payload Type
valid_states N/A uint16_t - PAYLOAD_STATE N/A Payload Type

PAYLOAD_LIST_ACK (#44204)

[Message]
Acknowledgment Message from a Companion Computer upon receiving all
PAYLOAD_LIST_ITEM Messages.

Field Name Default Value Type Units Description
target_system N/A uint8_t N/A System ID
target_component N/A uint8_t N/A Component ID
result N/A PAYLOAD_LIST_RESULT N/A Payload List result

PAYLOAD_STATUS (#44206)

[Message] This
message is emitted as response to
MAV_CMD_REQUEST_MESSAGE messages with
Param 1 specifying the message ID
(44206) and Param 2 specifying the
payload ID. This message contains the details (ID and Type) and health
and status (as bitmasks) of the specified payload.

Field Name Default Value Type Units Description
target_system N/A uint8_t N/A System ID
target_component N/A uint8_t N/A Component ID
payload_id N/A uint8_t N/A Payload ID, 1 - N
payload_type N/A PAYLOAD_TYPE N/A Payload Type
payload_health N/A uint16_t PAYLOAD_HEALTH Payload Health (bitmask)
payload_state N/A uint16_t PAYLOAD_STATE Payload State (bitmask)

PAYLOAD_CHANGE (#44207)

[Message]
Notification that a Payload has been added or removed from the MAVLink
system.

Field Name Default Value Type Units Description
target_system N/A uint8_t N/A System ID
target_component N/A uint8_t N/A Component ID
payload_change N/A uint8_t 1: Added, 0: Removed Payload ID change
payload_id N/A uint8_t N/A Payload ID (1-N)

WATER_CURRENT (#44300)

[Message] Water
current values.

Note

Calculated Water current = (Vehicle Velocity - Measured Current).

Field Name Default Value Type Units Description
measured_current_x N/A float m/s Raw Measured water current in X (NED) direction
measured_current_y N/A float m/s Raw Measured water current in Y (NED) direction
measured_current_z N/A float m/s Raw Measured water current in Z (NED) direction
calculated_current_x N/A float m/s Calculated Water current in X (NED)
calculated_current_y N/A float m/s Calculated Water current in Y (NED)
calculated_current_z N/A float m/s Calculated Water current in Z (NED)
distance N/A float m Measurement distance from the sensor

DVL (#44301)

[Message]
Doppler Velocity Log Sensor. Used to provide vehicle velocity.

Field Name Default Value Type Units Description
has_lock N/A uint8_t N/A Boolean indicating if the DVL has bottom lock to the floor (true: 1, false: 0).
altitude_water N/A float[16] m Vehicle altitude to the floor of body of water for each beam
vehicle_velocity_x N/A float m/s Vehicle velocity in X (NED)
vehicle_velocity_y N/A float m/s Vehicle velocity in Y (NED)
vehicle_velocity_z N/A float m/s Vehicle velocity in Z (NED)

APPENDIX 2

Autonomy Protocol

The autonomy microservice is used by AutoPilots<AutoPilot> to get
information about Companion Computers<Companion Computer> that provide
autonomy. It also allows AutoPilots to configure the state of autonomy
systems.

Full definitions can be found in
marine.xml.

Message/Enum Summary

Message Description
MAV_CMD_AUTONOMY_DEMAND Send a demand to autonomy system.
AUTONOMY_STATUS The state of the autonomy system.

Autonomy Protocol Message Summary

Message Description
AUTONOMY_DEMAND Demands to be made to the autonomy system.
AUTONOMY_COMPONENT These encode the components that can be present in an autonomy system.
AUTONOMY_STATE Current state of the Autonomy System.

Autonomy Protocol Enum Summary

Operation Exceptions

Timeouts and Retires

A timeout should be set for all messages that require a response. If the
expected response is not received before the timeout then the message
must be resent. If no response is received after a number of retries
then the client must cancel the operation and return to a clean state as
it was before the initial message was sent.

The recommended timeout values before resending, and the number of
retries are:

  • Timeout (default): 1500 ms
  • Retries (max): 5

Errors/Completion

On acceptance of a MAV_CMD_AUTONOMY_DEMAND, the autonomy component
must respond with a COMMAND_ACK message
with a MAV_RESULT_ACCEPTED MAV_RESULT
and then it must publish a AUTONOMY_STATUS message containing the
updated execution state.

If a command is received by the autonomy component when it is not in a
state to carry it out, the resulting
COMMAND_ACK must contain the
MAV_RESULT_TEMPORARILY_REJECTED
MAV_RESULT.

If a command is received by the autonomy component when would constitute
an invalid state transition (for example if the autonomy sytem does not
allow a AUTONOMY_DEMAND_START when the current execution mode is
AUTONOMY_STATE_EXECUTING), then the autonomy system should continue in
its current state, rejecting the new one, and send a resulting
COMMAND_ACK containing the
MAV_RESULT_DENIED MAV_RESULT.

APPENDIX 3

Payload Protocol

The payload microservice is used by Companion Computers<Companion Computer> to get information about Payloads<Payload> from the
AutoPilot. It also allows Companion Computers to configure Payloads via
the AutoPilot.

Full definitions can be found in
marine.xml.

Message/Enum Summary

Payload Protocol Message Summary
Message Description
PAYLOAD_REQUEST_LIST Used to request the list of registered Payloads from the AutoPilot.
PAYLOAD_COUNT Emitted as response to PAYLOAD_REQUEST_LIST
PAYLOAD_LIST_ITEM_REQUEST Request the status of the Payload with the specified Payload ID.
PAYLOAD_LIST_ITEM This message is emitted as response to PAYLOAD_LIST_ITEM_REQUEST.
PAYLOAD_LIST_ACK Acknowledgment Message from a Companion Computer upon receiving all PAYLOAD_LIST_ITEM Messages.
PAYLOAD_STATUS

Emitted as response to MAV_CMD_REQUEST_MESSAGE with Param 1 set to 44206.

It contains the ID, Type, Health and State of the Payload specified in Param 2 of the MAV_CMD_REQUEST_MESSAGE Message.

PAYLOAD_CHANGE Notification that a Payload has been added or removed from the MAVLink system.
MAV_CMD_PAYLOAD_SET_STATE Put the Payload with the specified ID into the given state.
Message Description
PAYLOAD_TYPE List of supported payload types and generic placeholders
PAYLOAD_HEALTH Flags to report health of a registered payload
PAYLOAD_STATE Flags to report state of a registered payload
PAYLOAD_LIST_RESULT Results of payload discovery operation

Payload Protocol Enum Summary

Operation Exceptions

Timeouts and Retires

A timeout should be set for all messages that require a response. If the
expected response is not received before the timeout then the message
must be resent. If no response is received after a number of retries
then the client must cancel the operation and return to a clean state as
it was before the initial message was sent.

The recommended timeout values before resending, and the number of
retries are:

  • Timeout (default): 1500 ms
  • Timeout (payload items): 250 ms
  • Retries (max): 5

Errors/Completion

On successful completion of a payload list exchange the participant that
made the initial PAYLOAD_REQUEST_LIST, will send a PAYLOAD_LIST_ACK
messages with a result value of
PAYLOAD_LIST_ACCEPTED (see the PAYLOAD_LIST_RESULT enum).

Any other value in the result field of
the PAYLOAD_LIST_ACK message indicates an error. Both participants in
the exchange must reset themselves to the state they were in before the
initial PAYLOAD_REQUEST_LIST message, and the initiator must ignore
any information it received during the erronious list exchange.

bazfp and others added 12 commits May 26, 2023 16:05
I don't think there is a good reason to use cm when it's a float.
I'd just use the SI unit instead.
The payload_type fields are only uint8_t, so we have to use values
smaller equal 255.
This state is required in response to the demand GO_TO_RECOVERY.
By using the command MAV_CMD_REQUEST_MESSAGE we have the advantage that
we can re-use the existing infrastructure for commands which includes:
- Retransmission in case of lost messages (instead of just a timeout).
- Better acks to signal if something is unsupported or deny it if the
  payload ID is invalid (again, instead of just a timeout).
@auturgy
Copy link
Collaborator

auturgy commented May 27, 2023

This is a pretty substantial pr: will likely take a little while to work through it.
@stephendade @Williangalvani

@bazfp
Copy link
Author

bazfp commented May 30, 2023

I'm happy to answer any questions about the implementation and the rationale behind this change

For a little bit more background:

UUVs tend to operate in very comms limited environments (no RF / limited acoustic comms). As with most robots they have an on-board "autopilot" or "front-seat" that controls low-level vehicle movement (Control Fins to set Heading, Control Motor to Set Speed etc). They also often run a generic Autonomy system on an additional "back-seat" computer, which accepts high-level commands and breaks them down for the front-seat vehicle to consume (Scan this point, Scan this area etc.)

Typically each vehicle manufacturer creates their own bespoke interface to allow external-control from an autonomy system, we are pushing to standardise this approach with an open standard.

We are using MAVLink now as our vehicle interface for this Autonomy <-> Frontseat link and have been working with vehicle manufacturers have MAVLink integrated as a "frontseat" control interface.

@hamishwillee
Copy link
Collaborator

hamishwillee commented Jun 1, 2023

Brief brain dump of some thoughts/concerns (not expecting any particular response at this time, just capturing first impressions). You may well have answered these already in the docs.

  • This is essentially a "protocol dialect" or "service dialect". I very much like the concept, but there is work for MAVLink team to make sure the role of this dialect and how it fits with "the standard" is clear.

  • This isn't just marine centric and really shouldn't have that name. Probably should split into payload, autonomy, sensors, the stuff around squads etc. In particular this is true if this is to go into common.xml at some point. But either way, if it doesn't apply as something all marine systems use, it should have some more specific name for vendor or more standard name for microservice functions.

  • Payload service:

    • Payload is an overloaded term.
    • The interworking and overloading of payload with component id is not clear to me. How are the IDs allocated? Does a payload have a component ID as well?
    • Is the intent just to convey status and health? Or is there more generic value to this framework? Where I'm getting here is consider a mavlink camera-gimbal. What does this give you over just having a gimbal and the gimbal info
    • Does every payload have a separate MAVLink identity? Can we have a payload that is not a mavlink item - e.g. is this just your way of showing status for everything, including non mavlink stuff in a common way?
    • The status is emitted on request. Should it be streamed?
    • Users that support component information would probably benefit from a parallel implementation that shares component data in a json file, with fallback to being able to request detail of dynamically added payloads using the MAVLink message APIs.
  • Autonomy service.

    • Not entirely clear how this interworks with existing autopilot modes.
    • Who demands what? I think you're saying that an autonomy system might set a mode such as offboard in which it has full control over the vehicle. It then does whatever control algorithm makes sense for the autonomy system (I'm going to call it companion computer). At any time the autopilot can say "no, I'm in control" and switch mode. But you expect it to send a demand for control at that point? Is that right?
      • I kind of think that the autopilot always has control and chooses to take it. A remote system should suck it up and monitor for these kinds of changes. It certainly shouldn't rely on a message in a constrained comms environment.
    • One example is a mission on a companion computer. How do the ground station, autopilot, and companion computer interact here? I.e. Where does QGC send the mission. Does the autopilot sync it, and so on?
    • @bkueng This is worth you looking at. There is some overlap with the way you are doing mode overloads on a companion computer with failsafe fallback.
  • Other stuff. The sensors and squad stuff is really outlying. NOt sure how it would be split up, but not really part of any kind of "standard" as is.

@hamishwillee
Copy link
Collaborator

As @auturgy says, this is a lot to digest.

I very much like the idea of standardization of component information on the network, including non-mavlink components.
However I am not sure how this interworks with various autopilot services and "normal mavlink". My first thoughts, in order were:

  • not another enum with ids and types for stuff like camera, etc
  • can/could this API simplify our existing APIs or future designs. Specifically, how might we have designed the recent gimbal API if this approach existed
  • How does this interwork with GCS for various use cases, such as missions

Generally we can take a dialect like this, but if this is to be in standard it would have to be split and probably go through RFC process, as per my comment above.

FYI @julianoes @bkueng @rmackay9

@bazfp
Copy link
Author

bazfp commented Jun 1, 2023

Thanks for your reply Hamish, really useful to get your views :)

Splitting of Autonomy + Payload + Sensor things sounds good to me. I would like the new services to be available to others for maximum compatibility. I am open to iteration to get them up to scratch. I never liked running as a separate MAVLink dialect and I aimed to keep features as generic as possible. Do you suggest I pull out the services into their own files?

So the concept of the payload service stems from us having the ability to turn on onboard power-intensive sensors/payloads that are not directly MAVLink aware, but the vehicle is. Examples include things like sidescan sonar, where you only want them enabled during segments of the mission. Payload ID is unique to payloads only. We also needed a way to configure payloads, which we achieved through a mapping between parameters naming and payload IDs (not included here, but effectively PayloadID 1 will have its params accessible via P001_SOMENAME). We also needed to be able to support the use case where the user can add and remove these payloads on the fly. We had a brief look at gimble control, but to be honest the naming confused manufacturers a lot and we couldn't identify a way to easily register and signal these kinds of payloads with MAVLink.

I like the idea of combining payloads with components. For our use case all the payloads were controlled internally by the vehicle. The payloads do not have the capacity to be MAVLink-aware themselves. We could have had the vehicle emulate a component for each payload (MAVSDK work here @julianoes?) as they were added or removed but i'm still unsure how controlling the payloads (on/off/arm) would have worked in this case. Perhaps this is something to look at. Our payloads are controlled entirely by the Autonomy at current, but we could embed them as the a mavlink mission item also.

Now some background to the Autonomy service, the Autonomy is unrated to AP modes. The AP is almost always in control of the actual vehicle via Auto/Mission. The Autonomy is monitoring the situation and packaging missions and sending them to the AP to execute and cancelling/re-issuing where appropriate. You can think of it as an autonomous GCS. The Autonomy has a higher level view of the objectives than an Autopilot. Imagine a mission with tens of surveys. This would be an unwieldy single MAVLink mission for the AP to run. The Autonomy is aware of the full-scale mission and is planning on the fly based on the vehicle situation. The MAVLink AP is receiving at most a "chunk" of the mission that is up-to-date with the vehicles current situation. As the vehicle completes the mission, the second one is issued from the Autonomy with the latest up to date information. Imagine while the AP completes a mission "chunk" some future surveys in the overall mission are now no longer needed, the autonomy is tracking this and can adjust the future mission "chunks" as they are issued. It can also add in new chunks and respond to information recovered during the survey.

The Autonomy demands are control messages to the Autonomy system only. They can come from a ground control system to start/stop the Autonomy. They can come from an AP if the AP has a reason to demand start/stop the Autonomy system (fault? Mission from elsewhere?). If the AP accepts a mission from QGC, it should probably stop the Autonomy (if it is running!) as it's unrelated to the Autonomy mission. Alternatively as you say, the AP should just ignore any requests if Autonomy is in control, until it gets stopped or booted out. It's worth detailing these scenarios.

@hamishwillee
Copy link
Collaborator

Thanks @bazfp - I'm on other tasks until Wednesday so I can't give this the attention it deserves until then. But yes, I think that this would be better split into 2 or three files with a protocol-specific name (might or might not eventually end up inside common.xml, or linked from it). This is mostly so that they can be digested and accepted or rejected in parts. It is such a lot to take in otherwise.

I have added this to discussion in the dev call next week. Given how much there is, I expect that will be just a broad chat about our top level thinking. I am personally very interested in this but want to understand the problems that it solves/doesn't solve better.

@hamishwillee
Copy link
Collaborator

Payload stuff:

  • we already have "payload services" here https://mavlink.io/en/services/payload.html so we need to think how this works with that.
  • The normal MAVLink way to this would be to create a MAVLink identity for each component you want to control. This has a command for doing stuff and a message for notifying on status.
    • For example, consider the winch, which has MAV_CMD_DO_WINCH and WINCH_STATUS
    • The "thing" does not need a specific mavlink identity - it can be accessed through the autopilot or a companion.
    • This is "generally better" than a generic "command something with ID", "Get status from ID", because all components are different.
      • A mission become becomes opaque - you can't interpret it without a custom UI that knows your payloads.
      • Missions are hard to write - consider a winch - it isn't instant, and you have no real feedback. So you need to think a lot to make it work properly and you can't make it easy to be generic (FYI PX4 just added new code to allow a gripper to be used a mission sensibly)
      • Generally UIs are hard - "do actuator" in the UI could mean anything - winch, payload, sidescan sonar, or whatever.
  • We do have generic things like MAV_CMD_DO_SET_ACTUATOR because getting stuff into MAVLink can be slow, and this allows people to do something manually. So perhaps there is a place for this.
  • It is useful to understand this is primarily for non-mavlink components.
  • MAVLink does not support the concept of named and reserved parameters.
    • Parameters are explicitly flight stack specific except for the these in the camera definition - that was required to allow UIs to choose the location of specific elements.
    • That is not set in stone.
    • In addition to ideology and having to manage these, we are a bit worried about param proliferation, and there are technical reasons why this approach sucks
      • cases where the data is naturally nested
      • cases where multiple parameter need to be changed together/atomically.
  • Autopilots have trouble emitting multiple component ids/identities (an architectural limitation) but you might have a component for sonar (say) on a companion. You don't need it though as long as you can discover what is available - once you have an ID you can address a command and that command can have an index for "multiples" - as per my point on the winch API.
  • Adding extra component mappings for non mavlink things does add extra traffic, and needs systems to be able to properly forward stuff.

Another tool that might be useful for this is currently only available on PX4 - component metadata. The component metadata concept allows you to define deeply nested structures mapping to parameters, and has been used to define UIs. See the PX4 actuators setup - and the same concept came first in the camera definition file.
This could allow you to document your generic payload in such a way that a GCS could interpret it.

Anyway, may take on this is that dedicated APIs mediated through companion or autopilot are generally more flexible.

@hamishwillee
Copy link
Collaborator

Re Autonomy - I get it. The model is pretty much

  • use the AP to do basic stabilization, manual control, and safety failsafe
  • implement all higher level control and advanced features on a companion computer.

Just to be aware of, a flight stack always has to be able to seize control, and you can't guarantee that it will send a "taking control" message, or that the companion will get it. Normally the companion detects this by monitoring mode - i.e. if control is via a dynamically updating mission, then it will monitor the mission mode and detect it has lost control by the mode changing.
If control is via offboard/guided mode setpoints then it will monitor for change out off offboard mode.

The last case to consider is control from a companion in another mode. The example I know of here is that PX in a mission can enable obstacle avoidance. The mode is mission and the AP emits a desired trajectory. The companion responds by mirroring the trajectory or providing an avoidance path. The AP will just use its own path if no points come back.
The approach needs to work with this kind of model too.

@hamishwillee
Copy link
Collaborator

@bazfp We discussed briefly in the dev call https://github.com/mavlink/mavlink/wiki/20230607-Dev-Meeting. Would love to discuss next steps in the dev call in two weeks.

Wr.t.. handover of control, we discussed in the dev call. A vehicle can always take control of itself and should already emit values to indicate this in the heartbeat state - e.g. https://mavlink.io/en/messages/common.html#MAV_STATE_CRITICAL,
https://mavlink.io/en/messages/common.html#MAV_STATE_EMERGENCY and the flight termination case. A companion should monitor for that.

@hamishwillee
Copy link
Collaborator

@bazfp Are you up for coming along to the MAVLink call in two weeks to discuss? Julian says he tried to skype you to no avail.

FYI We talked about it in last nights call briefly. Some comments were similar

  • needs to be split into separate PRs for easier digestion
  • needs better name for the protocols than "marine.xml".
  • If name is changed can be merged as just a dialect but MAVLink team need to somehow make it more clear that it is a dialect. That's on us to work out how.

New questions

  • Who allocated you the 44xxx range? WHat range was allocated? This needs to be added to https://github.com/mavlink/mavlink/blob/master/message_definitions/v1.0/all.xml
  • There was a general comment that this PR looks great, with lots of effort clearly put in
  • MAVLink team needs to think about this from the Autonomy centric world you come from, where the flight stack is not the center of the universe, and make sure that either it works for both, or the separation is clear. There are other perspectives such as the "one holistic vehicle" viewpoint, where all messages go to a vehicle, and it manages internal routing etc.

@bazfp
Copy link
Author

bazfp commented Jun 22, 2023

Thanks Hamish, appreciate these discussions and feedback. I was on leave last week so not available.

We're keen to join the next discussion and discuss in detail the next actions.

We allocated the range based on usage, happy to change if needed.

  • There was a general comment that this PR looks great, with lots of effort clearly put in

Great to here :) we tried to maintain genericness as much as we could.

  • MAVLink team needs to think about this from the Autonomy centric world you come from, where the flight stack is not the center of the universe, and make sure that either it works for both, or the separation is clear. There are other perspectives such as the "one holistic vehicle" viewpoint, where all messages go to a vehicle, and it manages internal routing etc.

Yes this autonomy control is a new paradigm for MAVLINK, for UUVs this frontseat <-> backseat control has been used for a long time. I am keen to make sure we slot this in nicely.

I will look to split up this PR in the next two weeks

@MatthewMcGill-Ocius
Copy link

A couple of questions. Separated into the separate services.

Payload Service

NB: This assumes your system is running some form of MAVLINK router allowing multiple streams to be combined/split.
To register with the Autopilot the payload needs to send a MAVLINK message which requires it to be on the MAVLINK network, in which case can it just send the PAYLOAD_STATUS message itself regularly as a heartbeat rather than using the Autopilot as an intermediary. If using the of the vehicle and a system unique COMPID it can then receive targeted commands directly.
Targeting the PAYLOAD_REQUEST_LIST to (SYSID:X,COMPID:0) could then be sent to all components with NACKS from any non-payloads.
Is there any specific requirement for registering the payloads in the autopilot? (ie. for referencing via LUA scripts)

Autonomy Service

NB: Similar to the Payload service I'm not sure using the autopilot as an intermediary for status updates is necessary as the Autonomy component will need to be on the MAVLINK network anyway.
Would this service allow registering of more generic Autonomy components? (ie AUTONOMY_COMPONENT_PATH_PLANNING, AUTONOMY_COMPONENT_GEOFENCING)

@hamishwillee
Copy link
Collaborator

@bazfp Mav call this evening.

Who allocated you the 44xxx range? WHat range was allocated? This needs to be added to https://github.com/mavlink/mavlink/blob/master/message_definitions/v1.0/all.xml

We allocated the range based on usage, happy to change if needed.

Let's discuss. I'd prefer to restrict the range - probably to 100 ids in first place at 52100 - 52199

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.

None yet

5 participants