Localization & SLAM · Theory · M7
M7-T3 — Sensor Topics and Message Timing
SLAM needs to know when a measurement was taken. A scan stamped at the wrong time is a scan taken from the wrong place.
A transform tree says where frames are; a time stamp says when. Every sensor message in ROS carries a header with a frame id and a stamp, and a SLAM node uses the stamp to look up where the robot was at the moment of measurement. Get the stamp wrong by a fraction of a second and the data is projected from a pose the robot was never in, or the lookup fails and the message is silently dropped. This lesson covers what the stamp means, how quality-of-service settings decide whether messages arrive at all, and how timing errors show up.
Learning objectives
After this lesson, you should be able to:
- State what a header stamp must represent and estimate the error caused by a wrong stamp.
- Apply the QoS compatibility rules for sensor and map topics and predict whether a connection forms.
- Explain transform lookup, the buffer, and the causes of extrapolation errors.
- Measure rate, jitter and delay of a topic and recognise the signatures of timing faults.
The problem and the intuition
A photograph of a speeding car is useful only if you know when it was taken. If the label says the photo was taken a tenth of a second later than it really was, you will place the car a tenth of a second too far along. A lidar scan is the same: it is a photograph of the surroundings from the robot’s pose at the moment of the scan. SLAM asks TF “where was the robot when this scan was taken?”. With the right stamp the answer is right; with a stamp that is late by the transport latency, it is the pose where the robot was when the message arrived.
The second half of the story is delivery. ROS 2 decides which publishers and subscribers connect using quality-of-service (QoS) profiles. If they are incompatible, the connection is simply not made, and (in some versions) the only trace is a warning. A sensor driver that publishes with best effort and a node that subscribes with reliable never exchange a single message.
Two questions decide whether a message is used: does the data connect (topic, type, QoS), and does it make sense in time (stamp, frame, buffer)?
The rules: stamps, QoS, filters, lookups
Problem. Deliver sensor data to the SLAM node so that every message is received, stamped with the time of measurement, in a frame whose transform to the map is available at that time.
Assumptions. The system has one clock (wall time on hardware; /clock in simulation); drivers can report the measurement time; transforms are published at a steady rate; the buffer is long enough for the processing latency.
What the stamp must be
header.stamp is the time at which the data was measured. For a camera, the middle of the exposure; for a spinning lidar, the start (or in some drivers the end) of the sweep, with per-point times for deskewing (M5-T2). It is not the time the driver received the packet, nor the time the message was published. If a driver only knows the arrival time, the stamp is late by the unknown latency L, and the SLAM node projects the scan from the pose at t + L. The resulting error is:
Clock and simulated time
In simulation, Gazebo publishes /clock and every node must have use_sim_time: true. Mixing wall time and sim time gives stamps that differ by decades, or time that jumps when the simulation is paused or reset. On hardware, all computers must share a clock (chrony, NTP or PTP), otherwise stamps from different machines disagree by seconds.
Quality of service
Each endpoint declares reliability (RELIABLE or BEST_EFFORT), durability (VOLATILE or TRANSIENT_LOCAL), and history (KEEP_LAST with a depth). The rules for a publisher P and a subscriber S:
| Setting | P offers | S requests | Connects? |
|---|---|---|---|
| Reliability | RELIABLE | RELIABLE or BEST_EFFORT | Yes |
| Reliability | BEST_EFFORT | BEST_EFFORT | Yes |
| Reliability | BEST_EFFORT | RELIABLE | No: the subscriber demands what the publisher cannot give |
| Durability | TRANSIENT_LOCAL | TRANSIENT_LOCAL or VOLATILE | Yes (a late joiner gets the last message only if S is transient local) |
| Durability | VOLATILE | TRANSIENT_LOCAL | No |
The conventions of REP 2003 (and the qos_profile_sensor_data preset) are: sensor streams (scans, images, IMU) use BEST_EFFORT, VOLATILE, a small depth, so that a slow consumer drops old data instead of building a queue; maps and static transforms use RELIABLE, TRANSIENT_LOCAL so that a node that starts late still receives the last map. The map topic is thus the classic late-joiner case: an RViz display or Nav2 costmap that subscribes with VOLATILE misses a map published once before it started.
Synchronising and looking up
- message_filters. ApproximateTime and ExactTime synchronisers match messages from different topics by stamp (for example camera and lidar, or two cameras). A slop that is too small drops pairs; too large mixes frames.
- tf2 buffer. Stores transforms for a duration (10 s by default; SLAM Toolbox lets you set
tf_buffer_duration).lookupTransform(target, source, time)interpolates between samples that brackettime. Iftimeis newer than the newest sample, it must extrapolate, which is refused. - tf2 message filter. Holds a message until the transform for its stamp is available (up to a timeout), so that short transform latency does not drop scans; a long delay does.
- stamp
- header time: when the data was measured.
- L
- latency between measurement and the stamp (zero when the driver stamps correctly).
- jitter
- variation of the interval between consecutive messages around its mean.
- extrapolation
- looking up a transform at a time outside the buffered samples; refused by tf2.
Measuring timing
ros2 topic hz /scan # rate, min/max/std of the interval ros2 topic delay /scan # now minus header.stamp (needs a header) ros2 topic bw /scan # bandwidth ros2 topic info /scan -v # QoS of every publisher and subscriber
Signatures of timing faults
| Signature | Likely cause | Remedy |
|---|---|---|
topic delay is large and constant (e.g. 0.12 s) | Driver stamps on arrival, or the clock offset between machines | Use the driver’s hardware time, synchronise clocks |
topic delay negative | Stamps in the future: clock ahead of the receiver, or sim-time mismatch | Fix the clock source |
| Stamps jump back or repeat | Simulation reset, driver restart, duplicate publishers | Reset the SLAM node; remove the duplicate |
Stamp zero (0.0) | Node forgot to fill the header | Fix the node; zero means “latest” to some APIs and “1970” to others |
| Rate drops, big gaps | CPU starved, wireless link, QoS reliable with backpressure | Reduce load, use best effort for sensors |
| No messages at all, no error | Incompatible QoS | ros2 topic info -v, align the profiles |
A worked example: the size of a stamp delay, and the arithmetic of a jitter log
- A stamp delay. A lidar driver stamps scans at arrival; the USB transport and buffering add L = 0.1 s. The robot moves at v = 0.5 m/s and rotates at ω = 1 rad/s (a brisk turn). The position error is v·L = 0.05 m. The bearing error is ω·L = 0.1 rad ≈ 5.7°. A wall point at range r = 5 m is placed r·ω·L = 0.5 m wrong. A scan matcher would see the walls smeared by tens of centimetres during every turn, and the map would show doubled walls.
- Reading a jitter log. Six consecutive scan stamps (seconds): 10.000, 10.100, 10.201, 10.300, 10.400, 10.650. The intervals are 0.100, 0.101, 0.099, 0.100, 0.250. The median interval is 0.100 s (10 Hz). The last interval is 2.5 times the median: one or two scans were lost. If the next stamp were 10.640, an earlier time than the previous one, that would be non-monotonic and a driver or clock problem.
- A lookup that fails. The odometry transform is published at 50 Hz; the newest sample is at t = 100.000 s. A scan stamped 100.012 s arrives. The next transform sample is due at 100.020 s, so the lookup fails with “extrapolation into the future”. The tf2 message filter holds the scan for up to the timeout (a couple of tenths of a second in SLAM Toolbox:
transform_timeout) and succeeds once the 100.020 sample arrives; with a timeout of zero the scan is dropped. A scan stamped 100.5 s because the clock is half a second ahead would be dropped every time. - A QoS mismatch. The lidar driver publishes
/scanwith BEST_EFFORT (the sensor convention). A custom node subscribes with the default RELIABLE profile.ros2 topic listshows the topic,ros2 topic hz /scanfrom the command line (which uses a compatible profile) shows 10 Hz, and the custom node receives nothing. The log may print “New publisher discovered on topic ‘/scan’, offering incompatible QoS”. The fix is to subscribe withqos_profile_sensor_data. - A late joiner. The map server publishes
/maponce with TRANSIENT_LOCAL. RViz starts later with a VOLATILE subscription and shows nothing; changing its display to “Transient Local” durability, or republishing, fixes it. The same applies to/tf_staticand Nav2’s static layer.
Engineering implications and limitations
Engineering implications
- Prefer driver hardware timestamps. If the sensor supports time synchronisation (PTP, PPS, an external trigger), use it; otherwise estimate and subtract a fixed latency, and verify by turning the robot in front of a wall.
- Synchronise clocks across machines with chrony or PTP; check offsets with
chronyc tracking. - Choose QoS deliberately. Sensors: best effort, small depth. Maps, static transforms and parameters: reliable, transient local. Mirror the publisher’s profile in your subscribers or use the presets.
- Give transforms headroom. Publish odometry TF at 30–50 Hz and set a transform timeout of a few hundred milliseconds in the SLAM node; do not make it so long that you hide real delays.
- Log timing. Record rate, jitter and delay for each sensor in every run; a change between runs is a symptom of a hardware or load problem.
- Test with a sharp turn. Timing errors show in rotation, as a smeared or doubled wall; a straight drive hides them.
Limits
These checks assume messages carry usable stamps; some drivers are wrong in ways that only physical tests reveal. DDS vendors differ in how QoS events are reported and in default behaviour under load, and the ROS 2 releases differ in tooling (for example, ros2 topic delay is available in current distributions but not in all older ones). Finally, a correct stamp does not remove motion distortion within a single scan, which needs deskewing (M5-T2).
Common misconceptions
“The stamp is when the message was published.”
It is the time of measurement; publishing time is the receipt time and is not the same.
“If ros2 topic hz shows data, my node receives it.”
The CLI uses a permissive QoS profile; your subscriber may be incompatible.
“Reliable is always safer.”
For high-rate sensors a reliable queue can add latency and starve the system; best effort lets old data drop.
“Time errors of 50–100 ms are irrelevant for a slow robot.”
Rotation magnifies them: 0.1 s at 1 rad/s moves a wall point at 5 m by half a metre.
Engineering takeaways
- The header stamp must be the measurement time; a delay L produces errors of v·L in position and ω·L in bearing.
- Simulation requires use_sim_time everywhere; hardware requires synchronised clocks.
- A BEST_EFFORT publisher cannot serve a RELIABLE subscriber; a VOLATILE publisher cannot serve a TRANSIENT_LOCAL one.
- tf2 lookups need the stamp inside the buffered range; future stamps cause extrapolation errors.
- Measure rate, delay and jitter with ros2 topic hz and delay, and check QoS with ros2 topic info -v.
References and further reading
Primary papers and authoritative documentation.
- Open Robotics. ROS 2 documentation: About Quality of Service settings; About Time. docs.ros.org.
- REP 2003: Sensor Data and Map QoS Settings. ROS Enhancement Proposals (ros.org/reps/rep-2003.html).
- Foote, T. (2013). tf: The transform library. IEEE International Conference on Technologies for Practical Robot Applications (TePRA).
- Macenski, S., Foote, T., Gerkey, B., Lalancette, C. and Woodall, W. (2022). Robot Operating System 2: Design, architecture, and uses in the wild. Science Robotics 7(66).
- Furgale, P., Rehder, J. and Siegwart, R. (2013). Unified temporal and spatial calibration for multi-sensor systems. IEEE/RSJ IROS: on estimating sensor time offsets.
Knowledge check
Three conceptual questions. Write an answer, then reveal the explanation. Your answers stay in your browser.
Question 1
A driver stamps lidar scans 80 ms late. The robot turns at 0.8 rad/s. How far off is a wall point 6 m away?
Explanation
The bearing error is ω L = 0.8 × 0.08 = 0.064 rad, so a point at 6 m is displaced by about 6 × 0.064 ≈ 0.38 m (plus the translation error v L). Walls smear during turns.
Question 2
A custom node subscribes to /scan with default (RELIABLE) QoS but receives nothing, while ros2 topic hz /scan works. Why?
Explanation
The publisher offers BEST_EFFORT, and a RELIABLE subscriber cannot be satisfied, so no connection is made. The CLI tool subscribes with a compatible profile. Use qos_profile_sensor_data (best effort) in the node.
Question 3
The log shows “extrapolation into the future” for every scan in a simulation. What do you check first?
Explanation
The clock source: whether all nodes, including the SLAM node and the sensor plugin, use use_sim_time. A node on wall time stamps messages decades away from the simulation clock, and no transform covers those times.
What’s next
With wiring, frames and timing in order, the next lesson looks at the SLAM node itself: SLAM Toolbox, its modes, and the parameters that matter.
Related content
Nothing below is required to finish this lesson.
- BeforeM7-T2: TF Frames and Coordinate Consistency
Apply REP 105 (map, odom, base_link) and know who publishes each transform.
- LabM7-L3: Diagnose Sensor Timestamp Problems
Find clock, stamp and QoS problems that make SLAM drop scans or jump.
Get notified when the next lesson and new labs are released.
One email per new lesson or lab.