Skip to content
Onboard ROS 2 Interfaces

Onboard ROS 2 Interfaces

Andi Lamprecht Andi Lamprecht ·· 8 min read· Accepted
ADR-0121 · Author: Sybil Melton · Date: 2025-02-07 · Products: uncrew
Originally ADR-0107-OnBoard-ROS-2-Interfaces (v3) · Source on Confluence ↗

OnBoard ROS 2 Interfaces

Context

This ADR proposes the 2nd iteration and additional level of detail for the Uncrew onboard “right-sized”-service architecture to break apart the Mavlink Shim.

This ADR will also propose a path forward for integrating these services into the existing architecture.

Decision

We have decided to use ROS 2 and implement onboard services as nodes in the ROS 2 Graph.

To do so, we must define the necessary ROS 2 interfaces.

Specifically:

  • The ROS 2 Nodes (i.e. microservices) necessary, and their responsibilities
  • The ROS 2 Topics (pubsub topics)
  • The ROS 2 Services (remote procedure calls) available to nodes
  • The ROS 2 Actions (long-running remote procedure calls) available to nodes
  • The ROS 2 Messages (data which is used to define Topics, Services, and Actions)

These will be listed in this document for convenience, but the actual definitions can be found in the common-cpp-ros2-pkg repo.

ROS 2 Nodes

Nodes represent a unit of computation in the ROS graph.
Here we will define each node, its responsibilities, and the interfaces it uses.

Inventory Client Node

cb0763d7d2b5199e9544152405e30c6f-inventory_client_node.png

  • Connects via gRPC to the Inventory Service in the cloud;

  • Calls RegisterNewUav to obtain UAV’s personal mTLS certificate needed to connect to the UAV’s Avatar and writes them to disk;

  • Periodically calls CheckIn in order to:

    • Verify the cached mTLS certificate hasn’t been revoked and if found revoked, stops calling CheckIn and goes to back to (2);
    • Obtain new/rotated personal mTLS certificates
  • Publishes certificates to AvatarCertificate Topic

  • Publishes configuration to the Configuration Topic

Avatar Client Node

