@@ -107,6 +107,11 @@ class TestDiffDriveController : public ::testing::Test
107107 * angular - the magnitude of the angular command in geometry_msgs::twist message
108108 */
109109 void publish (double linear, double angular)
110+ {
111+ publish_timestamped (linear, angular, pub_node->get_clock ()->now ());
112+ }
113+
114+ void publish_timestamped (double linear, double angular, rclcpp::Time timestamp)
110115 {
111116 int wait_count = 0 ;
112117 auto topic = velocity_publisher->get_topic_name ();
@@ -122,7 +127,7 @@ class TestDiffDriveController : public ::testing::Test
122127 }
123128
124129 geometry_msgs::msg::TwistStamped velocity_message;
125- velocity_message.header .stamp = pub_node-> get_clock ()-> now () ;
130+ velocity_message.header .stamp = timestamp ;
126131 velocity_message.twist .linear .x = linear;
127132 velocity_message.twist .angular .z = angular;
128133 velocity_publisher->publish (velocity_message);
@@ -1085,6 +1090,50 @@ TEST_F(TestDiffDriveController, deactivate_then_activate)
10851090 executor.cancel ();
10861091}
10871092
1093+ TEST_F (TestDiffDriveController, command_with_zero_timestamp_is_accepted_with_warning)
1094+ {
1095+ ASSERT_EQ (
1096+ InitController (
1097+ left_wheel_names, right_wheel_names,
1098+ {rclcpp::Parameter (" wheel_separation" , 0.4 ), rclcpp::Parameter (" wheel_radius" , 1.0 )}),
1099+ controller_interface::return_type::OK);
1100+ // choose radius = 1 so that the command values (rev/s) are the same as the linear velocity (m/s)
1101+
1102+ rclcpp::executors::SingleThreadedExecutor executor;
1103+ executor.add_node (controller_->get_node ()->get_node_base_interface ());
1104+
1105+ ASSERT_TRUE (controller_->set_chained_mode (false ));
1106+
1107+ auto state = controller_->get_node ()->configure ();
1108+ ASSERT_EQ (State::PRIMARY_STATE_INACTIVE, state.id ());
1109+ assignResourcesPosFeedback ();
1110+
1111+ state = controller_->get_node ()->activate ();
1112+ ASSERT_EQ (State::PRIMARY_STATE_ACTIVE, state.id ());
1113+
1114+ waitForSetup ();
1115+
1116+ // published command message with zero timestamp sets the command interfaces to the correct values
1117+ const double linear = 1.0 ;
1118+ publish_timestamped (linear, 0.0 , rclcpp::Time (0 , 0 , RCL_ROS_TIME));
1119+ // wait for msg is be published to the system
1120+ controller_->wait_for_twist (executor);
1121+
1122+ ASSERT_EQ (
1123+ controller_->update (rclcpp::Time (0 , 0 , RCL_ROS_TIME), rclcpp::Duration::from_seconds (0.01 )),
1124+ controller_interface::return_type::OK);
1125+ EXPECT_EQ (linear, left_wheel_vel_cmd_.get_value ());
1126+ EXPECT_EQ (linear, right_wheel_vel_cmd_.get_value ());
1127+
1128+ // Deactivate and cleanup
1129+ std::this_thread::sleep_for (std::chrono::milliseconds (300 ));
1130+ state = controller_->get_node ()->deactivate ();
1131+ ASSERT_EQ (state.id (), State::PRIMARY_STATE_INACTIVE);
1132+ state = controller_->get_node ()->cleanup ();
1133+ ASSERT_EQ (state.id (), State::PRIMARY_STATE_UNCONFIGURED);
1134+ executor.cancel ();
1135+ }
1136+
10881137int main (int argc, char ** argv)
10891138{
10901139 ::testing::InitGoogleTest (&argc, argv);
0 commit comments