From 2009ca676b141306aabcf6e396231f9a1bab3186 Mon Sep 17 00:00:00 2001 From: William Woodall Date: Mon, 20 Mar 2017 17:04:12 -0700 Subject: [PATCH] add a new Node::get_parameter() with a default value (#309) * add a new Node::get_parameter() with a default value * update function parameter name (signature) * update function parameter name (definition) * rename new function to get_parameter_or * rename arg "parameter" to "value" and fix get_parameter * add set_parameter_if_not_set * add some comments to clarify logic in set_parameters_atomically * uncrustify * address comments * add some docs for get_parameter* --- rclcpp/include/rclcpp/node.hpp | 32 ++++++++++++++++ rclcpp/include/rclcpp/node_impl.hpp | 38 +++++++++++++++++-- .../node_interfaces/node_parameters.cpp | 7 ++++ 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/rclcpp/include/rclcpp/node.hpp b/rclcpp/include/rclcpp/node.hpp index 48ff732..40679ff 100644 --- a/rclcpp/include/rclcpp/node.hpp +++ b/rclcpp/include/rclcpp/node.hpp @@ -235,6 +235,12 @@ public: rcl_interfaces::msg::SetParametersResult set_parameters_atomically(const std::vector & parameters); + template + void + set_parameter_if_not_set( + const std::string & name, + const ParameterT & value); + RCLCPP_PUBLIC std::vector get_parameters(const std::vector & names) const; @@ -249,10 +255,36 @@ public: const std::string & name, rclcpp::parameter::ParameterVariant & parameter) const; + /// Assign the value of the parameter if set into the parameter argument. + /** + * If the parameter was not set, then the "parameter" argument is never assigned a value. + * + * \param[in] name The name of the parameter to get. + * \param[out] parameter The output where the value of the parameter should be assigned. + * \returns true if the parameter was set, false otherwise + */ template bool get_parameter(const std::string & name, ParameterT & parameter) const; + /// Get the parameter value, or the "alternative value" if not set, and assign it to "value". + /** + * If the parameter was not set, then the "value" argument is assigned + * the "alternative_value". + * In all cases, the parameter remains not set after this function is called. + * + * \param[in] name The name of the parameter to get. + * \param[out] value The output where the value of the parameter should be assigned. + * \param[in] alternative_value Value to be stored in output if the parameter was not set. + * \returns true if the parameter was set, false otherwise + */ + template + bool + get_parameter_or( + const std::string & name, + ParameterT & value, + const ParameterT & alternative_value) const; + RCLCPP_PUBLIC std::vector describe_parameters(const std::vector & names) const; diff --git a/rclcpp/include/rclcpp/node_impl.hpp b/rclcpp/include/rclcpp/node_impl.hpp index b249bc3..5a2f01f 100644 --- a/rclcpp/include/rclcpp/node_impl.hpp +++ b/rclcpp/include/rclcpp/node_impl.hpp @@ -208,16 +208,46 @@ Node::register_param_change_callback(CallbackT && callback) } template -bool -Node::get_parameter(const std::string & name, ParameterT & parameter) const +void +Node::set_parameter_if_not_set( + const std::string & name, + const ParameterT & value) { - rclcpp::parameter::ParameterVariant parameter_variant(name, parameter); + rclcpp::parameter::ParameterVariant parameter_variant; + if (!this->get_parameter(name, parameter_variant)) { + this->set_parameters({ + rclcpp::parameter::ParameterVariant(name, value), + }); + } +} + +template +bool +Node::get_parameter(const std::string & name, ParameterT & value) const +{ + rclcpp::parameter::ParameterVariant parameter_variant; bool result = get_parameter(name, parameter_variant); - parameter = parameter_variant.get_value(); + if (result) { + value = parameter_variant.get_value(); + } return result; } +template +bool +Node::get_parameter_or( + const std::string & name, + ParameterT & value, + const ParameterT & alternative_value) const +{ + bool got_parameter = get_parameter(name, value); + if (!got_parameter) { + value = alternative_value; + } + return got_parameter; +} + } // namespace node } // namespace rclcpp diff --git a/rclcpp/src/rclcpp/node_interfaces/node_parameters.cpp b/rclcpp/src/rclcpp/node_interfaces/node_parameters.cpp index 61a79f0..37e57a2 100644 --- a/rclcpp/src/rclcpp/node_interfaces/node_parameters.cpp +++ b/rclcpp/src/rclcpp/node_interfaces/node_parameters.cpp @@ -83,11 +83,18 @@ NodeParameters::set_parameters_atomically( for (auto p : parameters) { if (parameters_.find(p.get_name()) == parameters_.end()) { if (p.get_type() != rclcpp::parameter::ParameterType::PARAMETER_NOT_SET) { + // case: parameter not set before, and input is something other than "NOT_SET" parameter_event->new_parameters.push_back(p.to_parameter()); } } else if (p.get_type() != rclcpp::parameter::ParameterType::PARAMETER_NOT_SET) { + // case: parameter was set before, and input is something other than "NOT_SET" parameter_event->changed_parameters.push_back(p.to_parameter()); } else { + // case: parameter was set before, and input is "NOT_SET" + // therefore we will "unset" the previously set parameter + // it is not necessary to erase the parameter from parameters_ + // because the new value for this key (p.get_name()) will be a + // ParameterVariant with type "NOT_SET" parameter_event->deleted_parameters.push_back(p.to_parameter()); } tmp_map[p.get_name()] = p;