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

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 35 additions & 16 deletions nav2_util/include/nav2_util/node_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,63 +161,82 @@ using NodeParamInterfacePtr = rclcpp::node_interfaces::NodeParametersInterface::
/**
* If the parameter is already declared, returns its value,
* otherwise declares it and returns the default value.
* The method will by default print a warning when the override is missing.
* The method can optionally print a warning or throw when the override is missing.
*
* \param[in] logger Node logging interface
* \param[in] param_interface Node parameter interface
* \param[in] parameter_name Name of the parameter
* \param[in] default_value Default value of the parameter
* \param[in] warn_if_no_override If true, prints a warning whenever the parameter override is missing
* \param[in] strict_param_loading If true, throws an InvalidParameterValueException if the parameter override is missing
* \param[in] parameter_descriptor Optional parameter descriptor
* \return The value of the param from the override if existent, otherwise the default value
*/
template<typename ParamType>
ParamType declare_or_get_parameter(
const rclcpp::Logger & logger, NodeParamInterfacePtr param_interface,
const std::string & parameter_name, const ParamType & default_value,
bool warn_if_no_override = false,
bool warn_if_no_override = false, bool strict_param_loading = false,
const ParameterDescriptor & parameter_descriptor = ParameterDescriptor())
{
if (param_interface->has_parameter(parameter_name)) {
rclcpp::Parameter param(parameter_name, default_value);
param_interface->get_parameter(parameter_name, param);
return param.get_value<ParamType>();
}
if (warn_if_no_override && param_interface->get_parameter_overrides().find(parameter_name) ==
param_interface->get_parameter_overrides().end())
{
RCLCPP_WARN_STREAM(
logger,
"Failed to get param " << parameter_name << " from overrides, using default value.");
}
return param_interface
->declare_parameter(parameter_name, rclcpp::ParameterValue{default_value},

auto return_value = param_interface
->declare_parameter(parameter_name, rclcpp::ParameterValue{default_value},
parameter_descriptor)
.get<ParamType>();
.get<ParamType>();

const bool no_param_override = param_interface->get_parameter_overrides().find(parameter_name) ==
param_interface->get_parameter_overrides().end();
if (no_param_override) {
if (warn_if_no_override) {
RCLCPP_WARN_STREAM(
logger,
"Failed to get param " << parameter_name << " from overrides, using default value.");
}
if (strict_param_loading) {
std::string description = "Parameter " + parameter_name +
" not in overrides and strict_param_loading is True";
throw rclcpp::exceptions::InvalidParameterValueException(description.c_str());
}
}

return return_value;
}

/// If the parameter is already declared, returns its value,
/// otherwise declares it and returns the default value
/**
* If the parameter is already declared, returns its value,
* otherwise declares it and returns the default value.
* The method will by default print a warning when the override is missing.
* The method can be configured to print a warn message or throw an InvalidParameterValueException
* when the override is missing by enabling the parameters warn_on_missing_params
* or strict_param_loading respectively.
*
* \param[in] node Pointer to a node object
* \param[in] parameter_name Name of the parameter
* \param[in] default_value Default value of the parameter
* \param[in] warn_if_no_override If true, prints a warning whenever the parameter override is missing
* \param[in] parameter_descriptor Optional parameter descriptor
* \return The value of the param from the override if existent, otherwise the default value
*/
template<typename ParamType, typename NodeT>
ParamType declare_or_get_parameter(
NodeT node, const std::string & parameter_name,
const ParamType & default_value, bool warn_if_no_override = false,
const ParamType & default_value,
const ParameterDescriptor & parameter_descriptor = ParameterDescriptor())
{
declare_parameter_if_not_declared(node, "warn_on_missing_params", rclcpp::ParameterValue(false));
bool warn_if_no_override{false};
node->get_parameter("warn_on_missing_params", warn_if_no_override);
declare_parameter_if_not_declared(node, "strict_param_loading", rclcpp::ParameterValue(false));
bool strict_param_loading{false};
node->get_parameter("strict_param_loading", strict_param_loading);
return declare_or_get_parameter(node->get_logger(), node->get_node_parameters_interface(),
parameter_name, default_value, warn_if_no_override, parameter_descriptor);
parameter_name, default_value, warn_if_no_override, strict_param_loading, parameter_descriptor);
}

/// Gets the type of plugin for the selected node and its plugin
Expand Down
22 changes: 19 additions & 3 deletions nav2_util/test/test_node_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,19 +85,35 @@ TEST(DeclareOrGetParam, DeclareOrGetParam)

// test declared parameter
node->declare_parameter("foobar", "foo");
std::string param = declare_or_get_parameter(node, "foobar", std::string{"bar"}, true);
std::string param = declare_or_get_parameter(node, "foobar", std::string{"bar"});
EXPECT_EQ(param, "foo");
node->get_parameter("foobar", param);
EXPECT_EQ(param, "foo");

// test undeclared parameter
int int_param = declare_or_get_parameter(node, "waldo", 3, true);
node->set_parameter(rclcpp::Parameter("warn_on_missing_params", true));
int int_param = declare_or_get_parameter(node, "waldo", 3);
EXPECT_EQ(int_param, 3);

// test unknown parameter with strict_param_loading enabled
bool got_exception{false};
node->set_parameter(rclcpp::Parameter("strict_param_loading", true));
try {
declare_or_get_parameter(node, "burpy", true);
} catch (const rclcpp::exceptions::InvalidParameterValueException & exc) {
got_exception = true;
}
EXPECT_TRUE(got_exception);
// The parameter is anyway declared with the default val and subsequent calls won't fail
EXPECT_TRUE(declare_or_get_parameter(node, "burpy", true));

// test declaration by type of existing param
int_param = declare_or_get_parameter<int>(node, "waldo",
rclcpp::ParameterType::PARAMETER_INTEGER);
EXPECT_EQ(int_param, 3);

// test declaration by type of non existing param
bool got_exception{false};
got_exception = false;
try {
int_param = declare_or_get_parameter<int>(node, "wololo",
rclcpp::ParameterType::PARAMETER_INTEGER);
Expand Down
Loading