Establish the baseline.
Load the nominal case. While publishing continues, compare callback age and retained-state age. Do the three readers receive the same sequence numbers?
15 / ROS 2 · QUALITY OF SERVICE · MESSAGE AGE
A source publishes a synthetic drone position. Three real ROS 2 reader processes listen to the same stream with different history depths and acceptance rules. Pause their executors for one second, then inspect the position each reader still remembers.
Predict: which helps a reader recover a recent position: keeping 20 messages, keeping only the latest one, or rejecting messages older than 150 ms?
All endpoints use RELIABLE delivery and VOLATILE durability. Reader history is KEEP_LAST, with depth 20 or 1. Reliability is held constant.
One depth-20 reader rejects old callback samples. This is application validation, separate from DDS history, deadline and lifespan policies.
Separate processes on one host. The source publishes every 50 ms. Readers take at most one telemetry callback per 50 ms; a scheduled executor pause changes availability.
The browser replays measured timestamps and callbacks. A prescribed 3D trajectory provides visual context; it is no flight-physics or radio simulation.
Available information: a reader receives stamped position samples only when its callback executes. The moving solid drone and the full reference curve are evaluator context. They never update a reader’s retained position.
ONE STREAM · THREE READERS · RECORDED EXECUTION
Play changes the recorded-time cursor. It does not launch ROS processes, emulate DDS delivery, or measure network speed.
Drag to orbit · scroll to zoom. The drone follows synthetic XYZ positions, with no flight dynamics. A ghost moves only when the selected reader accepts a recorded callback.
Source stamps and callback times share this host’s monotonic clock.
COMPARE THE SAME STREAM
Age of information keeps growing between accepted samples.
ACTUAL CALLBACK / WHAT ARRIVED
| Sequence | Time / s | Age / ms | Decision |
|---|
RETAINED STATE / WHAT IS STILL BEING USED
Callback age = callback time − sample generation time.
Age of Information (AoI) = cursor time − generation time of the last accepted sample.
The chart reveals elapsed time only. A drop means a newer sample was accepted. The 150 ms line is the common display freshness threshold; only the gated reader enforces it at callback time.
| Reader | History | Callbacks | Accepted | Rejected | Sequences not observed |
|---|
Actual DDS queue occupancy was not recorded. The interface shows publications and executed callbacks, without inventing queued packets.
Process IDs belong to the recorded run, not live programs in this page. Imported metadata is untrusted provenance. Structural consistency does not authenticate that ROS produced a file.
PREDICT · INSPECT · EXPLAIN
Load the nominal case. While publishing continues, compare callback age and retained-state age. Do the three readers receive the same sequence numbers?
Compare depth 20 with depth 1. Both use reliable delivery. One callback per publication period leaves little spare capacity to catch up with a retained history.
Select the gated depth-20 reader after resume. It can reject old messages correctly while its last accepted position becomes increasingly outdated. At the end, the stopped publisher makes every retained state age.
ROS 2 / QUALITY OF SERVICE
Reliability concerns middleware delivery behavior. History and depth bound retained samples. An executor runs the callback that lets the application see a message. These are distinct from validating a timestamp.
This experiment pauses reader execution on one host. It introduces no radio failure, packet-loss rate, multi-machine clock offset, drone dynamics or controller.
The source samples x = 3 cos(t), y = 2 sin(t), z = 1.5 + 0.4 sin(2t), in meters with t in seconds. The reference continues through the observation window after publications stop. Those unsent positions remain evaluator-only information.
The display labels retained data fresh at age ≤ 150 ms. Only the gated reader checks that threshold when accepting a callback. Stopping, requesting data or changing a flight command requires a separate application policy.
With Docker available, run npm run record:qos, then import local/ros2-qos.json above. The runner launches actual publisher and reader processes. Browser playback simply observes their saved results. The repository guide docs/lessons/15-ros2-freshness.md defines the experiment and its limits.
Primary documentation: the Age of Information survey, ROS 2 Jazzy Quality of Service settings and executors. This is a middleware and application-policy experiment, not a new named coordination algorithm.