Skip to content

Proposal: ROS client API & middleware strategy — standardise on CycloneDDS, retire micro-ROS/XRCE, time-box a nano-ros evaluation #25

Closed

Description

@youtalk

TL;DR

Three efforts are exploring how the safety island should expose a ROS client API and talk to ROS 2:

This issue proposes a direction and asks for feedback.

Proposed direction:

  1. Standardise the wire layer on CycloneDDS (peer RTPS, agent-free).
  2. Retire micro-ROS / XRCE-DDS (feat(freertos): scaffold POSIX simulator with FreeRTOS-Kernel submodule #16–feat(shim): add upstream-ism stubs and document FreeRTOS POSIX target #20) as a primary direction.
  3. Evaluate nano-ros (nros-cpp + CycloneDDS backend) as the long-term standard ROS client API through a time-boxed (4–6 week) go/no-go evaluation, with hardening the in-house C++ facade as the fallback.

Feedback wanted from the Reference Design WG, the safety-island maintainers, and NTU NEWSLab.

Background — current state

  • Shipping firmware: Zephyr + CycloneDDS, with no ROS 2 runtime on the island.
  • The ROS-like surface is a hand-maintained ~290-line C++ facade (actuation_module/include/common/node/node.hpp) directly over CycloneDDS. The common/ layer isolates the RTOS/middleware behind four headers (node / dds / clock / logger), so the backend is swappable.
  • Interop with stock ROS 2 is native RTPS (an optional ros2 domain_bridge is used for domain isolation; there is no protocol-translating agent).

The three in-flight efforts

(A) in-house facade + HW (B) micro-ROS (#16–#20) (C) nano-ros (NTU)
ROS API hand-rolled node.hpp hand-written rclcpp facade over rcl/rclc nros-cpp (Rust no_std)
Middleware CycloneDDS XRCE-DDS (host Agent required) zenoh / xrce / CycloneDDS (selectable)
ROS 2 interop native RTPS, agent-free via Agent CycloneDDS backend = agent-free
Real HW S32Z2/R52 round-trip done (#21–#24) POSIX simulator only S32Z270-R52 board crate exists (Zephyr, skeleton)
Backing AWF mature ROS community NTU NEWSLab (v0.4.0, ~single maintainer)

Key findings

  1. "Unmodified rclcpp on an MCU" is not actually delivered by any option. The micro-ROS effort became a hand-written rclcpp facade with the target controller (autoware_universe_utils / autoware_mpc_lateral_controller) still not compiling; nano-ros offers its own rclcpp-flavoured nros-cpp. So the real question is which facade to standardise on for long-term maintainability, not "which one gives real rclcpp."
  2. All three converge on CycloneDDS as the agent-free wire layer (it is also nano-ros's recommended backend). The wire-layer decision and the client-API decision are therefore separable.
  3. nano-ros source profile (verified from source):
    • Rust no_std; no async runtime pulled in. Selectable RMW with a native CycloneDDS (agent-free RTPS) backend.
    • A FreeRTOS + lwIP platform layer exists, and a dedicated S32Z270 Cortex-R52 board crate — but it is Zephyr-based and at skeleton / build-smoke maturity.
    • The FreeRTOS + lwIP + CycloneDDS + S32Z2 combination is wired in the build but not validated end-to-end upstream; lwIP UDP multicast is stubbed (DDS SPDP discovery needs static / unicast peers).
    • Single-maintainer, pre-1.0 (v0.4.0, no release tags). Credible certification groundwork (Kani proofs, an ISO 26262 Part 8 tool-confidence analysis, a documented Ferrocene-for-ASIL path). License MIT OR Apache-2.0.

Options considered

  • O1 — Harden the in-house C++ facade. Lowest risk, but doubles down on a self-maintained API (against the maintainability goal).
  • O2 — Continue micro-ROS / XRCE-DDS. Rejected: the mandatory host Agent is an interop regression versus today; the rclcpp-reuse premise is unmet; validation is POSIX-simulator only.
  • O3 — Commit to nano-ros now. Best architectural fit, but bets the island on a single-maintainer pre-1.0 upstream, an unvalidated integration, and a new Rust toolchain — hard to reconcile with the demo deadline.
  • O4 — Layered, evidence-based (proposed below).

Proposed direction (O4)

Evaluation plan

Go / No-Go criteria (all hard gates)

  1. Agent-free interop: reproduce the feat(freertos-s32z2): DDS round-trip controller and edge-ECU peer #24 round-trip via nros-cpp — the island publishes control_cmd (echoed by a stock ROS 2 / CycloneDDS host) and receives all five inputs — with no agent or protocol bridge.
  2. Footprint: flash and RAM within the S32Z2 budget; the CycloneDDS participant heap (~96 KiB+) fits the 7 MiB int_sram; the delta versus the in-house facade is acceptable.
  3. Maintainability win: porting the Controller node + the autoware_msgs 1.3.0 types (via cargo nano-ros generate) is mechanical and net-reduces ASI-maintained lines of code.
  4. Build / toolchain: the Rust target (armv7r-none-eabihf) + cargo integrate into build.sh / CMake and the dev container / CI without breaking the existing C++ / Zephyr / FreeRTOS builds.
  5. C++ boundary: nros-cpp ergonomics are acceptable for the retained C++ application / safety logic.
  6. Certification trajectory: a credible, documented path to ASIL via Ferrocene with no architectural blocker; the Kani harness is real and runs.
  7. Upstream / collaboration: NTU responsiveness is verified and there is willingness to co-own the FreeRTOS / CycloneDDS / S32Z2 fixes upstream; a fork-and-pin strategy is accepted as bus-factor mitigation.

Risks

Questions for discussion

  1. Agreement on CycloneDDS as the standard wire layer and on retiring micro-ROS / XRCE-DDS?
  2. Is a time-boxed nano-ros evaluation the right next step, or should we commit to / decline it now?
  3. Are the go/no-go criteria the right bar? Anything missing (e.g., real-time / WCET, security)?
  4. NTU: appetite to co-own the FreeRTOS / CycloneDDS / S32Z2 bring-up and upstream the fixes?
  5. Phase B RTOS preference (FreeRTOS vs Zephyr)?

References

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions