Summary
Add end-to-end integration tests for MRUTransform::updateVelocity and
updateOrientation that exercise the actual callback code path —
TF lookups, rotation application, failure handling, publishing —
rather than only the rotation math in isolation.
Background
PR #19 added test_twist_rotation.cpp which covers
rotate_covariance_block_3x3 with hand-computed expected outputs.
That is good coverage for the math itself, but it doesn't exercise:
updateVelocity reading velocity.header.frame_id and performing
a TF lookup at velocity.header.stamp
- The drop-on-TF-failure path in
updateVelocity
- The zero-angular-on-TF-failure path in
updateOrientation
(added post-review)
- The same-frame short-circuit in
updateOrientation
- Correct placement of rotated values into
odom_.twist when the
publish fires
- The interaction between
updatePosition / updateOrientation /
updateVelocity updates and the single odom_ publish
A regression in any of those paths would pass the current tests.
Proposed Scope
A new test target, e.g. test_mru_transform_integration, that:
- Constructs a minimal
rclcpp::Node fixture.
- Populates a
tf2_ros::Buffer with known static transforms
(base_link → imu_link, base_link → velocity_frame).
- Instantiates
MRUTransform with deterministic params.
- Uses
NavigationSensors' callbacks directly — or
call_callbacks_ equivalents — to feed synthetic position,
orientation, and velocity messages.
- Subscribes to
/odom on a mock subscriber and asserts the
published message's twist has the expected body-frame values.
Suggested cases:
| Case |
Setup |
Expected |
| Velocity in world frame, IMU in base_link |
TF map → base_link rotated 90° yaw, gps_vel pointing east |
odom.twist.linear = north in body |
| Velocity with unknown frame |
header.frame_id = "ghost_frame" |
no publish, WARN_THROTTLE observed |
| IMU in sensor frame |
TF base_link → imu_link rotated 180° roll, gyro = (0, 0, 1) |
odom.twist.angular.z = -1 |
| IMU with missing TF |
no base_link → imu_link entry, gyro = (1, 2, 3) |
odom.twist.angular = (0, 0, 0), WARN observed |
| Same-frame short-circuit |
IMU header.frame_id = "base_link" |
odom.twist.angular == input gyro, no TF lookup performed |
Why not in PR #19
PR #19 was already +528 −6. Adding the rclcpp + tf fixture would
roughly double it and expand the review surface. The review-time
trade-off was to keep PR #19 focused on the fix + math coverage and
split integration coverage into a follow-up.
Related
Authored-By: Claude Code Agent
Model: Claude Opus 4.7 (1M context)
Summary
Add end-to-end integration tests for
MRUTransform::updateVelocityandupdateOrientationthat exercise the actual callback code path —TF lookups, rotation application, failure handling, publishing —
rather than only the rotation math in isolation.
Background
PR #19 added
test_twist_rotation.cppwhich coversrotate_covariance_block_3x3with hand-computed expected outputs.That is good coverage for the math itself, but it doesn't exercise:
updateVelocityreadingvelocity.header.frame_idand performinga TF lookup at
velocity.header.stampupdateVelocityupdateOrientation(added post-review)
updateOrientationodom_.twistwhen thepublish fires
updatePosition/updateOrientation/updateVelocityupdates and the singleodom_publishA regression in any of those paths would pass the current tests.
Proposed Scope
A new test target, e.g.
test_mru_transform_integration, that:rclcpp::Nodefixture.tf2_ros::Bufferwith known static transforms(base_link → imu_link, base_link → velocity_frame).
MRUTransformwith deterministic params.NavigationSensors' callbacks directly — orcall_callbacks_equivalents — to feed synthetic position,orientation, and velocity messages.
/odomon a mock subscriber and asserts thepublished message's twist has the expected body-frame values.
Suggested cases:
map → base_linkrotated 90° yaw, gps_vel pointing eastheader.frame_id = "ghost_frame"base_link → imu_linkrotated 180° roll, gyro = (0, 0, 1)base_link → imu_linkentry, gyro = (1, 2, 3)header.frame_id = "base_link"Why not in PR #19
PR #19 was already +528 −6. Adding the rclcpp + tf fixture would
roughly double it and expand the review surface. The review-time
trade-off was to keep PR #19 focused on the fix + math coverage and
split integration coverage into a follow-up.
Related
Authored-By:
Claude Code AgentModel:
Claude Opus 4.7 (1M context)