From 1081e7507946c702f767fef14842764c194df52a Mon Sep 17 00:00:00 2001 From: Michael Jeronimo Date: Wed, 15 May 2019 15:15:40 -0700 Subject: [PATCH] Add missing template functionality to lifecycle_node. (#707) * Add missing template functionality to lifecycle_node. Recent changes to the node_parameters interface was accompanied by additions to the node.hpp header and implementation files. However, these additions were not also made to the corresponding lifecycle node files. This PR includes the changes required for the lifecycle node. Going forward, I suggest that any code like this that supplements the basic node interfaces should either be factored out into a separate header that both node and lifecycle_node include, or that the supplemental code simply be included in the appropriate node_interface file directly, if possible. That way we can avoid code duplication and its symptoms which is node and lifecycle_node getting out of sync (which they have several times). Signed-off-by: Michael Jeronimo * consolidate documentation to just be in rclcpp/node.hpp Signed-off-by: William Woodall * fix visibility macros Signed-off-by: William Woodall * deprecation methods that were also deprecated in rclcpp::Node Signed-off-by: William Woodall * fixup variable name Signed-off-by: William Woodall * add missing template method implementations Signed-off-by: William Woodall * add more methods that were not ported to lifecycle node originally Signed-off-by: William Woodall * fix cpplint Signed-off-by: William Woodall --- rclcpp/include/rclcpp/node.hpp | 1 - .../rclcpp_lifecycle/lifecycle_node.hpp | 198 ++++++++++++++---- .../rclcpp_lifecycle/lifecycle_node_impl.hpp | 60 +++++- rclcpp_lifecycle/src/lifecycle_node.cpp | 49 ++++- 4 files changed, 267 insertions(+), 41 deletions(-) diff --git a/rclcpp/include/rclcpp/node.hpp b/rclcpp/include/rclcpp/node.hpp index 8c62250..240772a 100644 --- a/rclcpp/include/rclcpp/node.hpp +++ b/rclcpp/include/rclcpp/node.hpp @@ -940,7 +940,6 @@ public: void register_param_change_callback(CallbackT && callback); - /// Get the fully-qualified names of all available nodes. /** * The fully-qualified name includes the local namespace and name of the node. diff --git a/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node.hpp b/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node.hpp index 7779ca1..05bd0d2 100644 --- a/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node.hpp +++ b/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node.hpp @@ -15,10 +15,11 @@ #ifndef RCLCPP_LIFECYCLE__LIFECYCLE_NODE_HPP_ #define RCLCPP_LIFECYCLE__LIFECYCLE_NODE_HPP_ -#include #include -#include #include +#include +#include +#include #include "rcl/error_handling.h" #include "rcl/node.h" @@ -333,15 +334,100 @@ public: const rmw_qos_profile_t & qos_profile = rmw_qos_profile_services_default, rclcpp::callback_group::CallbackGroup::SharedPtr group = nullptr); + /// Declare and initialize a parameter, return the effective value. + /** + * \sa rclcpp::Node::declare_parameter + */ + RCLCPP_LIFECYCLE_PUBLIC + const rclcpp::ParameterValue & + declare_parameter( + const std::string & name, + const rclcpp::ParameterValue & default_value = rclcpp::ParameterValue(), + const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor = + rcl_interfaces::msg::ParameterDescriptor()); + + /// Declare and initialize a parameter with a type. + /** + * \sa rclcpp::Node::declare_parameter + */ + template + auto + declare_parameter( + const std::string & name, + const ParameterT & default_value, + const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor = + rcl_interfaces::msg::ParameterDescriptor()); + + /// Declare and initialize several parameters with the same namespace and type. + /** + * \sa rclcpp::Node::declare_parameters + */ + template + std::vector + declare_parameters( + const std::string & namespace_, + const std::map & parameters); + + /// Declare and initialize several parameters with the same namespace and type. + /** + * \sa rclcpp::Node::declare_parameters + */ + template + std::vector + declare_parameters( + const std::string & namespace_, + const std::map< + std::string, + std::pair + > & parameters); + + /// Undeclare a previously declared parameter. + /** + * \sa rclcpp::Node::undeclare_parameter + */ + RCLCPP_LIFECYCLE_PUBLIC + void + undeclare_parameter(const std::string & name); + + /// Return true if a given parameter is declared. + /** + * \sa rclcpp::Node::has_parameter + */ + RCLCPP_LIFECYCLE_PUBLIC + bool + has_parameter(const std::string & name) const; + + /// Set a single parameter. + /** + * \sa rclcpp::Node::set_parameter + */ + RCLCPP_LIFECYCLE_PUBLIC + rcl_interfaces::msg::SetParametersResult + set_parameter(const rclcpp::Parameter & parameter); + + /// Set one or more parameters, one at a time. + /** + * \sa rclcpp::Node::set_parameters + */ RCLCPP_LIFECYCLE_PUBLIC std::vector set_parameters(const std::vector & parameters); + /// Set one or more parameters, all at once. + /** + * \sa rclcpp::Node::set_parameters_atomically + */ RCLCPP_LIFECYCLE_PUBLIC rcl_interfaces::msg::SetParametersResult set_parameters_atomically(const std::vector & parameters); + /// Set one parameter, unless that parameter has already been set. + /** + * \sa rclcpp::Node::set_parameter_if_not_set + */ template + // cppcheck-suppress syntaxError // bug in cppcheck 1.82 for [[deprecated]] on templated function + [[deprecated("use declare_parameter() instead")]] void set_parameter_if_not_set( const std::string & name, @@ -349,54 +435,46 @@ public: /// Set a map of parameters with the same prefix. /** - * For each key in the map, a parameter with a name of "name.key" will be set - * to the value in the map. - * - * \param[in] name The prefix of the parameters to set. - * \param[in] values The parameters to set in the given prefix. + * \sa rclcpp::Node::set_parameters_if_not_set */ template + // cppcheck-suppress syntaxError // bug in cppcheck 1.82 for [[deprecated]] on templated function + [[deprecated("use declare_parameters() instead")]] void set_parameters_if_not_set( const std::string & name, const std::map & values); - RCLCPP_LIFECYCLE_PUBLIC - std::vector - get_parameters(const std::vector & names) const; - + /// Return the parameter by the given name. + /** + * \sa rclcpp::Node::get_parameter + */ RCLCPP_LIFECYCLE_PUBLIC rclcpp::Parameter get_parameter(const std::string & name) const; + /// Get the value of a parameter by the given name, and return true if it was set. + /** + * \sa rclcpp::Node::get_parameter + */ RCLCPP_LIFECYCLE_PUBLIC bool get_parameter( const std::string & name, rclcpp::Parameter & parameter) const; + /// Get the value of a parameter by the given name, and return true if it was set. + /** + * \sa rclcpp::Node::get_parameter + */ template bool get_parameter(const std::string & name, ParameterT & parameter) const; - /// Assign the value of the map parameter if set into the values argument. + /// Get the parameter value, or the "alternative_value" if not set, and assign it to "parameter". /** - * Parameter names that are part of a map are of the form "name.member". - * This API gets all parameters that begin with "name", storing them into the - * map with the name of the parameter and their value. - * If there are no members in the named map, then the "values" argument is not changed. - * - * \param[in] name The prefix of the parameters to get. - * \param[out] values The map of output values, with one std::string,MapValueT - * per parameter. - * \returns true if values was changed, false otherwise + * \sa rclcpp::Node::get_parameter_or */ - template - bool - get_parameters( - const std::string & name, - std::map & values) const; - template bool get_parameter_or( @@ -404,42 +482,88 @@ public: ParameterT & value, const ParameterT & alternative_value) const; + /// Return the parameters by the given parameter names. + /** + * \sa rclcpp::Node::get_parameters + */ + RCLCPP_LIFECYCLE_PUBLIC + std::vector + get_parameters(const std::vector & names) const; + + /// Get the parameter values for all parameters that have a given prefix. + /** + * \sa rclcpp::Node::get_parameters + */ + template + bool + get_parameters( + const std::string & prefix, + std::map & values) const; + /// Get the parameter value; if not set, set the "alternative value" and store it in the node. /** - * If the parameter is set, then the "value" argument is assigned the value - * in the parameter. - * If the parameter is not set, then the "value" argument is assigned the "alternative_value", - * and the parameter is set to the "alternative_value" on the node. - * - * \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 and parameter if the parameter was not set. + * \sa rclcpp::Node::get_parameter_or_set */ template + // cppcheck-suppress syntaxError // bug in cppcheck 1.82 for [[deprecated]] on templated function + [[deprecated("use declare_parameter() and it's return value instead")]] void get_parameter_or_set( const std::string & name, ParameterT & value, const ParameterT & alternative_value); + /// Return the parameter descriptor for the given parameter name. + /** + * \sa rclcpp::Node::describe_parameter + */ + RCLCPP_LIFECYCLE_PUBLIC + rcl_interfaces::msg::ParameterDescriptor + describe_parameter(const std::string & name) const; + + /// Return a vector of parameter descriptors, one for each of the given names. + /** + * \sa rclcpp::Node::describe_parameters + */ RCLCPP_LIFECYCLE_PUBLIC std::vector describe_parameters(const std::vector & names) const; + /// Return a vector of parameter types, one for each of the given names. + /** + * \sa rclcpp::Node::get_parameter_types + */ RCLCPP_LIFECYCLE_PUBLIC std::vector get_parameter_types(const std::vector & names) const; + /// Return a list of parameters with any of the given prefixes, up to the given depth. + /** + * \sa rclcpp::Node::list_parameters + */ RCLCPP_LIFECYCLE_PUBLIC rcl_interfaces::msg::ListParametersResult list_parameters(const std::vector & prefixes, uint64_t depth) const; + using OnParametersSetCallbackType = + rclcpp::node_interfaces::NodeParametersInterface::OnParametersSetCallbackType; + + /// Register a callback to be called anytime a parameter is about to be changed. + /** + * \sa rclcpp::Node::set_on_parameters_set_callback + */ + RCLCPP_LIFECYCLE_PUBLIC + rclcpp_lifecycle::LifecycleNode::OnParametersSetCallbackType + set_on_parameters_set_callback( + rclcpp_lifecycle::LifecycleNode::OnParametersSetCallbackType callback); + /// Register the callback for parameter changes /** - * \param[in] callback User defined function which is expected to atomically set parameters. - * \note Repeated invocations of this function will overwrite previous callbacks + * \sa rclcpp::Node::register_param_change_callback */ template + // cppcheck-suppress syntaxError // bug in cppcheck 1.82 for [[deprecated]] on templated function + [[deprecated("use set_on_parameters_set_callback() instead")]] void register_param_change_callback(CallbackT && callback); diff --git a/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node_impl.hpp b/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node_impl.hpp index aeab685..e9429a1 100644 --- a/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node_impl.hpp +++ b/rclcpp_lifecycle/include/rclcpp_lifecycle/lifecycle_node_impl.hpp @@ -223,6 +223,62 @@ LifecycleNode::create_service( service_name, std::forward(callback), qos_profile, group); } +template +auto +LifecycleNode::declare_parameter( + const std::string & name, + const ParameterT & default_value, + const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor) +{ + return this->declare_parameter( + name, + rclcpp::ParameterValue(default_value), + parameter_descriptor + ).get(); +} + +template +std::vector +LifecycleNode::declare_parameters( + const std::string & namespace_, + const std::map & parameters) +{ + 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); + } + ); + return result; +} + +template +std::vector +LifecycleNode::declare_parameters( + const std::string & namespace_, + const std::map< + std::string, + std::pair + > & parameters) +{ + 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 static_cast( + this->declare_parameter( + normalized_namespace + element.first, + element.second.first, + element.second.second) + ); + } + ); + return result; +} + template bool LifecycleNode::get_parameter(const std::string & name, ParameterT & parameter) const @@ -283,11 +339,11 @@ LifecycleNode::set_parameters_if_not_set( template bool LifecycleNode::get_parameters( - const std::string & name, + const std::string & prefix, std::map & values) const { std::map params; - bool result = node_parameters_->get_parameters_by_prefix(name, params); + bool result = node_parameters_->get_parameters_by_prefix(prefix, params); if (result) { for (const auto & param : params) { values[param.first] = param.second.get_value(); diff --git a/rclcpp_lifecycle/src/lifecycle_node.cpp b/rclcpp_lifecycle/src/lifecycle_node.cpp index 4c60f41..f277d0f 100644 --- a/rclcpp_lifecycle/src/lifecycle_node.cpp +++ b/rclcpp_lifecycle/src/lifecycle_node.cpp @@ -154,6 +154,33 @@ LifecycleNode::create_callback_group( return node_base_->create_callback_group(group_type); } +const rclcpp::ParameterValue & +LifecycleNode::declare_parameter( + const std::string & name, + const rclcpp::ParameterValue & default_value, + const rcl_interfaces::msg::ParameterDescriptor & parameter_descriptor) +{ + return this->node_parameters_->declare_parameter(name, default_value, parameter_descriptor); +} + +void +LifecycleNode::undeclare_parameter(const std::string & name) +{ + this->node_parameters_->undeclare_parameter(name); +} + +bool +LifecycleNode::has_parameter(const std::string & name) const +{ + return this->node_parameters_->has_parameter(name); +} + +rcl_interfaces::msg::SetParametersResult +LifecycleNode::set_parameter(const rclcpp::Parameter & parameter) +{ + return this->set_parameters_atomically({parameter}); +} + bool LifecycleNode::group_in_node(rclcpp::callback_group::CallbackGroup::SharedPtr group) { @@ -187,13 +214,27 @@ LifecycleNode::get_parameter(const std::string & name) const return node_parameters_->get_parameter(name); } -bool LifecycleNode::get_parameter( +bool +LifecycleNode::get_parameter( const std::string & name, rclcpp::Parameter & parameter) const { return node_parameters_->get_parameter(name, parameter); } +rcl_interfaces::msg::ParameterDescriptor +LifecycleNode::describe_parameter(const std::string & name) const +{ + auto result = node_parameters_->describe_parameters({name}); + if (0 == result.size()) { + throw rclcpp::exceptions::ParameterNotDeclaredException(name); + } + if (result.size() > 1) { + throw std::runtime_error("number of described parameters unexpectedly more than one"); + } + return result.front(); +} + std::vector LifecycleNode::describe_parameters( const std::vector & names) const @@ -215,6 +256,12 @@ LifecycleNode::list_parameters( return node_parameters_->list_parameters(prefixes, depth); } +rclcpp::Node::OnParametersSetCallbackType +LifecycleNode::set_on_parameters_set_callback(rclcpp::Node::OnParametersSetCallbackType callback) +{ + return node_parameters_->set_on_parameters_set_callback(callback); +} + std::vector LifecycleNode::get_node_names() const {