Skip to content

Commit a10c564

Browse files
authored
Reject non-finite values in forward controller subscriber callback (#1815)
1 parent 9f8af76 commit a10c564

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

forward_command_controller/src/forward_controllers_base.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,21 @@ controller_interface::CallbackReturn ForwardControllersBase::on_configure(
7272

7373
joints_command_subscriber_ = get_node()->create_subscription<CmdType>(
7474
"~/commands", rclcpp::SystemDefaultsQoS(),
75-
[this](const CmdType::SharedPtr msg) { rt_command_.set(*msg); });
75+
[this](const CmdType::SharedPtr msg)
76+
{
77+
const auto cmd = *msg;
78+
79+
if (!std::all_of(
80+
cmd.data.cbegin(), cmd.data.cend(),
81+
[](const auto & value) { return std::isfinite(value); }))
82+
{
83+
RCLCPP_WARN_THROTTLE(
84+
get_node()->get_logger(), *(get_node()->get_clock()), 1000,
85+
"Non-finite value received. Dropping message");
86+
return;
87+
}
88+
rt_command_.set(cmd);
89+
});
7690

7791
RCLCPP_INFO(get_node()->get_logger(), "configure successful");
7892
return controller_interface::CallbackReturn::SUCCESS;

forward_command_controller/test/test_forward_command_controller.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,52 @@ TEST_F(ForwardCommandControllerTest, CommandCallbackTest)
329329
ASSERT_EQ(joint_3_pos_cmd_.get_value(), 30.0);
330330
}
331331

332+
TEST_F(ForwardCommandControllerTest, DropInfiniteCommandCallbackTest)
333+
{
334+
SetUpController();
335+
336+
controller_->get_node()->set_parameter({"joints", joint_names_});
337+
controller_->get_node()->set_parameter({"interface_name", "position"});
338+
339+
// default values
340+
ASSERT_EQ(joint_1_pos_cmd_.get_value(), 1.1);
341+
ASSERT_EQ(joint_2_pos_cmd_.get_value(), 2.1);
342+
ASSERT_EQ(joint_3_pos_cmd_.get_value(), 3.1);
343+
344+
auto node_state = controller_->configure();
345+
ASSERT_EQ(node_state.id(), lifecycle_msgs::msg::State::PRIMARY_STATE_INACTIVE);
346+
347+
node_state = controller_->get_node()->activate();
348+
ASSERT_EQ(node_state.id(), lifecycle_msgs::msg::State::PRIMARY_STATE_ACTIVE);
349+
350+
// send a new command
351+
rclcpp::Node test_node("test_node");
352+
auto command_pub = test_node.create_publisher<std_msgs::msg::Float64MultiArray>(
353+
std::string(controller_->get_node()->get_name()) + "/commands", rclcpp::SystemDefaultsQoS());
354+
std_msgs::msg::Float64MultiArray command_msg;
355+
command_msg.data = {10.0, std::numeric_limits<double>::infinity(), 30.0};
356+
command_pub->publish(command_msg);
357+
358+
// wait for command message to be passed
359+
const auto timeout = std::chrono::milliseconds{10};
360+
const auto until = controller_->get_node()->get_clock()->now() + timeout;
361+
while (controller_->get_node()->get_clock()->now() < until)
362+
{
363+
executor.spin_some();
364+
std::this_thread::sleep_for(std::chrono::microseconds(10));
365+
}
366+
367+
// update successful
368+
ASSERT_EQ(
369+
controller_->update(rclcpp::Time(0), rclcpp::Duration::from_seconds(0.01)),
370+
controller_interface::return_type::OK);
371+
372+
// check message containing infinite command value was rejected
373+
ASSERT_EQ(joint_1_pos_cmd_.get_value(), 1.1);
374+
ASSERT_EQ(joint_2_pos_cmd_.get_value(), 2.1);
375+
ASSERT_EQ(joint_3_pos_cmd_.get_value(), 3.1);
376+
}
377+
332378
TEST_F(ForwardCommandControllerTest, ActivateDeactivateCommandsResetSuccess)
333379
{
334380
SetUpController();

0 commit comments

Comments
 (0)