ZeroDDS: a pure-Rust RMW for ROS 2 (rc.3), built against 349 real ROS↔DDS pain reports

Full disclosure up front: I work on ZeroDDS, so this is our project, not a neutral review. Sharing it here because it’s specifically aimed at problems this community has been reporting for years, and we’d genuinely like the feedback.

What it is: an alternative RMW for ROS 2, with the whole DDS stack underneath written from scratch in Rust (memory-safe, Apache-2.0, no per-seat license). It speaks native RTPS 2.5 and interoperates with your existing setup: ROS 2 over `rmw_zerodds` talks to ROS 2 over `rmw_cyclonedds` bidirectionally (20/20 in our pub/sub + service tests). It’s a drop-in `RMW_IMPLEMENTATION`, not a fork of your graph.

We didn’t guess at the pain, we catalogued it. Before writing “ROS 2 support” anywhere, we collected 349 real-world ROS↔DDS pain reports from this forum, GitHub and elsewhere, and engineered against the recurring ones:

  • Silent QoS / type mismatches — the classic where two endpoints just never match and nothing is logged. Fixed the keyed/no-key entity-id case, and shipped `zerodds-ros2-shim doctor`, a discovery-independent check that flags the most common WiFi misconfig (multicast-free with no unicast peers) as a hard error instead of a silent no-match.

  • WiFi discovery loss — a single SPDP beacon dropped during 802.11 power-save leaves you at `participants=0`. We send an initial-announcement burst (10×200 ms until matched), like FastDDS’ `initial_announcements`. Verified on a real WiFi rig, not just loopback.

  • Large fleets / WAN — a `multi_robot()` profile: unicast-only discovery, no multicast storm.

  • DDS-Security / SROS2. ZeroDDS consumes SROS2 enclave files (identity/permissions CA, cert, key, governance, permissions) and fails hard on a broken config (no silent downgrade). Caveat for ROS-users: today you point it at the enclave via a ZERODDS_SECURITY_DIR env var, not the standard ROS_SECURITY_KEYSTORE / ROS_SECURITY_ENABLE variables yet. Wiring those up so ros2 security works unmodified is still open.

  • Introspection — `ros2 topic info -v` resolves endpoint GUIDs to node names.

Works with rclpy and rclcpp.

New in rc.3: zero-copy shared memory now works on Windows too (via `CreateFileMapping` + `LockFileEx`), tested on a real Windows runner.

Next (rc.4): a continuous multi-distro live `ros2` smoke as a CI gate across Humble, Iron and Jazzy, so interop is proven on every commit rather than by hand. The `rmw_zerodds` surface itself is code-complete (pub/sub, services, wait-sets, loaned messages, REP-2009 type hash + endpoint info; nothing left `UNSUPPORTED`).

Honest about maturity: it’s a release candidate, not years-hardened. On performance we’re on par with the established stacks across real workloads, not uniformly ahead, and we don’t claim to beat RT-tuned commercial configs. An OMG Vendor-ID is filed but not yet assigned. We are not safety-certified.

Try it:

If you hit a mismatch with your Cyclone/Fast-DDS nodes, or a QoS combination that doesn’t behave, that’s exactly the feedback we want. Tell us where it breaks.

(For the DDS/non-ROS folks who wander in: the same codebase also covers XTypes, DDS-Security, RPC, bridges, seven language bindings, and a full CORBA 3.3 ORB. Happy to go into any of it, but I’ll keep this post ROS-focused.)

8 Likes

ZeroDDS 1.0.0-rc.6 is out, and this one goes where Rust doesn’t.

The easy part of “DDS everywhere” was always the modern Linux box. The hard part is the endpoint that will never get a Rust toolchain: a big-endian controller older than the language, a node too constrained for a modern compiler, a platform frozen on a decade-old stack. rc.6 puts the ZeroDDS wire on those, without a Rust runtime underneath.

Native endpoint SDKs (ADR 0013): conservative, no-Rust DDS-XRCE endpoints in C89, C++98, pure Python and Java 8. The same wire the Rust core speaks. Every encoder is checked byte-for-byte against the core on little-endian x86-64 and big-endian PowerPC, live over UDP against a real agent. Big-endian is a first-class case, not a patch. There is exactly one integration point, a frame-hook where you drop in whatever transport your platform actually has, a socket, a serial line, a bus. Bring the wire, keep your board.

Two things I said were next in rc.5 landed:

  • SpatialDDS 1.6 profile: every published module run through ZeroDDS’ own IDL→Rust codegen, plus a SpatialDDS to ROS 2 semantic map.
  • DDS-CVE threat matrix: the memory-corruption and XML classes, structural immunity where it exists, honest residuals where it doesn’t, with an opt-in fail-closed multicast-locator allowlist.

Also new in rc.6:

  • PostgreSQL / TimescaleDB durability tier, with source-identity dedup. A late service back-fills a writer’s history, and a restart no longer duplicates it.
  • Routing service, hardened: source-timestamp preservation, per-route throttling, tenant-scoped ACLs, router-to-router chaining.
  • Native endpoints ship both backends, wire-fixed codegen for known types and wire-variable reflective for evolving or unknown ones, plus XRCE and serial (HDLC) framing.

Everything from rc.5 still holds: full 7-language wire parity (C, C++, C#, Java, Python, TypeScript, Rust), the reflective type system (maps, arbitrary nesting, TypeObjects), ten protocol bridges, swappable FIPS crypto backends (ring, aws-lc-rs, wolfCrypt), a wire-validated CORBA 3.3 ORB, cross-vendor conformance, native RTPS 2.5. 125 crates on crates.io, one workspace, Apache-2.0, no vendor lock-in.

Next: on-target runs of the embedded/XRCE story on real boards (Pi, STM32, Nordic BLE, LoRaWAN, ESP, already in the lab), per-board latency baselines, and the smallest-node footprint.

Still waiting on the OMG Vendor-ID: filed, not yet assigned. Not safety-certified, talk to me if certification interests you.

If you’re evaluating DDS in C, C++, C#, Java, Python, TypeScript or Rust, or you have a platform everyone told you was too old or too odd to reach, run rc.6 and tell me where it breaks. The best parts of the last release came from exactly that, and I want more of it.

Release → Release v1.0.0-rc.6 · zero-objects/zero-dds · GitHub
Changelog → zero-dds/CHANGELOG.md at main · zero-objects/zero-dds · GitHub
Docs + spec-coverage → https://zerodds.org

dds rust ros2 #RTPS #CORBA #OpenSource robotics #Middleware embedded

1 Like