Chapter 05 · Build and debug a real ROS 2 system
Today in the field story
One problem, then the next
The graph exists, but the Aisle Seven Watchdog receives an unlabelled number that could be battery level, wheel speed, or age. Define a telemetry message with source timestamp, frame where relevant, unit, validity, bounded fields, and semantic version. Run two subscribers and prove that publish rate, arrival, source age, and consumer processing are separate observations.
- Why now
QoS and watchdog decisions are meaningless when the message’s physical contract is ambiguous.
- Ignore today
Ignore custom serialization optimization and broad internal object dumps.
- Unlocks next
Typed continuous evidence that can be checked for freshness and compatibility.
Understand
Build the physical picture first
A topic is a labelled conveyor belt carrying identical-shaped boxes. Publishers place boxes on it; subscribers take copies when available. The box shape is the message type, while the printed unit, frame, and timestamp tell a receiver what the numbers mean in the physical world.
A ROS topic supports asynchronous publish-subscribe communication. A publisher sends typed messages under a topic name without naming a particular receiver or waiting for a reply. Zero, one, or several subscribers may listen, and a topic may also have multiple publishers if the system design permits it. This loose coupling is excellent for ongoing sensor data and state streams, but it means a publisher cannot treat message publication as proof that a specific consumer processed the data.
The topic name and message type form only part of the contract. A numeric field such as value: 2.4 is unusable unless a reader knows whether it is volts, metres, radians, or metres per second; which coordinate frame it belongs to; when it was measured; and whether the measurement is valid. Prefer established standard messages when their semantics fit. When designing a custom .msg, use clear field names, bounded sequences or strings where resource limits matter, a timestamp and frame where the data is spatial or time-sensitive, and comments that state units and valid ranges.
Measurement time and arrival time answer different questions. A camera can capture an image at 10.000 s, spend 35 ms processing it, and deliver it at 10.050 s. The image describes the earlier physical scene. A downstream node that substitutes arrival time may combine it with a newer robot pose and create a spatial error. Preserve source timestamps across the pipeline, measure age separately, and define what the consumer does when data is too old or out of order.
Rate affects freshness, bandwidth, and callback load. At frequency f, the ideal period is T=1/f. A 20 Hz publisher aims for one message every 50 ms, not twenty messages all at once each second. Payload bandwidth can be estimated as payload bytes × messages per second, but actual network use is higher because serialization, middleware, discovery, and transport add overhead. Measure message rate, size, age, and loss on the deployed path rather than turning the estimate into a guarantee.
A useful message is stable at its public boundary. Do not publish a whole internal object merely because it is convenient. Consumers then depend on fields they do not need and every internal refactor becomes an interface change. Design around physical meaning and consumer needs, version incompatible semantics deliberately, and write tests that reject wrong units, missing timestamps, invalid enum values, oversized arrays, and impossible ranges.
Words you need
Name each idea precisely
- Topic
A named channel for asynchronous streams of typed messages.
Physical example:The
/battery_statetopic continuously carries voltage, percentage, and status.- Publisher
A ROS endpoint that writes messages of one declared type to a topic.
Physical example:A motor driver publishes encoder readings after each measurement cycle.
- Subscriber
A ROS endpoint whose callback receives messages from a compatible topic publisher.
Physical example:A speed estimator subscribes to wheel encoder samples.
- Message type
The generated data structure and field contract shared by publishers and subscribers.
Physical example:sensor_msgs/msg/Temperatureincludes a header, temperature, and variance.- Source timestamp
The time at which the physical observation was made, not simply when a subscriber received it.
Physical example:A camera exposure time is earlier than the moment the processed image reaches navigation.
- Message age
The difference between the current/receipt time and the source timestamp.
Physical example:A pose received at 12.075 s with stamp 12.000 s is already 75 ms old.
Math, one line at a time
Work through today’s relationship
Prerequisite rescue · optionalMessage rates, queues, and latency
ROS nodes form a distributed timing system; rates and queue depth decide freshness.
- λ
- messages arriving each secondUnit: messages/s
- μ
- messages processed each secondUnit: messages/s
- latency
- receive time minus source timestampUnit: milliseconds (ms)
A camera publishes λ = 30 messages/s while a node processes μ = 20 messages/s.
The backlog grows by λ − μ = 10 messages each second.
A depth-5 queue fills in about 0.5 s; choose a QoS policy based on whether freshness or completeness matters.
ROS pub/sub resembles backend messaging, but an old robot message can command the wrong physical state.
Input is 50 Hz and processing is 40 Hz. How fast does backlog grow?
10 messages per second.
For ,
A -byte payload at that rate produces
before middleware overhead.
Check cadence, payload estimate, and freshness
A simulated telemetry message has a 64-byte payload and is published at 20 Hz. One sample is stamped 5.000 s and arrives at the monitor at 5.075 s; the monitor's maximum accepted age is 60 ms.
Calculate the intended period: T = 1/20 = 0.05 s = 50 ms.
Estimate payload-only throughput: 64 bytes × 20 messages/s = 1,280 bytes/s.
State the limit of that estimate: middleware and transport overhead are not included.
Calculate message age: 5.075 s - 5.000 s = 0.075 s = 75 ms.
Compare 75 ms with the 60 ms acceptance limit and classify this sample as stale for that consumer.
Keep the sample available for diagnostics, but prevent it from updating the live safe-state decision as if it were fresh.
The stream targets a 50 ms period and at least 1,280 payload bytes/s; the example sample is 75 ms old and exceeds the monitor's 60 ms freshness contract.
Rate, bandwidth, and age are separate properties. A message can arrive at the expected rate yet still contain stale physical information.
Physical examples
Where this appears in real life
Electronics-bay temperature
A sensor publishes 32.5 °C with a measurement timestamp and variance; a cooling controller and operator UI both subscribe.
One stream serves two consumers, but each consumer still needs an age limit and cannot infer that the other processed the sample.
Conveyor encoder
An encoder reports a count every 10 ms while a velocity estimator sometimes takes 15 ms to process a callback.
The queue can accumulate older measurements. Timestamp order, depth, callback duration, and stale-data policy matter as much as nominal publish rate.
Hands-on exercise
Make the idea observable
Use Python ROS 2 nodes and a simulated temperature value. No physical sensor or actuator is required.
Create a publisher node that emits
sensor_msgs/msg/Temperatureat 2 Hz and fills the source timestamp, frame idelectronics_bay, temperature in °C, and variance.Create a monitor subscriber that logs source stamp, receipt time, calculated age in milliseconds, unit, and whether age is within a declared limit.
Run a second subscriber representing an operator display and prove both receive the same typed stream without the publisher naming either consumer.
Use CLI tools to inspect the topic type, message fields, publisher/subscriber counts, measured rate, and one live message.
Add an artificial 300 ms publication delay before one sample while keeping its original source timestamp; verify the monitor marks it stale.
Document the message contract: meaning, unit, frame, timestamp source, valid range, expected rate, freshness limit, and invalid-data behavior.
Subscribers receive independently, and a delayed sample can look numerically reasonable while its timestamp proves it is not current.
Two subscribers receive the typed stream, the normal measured rate is close to 2 Hz, the delayed sample is rejected by age, and the contract is readable without opening the publisher implementation.
Build today
Build a Python/C++ telemetry, command, and watchdog system; then reproduce QoS, discovery, executor, lifecycle, and cancellation failures.
Evidence to save
DONE when “Topics, message design, publishers, and subscribers” runs from one documented command and the nominal plus boundary outputs are attached.
Common mistakes
Catch the wrong mental model
Publishing an unlabelled Float64 for a physical quantity.
Use or design a message whose field name, unit, frame, timestamp, and validity are explicit.
Using callback arrival time as the sensor measurement time.
Carry the source stamp through the pipeline and calculate transport/processing age separately.
Assuming publish success means every subscriber processed the message.
Publication hands data to the middleware; consumer processing needs its own acknowledgement or observable state if required.
Estimating payload bandwidth and reporting it as measured network traffic.
Label it as a lower-bound estimate and measure serialized/transport behavior on the actual system.
Job connection
How this becomes employable evidence
A fleet UI displays robot pose and battery data received through a bridge. The engineer preserves source timestamps and units, marks stale values visibly, bounds queues, and avoids showing an old location as live after a network interruption.
Relevant target roles
- Robot HMI / Control & Monitoring Engineer
- Robot Fleet Backend / Platform Engineer
- Robotics Application / ROS 2 Integration Engineer
- Robotics Software Engineer — ROS 2 / AMR
Chapter 05 interview drill
Interview questions: Topics, message design, publishers, and subscribers
Practise a 60–90 second answer: define the idea, connect it to a physical robot, state assumptions, frames, and units when relevant, then finish with the failure signal or evidence you would inspect.
Primary interview scenario
Design a wheel-speed topic used by control, logging, and a dashboard. State the message fields, units, frame/timestamp rules, rate, freshness limits, and what publication does not prove.
Answer shape: clarify the situation → trace the physical and software path → test the most likely boundaries → name the evidence that would confirm the result.
Technical follow-up questions
Q1Why is a topic a better default for a continuing temperature stream than a service?
The producer decides when each new measurement exists, and any number of subscribers can receive the asynchronous stream without repeatedly requesting it.
Q2What must match before a publisher and subscriber can exchange topic data?
They need compatible topic names after namespace/remapping, the same interface type, successful discovery, and compatible QoS.
Q3A 10 Hz stream delivers one message every 100 ms, but each message is 500 ms old. Is the stream healthy?
Its arrival cadence is regular, but its physical information violates freshness; rate alone is not health.