Compare commits
17 Commits
runtime_in
...
check_para
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36ca813813 | ||
|
|
8f0705b08b | ||
|
|
2e32bc300c | ||
|
|
7e5e75a748 | ||
|
|
c94a1bf286 | ||
|
|
17b3b971b3 | ||
|
|
c026f89650 | ||
|
|
1eecfe73cc | ||
|
|
2e20bcb844 | ||
|
|
be9f07a414 | ||
|
|
3f344549b9 | ||
|
|
58fd8edee1 | ||
|
|
b0ac4453a3 | ||
|
|
3845f03d8a | ||
|
|
6651abcbe9 | ||
|
|
e86de20b7a | ||
|
|
bf03325e0a |
@@ -95,6 +95,7 @@ public:
|
||||
* pipeline to pass messages between nodes in the same process using shared memory.
|
||||
* \param[in] start_parameter_services True to setup ROS interfaces for accessing parameters
|
||||
* in the node.
|
||||
* \param[in] allow_undeclared_parameters True to allow any parameter name to be set on the node.
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
Node(
|
||||
@@ -105,7 +106,8 @@ public:
|
||||
const std::vector<Parameter> & initial_parameters,
|
||||
bool use_global_arguments = true,
|
||||
bool use_intra_process_comms = false,
|
||||
bool start_parameter_services = true);
|
||||
bool start_parameter_services = true,
|
||||
bool allow_undeclared_parameters = false);
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
virtual ~Node();
|
||||
@@ -265,6 +267,36 @@ 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.
|
||||
/**
|
||||
* This method is used to declare that a parameter exists on this node.
|
||||
* If a run-time user has provided an an initial value then it will be set in this method,
|
||||
* otherwise the default_value will be set.
|
||||
* \param[in] name the name of the parameter
|
||||
* \param[in] default_value An initial value to be used if a run-time user did not override it.
|
||||
* \param[in] read_only if True then this parameter may not be changed after initialization.
|
||||
* \throws std::runtime_error if parameter has already been declared.
|
||||
* \throws std::runtime_error if a parameter name is invalid.
|
||||
* \throws rclcpp::exceptions::InvalidParameterValueException if initial value fails to be set.
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
void
|
||||
declare_parameter(
|
||||
const std::string & name,
|
||||
const rclcpp::ParameterValue & default_value = rclcpp::ParameterValue(),
|
||||
bool read_only = false);
|
||||
|
||||
/// Declare and initialize a parameter with a type.
|
||||
/**
|
||||
* See the non-templated declare_parameter() on this class for details.
|
||||
*/
|
||||
template<typename ParameterT>
|
||||
void
|
||||
declare_parameter(
|
||||
const std::string & name,
|
||||
const ParameterT & default_value,
|
||||
bool read_only = false);
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
std::vector<rcl_interfaces::msg::SetParametersResult>
|
||||
set_parameters(const std::vector<rclcpp::Parameter> & parameters);
|
||||
|
||||
@@ -210,6 +210,16 @@ Node::register_param_change_callback(CallbackT && callback)
|
||||
this->node_parameters_->register_param_change_callback(std::forward<CallbackT>(callback));
|
||||
}
|
||||
|
||||
template<typename ParameterT>
|
||||
void
|
||||
Node::declare_parameter(
|
||||
const std::string & name,
|
||||
const ParameterT & default_value,
|
||||
bool read_only)
|
||||
{
|
||||
this->declare_parameter(name, rclcpp::ParameterValue(default_value), read_only);
|
||||
}
|
||||
|
||||
template<typename ParameterT>
|
||||
void
|
||||
Node::set_parameter_if_not_set(
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
// Copyright 2018 Open Source Robotics Foundation, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef RCLCPP__NODE_INTERFACES__GET_NODE_PARAMETERS_INTERFACE_HPP_
|
||||
#define RCLCPP__NODE_INTERFACES__GET_NODE_PARAMETERS_INTERFACE_HPP_
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <type_traits>
|
||||
|
||||
#include "rclcpp/node_interfaces/node_parameters_interface.hpp"
|
||||
|
||||
/// This header provides the get_node_parameters_interface() template function.
|
||||
/**
|
||||
* This function is useful for getting the NodeParametersInterface pointer from
|
||||
* various kinds of Node-like classes.
|
||||
*
|
||||
* It's able to get the NodeParametersInterface pointer so long as the class
|
||||
* has a method called ``get_node_parameters_interface()`` which returns
|
||||
* either a pointer (const or not) to a NodeParametersInterface or a
|
||||
* std::shared_ptr to a NodeParametersInterface.
|
||||
*/
|
||||
|
||||
namespace rclcpp
|
||||
{
|
||||
namespace node_interfaces
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// This is a meta-programming checker for if a given Node-like object has a
|
||||
// getter called get_node_parameters_interface() which returns various types,
|
||||
// e.g. const pointer or a shared pointer.
|
||||
template<typename NodeType, typename ReturnType>
|
||||
struct has_get_node_parameters_interface
|
||||
{
|
||||
private:
|
||||
template<typename T>
|
||||
static constexpr
|
||||
auto
|
||||
check(T *)->typename std::is_same<
|
||||
decltype(std::declval<T>().get_node_parameters_interface()),
|
||||
ReturnType
|
||||
>::type;
|
||||
|
||||
template<typename>
|
||||
static constexpr
|
||||
std::false_type
|
||||
check(...);
|
||||
|
||||
public:
|
||||
using type = decltype(check<NodeType>(nullptr));
|
||||
static constexpr bool value = type::value;
|
||||
};
|
||||
|
||||
// If NodeType is a pointer to NodeParametersInterface already (just normal function overload).
|
||||
inline
|
||||
const rclcpp::node_interfaces::NodeParametersInterface *
|
||||
get_node_parameters_interface_from_pointer(
|
||||
const rclcpp::node_interfaces::NodeParametersInterface * pointer)
|
||||
{
|
||||
return pointer;
|
||||
}
|
||||
|
||||
// If NodeType has a method called get_node_parameters_interface() which returns a shared pointer.
|
||||
template<
|
||||
typename NodeType,
|
||||
typename std::enable_if<has_get_node_parameters_interface<
|
||||
typename std::remove_pointer<NodeType>::type,
|
||||
std::shared_ptr<rclcpp::node_interfaces::NodeParametersInterface>
|
||||
>::value, int>::type = 0
|
||||
>
|
||||
const rclcpp::node_interfaces::NodeParametersInterface *
|
||||
get_node_parameters_interface_from_pointer(NodeType node_pointer)
|
||||
{
|
||||
return node_pointer->get_node_parameters_interface().get();
|
||||
}
|
||||
|
||||
// If NodeType has a method called get_node_parameters_interface() which returns a pointer.
|
||||
template<
|
||||
typename NodeType,
|
||||
typename std::enable_if<has_get_node_parameters_interface<
|
||||
typename std::remove_pointer<NodeType>::type,
|
||||
rclcpp::node_interfaces::NodeParametersInterface *
|
||||
>::value, int>::type = 0
|
||||
>
|
||||
const rclcpp::node_interfaces::NodeParametersInterface *
|
||||
get_node_parameters_interface_from_pointer(NodeType node_pointer)
|
||||
{
|
||||
return node_pointer->get_node_parameters_interface();
|
||||
}
|
||||
|
||||
// If NodeType has a method called get_node_parameters_interface() which returns a const pointer.
|
||||
template<
|
||||
typename NodeType,
|
||||
typename std::enable_if<has_get_node_parameters_interface<
|
||||
typename std::remove_pointer<NodeType>::type,
|
||||
const rclcpp::node_interfaces::NodeParametersInterface *
|
||||
>::value, int>::type = 0
|
||||
>
|
||||
const rclcpp::node_interfaces::NodeParametersInterface *
|
||||
get_node_parameters_interface_from_pointer(NodeType node_pointer)
|
||||
{
|
||||
return node_pointer->get_node_parameters_interface();
|
||||
}
|
||||
|
||||
// Forward shared_ptr's to const node pointer signatures.
|
||||
template<
|
||||
typename NodeType,
|
||||
typename std::enable_if<std::is_same<
|
||||
NodeType,
|
||||
typename std::shared_ptr<typename std::remove_pointer<NodeType>::type::element_type> *
|
||||
>::value, int>::type = 0
|
||||
>
|
||||
const rclcpp::node_interfaces::NodeParametersInterface *
|
||||
get_node_parameters_interface_from_pointer(NodeType node_shared_pointer)
|
||||
{
|
||||
return get_node_parameters_interface_from_pointer(node_shared_pointer->get());
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// Get the NodeParametersInterface as a const pointer from a pointer to a "Node like" object.
|
||||
template<
|
||||
typename NodeType,
|
||||
typename std::enable_if<std::is_pointer<NodeType>::value, int>::type = 0
|
||||
>
|
||||
const rclcpp::node_interfaces::NodeParametersInterface *
|
||||
get_node_parameters_interface(NodeType && node_pointer)
|
||||
{
|
||||
// Forward pointers to detail implmentation directly.
|
||||
return detail::get_node_parameters_interface_from_pointer(std::forward<NodeType>(node_pointer));
|
||||
}
|
||||
|
||||
/// Get the NodeParametersInterface as a const pointer from a "Node like" object.
|
||||
template<
|
||||
typename NodeType,
|
||||
typename std::enable_if<!std::is_pointer<NodeType>::value, int>::type = 0
|
||||
>
|
||||
const rclcpp::node_interfaces::NodeParametersInterface *
|
||||
get_node_parameters_interface(NodeType && node_reference)
|
||||
{
|
||||
// Forward const-references to detail implmentation as a pointer.
|
||||
return detail::get_node_parameters_interface_from_pointer(&node_reference);
|
||||
}
|
||||
|
||||
} // namespace node_interfaces
|
||||
} // namespace rclcpp
|
||||
|
||||
#endif // RCLCPP__NODE_INTERFACES__GET_NODE_PARAMETERS_INTERFACE_HPP_
|
||||
@@ -61,6 +61,7 @@ private:
|
||||
rclcpp::node_interfaces::NodeTopicsInterface::SharedPtr node_topics_;
|
||||
rclcpp::node_interfaces::NodeGraphInterface::SharedPtr node_graph_;
|
||||
rclcpp::node_interfaces::NodeServicesInterface::SharedPtr node_services_;
|
||||
rclcpp::node_interfaces::NodeParametersInterface::SharedPtr node_parameters_;
|
||||
rclcpp::node_interfaces::NodeLoggingInterface::SharedPtr node_logging_;
|
||||
|
||||
rclcpp::Clock::SharedPtr ros_clock_;
|
||||
|
||||
@@ -40,6 +40,19 @@ namespace rclcpp
|
||||
namespace node_interfaces
|
||||
{
|
||||
|
||||
// Internal struct for holding useful info about parameters
|
||||
struct ParameterInfo
|
||||
{
|
||||
/// True if a user called declare_parameter()
|
||||
bool is_declared = false;
|
||||
|
||||
/// Current value of the parameter.
|
||||
rclcpp::ParameterValue value;
|
||||
|
||||
/// A description of the parameter
|
||||
rcl_interfaces::msg::ParameterDescriptor descriptor;
|
||||
};
|
||||
|
||||
/// Implementation of the NodeParameters part of the Node API.
|
||||
class NodeParameters : public NodeParametersInterface
|
||||
{
|
||||
@@ -54,67 +67,65 @@ public:
|
||||
const node_interfaces::NodeClockInterface::SharedPtr node_clock,
|
||||
const std::vector<Parameter> & initial_parameters,
|
||||
bool use_intra_process,
|
||||
bool start_parameter_services);
|
||||
bool start_parameter_services,
|
||||
bool allow_undeclared_parameters);
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
virtual
|
||||
~NodeParameters();
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
virtual
|
||||
void
|
||||
declare_parameter(
|
||||
const std::string & name,
|
||||
const rclcpp::ParameterValue & default_value,
|
||||
bool read_only) override;
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
std::vector<rcl_interfaces::msg::SetParametersResult>
|
||||
set_parameters(
|
||||
const std::vector<rclcpp::Parameter> & parameters);
|
||||
const std::vector<rclcpp::Parameter> & parameters) override;
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
virtual
|
||||
rcl_interfaces::msg::SetParametersResult
|
||||
set_parameters_atomically(
|
||||
const std::vector<rclcpp::Parameter> & parameters);
|
||||
const std::vector<rclcpp::Parameter> & parameters) override;
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
virtual
|
||||
std::vector<rclcpp::Parameter>
|
||||
get_parameters(const std::vector<std::string> & names) const;
|
||||
get_parameters(const std::vector<std::string> & names) const override;
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
virtual
|
||||
rclcpp::Parameter
|
||||
get_parameter(const std::string & name) const;
|
||||
get_parameter(const std::string & name) const override;
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
virtual
|
||||
bool
|
||||
get_parameter(
|
||||
const std::string & name,
|
||||
rclcpp::Parameter & parameter) const;
|
||||
rclcpp::Parameter & parameter) const override;
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
virtual
|
||||
bool
|
||||
get_parameters_by_prefix(
|
||||
const std::string & prefix,
|
||||
std::map<std::string, rclcpp::Parameter> & parameters) const;
|
||||
std::map<std::string, rclcpp::Parameter> & parameters) const override;
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
virtual
|
||||
std::vector<rcl_interfaces::msg::ParameterDescriptor>
|
||||
describe_parameters(const std::vector<std::string> & names) const;
|
||||
describe_parameters(const std::vector<std::string> & names) const override;
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
virtual
|
||||
std::vector<uint8_t>
|
||||
get_parameter_types(const std::vector<std::string> & names) const;
|
||||
get_parameter_types(const std::vector<std::string> & names) const override;
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
virtual
|
||||
rcl_interfaces::msg::ListParametersResult
|
||||
list_parameters(const std::vector<std::string> & prefixes, uint64_t depth) const;
|
||||
list_parameters(const std::vector<std::string> & prefixes, uint64_t depth) const override;
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
virtual
|
||||
void
|
||||
register_param_change_callback(ParametersCallbackFunction callback);
|
||||
register_param_change_callback(ParametersCallbackFunction callback) override;
|
||||
|
||||
private:
|
||||
RCLCPP_DISABLE_COPY(NodeParameters)
|
||||
@@ -123,7 +134,11 @@ private:
|
||||
|
||||
ParametersCallbackFunction parameters_callback_ = nullptr;
|
||||
|
||||
std::map<std::string, rclcpp::Parameter> parameters_;
|
||||
std::map<std::string, ParameterInfo> parameters_;
|
||||
|
||||
std::map<std::string, rclcpp::ParameterValue> initial_parameter_values_;
|
||||
|
||||
bool allow_undeclared_ = false;
|
||||
|
||||
Publisher<rcl_interfaces::msg::ParameterEvent>::SharedPtr events_publisher_;
|
||||
|
||||
|
||||
@@ -38,6 +38,25 @@ class NodeParametersInterface
|
||||
public:
|
||||
RCLCPP_SMART_PTR_ALIASES_ONLY(NodeParametersInterface)
|
||||
|
||||
/// Declare and initialize a parameter.
|
||||
/* This method is used to declare that a parameter exists on this node.
|
||||
* If a run-time user has provided an an initial value then it will be set in this method,
|
||||
* otherwise the default_value will be set.
|
||||
* \param[in] name the name of the parameter
|
||||
* \param[in] default_value An initial value to be used if a run-time user did not override it.
|
||||
* \param[in] read_only if True then this parameter may not be changed after initialization.
|
||||
* \throws std::runtime_error if parameter has already been declared.
|
||||
* \throws std::runtime_error if a parameter name is invalid.
|
||||
* \throws rclcpp::exceptions::InvalidParameterValueException if initial value fails to be set.
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
virtual
|
||||
void
|
||||
declare_parameter(
|
||||
const std::string & name,
|
||||
const rclcpp::ParameterValue & default_value = rclcpp::ParameterValue(),
|
||||
bool read_only = false) = 0;
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
virtual
|
||||
~NodeParametersInterface() = default;
|
||||
|
||||
@@ -28,6 +28,25 @@
|
||||
namespace rclcpp
|
||||
{
|
||||
|
||||
class Parameter;
|
||||
|
||||
namespace node_interfaces
|
||||
{
|
||||
struct ParameterInfo;
|
||||
} // namespace node_interfaces
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// This helper function is required because you cannot do specialization on a
|
||||
// class method, so instead we specialize this template function and call it
|
||||
// from the unspecialized, but dependent, class method.
|
||||
template<typename T>
|
||||
auto
|
||||
get_value_helper(const rclcpp::Parameter * parameter);
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// Structure to store an arbitrary parameter with templated get/set methods.
|
||||
class Parameter
|
||||
{
|
||||
@@ -44,6 +63,9 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
explicit Parameter(const rclcpp::node_interfaces::ParameterInfo & parameter_info);
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
ParameterType
|
||||
get_type() const;
|
||||
@@ -60,6 +82,11 @@ public:
|
||||
rcl_interfaces::msg::ParameterValue
|
||||
get_value_message() const;
|
||||
|
||||
/// Get the internal storage for the parameter value.
|
||||
RCLCPP_PUBLIC
|
||||
const rclcpp::ParameterValue &
|
||||
get_parameter_value() const;
|
||||
|
||||
/// Get value of parameter using rclcpp::ParameterType as template argument.
|
||||
template<ParameterType ParamT>
|
||||
decltype(auto)
|
||||
@@ -71,10 +98,7 @@ public:
|
||||
/// Get value of parameter using c++ types as template argument.
|
||||
template<typename T>
|
||||
decltype(auto)
|
||||
get_value() const
|
||||
{
|
||||
return value_.get<T>();
|
||||
}
|
||||
get_value() const;
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
bool
|
||||
@@ -142,6 +166,49 @@ RCLCPP_PUBLIC
|
||||
std::ostream &
|
||||
operator<<(std::ostream & os, const std::vector<Parameter> & parameters);
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
auto
|
||||
get_value_helper(const rclcpp::Parameter * parameter)
|
||||
{
|
||||
return parameter->get_parameter_value().get<T>();
|
||||
}
|
||||
|
||||
// Specialization allowing Parameter::get() to return a const ref to the parameter value object.
|
||||
template<>
|
||||
inline
|
||||
auto
|
||||
get_value_helper<rclcpp::ParameterValue>(const rclcpp::Parameter * parameter)
|
||||
{
|
||||
return parameter->get_parameter_value();
|
||||
}
|
||||
|
||||
// Specialization allowing Parameter::get() to return a const ref to the parameter itself.
|
||||
template<>
|
||||
inline
|
||||
auto
|
||||
get_value_helper<rclcpp::Parameter>(const rclcpp::Parameter * parameter)
|
||||
{
|
||||
// Use this labmda to ensure it's a const reference being returned (and not a copy).
|
||||
auto type_enforcing_lambda =
|
||||
[¶meter]() -> const rclcpp::Parameter & {
|
||||
return *parameter;
|
||||
};
|
||||
return type_enforcing_lambda();
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<typename T>
|
||||
decltype(auto)
|
||||
Parameter::get_value() const
|
||||
{
|
||||
// use the helper to specialize for the ParameterValue and Parameter cases.
|
||||
return detail::get_value_helper<T>(this);
|
||||
}
|
||||
|
||||
} // namespace rclcpp
|
||||
|
||||
namespace std
|
||||
|
||||
@@ -28,7 +28,8 @@
|
||||
|
||||
namespace rclcpp
|
||||
{
|
||||
enum ParameterType
|
||||
|
||||
enum ParameterType : uint8_t
|
||||
{
|
||||
PARAMETER_NOT_SET = rcl_interfaces::msg::ParameterType::PARAMETER_NOT_SET,
|
||||
PARAMETER_BOOL = rcl_interfaces::msg::ParameterType::PARAMETER_BOOL,
|
||||
@@ -45,11 +46,11 @@ enum ParameterType
|
||||
/// Return the name of a parameter type
|
||||
RCLCPP_PUBLIC
|
||||
std::string
|
||||
to_string(const ParameterType type);
|
||||
to_string(ParameterType type);
|
||||
|
||||
RCLCPP_PUBLIC
|
||||
std::ostream &
|
||||
operator<<(std::ostream & os, const ParameterType type);
|
||||
operator<<(std::ostream & os, ParameterType type);
|
||||
|
||||
/// Indicate the parameter type does not match the expected type.
|
||||
class ParameterTypeException : public std::runtime_error
|
||||
|
||||
115
rclcpp/include/rclcpp/unused_parameters_checker.hpp
Normal file
115
rclcpp/include/rclcpp/unused_parameters_checker.hpp
Normal file
@@ -0,0 +1,115 @@
|
||||
// Copyright 2018 Open Source Robotics Foundation, Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef RCLCPP__UNUSED_PARAMETERS_CHECKER_HPP_
|
||||
#define RCLCPP__UNUSED_PARAMETERS_CHECKER_HPP_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "rclcpp/node_interfaces/get_node_parameters_interface.hpp"
|
||||
#include "rclcpp/node_interfaces/node_parameters_interface.hpp"
|
||||
#include "rclcpp/macros.hpp"
|
||||
#include "rclcpp/parameter.hpp"
|
||||
#include "rclcpp/visibility_control.hpp"
|
||||
|
||||
namespace rclcpp
|
||||
{
|
||||
|
||||
/// Check a Node-like class for unused parameters.
|
||||
/**
|
||||
* This class can be used to detect misconfigurations and typos by ensuring all
|
||||
* initial parameter values that were passed to the Node-like object were used.
|
||||
* So this class's methods are used after or during Node construction and after
|
||||
* all parameters have been declared.
|
||||
*
|
||||
* This class must not outlive the Node that it's being used with.
|
||||
*/
|
||||
class UnusedParametersChecker
|
||||
{
|
||||
public:
|
||||
template<typename NodeType>
|
||||
explicit UnusedParametersChecker(NodeType && node_like)
|
||||
: node_parameters_interface_(
|
||||
rclcpp::node_interfaces::get_node_parameters_interface(std::forward<NodeType>(node_like)))
|
||||
{}
|
||||
|
||||
/// Warn if any initial parameter values have not been used.
|
||||
/**
|
||||
* This function will complain with a RCLCPP_WARN if any provided initial
|
||||
* parameter values have not been used.
|
||||
*
|
||||
* \throws std::bad_alloc when trying to create an error message
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
void
|
||||
check_and_warn() const;
|
||||
|
||||
/// Throw an UnusedParameterExecption if any initial parameter values have not been used.
|
||||
/**
|
||||
* This function will throw an exception if any provided initial
|
||||
* parameter values have not been used.
|
||||
*
|
||||
* \throws std::bad_alloc when trying to create an error message
|
||||
* \throws rclcpp::UnusedParametersException when there are unused parameters
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
void
|
||||
check_and_throw() const;
|
||||
|
||||
/// Return the number of unused initial parameter values.
|
||||
/**
|
||||
* Similar to get_unused_initial_parameter_values(), but it returns the
|
||||
* number of unused parameter values rather than a vector of the unused
|
||||
* parameters (which involves allocating storage for the copies).
|
||||
* This function is faster and avoids memory allocation while checking for a
|
||||
* problem, and if one is detected then get_unused_initial_parameter_values()
|
||||
* may be used to format a useful error message.
|
||||
*
|
||||
* \returns the number of unused initial parameter values
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
size_t
|
||||
count_unused_initial_parameter_values() const;
|
||||
|
||||
/// Return the list of unused initial parameter values.
|
||||
/**
|
||||
* A common case where this returns a non-empty vector, is when someone makes
|
||||
* a typo when setting the parameters from outside the node.
|
||||
* For example, if they use `ip_addr` rather than the expected `ip_address`.
|
||||
*
|
||||
* \returns vector of parameters which where passed to the node but where
|
||||
* not declared before this function was called.
|
||||
* \throws std::bad_alloc
|
||||
*/
|
||||
RCLCPP_PUBLIC
|
||||
std::vector<rclcpp::Parameter>
|
||||
get_unused_initial_parameter_values() const;
|
||||
|
||||
private:
|
||||
const rclcpp::node_interfaces::NodeParametersInterface * node_parameters_interface_;
|
||||
};
|
||||
|
||||
/// Thrown when throw_if_unused_initialized_parameter_values() finds unused parameters.
|
||||
class UnusedParametersException : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
explicit UnusedParametersException(const std::vector<rclcpp::Parameter> & unused_parameters);
|
||||
};
|
||||
|
||||
} // namespace rclcpp
|
||||
|
||||
#endif // RCLCPP__UNUSED_PARAMETERS_CHECKER_HPP_
|
||||
@@ -60,7 +60,8 @@ Node::Node(
|
||||
const std::vector<rclcpp::Parameter> & initial_parameters,
|
||||
bool use_global_arguments,
|
||||
bool use_intra_process_comms,
|
||||
bool start_parameter_services)
|
||||
bool start_parameter_services,
|
||||
bool allow_undeclared_parameters)
|
||||
: node_base_(new rclcpp::node_interfaces::NodeBase(
|
||||
node_name, namespace_, context, arguments, use_global_arguments)),
|
||||
node_graph_(new rclcpp::node_interfaces::NodeGraph(node_base_.get())),
|
||||
@@ -82,7 +83,8 @@ Node::Node(
|
||||
node_clock_,
|
||||
initial_parameters,
|
||||
use_intra_process_comms,
|
||||
start_parameter_services
|
||||
start_parameter_services,
|
||||
allow_undeclared_parameters
|
||||
)),
|
||||
node_time_source_(new rclcpp::node_interfaces::NodeTimeSource(
|
||||
node_base_,
|
||||
@@ -132,6 +134,15 @@ Node::group_in_node(rclcpp::callback_group::CallbackGroup::SharedPtr group)
|
||||
return node_base_->callback_group_in_node(group);
|
||||
}
|
||||
|
||||
void
|
||||
Node::declare_parameter(
|
||||
const std::string & name,
|
||||
const rclcpp::ParameterValue & default_value,
|
||||
bool read_only)
|
||||
{
|
||||
return this->node_parameters_->declare_parameter(name, default_value, read_only);
|
||||
}
|
||||
|
||||
std::vector<rcl_interfaces::msg::SetParametersResult>
|
||||
Node::set_parameters(
|
||||
const std::vector<rclcpp::Parameter> & parameters)
|
||||
|
||||
@@ -39,8 +39,9 @@ NodeParameters::NodeParameters(
|
||||
const rclcpp::node_interfaces::NodeClockInterface::SharedPtr node_clock,
|
||||
const std::vector<rclcpp::Parameter> & initial_parameters,
|
||||
bool use_intra_process,
|
||||
bool start_parameter_services)
|
||||
: node_clock_(node_clock)
|
||||
bool start_parameter_services,
|
||||
bool allow_undeclared_parameters)
|
||||
: allow_undeclared_(allow_undeclared_parameters), node_clock_(node_clock)
|
||||
{
|
||||
using MessageT = rcl_interfaces::msg::ParameterEvent;
|
||||
using PublisherT = rclcpp::Publisher<MessageT>;
|
||||
@@ -114,8 +115,6 @@ NodeParameters::NodeParameters(
|
||||
combined_name_ = node_namespace + '/' + node_name;
|
||||
}
|
||||
|
||||
std::map<std::string, rclcpp::Parameter> parameters;
|
||||
|
||||
// TODO(sloretz) use rcl to parse yaml when circular dependency is solved
|
||||
// See https://github.com/ros2/rcl/issues/252
|
||||
for (const std::string & yaml_path : yaml_paths) {
|
||||
@@ -140,25 +139,19 @@ NodeParameters::NodeParameters(
|
||||
|
||||
// Combine parameter yaml files, overwriting values in older ones
|
||||
for (auto & param : iter->second) {
|
||||
parameters[param.get_name()] = param;
|
||||
initial_parameter_values_[param.get_name()] =
|
||||
rclcpp::ParameterValue(param.get_value_message());
|
||||
}
|
||||
}
|
||||
|
||||
// initial values passed to constructor overwrite yaml file sources
|
||||
for (auto & param : initial_parameters) {
|
||||
parameters[param.get_name()] = param;
|
||||
initial_parameter_values_[param.get_name()] =
|
||||
rclcpp::ParameterValue(param.get_value_message());
|
||||
}
|
||||
|
||||
std::vector<rclcpp::Parameter> combined_values;
|
||||
combined_values.reserve(parameters.size());
|
||||
for (auto & kv : parameters) {
|
||||
combined_values.emplace_back(kv.second);
|
||||
}
|
||||
|
||||
// TODO(sloretz) store initial values and use them when a parameter is created ros2/rclcpp#475
|
||||
// Set initial parameter values
|
||||
if (!combined_values.empty()) {
|
||||
rcl_interfaces::msg::SetParametersResult result = set_parameters_atomically(combined_values);
|
||||
if (!initial_parameters.empty() && allow_undeclared_) {
|
||||
rcl_interfaces::msg::SetParametersResult result = set_parameters_atomically(initial_parameters);
|
||||
if (!result.successful) {
|
||||
throw std::runtime_error("Failed to set initial parameters");
|
||||
}
|
||||
@@ -168,6 +161,59 @@ NodeParameters::NodeParameters(
|
||||
NodeParameters::~NodeParameters()
|
||||
{}
|
||||
|
||||
void
|
||||
NodeParameters::declare_parameter(
|
||||
const std::string & name,
|
||||
const rclcpp::ParameterValue & default_value,
|
||||
bool read_only)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
// TODO(sloretz) parameter name validation
|
||||
if (name.empty()) {
|
||||
throw std::runtime_error("parameter name must not be empty");
|
||||
}
|
||||
|
||||
// Error if this parameter has already been declared and is different
|
||||
auto param_iter = parameters_.find(name);
|
||||
if (param_iter != parameters_.end() && param_iter->second.is_declared) {
|
||||
if (
|
||||
param_iter->second.descriptor.type != default_value.get_type() ||
|
||||
param_iter->second.descriptor.read_only != read_only)
|
||||
{
|
||||
throw std::runtime_error("parameter '" + name + "' exists with conflicting description");
|
||||
}
|
||||
}
|
||||
|
||||
// Check if run-time user passed an initial value, else use the default.
|
||||
rclcpp::ParameterValue initial_value = default_value;
|
||||
auto value_iter = initial_parameter_values_.find(name);
|
||||
if (value_iter != initial_parameter_values_.end()) {
|
||||
initial_value = value_iter->second;
|
||||
}
|
||||
|
||||
// Save a description of the parameter
|
||||
rcl_interfaces::msg::ParameterDescriptor desc;
|
||||
desc.name = name;
|
||||
desc.type = initial_value.get_type();
|
||||
desc.read_only = read_only;
|
||||
|
||||
rclcpp::node_interfaces::ParameterInfo pinfo;
|
||||
pinfo.is_declared = true;
|
||||
pinfo.value = initial_value;
|
||||
pinfo.descriptor = desc;
|
||||
|
||||
// Add declared parameters to storage, even when they're not set.
|
||||
parameters_[name] = pinfo;
|
||||
|
||||
// If it has an actual value then add it to 'new_parameters' event
|
||||
if (rclcpp::ParameterType::PARAMETER_NOT_SET != initial_value.get_type()) {
|
||||
auto parameter_event = std::make_shared<rcl_interfaces::msg::ParameterEvent>();
|
||||
parameter_event->new_parameters.push_back(
|
||||
rclcpp::Parameter(name, initial_value).to_parameter_msg());
|
||||
events_publisher_->publish(parameter_event);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<rcl_interfaces::msg::SetParametersResult>
|
||||
NodeParameters::set_parameters(
|
||||
const std::vector<rclcpp::Parameter> & parameters)
|
||||
@@ -185,7 +231,7 @@ NodeParameters::set_parameters_atomically(
|
||||
const std::vector<rclcpp::Parameter> & parameters)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
std::map<std::string, rclcpp::Parameter> tmp_map;
|
||||
std::map<std::string, rclcpp::node_interfaces::ParameterInfo> tmp_map;
|
||||
auto parameter_event = std::make_shared<rcl_interfaces::msg::ParameterEvent>();
|
||||
|
||||
parameter_event->node = combined_name_;
|
||||
@@ -202,33 +248,79 @@ NodeParameters::set_parameters_atomically(
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::string> to_delete;
|
||||
|
||||
for (auto p : parameters) {
|
||||
if (p.get_type() == rclcpp::ParameterType::PARAMETER_NOT_SET) {
|
||||
if (parameters_.find(p.get_name()) != parameters_.end()) {
|
||||
// case: parameter was set before, and input is "NOT_SET"
|
||||
// therefore we will erase the parameter from parameters_ later
|
||||
auto param_iter = parameters_.find(p.get_name());
|
||||
bool exists = parameters_.end() != param_iter;
|
||||
bool want_to_delete = p.get_type() == rclcpp::ParameterType::PARAMETER_NOT_SET;
|
||||
|
||||
if (exists) {
|
||||
if (param_iter->second.descriptor.read_only) {
|
||||
result.successful = false;
|
||||
result.reason = "read_only parameter: '" + p.get_name() + "'";
|
||||
return result;
|
||||
}
|
||||
if (want_to_delete) {
|
||||
parameter_event->deleted_parameters.push_back(p.to_parameter_msg());
|
||||
if (param_iter->second.is_declared) {
|
||||
// clear declared parameter value, but don't delete it
|
||||
rclcpp::node_interfaces::ParameterInfo cleared_param_info = param_iter->second;
|
||||
cleared_param_info.value = rclcpp::ParameterValue();
|
||||
tmp_map[p.get_name()] = cleared_param_info;
|
||||
} else {
|
||||
// Truly delete an undeclared parameter
|
||||
to_delete.push_back(p.get_name());
|
||||
}
|
||||
} else {
|
||||
if (param_iter->second.value.get_type() == rclcpp::ParameterType::PARAMETER_NOT_SET) {
|
||||
// case: setting a value on a declared parameter that currently is unset
|
||||
parameter_event->new_parameters.push_back(p.to_parameter_msg());
|
||||
} else {
|
||||
// case: changing a parameter value
|
||||
parameter_event->changed_parameters.push_back(p.to_parameter_msg());
|
||||
}
|
||||
rclcpp::node_interfaces::ParameterInfo changed_param_info = param_iter->second;
|
||||
// TODO(sloretz) Add accessor for ParameterValue on Parameter class
|
||||
changed_param_info.value = rclcpp::ParameterValue(p.get_value_message());
|
||||
tmp_map[p.get_name()] = changed_param_info;
|
||||
}
|
||||
} else {
|
||||
if (parameters_.find(p.get_name()) == parameters_.end()) {
|
||||
// case: parameter not set before, and input is something other than "NOT_SET"
|
||||
parameter_event->new_parameters.push_back(p.to_parameter_msg());
|
||||
// case: parameter does not exist already
|
||||
if (!allow_undeclared_) {
|
||||
result.successful = false;
|
||||
result.reason = "undeclared parameter: '" + p.get_name() + "'";
|
||||
return result;
|
||||
} else if (want_to_delete) {
|
||||
result.successful = false;
|
||||
result.reason = "deleting parameter: '" + p.get_name() + "' that does not exist";
|
||||
return result;
|
||||
} else {
|
||||
// case: parameter was set before, and input is something other than "NOT_SET"
|
||||
parameter_event->changed_parameters.push_back(p.to_parameter_msg());
|
||||
// Create new undeclared parameter
|
||||
parameter_event->new_parameters.push_back(p.to_parameter_msg());
|
||||
|
||||
rcl_interfaces::msg::ParameterDescriptor desc;
|
||||
desc.name = p.get_name();
|
||||
desc.type = p.get_type();
|
||||
desc.read_only = false;
|
||||
|
||||
rclcpp::node_interfaces::ParameterInfo new_param_info;
|
||||
new_param_info.is_declared = false;
|
||||
// TODO(sloretz) Add accessor for ParameterValue on Parameter class
|
||||
new_param_info.value = rclcpp::ParameterValue(p.get_value_message());
|
||||
new_param_info.descriptor = desc;
|
||||
|
||||
tmp_map[p.get_name()] = new_param_info;
|
||||
}
|
||||
tmp_map[p.get_name()] = p;
|
||||
}
|
||||
}
|
||||
// std::map::insert will not overwrite elements, so we'll keep the new
|
||||
// ones and add only those that already exist in the Node's internal map
|
||||
tmp_map.insert(parameters_.begin(), parameters_.end());
|
||||
|
||||
// remove explicitly deleted parameters
|
||||
for (auto p : parameters) {
|
||||
if (p.get_type() == rclcpp::ParameterType::PARAMETER_NOT_SET) {
|
||||
tmp_map.erase(p.get_name());
|
||||
}
|
||||
// remove truly deleted parameters
|
||||
for (const std::string & param_name : to_delete) {
|
||||
tmp_map.erase(param_name);
|
||||
}
|
||||
|
||||
std::swap(tmp_map, parameters_);
|
||||
@@ -246,11 +338,11 @@ NodeParameters::get_parameters(const std::vector<std::string> & names) const
|
||||
|
||||
for (auto & name : names) {
|
||||
if (std::any_of(parameters_.cbegin(), parameters_.cend(),
|
||||
[&name](const std::pair<std::string, rclcpp::Parameter> & kv) {
|
||||
[&name](const std::pair<std::string, rclcpp::node_interfaces::ParameterInfo> & kv) {
|
||||
return name == kv.first;
|
||||
}))
|
||||
{
|
||||
results.push_back(parameters_.at(name));
|
||||
results.emplace_back(name, parameters_.at(name).value);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
@@ -275,8 +367,12 @@ NodeParameters::get_parameter(
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(mutex_);
|
||||
|
||||
if (parameters_.count(name)) {
|
||||
parameter = parameters_.at(name);
|
||||
auto param_iter = parameters_.find(name);
|
||||
if (
|
||||
parameters_.end() != param_iter &&
|
||||
param_iter->second.value.get_type() != rclcpp::ParameterType::PARAMETER_NOT_SET)
|
||||
{
|
||||
parameter = {name, param_iter->second.value};
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -296,7 +392,7 @@ NodeParameters::get_parameters_by_prefix(
|
||||
for (const auto & param : parameters_) {
|
||||
if (param.first.find(prefix_with_dot) == 0 && param.first.length() > prefix_with_dot.length()) {
|
||||
// Found one!
|
||||
parameters[param.first.substr(prefix_with_dot.length())] = param.second;
|
||||
parameters[param.first.substr(prefix_with_dot.length())] = rclcpp::Parameter(param.second);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
@@ -314,10 +410,7 @@ NodeParameters::describe_parameters(const std::vector<std::string> & names) cons
|
||||
return name == kv.first;
|
||||
}))
|
||||
{
|
||||
rcl_interfaces::msg::ParameterDescriptor parameter_descriptor;
|
||||
parameter_descriptor.name = kv.first;
|
||||
parameter_descriptor.type = kv.second.get_type();
|
||||
results.push_back(parameter_descriptor);
|
||||
results.push_back(kv.second.descriptor);
|
||||
}
|
||||
}
|
||||
return results;
|
||||
@@ -333,7 +426,7 @@ NodeParameters::get_parameter_types(const std::vector<std::string> & names) cons
|
||||
return name == kv.first;
|
||||
}))
|
||||
{
|
||||
results.push_back(kv.second.get_type());
|
||||
results.push_back(kv.second.value.get_type());
|
||||
} else {
|
||||
results.push_back(rcl_interfaces::msg::ParameterType::PARAMETER_NOT_SET);
|
||||
}
|
||||
|
||||
@@ -12,12 +12,14 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "rclcpp/parameter.hpp"
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "rclcpp/parameter.hpp"
|
||||
#include "rclcpp/node_interfaces/node_parameters.hpp"
|
||||
#include "rclcpp/utilities.hpp"
|
||||
|
||||
using rclcpp::ParameterType;
|
||||
@@ -33,6 +35,11 @@ Parameter::Parameter(const std::string & name, const rclcpp::ParameterValue & va
|
||||
{
|
||||
}
|
||||
|
||||
Parameter::Parameter(const rclcpp::node_interfaces::ParameterInfo & parameter_info)
|
||||
: Parameter(parameter_info.descriptor.name, parameter_info.value)
|
||||
{
|
||||
}
|
||||
|
||||
ParameterType
|
||||
Parameter::get_type() const
|
||||
{
|
||||
@@ -57,6 +64,12 @@ Parameter::get_value_message() const
|
||||
return value_.to_value_msg();
|
||||
}
|
||||
|
||||
const rclcpp::ParameterValue &
|
||||
Parameter::get_parameter_value() const
|
||||
{
|
||||
return value_;
|
||||
}
|
||||
|
||||
bool
|
||||
Parameter::as_bool() const
|
||||
{
|
||||
|
||||
@@ -44,10 +44,11 @@ TEST_F(TestNodeWithInitialValues, no_initial_values) {
|
||||
auto node = rclcpp::Node::make_shared(
|
||||
"node_name", "", context, arguments, initial_values, use_global_arguments, use_intra_process);
|
||||
auto list_params_result = node->list_parameters({}, 0);
|
||||
EXPECT_EQ(0u, list_params_result.names.size());
|
||||
// Has use_sim_time parameter
|
||||
EXPECT_EQ(1u, list_params_result.names.size());
|
||||
}
|
||||
|
||||
TEST_F(TestNodeWithInitialValues, multiple_initial_values) {
|
||||
TEST_F(TestNodeWithInitialValues, multiple_undeclared_initial_values) {
|
||||
auto context = rclcpp::contexts::default_context::get_global_default_context();
|
||||
const std::vector<std::string> arguments = {};
|
||||
const std::vector<rclcpp::Parameter> initial_values = {
|
||||
@@ -60,7 +61,53 @@ TEST_F(TestNodeWithInitialValues, multiple_initial_values) {
|
||||
auto node = rclcpp::Node::make_shared(
|
||||
"node_name", "", context, arguments, initial_values, use_global_arguments, use_intra_process);
|
||||
auto list_params_result = node->list_parameters({}, 0);
|
||||
EXPECT_EQ(3u, list_params_result.names.size());
|
||||
// Has use_sim_time parameter
|
||||
EXPECT_EQ(1u, list_params_result.names.size());
|
||||
}
|
||||
|
||||
TEST_F(TestNodeWithInitialValues, multiple_declared_initial_values) {
|
||||
auto context = rclcpp::contexts::default_context::get_global_default_context();
|
||||
const std::vector<std::string> arguments = {};
|
||||
const std::vector<rclcpp::Parameter> initial_values = {
|
||||
rclcpp::Parameter("foo", true),
|
||||
rclcpp::Parameter("bar", "hello world"),
|
||||
rclcpp::Parameter("baz", std::vector<double>{3.14, 2.718})
|
||||
};
|
||||
const bool use_global_arguments = false;
|
||||
const bool use_intra_process = false;
|
||||
auto node = rclcpp::Node::make_shared(
|
||||
"node_name", "", context, arguments, initial_values, use_global_arguments, use_intra_process);
|
||||
|
||||
node->declare_parameter("foo");
|
||||
node->declare_parameter("bar");
|
||||
node->declare_parameter("baz");
|
||||
|
||||
auto list_params_result = node->list_parameters({}, 0);
|
||||
EXPECT_TRUE(node->get_parameter("foo").get_value<bool>());
|
||||
EXPECT_STREQ("hello world", node->get_parameter("bar").get_value<std::string>().c_str());
|
||||
std::vector<double> double_array = node->get_parameter("baz").get_value<std::vector<double>>();
|
||||
ASSERT_EQ(2u, double_array.size());
|
||||
EXPECT_DOUBLE_EQ(3.14, double_array.at(0));
|
||||
EXPECT_DOUBLE_EQ(2.718, double_array.at(1));
|
||||
}
|
||||
|
||||
TEST_F(TestNodeWithInitialValues, multiple_undeclared_initial_values_allowed) {
|
||||
auto context = rclcpp::contexts::default_context::get_global_default_context();
|
||||
const std::vector<std::string> arguments = {};
|
||||
const std::vector<rclcpp::Parameter> initial_values = {
|
||||
rclcpp::Parameter("foo", true),
|
||||
rclcpp::Parameter("bar", "hello world"),
|
||||
rclcpp::Parameter("baz", std::vector<double>{3.14, 2.718})
|
||||
};
|
||||
const bool use_global_arguments = false;
|
||||
const bool use_intra_process = false;
|
||||
const bool start_param_services = true;
|
||||
const bool allow_undeclared_params = true;
|
||||
auto node = rclcpp::Node::make_shared(
|
||||
"node_name", "", context, arguments, initial_values, use_global_arguments, use_intra_process,
|
||||
start_param_services, allow_undeclared_params);
|
||||
|
||||
auto list_params_result = node->list_parameters({}, 0);
|
||||
EXPECT_TRUE(node->get_parameter("foo").get_value<bool>());
|
||||
EXPECT_STREQ("hello world", node->get_parameter("bar").get_value<std::string>().c_str());
|
||||
std::vector<double> double_array = node->get_parameter("baz").get_value<std::vector<double>>();
|
||||
|
||||
@@ -97,6 +97,7 @@ public:
|
||||
* pipeline to pass messages between nodes in the same process using shared memory.
|
||||
* \param[in] start_parameter_services True to setup ROS interfaces for accessing parameters
|
||||
* in the node.
|
||||
* \param[in] allow_undeclared_parameters True to allow any parameter name to be set on the node.
|
||||
*/
|
||||
RCLCPP_LIFECYCLE_PUBLIC
|
||||
LifecycleNode(
|
||||
@@ -107,7 +108,8 @@ public:
|
||||
const std::vector<rclcpp::Parameter> & initial_parameters,
|
||||
bool use_global_arguments = true,
|
||||
bool use_intra_process_comms = false,
|
||||
bool start_parameter_services = true);
|
||||
bool start_parameter_services = true,
|
||||
bool allow_undeclared_parameters = false);
|
||||
|
||||
RCLCPP_LIFECYCLE_PUBLIC
|
||||
virtual ~LifecycleNode();
|
||||
|
||||
@@ -66,7 +66,8 @@ LifecycleNode::LifecycleNode(
|
||||
const std::vector<rclcpp::Parameter> & initial_parameters,
|
||||
bool use_global_arguments,
|
||||
bool use_intra_process_comms,
|
||||
bool start_parameter_services)
|
||||
bool start_parameter_services,
|
||||
bool allow_undeclared_parameters)
|
||||
: node_base_(new rclcpp::node_interfaces::NodeBase(
|
||||
node_name, namespace_, context, arguments, use_global_arguments)),
|
||||
node_graph_(new rclcpp::node_interfaces::NodeGraph(node_base_.get())),
|
||||
@@ -88,7 +89,8 @@ LifecycleNode::LifecycleNode(
|
||||
node_clock_,
|
||||
initial_parameters,
|
||||
use_intra_process_comms,
|
||||
start_parameter_services
|
||||
start_parameter_services,
|
||||
allow_undeclared_parameters
|
||||
)),
|
||||
node_waitables_(new rclcpp::node_interfaces::NodeWaitables(node_base_.get())),
|
||||
use_intra_process_comms_(use_intra_process_comms),
|
||||
|
||||
Reference in New Issue
Block a user