diff --git a/rclcpp/include/rclcpp/node.hpp b/rclcpp/include/rclcpp/node.hpp index 837965c..a070868 100644 --- a/rclcpp/include/rclcpp/node.hpp +++ b/rclcpp/include/rclcpp/node.hpp @@ -369,6 +369,8 @@ public: * are ignored, and should be specified using the name argument to this * function and the default value's type instead. * + * If `ignore_override` is `true`, the parameter override will be ignored. + * * This method, if successful, will result in any callback registered with * set_on_parameters_set_callback to be called. * If that callback prevents the initial value for the parameter from being @@ -382,6 +384,8 @@ public: * did not override it. * \param[in] parameter_descriptor An optional, custom description for * the parameter. + * \param[in] ignore_override When `true`, the parameter override is ignored. + * Default to `false`. * \return A const reference to the value of the parameter. * \throws rclcpp::exceptions::ParameterAlreadyDeclaredException if parameter * has already been declared. @@ -396,7 +400,8 @@ public: const std::string & name, const rclcpp::ParameterValue & default_value = rclcpp::ParameterValue(), const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor = - rcl_interfaces::msg::ParameterDescriptor()); + rcl_interfaces::msg::ParameterDescriptor(), + bool ignore_override = false); /// Declare and initialize a parameter with a type. /** @@ -425,7 +430,8 @@ public: const std::string & name, const ParameterT & default_value, const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor = - rcl_interfaces::msg::ParameterDescriptor()); + rcl_interfaces::msg::ParameterDescriptor(), + bool ignore_override = false); /// Declare and initialize several parameters with the same namespace and type. /** @@ -440,11 +446,12 @@ public: * expanding "namespace.key". * This allows you to declare several parameters at once without a namespace. * - * The map may either contain default values for parameters, or a std::pair - * where the first element is a default value and the second is a - * parameter descriptor. - * This function only takes the default value, but there is another overload - * which takes the std::pair with the default value and descriptor. + * The map contains default values for parameters. + * There is another overload which takes the std::pair with the default value + * and descriptor. + * + * If `ignore_overrides` is `true`, all the overrides of the parameters declared + * by the function call will be ignored. * * This method, if successful, will result in any callback registered with * set_on_parameters_set_callback to be called, once for each parameter. @@ -453,6 +460,8 @@ public: * * \param[in] namespace_ The namespace in which to declare the parameters. * \param[in] parameters The parameters to set in the given namespace. + * \param[in] ignore_overrides When `true`, the parameters overrides are ignored. + * Default to `false`. * \throws rclcpp::exceptions::ParameterAlreadyDeclaredException if parameter * has already been declared. * \throws rclcpp::exceptions::InvalidParametersException if a parameter @@ -464,7 +473,8 @@ public: std::vector declare_parameters( const std::string & namespace_, - const std::map & parameters); + const std::map & parameters, + bool ignore_overrides = false); /// Declare and initialize several parameters with the same namespace and type. /** @@ -480,7 +490,8 @@ public: const std::map< std::string, std::pair - > & parameters); + > & parameters, + bool ignore_overrides = false); /// Undeclare a previously declared parameter. /** diff --git a/rclcpp/include/rclcpp/node_impl.hpp b/rclcpp/include/rclcpp/node_impl.hpp index 94352fa..850ea0c 100644 --- a/rclcpp/include/rclcpp/node_impl.hpp +++ b/rclcpp/include/rclcpp/node_impl.hpp @@ -250,12 +250,14 @@ auto Node::declare_parameter( const std::string & name, const ParameterT & default_value, - const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor) + const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor, + bool ignore_override) { return this->declare_parameter( name, rclcpp::ParameterValue(default_value), - parameter_descriptor + parameter_descriptor, + ignore_override ).get(); } @@ -263,14 +265,19 @@ template std::vector Node::declare_parameters( const std::string & namespace_, - const std::map & parameters) + const std::map & parameters, + bool ignore_overrides) { std::vector result; std::string normalized_namespace = namespace_.empty() ? "" : (namespace_ + "."); std::transform( parameters.begin(), parameters.end(), std::back_inserter(result), - [this, &normalized_namespace](auto element) { - return this->declare_parameter(normalized_namespace + element.first, element.second); + [this, &normalized_namespace, ignore_overrides](auto element) { + return this->declare_parameter( + normalized_namespace + element.first, + element.second, + rcl_interfaces::msg::ParameterDescriptor(), + ignore_overrides); } ); return result; @@ -283,18 +290,20 @@ Node::declare_parameters( const std::map< std::string, std::pair - > & parameters) + > & parameters, + bool ignore_overrides) { std::vector result; std::string normalized_namespace = namespace_.empty() ? "" : (namespace_ + "."); std::transform( parameters.begin(), parameters.end(), std::back_inserter(result), - [this, &normalized_namespace](auto element) { + [this, &normalized_namespace, ignore_overrides](auto element) { return static_cast( this->declare_parameter( normalized_namespace + element.first, element.second.first, - element.second.second) + element.second.second, + ignore_overrides) ); } ); diff --git a/rclcpp/include/rclcpp/node_interfaces/node_parameters.hpp b/rclcpp/include/rclcpp/node_interfaces/node_parameters.hpp index c99f4c2..149bcbd 100644 --- a/rclcpp/include/rclcpp/node_interfaces/node_parameters.hpp +++ b/rclcpp/include/rclcpp/node_interfaces/node_parameters.hpp @@ -80,7 +80,8 @@ public: declare_parameter( const std::string & name, const rclcpp::ParameterValue & default_value, - const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor) override; + const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor, + bool ignore_override) override; RCLCPP_PUBLIC void diff --git a/rclcpp/include/rclcpp/node_interfaces/node_parameters_interface.hpp b/rclcpp/include/rclcpp/node_interfaces/node_parameters_interface.hpp index deb2be2..68f8c55 100644 --- a/rclcpp/include/rclcpp/node_interfaces/node_parameters_interface.hpp +++ b/rclcpp/include/rclcpp/node_interfaces/node_parameters_interface.hpp @@ -53,7 +53,8 @@ public: const std::string & name, const rclcpp::ParameterValue & default_value = rclcpp::ParameterValue(), const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor = - rcl_interfaces::msg::ParameterDescriptor()) = 0; + rcl_interfaces::msg::ParameterDescriptor(), + bool ignore_override = false) = 0; /// Undeclare a parameter. /** diff --git a/rclcpp/src/rclcpp/node.cpp b/rclcpp/src/rclcpp/node.cpp index 3260313..98aab12 100644 --- a/rclcpp/src/rclcpp/node.cpp +++ b/rclcpp/src/rclcpp/node.cpp @@ -236,9 +236,14 @@ const rclcpp::ParameterValue & Node::declare_parameter( const std::string & name, const rclcpp::ParameterValue & default_value, - const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor) + const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor, + bool ignore_override) { - return this->node_parameters_->declare_parameter(name, default_value, parameter_descriptor); + return this->node_parameters_->declare_parameter( + name, + default_value, + parameter_descriptor, + ignore_override); } void diff --git a/rclcpp/src/rclcpp/node_interfaces/node_parameters.cpp b/rclcpp/src/rclcpp/node_interfaces/node_parameters.cpp index 252e1cf..df05954 100644 --- a/rclcpp/src/rclcpp/node_interfaces/node_parameters.cpp +++ b/rclcpp/src/rclcpp/node_interfaces/node_parameters.cpp @@ -170,7 +170,8 @@ NodeParameters::NodeParameters( this->declare_parameter( pair.first, pair.second, - rcl_interfaces::msg::ParameterDescriptor()); + rcl_interfaces::msg::ParameterDescriptor(), + true); } } } @@ -333,7 +334,7 @@ __declare_parameter_common( const std::map & overrides, OnParametersSetCallbackType on_set_parameters_callback, rcl_interfaces::msg::ParameterEvent * parameter_event_out, - bool use_overrides = true) + bool ignore_override = false) { using rclcpp::node_interfaces::ParameterInfo; std::map parameter_infos {{name, ParameterInfo()}}; @@ -342,7 +343,7 @@ __declare_parameter_common( // Use the value from the overrides if available, otherwise use the default. const rclcpp::ParameterValue * initial_value = &default_value; auto overrides_it = overrides.find(name); - if (use_overrides && overrides_it != overrides.end()) { + if (!ignore_override && overrides_it != overrides.end()) { initial_value = &overrides_it->second; } @@ -369,7 +370,8 @@ const rclcpp::ParameterValue & NodeParameters::declare_parameter( const std::string & name, const rclcpp::ParameterValue & default_value, - const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor) + const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor, + bool ignore_override) { std::lock_guard lock(mutex_); @@ -392,7 +394,8 @@ NodeParameters::declare_parameter( parameters_, parameter_overrides_, on_parameters_set_callback_, - ¶meter_event); + ¶meter_event, + ignore_override); // If it failed to be set, then throw an exception. if (!result.successful) { @@ -524,7 +527,7 @@ NodeParameters::set_parameters_atomically(const std::vector & parameter_overrides_, nullptr, // callback is explicitly null, so that it is called only once, when setting below. ¶meter_event_msg, - false); + true); if (!result.successful) { // Declare failed, return knowing that nothing was changed because the // staged changes were not applied. diff --git a/rclcpp/test/test_node.cpp b/rclcpp/test/test_node.cpp index ea55ca2..862bcb6 100644 --- a/rclcpp/test/test_node.cpp +++ b/rclcpp/test/test_node.cpp @@ -362,14 +362,15 @@ TEST_F(TestNode, declare_parameter_with_no_initial_values) { } } -TEST_F(TestNode, declare_parameter_with_initial_values) { - // test cases with initial values +TEST_F(TestNode, declare_parameter_with_overrides) { + // test cases with overrides rclcpp::NodeOptions no; no.parameter_overrides({ {"parameter_no_default", 42}, {"parameter_no_default_set", 42}, {"parameter_no_default_set_cvref", 42}, {"parameter_and_default", 42}, + {"parameter_and_default_ignore_override", 42}, {"parameter_custom", 42}, {"parameter_template", 42}, {"parameter_already_declared", 42}, @@ -378,13 +379,13 @@ TEST_F(TestNode, declare_parameter_with_initial_values) { }); auto node = std::make_shared("test_declare_parameter_node"_unq, no); { - // no default, with initial + // no default, with override rclcpp::ParameterValue value = node->declare_parameter("parameter_no_default"); EXPECT_EQ(value.get_type(), rclcpp::PARAMETER_INTEGER); EXPECT_EQ(value.get(), 42); } { - // no default, with initial, and set after + // no default, with override, and set after rclcpp::ParameterValue value = node->declare_parameter("parameter_no_default_set"); EXPECT_EQ(value.get_type(), rclcpp::PARAMETER_INTEGER); EXPECT_EQ(value.get(), 42); @@ -393,7 +394,7 @@ TEST_F(TestNode, declare_parameter_with_initial_values) { EXPECT_EQ(node->get_parameter("parameter_no_default_set").get_value(), 44); } { - // no default, with initial + // no default, with override const rclcpp::ParameterValue & value = node->declare_parameter("parameter_no_default_set_cvref"); EXPECT_EQ(value.get_type(), rclcpp::PARAMETER_INTEGER); @@ -403,12 +404,23 @@ TEST_F(TestNode, declare_parameter_with_initial_values) { EXPECT_EQ(value.get(), 44); } { - // int default, with initial + // int default, with override rclcpp::ParameterValue default_value(43); rclcpp::ParameterValue value = node->declare_parameter("parameter_and_default", default_value); EXPECT_EQ(value.get_type(), rclcpp::PARAMETER_INTEGER); EXPECT_EQ(value.get(), 42); // and not 43 which is the default value } + { + // int default, with override and ignoring it + rclcpp::ParameterValue default_value(43); + rclcpp::ParameterValue value = node->declare_parameter( + "parameter_and_default_ignore_override", + default_value, + rcl_interfaces::msg::ParameterDescriptor(), + true); + EXPECT_EQ(value.get_type(), rclcpp::PARAMETER_INTEGER); + EXPECT_EQ(value.get(), 43); // and not 42, the parameter override is ignored. + } { // int default, with initial, custom parameter descriptor rclcpp::ParameterValue default_value(43);