Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 9 additions & 13 deletions rclcpp/src/rclcpp/node_interfaces/node_parameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -201,12 +201,10 @@ __check_parameter_value_in_range(
rcl_interfaces::msg::SetParametersResult result;
result.successful = true;
if (!descriptor.integer_range.empty() && value.get_type() == rclcpp::PARAMETER_INTEGER) {
int64_t v = value.get<int64_t>();
auto integer_range = descriptor.integer_range.at(0);
if (v == integer_range.from_value || v == integer_range.to_value) {
return result;
}
if ((v < integer_range.from_value) || (v > integer_range.to_value)) {
const int64_t v = value.get<int64_t>();
const auto& integer_range = descriptor.integer_range.at(0);
const bool within_range = (v >= integer_range.from_value) && (v <= integer_range.to_value);
if (!within_range) {
result.successful = false;
result.reason = format_range_reason(descriptor.name, "integer");
return result;
Expand All @@ -223,20 +221,18 @@ __check_parameter_value_in_range(
}

if (!descriptor.floating_point_range.empty() && value.get_type() == rclcpp::PARAMETER_DOUBLE) {
double v = value.get<double>();
auto fp_range = descriptor.floating_point_range.at(0);
if (__are_doubles_equal(v, fp_range.from_value) || __are_doubles_equal(v, fp_range.to_value)) {
return result;
}
if ((v < fp_range.from_value) || (v > fp_range.to_value)) {
const double v = value.get<double>();
const auto& fp_range = descriptor.floating_point_range.at(0);
const bool within_range = (v >= fp_range.from_value) && (v <= fp_range.to_value);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This removed the epsilon, shouldn't it be

Suggested change
const bool within_range = (v >= fp_range.from_value) && (v <= fp_range.to_value);
const bool within_range = (v >= fp_range.from_value - std::numeric_limits<double>::epsilon() ) && (v <= fp_range.to_value + + std::numeric_limits<double>::epsilon() );

Also, if the __are_doubles_equal function is obviously broken, why was it not removed ?

if (!within_range) {
result.successful = false;
result.reason = format_range_reason(descriptor.name, "floating point");
return result;
}
if (fp_range.step == 0.0) {
return result;
}
double rounded_div = std::round((v - fp_range.from_value) / fp_range.step);
const double rounded_div = std::round((v - fp_range.from_value) / fp_range.step);
if (__are_doubles_equal(v, fp_range.from_value + rounded_div * fp_range.step)) {
return result;
}
Expand Down
63 changes: 63 additions & 0 deletions rclcpp/test/rclcpp/node_interfaces/test_node_parameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,69 @@ TEST_F(TestNodeParameters, set_parameters) {
EXPECT_TRUE(result[0].successful);
}

TEST_F(TestNodeParameters, double_parameter_range)
{
rclcpp::NodeOptions node_options;
node_options.allow_undeclared_parameters(true);

rcl_interfaces::msg::ParameterDescriptor double_descriptor;
double_descriptor.name = "double_parameter";
double_descriptor.type = rcl_interfaces::msg::ParameterType::PARAMETER_DOUBLE;
double_descriptor.read_only = false;

rcl_interfaces::msg::FloatingPointRange range;
range.from_value = -1.0;
range.to_value = 666.0;
double_descriptor.floating_point_range.push_back(range);

const auto default_value = rclcpp::ParameterValue(0.0);

const auto loaded_value = node->declare_parameter(
double_descriptor.name,
default_value,
double_descriptor
);
EXPECT_EQ(loaded_value, default_value);

{
const rclcpp::Parameter new_parameter = rclcpp::Parameter(
"double_parameter",
std::numeric_limits<double>::infinity()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

include <limits>

);
const auto result = node->set_parameter(new_parameter);
EXPECT_FALSE(result.successful);
EXPECT_EQ(
"Parameter {double_parameter} doesn't comply with floating point range.",
result.reason
);
}

{
const rclcpp::Parameter new_parameter = rclcpp::Parameter(
"double_parameter",
std::numeric_limits<double>::quiet_NaN()
);
const auto result = node->set_parameter(new_parameter);
EXPECT_FALSE(result.successful);
EXPECT_EQ(
"Parameter {double_parameter} doesn't comply with floating point range.",
result.reason
);
}

{
const rclcpp::Parameter new_parameter = rclcpp::Parameter("double_parameter", range.to_value);
const auto result = node->set_parameter(new_parameter);
EXPECT_TRUE(result.successful);
}

{
const rclcpp::Parameter new_parameter = rclcpp::Parameter("double_parameter", range.from_value);
const auto result = node->set_parameter(new_parameter);
EXPECT_TRUE(result.successful);
}
}

TEST_F(TestNodeParameters, add_remove_on_set_parameters_callback) {
rcl_interfaces::msg::ParameterDescriptor bool_descriptor;
bool_descriptor.name = "bool_parameter";
Expand Down