17 / ROS 2 · DDS & ZENOH · LATE-JOINING READERS
Same application.
A different path to the reader.
A publisher sends ten positions, pauses, then sends ten more. A reader subscribes during the quiet interval. Change the middleware and the durability policy: will it learn an old position before a new one is published?
Predict: if a reader receives a position immediately after joining, does that make the position recent? Does changing DDS to Zenoh change the coordination algorithm?
ROS Middleware (RMW) + a durability contract.
Know the layers ↗- Software stack / not a new algorithm
- Fast DDS vs Eclipse Zenoh
The same ROS 2 publisher and reader run through rmw_fastrtps_cpp or rmw_zenoh_cpp. RMW is the abstraction between ROS 2 and its middleware implementation.
- QoS / the controlled change
- VOLATILE vs TRANSIENT_LOCAL
Both endpoints use RELIABLE and KEEP_LAST depth 5. VOLATILE supplies no late-join history. TRANSIENT_LOCAL makes the living publisher’s retained history available to a compatible late reader.
- Architecture and topology
- One publisher → one reader
Fast DDS discovers endpoints locally. Zenoh uses a router for discovery and default peer connectivity for data. The router is not an application decision-maker or a forced relay for every sample.
- Timing and fidelity
- Separate processes · actual recordings
Ten samples at 0–0.9 s, reader subscription at about 2 s, then ten samples at 4–4.9 s. Both processes stay alive. Each 6 s case is an independent run, replayed here with one shared 2D/3D cursor.
Information boundary: the reader holds only its last recorded callback. The moving solid drone shows a synthetic evaluator reference, including during publication silence. Neither the view nor the middleware provides that unsent position to the reader.
TWO RMW IMPLEMENTATIONS · ONE BOUNDED QOS COMPARISON
See what a late reader actually learns.
Playback replays actual publications, subscription creation and callbacks. It does not run DDS or Zenoh inside this browser.
Drag to orbit · scroll to zoom. The ghost stays at its last received position while the reference continues. No flight physics.
One cursor follows the recorded events.
READER CALLBACK / AVAILABLE INFORMATION
Received now can mean generated earlier.
Recorded callback envelope
Received envelopes up to the cursor
| Sequence | Receipt / s | Sample | Age / ms |
|---|
PUBLICATION TIME ≠ CALLBACK TIME
Twenty samples, one late reader.
Each column is one sequence number. Rows show actual publication and callback evidence up to the cursor. A dash on the reader row does not establish packet loss.
Retained reader state
callback age = callback time − generation time
held sample age = cursor − generation time
The application holds every callback without a freshness gate. Durability and freshness solve different problems.
SOFTWARE TOPOLOGY / DECLARED CONFIGURATION
Discover endpoints, then exchange data.
The publisher stays alive.
The reader process exists before the run; only its subscription is created late. Publisher history is tied to this living publisher. No publisher restart, wireless loss, router outage or durable database is tested.
Recording provenance, process identities and runtime
PIDs belong to the saved runs. Imported metadata is untrusted provenance: structural checks cannot authenticate that ROS produced a file.
FOUR INDEPENDENT RECORDINGS / MEASURED OUTCOMES
The contract is the comparison.
Same schedule, message type, source curve, reliability and depth. Change RMW and durability. Counts below describe the complete recordings, including events beyond the current cursor.
| Recorded case | Published | History / live callbacks | Observed history sequences | Creation → first callback |
|---|
A matching result for these settings does not establish feature parity across all DDS and Zenoh QoS policies, topologies, loads or failures.
PREDICT · INSPECT · EXPLAIN
Joining is not the same as catching up.
Wait for something new.
Join during publication silence with VOLATILE durability. Is the reader empty because a packet was lost, or because it was not entitled to past data? Seek to the first callback.
Get history, then inspect its age.
Repeat with a retained depth of five. Inspect which old sequences arrive and the positions they contain. A callback that just ran may carry a position recorded more than a second earlier.
Keep the application contract.
Load the other middleware with the same durability. Compare the recorded sequences and discovery configuration. The RMW changed; the application still holds its most recent callback.
METHOD PROFILE / MIDDLEWARE AND QOS
Name the layer
before comparing the behavior.
Data Distribution Service (DDS) is a publish/subscribe standard. eProsima Fast DDS is the DDS implementation used here through rmw_fastrtps_cpp. Eclipse Zenoh is a separate communication system used here through rmw_zenoh_cpp; it is not another DDS implementation.
Quality of Service (QoS) describes endpoint policies. This experiment changes durability while keeping reliability, history kind and depth fixed. There is no consensus rule, leader election, path planner or autonomous mission in this application.
→ Fast DDS or Eclipse Zenoh
history = KEEP_LAST · depth = 5
reliability = RELIABLE
durability = VOLATILE or TRANSIENT_LOCAL
- RMW / ROS Middleware
- The ROS abstraction that allows an application to use different middleware implementations. Switching it does not establish identical behavior for every feature, configuration or environment.
- Durability / late-join history
- VOLATILE does not supply samples from before the subscription. TRANSIENT_LOCAL allows the living publisher’s retained history to reach a compatible late subscriber. Both endpoints request the same policy here.
- History / bounded retention
- KEEP_LAST depth 5 retains a bounded number of samples under this contract. It is not a lifetime delivery count: a reader can receive more than five callbacks over the run.
- Reliability / not freshness
- RELIABLE is a delivery policy within its endpoint and resource conditions. It does not make a historical position current, create a callback for every pre-subscription publication, or prove mission success.
A router is not necessarily the data path.
In the Zenoh configuration used here, ROS nodes connect to a Zenoh router for discovery. Default peer connectivity can carry application data directly. The schematic shows configuration, not captured packet routes or measured bytes.
A bounded comparison, not a speed contest.
All processes run on one host and share a monotonic clock. Actual generation, subscription and callback times are preserved. Different discovery delays from individual runs do not rank middleware performance.
Record the same experiment again
With Docker available, run npm run record:middleware, then import local/ros2-middleware.json. See docs/lessons/17-middleware-durability.md for the exact setup, recorder and interpretation boundaries.
Primary references: ROS 2 Jazzy Quality of Service settings, middleware implementations, and the official rmw_zenoh implementation and configuration. The recordings cover these declared policies and one local topology.