Running ROS 2 on DDS? ZeroDDS fixes the reasons people leave DDS — without leaving the wire.
ROS 2 runs on DDS, and DDS's default behaviour floods networks, breaks on WiFi, fails silently on QoS mismatches and drops large messages. ZeroDDS is a from-scratch, pure-Rust DDS that removes those structural causes but stays on native RTPS 2.5 — interoperable with Fast DDS, Cyclone DDS, OpenDDS and Connext. It speaks the ROS 2 middleware ABI as a drop-in rmw_zerodds, not a fork of ROS.
Grounded in a field scan of 349 real reports · Apache 2.0 · one workspace
why?
Why ZeroDDS for ROS 2
Removes the structural causes of the DDS pain — and stays on the RTPS wire, so you keep interop.
- Native RTPS 2.5 — no fork of ROS
- Pure-Rust, MCU to server
- Apache 2.0, fully audited
how to switch?
Drop-in rmw_zerodds
Set one environment variable. No ROS fork, no node changes — your graph runs as-is.
RMW_IMPLEMENTATION=rmw_zerodds- REP-2003 … 2009 conformant
- Live 20/20 interop with rmw_cyclonedds
which pains?
The structural fixes
The DDS failures that cost lab afternoons — addressed at the root, not patched with XML.
- Discovery without multicast (WiFi/Docker)
- Loud QoS failures, not silent no-match
- Large data that arrives + zero-copy SHM
prove it?
The pain map — 349 reports
A field scan of 12 pain clusters with the most-recent ticket for each — falsifiable claims, not a brochure.
- GitHub + Discourse + Stack Exchange
- Most-recent ticket per cluster
- Each fix reproducible from open harnesses
Why ZeroDDS for the ROS 2 world
DDS is a good standard with a hard reality: the default configuration floods networks, breaks on WiFi, fails silently on QoS mismatches, drops large messages, and needs expert XML tuning before it works. Those are not rare edge cases — they are the most-reported, most-recent problems in the ROS community, and they are the reason the project adopted an alternate middleware (Zenoh) in 2023.
ZeroDDS takes the other path. It is a from-scratch, pure-Rust DDS implementation that stays on the wire — native RTPS 2.5, interoperable with Fast DDS, Cyclone DDS, OpenDDS and Connext — but removes the structural causes of those failures. You keep RTPS interop and the whole DDS spec family (DCPS 1.4, XTypes 1.3, DDS-Security 1.2, RPC, XRCE); you lose the daily tax.
It is a complete, audited implementation of the OMG DDS specification family — the same stack RTI, eProsima, ZettaScale and OpenDDS implement, written in safe Rust, published on crates.io and 100 % documented. Read the full why-trail →
A drop-in RMW, not a fork
ROS 2 talks to its middleware through the RMW ABI. rmw_zerodds implements that ABI over the DCPS public API of ZeroDDS, conformant to the relevant REPs (2003/2004/2005/2007/2008/2009). Switching is a single environment variable — RMW_IMPLEMENTATION=rmw_zerodds — with no changes to your nodes, launch files or message types.
Because ZeroDDS stays on native RTPS 2.5, a ZeroDDS node and a rmw_cyclonedds node discover each other and exchange data bidirectionally — verified 20/20 on rt/chatter. You can migrate one node, one robot or one fleet at a time; the rest of the graph keeps running on its current RMW and still interoperates.
The structural fixes
- Discovery without multicast. Unicast initial-peers (
ZERODDS_PEERS,ZERODDS_NO_MULTICAST) give working discovery on WiFi, in Docker and across subnets — with no discovery server to deploy and babysit. → doc - Loud failures instead of silent ones. An incompatible QoS match emits a
qos.incompatibleevent naming the exact offending policy, and a staticqos_checkCLI validates compatibility before you launch. → doc - Large data that actually arrives. Application-level fragmentation with selective NACK_FRAG retransmit and a 16 MiB default reassembly cap — no silent drop at 1 MiB / 262 kB. → doc
- Variable-size zero-copy shared memory. A length-prefixed SHM ring, not a fixed-size Iceoryx pool you have to dimension by hand. → doc
- Runs from MCU to server. Pure-Rust
no_std + alloc; the core builds for Cortex-M4F (thumbv7em-none-eabihf) at a ~1.6 MB footprint and scales up to fleet servers.
The pain map — grounded in 349 reports
The case is not theoretical. A scan of the field (2016–2026, newest dominating) over GitHub issues, ROS Discourse, Stack Exchange and vendor blogs breaks the pain into twelve clusters — each with a most-recent, checkable ticket:
- Discovery (62) · Shared memory (52) · QoS silent no-match (36) · Multicast / WiFi (34)
- Cross-vendor interop (32) · Large data / fragmentation (29) · DDS-Security / SROS2 (22)
- Configuration complexity (21) · Docker / cloud (19) · Performance (19) · Scaling (16) · Migration (7)
Every performance and interop claim ships with the command that produced it. This is a set of falsifiable claims — run them, break them, file what you find. The full trail (pain → most-recent ticket → how ZeroDDS solves it → reproduce it yourself) lives in the repository under docs/why-zerodds-for-ros/.
And the rest of the workspace
The same workspace ships the complete DDS spec family (DCPS 1.4, XTypes 1.3, DDS-Security 1.2, DDS-RPC, DDS-XRCE), seven language bindings from one IDL, ten protocol bridges (MQTT / AMQP / CoAP / WebSocket / gRPC / ROS 2 / Zenoh / OPC UA / SOAP / XRCE) and the full CORBA 3.3 family — all Apache 2.0.
Open the DDS landing →