Your L4 decision loop runs at 100Hz. The sensor fusion node publishes at 100Hz. But the actuator command arrives 12ms late. The culprit isn't your algorithm — it's the middleware. ROS 2 Humble's default DDS settings prioritize throughput over determinism, and for L4 autonomy, that gap is the difference between a smooth stop and a near-miss.
Why Default DDS Fails at L4
Out of the box, Cyclone DDS uses best-effort reliability, large socket buffers, and no CPU pinning. It batches packets to maximize throughput. That's fine for telemetry. It's fatal for a braking command that must traverse three nodes in under 5ms end-to-end. The RTPS wire protocol adds serialization overhead. The OS scheduler adds jitter. The NIC interrupt handling adds variance. Defaults ignore all three.
"In autonomous systems, latency isn't a metric — it's a safety budget. Every microsecond stolen by middleware is a microsecond lost for perception and planning.
— ROS 2 Real-Time Working Group
Tune Cyclone DDS for Determinism
This configuration pins writer, reader, and event threads to isolated CPU cores (0, 1, 2), disables multicast to eliminate switch jitter, and caps buffer sizes to prevent bufferbloat. Watermarks trigger backpressure before queues saturate. Save as cyclonedds.xml and export CYCLONEDDS_URI=file:///path/cyclonedds.xml.
QoS Policies That Matter
| Policy | Default | L4 Tuned | Reason |
|---|---|---|---|
| Reliability | Best Effort | Reliable | Guarantees delivery for safety-critical topics |
| History | Keep Last 1 | Keep Last 5 | Absorbs transient spikes without loss |
| Durability | Volatile | Transient Local | Late joiners get last command (e.g. watchdog) |
| Deadline | Infinite | 10ms | Triggers callback on missed cycle |
| Lifespan | Infinite | 20ms | Auto-purges stale actuator commands |
Zero-Copy & Loaned Messages
Humble supports zero-copy transfer via loaned messages when publisher and subscriber share a process or use shared memory transport. For inter-process, enable SHM in Cyclone: . Then use rclcpp::LoanedMessage in the publisher:
This avoids memcpy from user buffer to DDS buffer. Measured savings: 15-30µs per 1KB message on x86_64.
Validate With Tracing
Instrument with ros2 trace and babeltrace2. Capture ros2:rclcpp_publish, ros2:rmw_publish, ros2:dds_write events. Plot latency CDF. Target: p99 < 1ms for intra-node, p99 < 3ms for inter-node on same host.
Checklist Before Deploy
1. Cyclone XML pinned to isolated cores. 2. QoS profiles applied per topic (not global). 3. Zero-copy enabled for >500Hz topics. 4. SHM transport verified with ros2 doctor --report. 5. Latency CDF captured under load (simulated sensor replay). 6. Watchdog monitors deadline misses on command topic.
✦









