Hi ROS community,
Two weeks ago, I posted about a hard-braking middleware for handling Wi-Fi ghost commands. Thanks to the incredibly valuable feedback from @peci1, @chfritz, and @bmagyar, I realized that active control interception (like instant stops) is often too invasive and vehicle-specific for standard deployments.
Taking that feedback to heart, I have pivoted and been working on a new, much cleaner ROS 2 runtime observer called runtime_integrity. The idea is simple: Most robot diagnostics tell us whether the software infrastructure is alive:
Did the node crash?
Is the topic publishing?
Did a timeout happen?
But for mobile robots, there is another question that often matters more at runtime:
The autonomy stack commanded velocity X.
Did the physical robot actually execute motion consistent with X?
This is the gap runtime_integrity is trying to expose.
What it can surface
The current v0.3-alpha focuses on making these physical execution failures visible as ROS-native diagnostic signals:
-
Wheel slip
Commanded motion expects progress, but odometry shows insufficient physical movement. -
Localization jump
Pose feedback changes in a way that is physically inconsistent with the recent command window. -
Timing / command-stream disturbance
Command arrival timing or command/odom alignment becomes inconsistent.
Example output:
message: "ERROR | RESYNCING: WHEEL_SLIP"
name: "runtime_integrity/execution_integrity"
values:
- key: "diagnosticLevelName"
value: "ERROR"
- key: "status"
value: "RESYNCING"
- key: "dominantCause"
value: "WHEEL_SLIP"
- key: "totalResidual"
value: "1.730000"
- key: "cmdOdomResidual"
value: "1.462117"
- key: "staleStreams"
value: ""
For a hard localization jump test, I was able to get:
message: "ERROR | RESYNCING: LOCALIZATION_JUMP"
dominantCause: "LOCALIZATION_JUMP"
totalResidual: "50.757462"
localizationJumpMetric: "1.349308"
cmdOdomResidual: "42.897885"
Why standard /diagnostics?
I wanted the first ROS-native integration to be boring and useful:
- No new dashboard required.
- No custom protocol required.
- No control authority required.
The output can be consumed by Foxglove Studio, rqt_robot_monitor, diagnostic_aggregator, or any existing diagnostics consumer.
What it does
runtime_integrity observes:
/cmd_vel + /odom
over short runtime windows and publishes execution-integrity state to standard ROS diagnostics:
/diagnostics
runtime_integrity/execution_integrity
It is currently observe-only:
No command interception.
No controller modification.
No Nav2 BT modification.
No base-driver modification.
Just run the observer and inspect /diagnostics.
One interesting edge case: localization jumps
Localization jump detection is more subtle than wheel slip. If an upstream EKF / SLAM backend exposes a hard pose discontinuity, the observer can catch it as LOCALIZATION_JUMP.
But if that correction is smoothed over multiple frames, the same physical issue may appear instead as sustained CMD_ODOM_MISMATCH, TIMING, or elevated residuals.
So I am treating LOCALIZATION_JUMP as a hard-discontinuity label, not a promise that every localization problem will map to that exact cause. This is one area where I would especially appreciate feedback from SLAM, sensor-fusion, and Nav2 developers.
Quick start
Current ROS package name is still:
ros2_kinematic_guard
Runtime concept name:
runtime_integrity
Build:
source /opt/ros/humble/setup.bash
colcon build --symlink-install --packages-select ros2_kinematic_guard
source install/setup.bash
Run observer:
ros2 run ros2_kinematic_guard execution_observer_node --ros-args \
-p cmd_input_topic:=/cmd_vel \
-p odom_topic:=/odom
Inspect diagnostics:
ros2 topic echo /diagnostics
Repository:
https://github.com/ZC502/runtime_integrity.git
I would be very interested in feedback on:
- Whether this belongs best as a standalone diagnostics observer, a Nav2-adjacent observer, or eventually a ros2_control-adjacent observer.
- Which diagnostic fields are most useful for real AMR/AGV debugging.
- How best to expose short-lived events like localization jumps in
/diagnosticswithout turning the observer into a controller.