Contents — find the section you need

Change parameters and verify

Open the panel, then press Run to load Python. You can stop execution and reset parameters. Results are computed on this device. No Python installation is required.

Local execution steps below are optional for reproducing the source results; they are not required for the browser experiment.

Open experiment panel in a new tab

Download reproduction source

Background and reading guide

Background IMUs, wheel odometry, ROS 2 topics and TF.

Fundamentals · Worked calculations and a diagnostic procedure, not a diagnosis of a specific robot.

Explore timing, mounting position and axes in your browser

Use the panel above to compare ideal examples without ROS or local Python. These calculations explain different sources of disagreement; they do not run a fusion filter, estimate calibration or diagnose a robot. The original diagnostic procedure remains below.

Time offset: Δt is the time of the compared value minus the reference time. The displayed differences are x(t+Δt)−x(t)=vx Δt and heading(t+Δt)−heading(t)=yaw_rate Δt. Positive Δt compares a later value; negative compares an earlier value. At 1 m/s, 90 deg/s and +50 ms, the differences are +0.05 m and +4.5°. These are separate constant-axis translation and constant-angular-rate examples, not an integrated turning trajectory or a prediction of filter error. Time offset is not automatically transport latency or a timestamp-sign convention for a particular driver. Zero motion can hide timing disagreement. No tolerance is recommended.

Mounting position: the lower diagrams describe velocities at one instant. Body axes use x forward, y left, z up; positive yaw is counterclockwise viewed from +z. The supplied base-point velocity is v_base=(vx,0) in body axes. The lever arm r=(rx,ry) points from that base origin to the sensor origin, also in body axes. With ω=yaw_rate × π/180, the mounting-point velocity difference is ω×r=(-ω ry, ω rx) m/s. Thus v_sensor_body=v_base+ω×r. The position plot uses metres; the velocity plot uses m/s with separate scales. Sensor-axis arrows have a display length of 0.15 m. The velocity plot places vectors at a common origin to compare their components, not to depict where the robot travels.

Mounting orientation: R_bs rotates sensor components into body components. The model constructs hypothetical sensor-point linear velocity as v_sensor_components=R_bsᵀ v_sensor_body. Rotating it back gives the velocity of the sensor point, still not the base point. Only after subtracting the known ω×r term does this ideal algebra recover the supplied base velocity. Reuse of the known exact geometry is not a calibration estimate. This is a hypothetical velocity measurement, not raw IMU acceleration or gyro output; acceleration lever-arm effects are not modeled.

The “raw component mismatch” deliberately subtracts sensor-axis numbers from base-axis numbers at another point. It is an example of an invalid comparison, not a filter innovation. Its norm may even cancel to zero for some wrong comparisons. The algebraic recovery residual measures floating-point roundoff after using the same exact model; it is not localization accuracy or evidence that real calibration is correct. The table labels every vector by its point and axes.

Try in-place rotation, zero lever arm, a sensor on the left, reversed rotation and a 90° sensor mounting. Changing mounting yaw changes sensor components but leaves physical body-frame velocity unchanged. Changing Δt affects only the timing exercise. By default the lever arm is 0.2 m and the rate is 90 deg/s, so the lever-arm speed is about 0.314 m/s; the article's separate 1 rad/s example gives 0.2 m/s. Do not confuse degrees/s with radians/s.

All inputs are synthetic and exact. No covariance, noise, observability test, slip, bias, interpolation, TF lookup, clock synchronization, ROS execution or fusion estimator is included. A/B uses matching position and velocity scales; slider limits are teaching choices. For point transforms, use the separate coordinate-transform Lab; for replay conditions, use the replay Lab.

References reviewed 2026-09-20: REP-103 coordinate conventions and Modern Robotics: rigid-body point velocity. The browser uses the site's existing planar rotation helper and the planar form of the rigid-body velocity relation.

When adding sensors makes localization worse, the filter is not the only suspect. Measurements cannot be compared directly if their times, frames or units differ. Check each input, then the boundaries where it enters fusion.

Fix the diagnostic order

Diagram 1 · Use the button to switch views
Check individual inputs, then time, frames and finally fusion

Reuse a short log and inspect wheels alone, IMU alone, then both. Changing the floor or driving speed at the same time obscures the cause. Review the principles in sensor fusion fundamentals.

Timing error becomes motion error

At a constant 1 m/s, a 50 ms timestamp error creates a 1\times0.05=0.05 m apparent displacement. At 90 degrees/s, the same error creates 4.5 degrees of rotation mismatch. These are constant-motion calculations, not recommended tolerances.

Determine whether a message timestamp denotes sensor acquisition or driver reception. A fixed transmission delay may be manageable with correct acquisition timestamps; clocks that disagree across hosts are a different problem. A longer queue does not correct clock offset. During replay, make all relevant nodes use the same simulation-time configuration.

Check axes and origins

ROS body frames normally use x forward, y left and z up; camera optical frames use z forward, x right and y down. Check conventions in REP-103. Renaming a frame does not rotate its values.

Transform a sensor point using p_b=R_{bs}p_s+t_{bs}. Both rotation and translation matter. The inverse translation is -R^Tt, not simply -t. Record whether calibration maps sensor to body or body to sensor.

Mounting offsets also change motion

For a rigid body, velocity at the sensor is v_s=v_b+\omega\times r. With a perpendicular 0.2 m offset and angular velocity 1 rad/s, the velocity difference is 0.2 m/s. A sensor away from the rotation center moves even during an in-place turn.

Include turns as well as translation in diagnostics. Full extrinsic calibration requires sufficiently informative motion; straight driving alone may not identify every degree of freedom. Compare frame responsibilities with REP-105.

Inspect residuals and covariance last

Symptom Hypothesis Compare next
Error grows with speed Timing mismatch Same route at different speeds
Error grows during turns Axes, offset or timing Stationary, straight and left/right turns
Estimate jumps when adding an input Frame, units or overconfidence Raw input and prediction residual
Slow drift Bias or slip Raw averages and observable directions

A residual is the difference between observation and prediction. Smaller covariance increases trust; it does not correct wrong axes or timestamps. Treating position and velocity derived from the same encoder as strongly independent observations can also overcount information. Inspect input selection and frame handling in the official robot_localization implementation.

Confirm one cause at a time

Change one setting, compare the same log, then confirm with a new run. Plausible stationary values do not rule out motion-dependent synchronization or mounting errors. Before SLAM evaluation, record timestamp semantics, units, TF publishers and calibration direction together.

Related reading

Evaluate the corrected systemHow to evaluate SLAM — ATE, RPE, runtime and failuresExplore another aspect of this fieldFrom mapping to navigation in ROS 2 — a minimal Jazzy and Nav2 procedureExplore another aspect of this fieldRobot coordinate transforms: matrices, quaternions and TF