-
Notifications
You must be signed in to change notification settings - Fork 412
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Get parameter map #575
Get parameter map #575
Conversation
rclcpp/include/rclcpp/node.hpp
Outdated
@@ -277,6 +277,12 @@ class Node : public std::enable_shared_from_this<Node> | |||
const std::string & name, | |||
const ParameterT & value); | |||
|
|||
template<typename MapValueT> | |||
void | |||
set_parameter_if_not_set( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the methods sets multiple parameters the method name should be plural: set_parameters_if_not_set
.
Same for get_parameter()
below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't feel strongly about the name, but I will point out that in ROS1 all of the methods were named the same, regardless of whether they were setting a map, a vector, or a single value. I think there is value to this here as well, since there is only "one" name to remember, regardless of the type you want to set. However, if you insist, I will change the name to be plural.
@@ -303,6 +309,24 @@ class Node : public std::enable_shared_from_this<Node> | |||
bool | |||
get_parameter(const std::string & name, ParameterT & parameter) const; | |||
|
|||
/// Assign the value of the map parameter if set into the values argument. | |||
/** | |||
* Parameter names that are part of a map are of the form "name.member". |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the signature I would rather not pass name
here. Each key in the map can already be a "full" name. Otherwise this function prohibits to set two parameters in different "branches" of the "naming tree".
Same below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While that is true (and makes some sense for set
), it doesn't really make much sense for get
. If we just make it so that there is no "grouping" with this API, then there is little reason to add this API; we can do the same thing by calling get_parameters
with a vector of names. The explicit purpose of the map-based one is to have a group of variables that we can get into a single map. This is similar to the map-based getParam overload in ROS1.
for (const auto & val : values) { | ||
std::string param_name = name + "." + val.first; | ||
rclcpp::Parameter parameter; | ||
if (!this->get_parameter(param_name, parameter)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of calling get_parameter
N times I would suggest to call get_parameters()
once.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can make this work using get_parameters()
, but I think it is much uglier and less efficient:
template<typename MapValueT>
void
Node::set_parameter_if_not_set(
const std::string & name,
const std::map<std::string, MapValueT> & values)
{
std::vector<std::string> names;
for (const auto & val : values) {
std::string param_name = name + "." + val.first;
names.push_back(param_name);
}
std::vector<rclcpp::Parameter> params = node_parameters_->get_parameters(names);
std::vector<rclcpp::Parameter> params_to_set;
for (const auto & val : values) {
std::string param_name = name + "." + val.first;
if (std::find_if(params.begin(), params.end(),
[¶m_name](const rclcpp::Parameter& param) {
return param.get_name() == param_name;
}) == params.end()) {
params_to_set.push_back(rclcpp::Parameter(param_name, val.second));
}
}
this->set_parameters(params_to_set);
}
This is due to the fact that get_parameters() returns only what is currently in the parameters, and silently ignores the ones that aren't there. Unless you can think of a way to reduce the number of loops and finds here, I'd prefer to stick to the current implementation.
@ros2/team There are two open questions on this PR:
|
(also, I'm going to close and re-open this PR to retrigger the build, since I think the failure was unrelated to this PR) |
|
|
Any parameters that have a "." in them will be considered to be part of a "map" (though they can also be get and set individually). This PR adds two new template specializations to the public node API so that it can take a map, and store the list of values (so setting the parameter with a name of "foo" and a key of "x" will end up with a parameter of "foo.x"). It also adds an API to get all of the keys corresponding to a prefix, and returing that as a map (so a get of "foo" will get all parameters that begin with "foo."). Note that all parameters within the map must have the same type, otherwise an rclcpp::ParameterTypeException will be thrown. Signed-off-by: Chris Lalancette <clalancette@openrobotics.org>
Signed-off-by: Chris Lalancette <clalancette@openrobotics.org>
Signed-off-by: Chris Lalancette <clalancette@openrobotics.org>
Signed-off-by: Chris Lalancette <clalancette@openrobotics.org>
f20dbf1
to
08b27b1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm, only comments about documentation
Signed-off-by: Chris Lalancette <clalancette@openrobotics.org>
* Add in the ability to get parameters in a map. Any parameters that have a "." in them will be considered to be part of a "map" (though they can also be get and set individually). This PR adds two new template specializations to the public node API so that it can take a map, and store the list of values (so setting the parameter with a name of "foo" and a key of "x" will end up with a parameter of "foo.x"). It also adds an API to get all of the keys corresponding to a prefix, and returing that as a map (so a get of "foo" will get all parameters that begin with "foo."). Note that all parameters within the map must have the same type, otherwise an rclcpp::ParameterTypeException will be thrown. Signed-off-by: Chris Lalancette <clalancette@openrobotics.org> * Fix style problems pointed out by uncrustify/cpplint. Signed-off-by: Chris Lalancette <clalancette@openrobotics.org> * Move tests for set_parameter_if_not_set/get_parameter map to rclcpp. Signed-off-by: Chris Lalancette <clalancette@openrobotics.org> * Rename get_parameter -> get_parameters. Signed-off-by: Chris Lalancette <clalancette@openrobotics.org> * Add in documentation from review. Signed-off-by: Chris Lalancette <clalancette@openrobotics.org>
* Get parameter map (#575) * Add in the ability to get parameters in a map. Any parameters that have a "." in them will be considered to be part of a "map" (though they can also be get and set individually). This PR adds two new template specializations to the public node API so that it can take a map, and store the list of values (so setting the parameter with a name of "foo" and a key of "x" will end up with a parameter of "foo.x"). It also adds an API to get all of the keys corresponding to a prefix, and returing that as a map (so a get of "foo" will get all parameters that begin with "foo."). Note that all parameters within the map must have the same type, otherwise an rclcpp::ParameterTypeException will be thrown. Signed-off-by: Chris Lalancette <clalancette@openrobotics.org> * Fix style problems pointed out by uncrustify/cpplint. Signed-off-by: Chris Lalancette <clalancette@openrobotics.org> * Move tests for set_parameter_if_not_set/get_parameter map to rclcpp. Signed-off-by: Chris Lalancette <clalancette@openrobotics.org> * Rename get_parameter -> get_parameters. Signed-off-by: Chris Lalancette <clalancette@openrobotics.org> * Add in documentation from review. Signed-off-by: Chris Lalancette <clalancette@openrobotics.org> * Use list_parameters instead of get_parameters_by_prefix. This way, we don't break ABI in crystal. Signed-off-by: Chris Lalancette <clalancette@openrobotics.org> * Fix style problems. Signed-off-by: Chris Lalancette <clalancette@openrobotics.org>
* Add in the ability to get parameters in a map. Any parameters that have a "." in them will be considered to be part of a "map" (though they can also be get and set individually). This PR adds two new template specializations to the public node API so that it can take a map, and store the list of values (so setting the parameter with a name of "foo" and a key of "x" will end up with a parameter of "foo.x"). It also adds an API to get all of the keys corresponding to a prefix, and returing that as a map (so a get of "foo" will get all parameters that begin with "foo."). Note that all parameters within the map must have the same type, otherwise an rclcpp::ParameterTypeException will be thrown. Signed-off-by: Chris Lalancette <clalancette@openrobotics.org> * Fix style problems pointed out by uncrustify/cpplint. Signed-off-by: Chris Lalancette <clalancette@openrobotics.org> * Move tests for set_parameter_if_not_set/get_parameter map to rclcpp. Signed-off-by: Chris Lalancette <clalancette@openrobotics.org> * Rename get_parameter -> get_parameters. Signed-off-by: Chris Lalancette <clalancette@openrobotics.org> * Add in documentation from review. Signed-off-by: Chris Lalancette <clalancette@openrobotics.org>
* fixed package.xml Signed-off-by: Alejandro Hernández <ahcorde@gmail.com> * removed rosidl_generator_c dependency Signed-off-by: Alejandro Hernández <ahcorde@gmail.com> * rcl lifecycle restoring rosidl_generator_c dependency Signed-off-by: Alejandro Hernández <ahcorde@gmail.com>
This PR adds the ability to get a
std::map
set of key-value pairs of parameters. In this case, parameters that form part of a map are all of the form:Assuming
param.x
has value 0.1 andparam.y
has value 1.5, then calling this API like:Would fill in the
params
map with keys ofx
andy
with values of0.1
and1.5
, respectively. There is also aset_parameter_if_not_set
that works much in the same way for setting values. Tests for this new functionality are added in a new test file; I'll move the rest of the "local" parameter tests from system_tests once this is in. This should solve #529 , and will unblock ros2/teleop_twist_joy#8connects to #529