Skip to content

Commit 6b9475f

Browse files
Add regression test to ensure odometry is calculated form limited refs
1 parent 7382edc commit 6b9475f

2 files changed

Lines changed: 57 additions & 0 deletions

File tree

steering_controllers_library/test/test_steering_controllers_library.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,56 @@ TEST_F(SteeringControllersLibraryTest, applies_velocity_limits_to_references)
443443
std::get<1>(expected_commands)[1], 1e-6);
444444
}
445445

446+
TEST_F(SteeringControllersLibraryTest, open_loop_odometry_uses_limited_references)
447+
{
448+
auto node_options = controller_->define_custom_node_options();
449+
node_options.append_parameter_override("open_loop", rclcpp::ParameterValue(true));
450+
node_options.append_parameter_override("linear.x.max_velocity", rclcpp::ParameterValue(0.1));
451+
node_options.append_parameter_override("angular.z.max_velocity", rclcpp::ParameterValue(0.1));
452+
SetUpController("test_steering_controllers_library", node_options);
453+
454+
ASSERT_TRUE(configure_succeeds(controller_));
455+
controller_->set_chained_mode(false);
456+
controller_->export_reference_interfaces();
457+
ASSERT_TRUE(activate_succeeds(controller_));
458+
459+
ControllerReferenceMsg msg;
460+
msg.header.stamp = controller_->get_node()->now();
461+
msg.twist.linear.x = 1.5;
462+
msg.twist.angular.z = 0.0;
463+
controller_->input_ref_.set(msg);
464+
465+
const double dt = 0.1;
466+
ASSERT_EQ(
467+
controller_->update(controller_->get_node()->now(), rclcpp::Duration::from_seconds(dt)),
468+
controller_interface::return_type::OK);
469+
470+
const double limited_linear = 0.1;
471+
const double limited_angular = 0.0;
472+
473+
EXPECT_NEAR(controller_->last_linear_velocity_, limited_linear, 1e-9);
474+
EXPECT_NEAR(controller_->last_angular_velocity_, limited_angular, 1e-9);
475+
476+
// In open-loop mode odometry twist must reflect limited commands, not raw refs.
477+
EXPECT_NEAR(controller_->odom_state_msg_.twist.twist.linear.x, limited_linear, 1e-6);
478+
EXPECT_NEAR(controller_->odom_state_msg_.twist.twist.angular.z, limited_angular, 1e-6);
479+
480+
// Position integration should use limited open-loop velocity.
481+
EXPECT_NEAR(controller_->odometry_.get_x(), limited_linear * dt, 1e-6);
482+
EXPECT_NEAR(controller_->odometry_.get_y(), 0.0, 1e-6);
483+
484+
EXPECT_GT(msg.twist.linear.x, controller_->odom_state_msg_.twist.twist.linear.x);
485+
EXPECT_DOUBLE_EQ(msg.twist.angular.z, controller_->odom_state_msg_.twist.twist.angular.z);
486+
487+
msg.header.stamp = controller_->get_node()->now();
488+
controller_->input_ref_.set(msg);
489+
const auto now = controller_->get_node()->now();
490+
ASSERT_EQ(
491+
controller_->update(now, rclcpp::Duration::from_seconds(dt)),
492+
controller_interface::return_type::OK);
493+
EXPECT_NEAR(controller_->odometry_.get_x(), 2.0 * limited_linear * dt, 1e-6);
494+
}
495+
446496
TEST_F(SteeringControllersLibraryTest, test_reset_buffers_clears_limiter_state)
447497
{
448498
SetUpController("test_steering_controllers_library");

steering_controllers_library/test/test_steering_controllers_library.hpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class TestableSteeringControllersLibrary
8080
FRIEND_TEST(SteeringControllersLibraryTest, test_lifecycle_transitions_reset_limiter_buffers);
8181
FRIEND_TEST(SteeringControllersLibraryTest, test_open_loop_update_ignore_nan_vals);
8282
FRIEND_TEST(SteeringControllersLibraryTest, test_open_loop_update_timeout);
83+
FRIEND_TEST(SteeringControllersLibraryTest, open_loop_odometry_uses_limited_references);
8384
FRIEND_TEST(SteeringControllersLibraryTest, odometry_set_service);
8485

8586
public:
@@ -140,6 +141,12 @@ class TestableSteeringControllersLibrary
140141
// Manual integration of odometry based on wheel states
141142
bool update_odometry(const rclcpp::Duration & period) override
142143
{
144+
if (params_.open_loop)
145+
{
146+
odometry_.update_open_loop(last_linear_velocity_, last_angular_velocity_, period.seconds());
147+
return true;
148+
}
149+
143150
return odometry_.update_from_velocity(
144151
state_interfaces_[STATE_TRACTION_RIGHT_WHEEL].get_optional().value(),
145152
state_interfaces_[STATE_TRACTION_LEFT_WHEEL].get_optional().value(),

0 commit comments

Comments
 (0)