5da33eb916c9077753714e6ae420badb-avatar_client_node.png

  • Subscribes to AvatarCertificate Topic
  • Connects via gRPC to the Avatar Service in the cloud
  • Subscribes to ThrottledTelemetry/* Topics and forwards telemetry messages to Avatar Service
  • Subscribes to Alerts Topic and forwards Alerts to Avatar Service
  • Subscribes to Operator Requests Topic and forwards messages to Avatar Service
  • Forwards C2 Action requests from Avatar Service to Uncrew Flight Controller

Monitoring Service Node

5c5e81c4ffcd57a4999b35fb65c3c69a-monitoring_service_node.png

  • Subscribes to the RawTelemetry/* Topics
  • Publishes ThrottledTelemetry/* Topics
  • Analyzes raw telemetry for alerting things and generates Alerts publishing them to the Alerts Topic.

Uncrew Flight Controller Node

616b29aafe89561d385da58bbc553e3b-uncrew_flight_controller_node.png

  • Publishes operator requests to the OperatorActionRequests Topic
  • Subscribes to the OperatorActionRequestsAcknowledgements Topic
  • Subscribes to the Alerts Topic
  • Subscribes to the RawTelemetry/* Topics
  • Calls Pathfinding Service
  • Implements RequestAction Service to proxy C2 Actions
  • Maps from Uncrew Mission to PX4 Mission, and later implements Uncrew Mission Flight Mode
  • Assigns PX4 Missions
  • Validates Missions
  • Crouch
  • Smart RTL

Mavlink Shim Node

02c42ba54df2d6b8b8973d2840bf370e-mavlink_shim_node.png

  • Translates mavlink messages into ROS messages
  • Publishes to the RawTelemetry/* Topics
  • Implements C2 Action Service Servers
  • For some time until we learn how to write Uncrew Flight Mode, exposes PX4 mission mode
  • Remains very simple and only does the mapping

ROS 2 Topics

Topics serve as a one-way communication pipe, and allow any number of nodes to subscribe to any number of topics.

Some topics will be “latched”, allowing late subscribers to receive the most recently published message.
These topics will be marked with “[Latched]” in the list below.
For more on how this is achieved please see the QoS settings in the docs.

Note that all topics generated by our services will be prefixed with /du/uncrew/.

TopicMessage TypeIsLatched?
/du/uncrew/AlertsAlertsYes
/du/uncrew/AvatarConnectionStatusAvatarConnectionStatusYes
/du/uncrew/CertificateCertificateYes
/du/uncrew/ConfigurationConfigurationYes
/du/uncrew/OperatorActionRequestsOperatorActionRequestsYes
/du/uncrew/RawTelemetry/AltitudeTelemetryAltitudeNo
/du/uncrew/RawTelemetry/ArmedTelemetryArmedNo
/du/uncrew/RawTelemetry/BatteryTelemetryBatteryNo
/du/uncrew/RawTelemetry/CameraModeTelemetryCameraModeNo
/du/uncrew/RawTelemetry/ConnectionEventTelemetryConnectionEventNo
/du/uncrew/RawTelemetry/CurrentMissionItemTelemetryCurrentMissionItemNo
/du/uncrew/RawTelemetry/DistanceSensorTelemetryDistanceSensorNo
/du/uncrew/RawTelemetry/ErrorTelemetryErrorNo
/du/uncrew/RawTelemetry/FlightModeTelemetryFlightModeNo
/du/uncrew/RawTelemetry/GPSInfoTelemetryGPSInfoNo
/du/uncrew/RawTelemetry/GimbalControlStatusTelemetryGimbalControlStatusNo
/du/uncrew/RawTelemetry/HeadingTelemetryHeadingNo
/du/uncrew/RawTelemetry/HealthTelemetryHealthNo
/du/uncrew/RawTelemetry/ImuTelemetryImuNo
/du/uncrew/RawTelemetry/OdometryTelemetryOdometryNo
/du/uncrew/RawTelemetry/PoseEulerTelemetryPoseEulerNo
/du/uncrew/RawTelemetry/PositionTelemetryPositionNo
/du/uncrew/RawTelemetry/StatusTextTelemetryStatusTextNo
/du/uncrew/RawTelemetry/UncrewFlightModeTelemetryUncrewFlightModeNo
/du/uncrew/RawTelemetry/VelocityNedTelemetryVelocityNedNo
/du/uncrew/RawTelemetry/VideoStreamSettingsTelemetryVideoStreamSettingsNo
/du/uncrew/RawTelemetry/WinchReelStatusTelemetryWinchReelStatusNo
/du/uncrew/RawTelemetry/WinchStatusTelemetryWinchStatusNo
/du/uncrew/ThrottledTelemetry/AltitudeTelemetryAltitudeNo
/du/uncrew/ThrottledTelemetry/ArmedTelemetryArmedNo
/du/uncrew/ThrottledTelemetry/BatteryTelemetryBatteryNo
/du/uncrew/ThrottledTelemetry/CameraModeTelemetryCameraModeNo
/du/uncrew/ThrottledTelemetry/ConnectionEventTelemetryConnectionEventNo
/du/uncrew/ThrottledTelemetry/CurrentMissionItemTelemetryCurrentMissionItemNo
/du/uncrew/ThrottledTelemetry/DistanceSensorTelemetryDistanceSensorNo
/du/uncrew/ThrottledTelemetry/ErrorTelemetryErrorNo
/du/uncrew/ThrottledTelemetry/FlightModeTelemetryFlightModeNo
/du/uncrew/ThrottledTelemetry/GPSInfoTelemetryGPSInfoNo
/du/uncrew/ThrottledTelemetry/GimbalControlStatusTelemetryGimbalControlStatusNo
/du/uncrew/ThrottledTelemetry/HeadingTelemetryHeadingNo
/du/uncrew/ThrottledTelemetry/HealthTelemetryHealthNo
/du/uncrew/ThrottledTelemetry/ImuTelemetryImuNo
/du/uncrew/ThrottledTelemetry/OdometryTelemetryOdometryNo
/du/uncrew/ThrottledTelemetry/PoseEulerTelemetryPoseEulerNo
/du/uncrew/ThrottledTelemetry/PositionTelemetryPositionNo
/du/uncrew/ThrottledTelemetry/StatusTextTelemetryStatusTextNo
/du/uncrew/ThrottledTelemetry/UncrewFlightModeTelemetryUncrewFlightModeNo
/du/uncrew/ThrottledTelemetry/VelocityNedTelemetryVelocityNedNo
/du/uncrew/ThrottledTelemetry/VideoStreamSettingsTelemetryVideoStreamSettingsNo
/du/uncrew/ThrottledTelemetry/WinchReelStatusTelemetryWinchReelStatusNo
/du/uncrew/ThrottledTelemetry/WinchStatusTelemetryWinchStatusNo

ROS 2 Services

Services represent remote procedure calls.

  • RequestAction

ROS 2 Actions

Actions represent long-running remote procedure calls.

  • Arm
  • AssignMission
  • ConfirmDeliveryComplete
  • ConfirmDeliveryReady
  • Crouch
  • DropOff
  • Hold
  • Land
  • Loiter
  • ReturnToLaunch
  • StartMission
  • Takeoff
  • Waypoint
  • Winch

ROS 2 Messages

Data formats which define Actions, Services, and Topics.

  • Alert
  • AlertBattery
  • AlertBatteryPercentage
  • AlertFlightTermination
  • AlertReaction
  • AlertReactionNone
  • AlertReactionRTL
  • Alerts
  • AvatarConnectionStatus
  • C2Arm
  • C2AssignMission
  • C2ConfirmDeliveryComplete
  • C2ConfirmDeliveryReady
  • C2Crouch
  • C2DropOff
  • C2Hold
  • C2Land
  • C2Loiter
  • C2ReturnToLaunch
  • C2StartMission
  • C2Takeoff
  • C2Waypoint
  • C2Winch
  • Certificate
  • Configuration
  • Metadata
  • MissionItem
  • MissionPlan
  • OperatorActionRequest
  • OperatorActionRequestConfirmDeliveryComplete
  • OperatorActionRequestConfirmDeliveryReady
  • OperatorActionRequests
  • ProcedureStatus
  • TelemetryAltitude
  • TelemetryArmed
  • TelemetryBattery
  • TelemetryCameraMode
  • TelemetryConnectionEvent
  • TelemetryCurrentMissionItem
  • TelemetryDistanceSensor
  • TelemetryError
  • TelemetryFlightMode
  • TelemetryGPSInfo
  • TelemetryGimbalControlStatus
  • TelemetryHeading
  • TelemetryHealth
  • TelemetryImu
  • TelemetryOdometry
  • TelemetryPoseEuler
  • TelemetryPosition
  • TelemetryStatusText
  • TelemetryUncrewFlightMode
  • TelemetryVelocityNed
  • TelemetryVideoStreamSettings
  • TelemetryWinchReelStatus
  • TelemetryWinchStatus
  • TypeAltitude
  • UAVCommandDropOff
  • UAVCommandLand
  • UAVCommandLoiter
  • UAVCommandTakeoff
  • UAVCommandWaypoint
  • WinchAbandonLine
  • WinchDeliver
  • WinchHold
  • WinchLoadLine
  • WinchLoadPayload
  • WinchLock
  • WinchRateControl
  • WinchRelativeLengthControl
  • WinchRelax
  • WinchRetract

Data Flows

UAV Registration / mTLS Certificate

  1. The Inventory Client Node uses the factory certificate on disk to establish a secure gRPC connection with the Inventory Server’s UavService.
  2. The Inventory Client Node calls RegisterNewUav, which returns a new certificate.
  3. The Inventory Client Node uses the new certificate to publish a Certificate Message to the du/uncrew/Certificate Topic.
  4. The Avatar Client Node is subscribed to the du/uncrew/Certificate Topic, and so it receives the Certificate Message.
  5. The Avatar Client Node uses the received certificate to establish a secure gRPC connection with the Avatar Server.

Telemetry

We will explore the flow for telemetry in the system through an example using the Battery telemetry.

Note that this should be the same for the other telemetry types.

  1. Battery telemetry is generated by PX4.
  2. The Mavlink Shim Node receives the PX4 Battery.
  3. The Mavlink Shim Node uses the received telemetry to publish a TelemetryBattery Message to the du/uncrew/RawTelemetry/Battery Topic.
  4. The Monitoring Service Node is subscribed to the du/uncrew/RawTelemetry/Battery Topic, and so it receives the TelemetryBattery Message.
  5. Every one second, the Monitoring Service Node publishes the most recent TelemetryBattery Message to the du/uncrew/ThrottledTelemetry/Battery Topic.
  6. The Avatar Client Node is subscribed to the du/uncrew/ThrottledTelemetry/Battery Topic, and so it receives the TelemetryBattery Message.
  7. The Avatar Client Node uses the received telemetry to call the PublishBattery RPC on the Avatar Server.

C2 Commands

We will explore the flow for C2 commands in the system through an example using the Arm C2 command.

Note that this should be the same for the other C2 commands except for Crouch.

  1. The Avatar Client Node receives a SubscribeUAVCommandsResponse Message from the Avatar Server’s SubscribeUAVCommands RPC, containing a C2 command to execute.
  2. The Avatar Client Node uses the received UAVCommand to call the RequestAction Service.
  3. The Uncrew Flight Controller Node receives the call to RequestAction, and calls the Arm Action.
  4. The Mavlink Shim Node receives the Arm Action Request and responds when it is finished.
  5. The Uncrew Flight Controller Node returns the result of the Arm Action Response to as a RequestAction Response.
  6. The Avatar Client Node uses the RequestAction Response to call the Avatar Server’s PublishUAVCommandResult RPC.

Note: for Crouch the Crouch Action Response is sent when the action is started, NOT when it is completed.

If errors occur during the execution, the Mavlink Shim Node publishes Error Messages to the du/uncrew/RawTelemetry/Errors Topic.

Operator Action Request

We will explore the flow for Operator Action Requests in the system through an example using the ConfirmDeliveryReady Operator Action Request.

Note that this should be the same for the other Operator Action Requests.

  1. The Uncrew Flight Controller Node determines that operator input is required, and publishes an OperatorActionRequest message to the /du/uncrew/OperatorActionRequests Topic.
  2. The Avatar Client Node is subscribed to the /du/uncrew/OperatorActionRequests Topic, and so it receives the OperatorActionRequest Message.
  3. The Avatar Client Node uses the received operator action request to call the PublishOperatorActionRequests RPC on the Avatar Server.

Alerts

We will explore the flow for Alerts in the system through an example using the AlertBatteryPercentage Alert.

Note that this should be similar for other Alerts.

Also note that this example will assume that the Telemetry Data Flow is currently active (i.e. telemetry is being sent throughout the system).

  1. The Monitoring Service Node is subscribed to the du/uncrew/RawTelemetry/Battery Topic, and so it receives the TelemetryBattery Message.
  2. The Monitoring Service Node analyzes the content of the TelemetryBattery Message.
  3. If the remaining battery percentage is below the configured threshold, the Monitoring Service Node publishes an Alerts Message, containing all active alerts, to the /du/uncrew/Alerts Topic.
  4. The Avatar Client Node is subscribed to the /du/uncrew/Alerts Topic, and so it receives the Alerts Message.
  5. The Avatar Client Node uses the received Alerts Message to call the Avatar Server’s PublishAlert RPC.

Consequences

As a consequence of this decision, there will be some amount of duplicated work.

Several of the services will encompass responsibilities which currently belong to the Mavlink Shim.

Since our intention is to create ROS 2 Nodes in Python first, we will have to reimplement many features.

However, we still feel it will save us time in the long run due to our improved ability to iterate and test compared to the existing monolithic architecture.

Alternatives Considered

Not Splitting the Mavlink Shim Yet

We have also considered not splitting apart the Mavlink Shim yet, and instead continuing to add features.

Then later, split apart the Shim when deadlines aren’t so tight.

We fear this would cause increasing larger delays in development and debugging, and that we will continue to “kick the can” in perpetuity.

A Hard Cut to New Architecture

We have also considered writing the entire onboard ROS 2 ecosystem first, and then cutting over from the existing Mavlink Shim to this new architecture all at once.

This was determined to be too expensive, as we would be bombarded with all bugs and defects at once.

Instead, we will iterate on the deployed architecture slowly and fix issues as they arise.

Last updated on