[Release] runtime_integrity v0.3-alpha: Turning command-to-physical execution consistency into standard ROS diagnostics

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:

  1. Whether this belongs best as a standalone diagnostics observer, a Nav2-adjacent observer, or eventually a ros2_control-adjacent observer.
  2. Which diagnostic fields are most useful for real AMR/AGV debugging.
  3. How best to expose short-lived events like localization jumps in /diagnostics without turning the observer into a controller.
1 Like

UPDATE (28 May 2026):

From day one, the core architectural vision behind runtime_integrity wasn’t just to light up a warning LED for live operators. It was built from the ground up to solve a fundamental bottleneck in robot learning and Sim2Real workflows:
learned autonomy is inherently “physics-blind.”
When an RL policy, neural local planner, or VLA module commands motion, it doesn’t actually know if the physical robot executed it or slipped on an oily floor. Traditional diagnostics look at node health; we look at kinematic execution consistency.

Today, I’ve pushed the next planned milestone of this architecture: diagnostics_to_csv_labeler.py.

This node officially bridges the gap between raw middleware /diagnostics and structured ML training pipelines. Instead of manually scrubbing through a 50GB rosbag to find that 3-second wheel slip or a hidden localization jump, this utility allows you to replay your field logs and automatically harvest those exact execution-collapse moments into ready-to-use CSV failure datasets.

Usage is exactly as designed:

ros2 run ros2_kinematic_guard diagnostics_to_csv_labeler --ros-args \
  -p output_csv:=runtime_integrity_failure_labels.csv

It exports timestamps and precise cross-modal residual metrics (WHEEL_SLIP, LOCALIZATION_JUMP, TIMING, etc.) using only the standard topics 100% of mobile robots already have: /cmd_vel and /odom (No custom torque or tactile sensors required for this command/odom residual label).

Example output format:

ros_time_sec,diagnostic_level_name,status,dominantCause,totalResidual,cmdOdomResidual,wheelSlipIndex,localizationJumpMetric 1779799999.12,ERROR,RESYNCING,WHEEL_SLIP,1.730000,1.462117,1.23,0.0 1779800001.54,ERROR,RESYNCING,LOCALIZATION_JUMP,50.757462,42.897885,0.0,1.349308

For teams deploying learned stacks, you can plug this into your headless overnight ingestion pipelines (with use_sim_time:=true) to index and label fleet-wide failures automatically.

The implementation remains strictly observe-only (no /cmd_vel interception, no Nav2 BT hacks).

Check out the update: GitHub - ZC502/runtime_integrity: runtime_integrity v0.3-alpha exposes the existing execution-integrity engine through standard ROS diagnostics. · GitHub

I’d appreciate feedback from the community on this data-centric direction—what other kinematic residuals or hardware synchronization metrics would be most critical to export for your training datasets?