Rosanswers logo

Hi, I'm using ROS 2 Bouncy and I'm trying to get parameters from a yaml file. I checked a few ways to get parameters and I found one that works but takes 3 lines for each parameter :

auto ip_port_param = rclcpp::Parameter("ip_port", 10940);
nh_->get_parameter("ip_port", ip_port_param);
ip_port_ = ip_port_param.as_int();

Is there a nicer way to get parameters in one line like in ROS 1 ?

pnh_.param<int>("ip_port", ip_port_, 10940);

I could change ip_port_ into a rclcpp::Parameter instead of an int but then I would have to modify the whole code. Would that be the "proper" way to do it ?

I also tried to use rclcpp::SyncParametersClient but I can't use it from within a node, I have to be outside of it (ie: in the main) because the class constructor takes a rclcpp::Node::SharedPtr node. But when I'm in the node if I use this I get a rclcpp::Node* or if I use this->shared_from_this() then it compiles and run but I don't get the parameters, they take the default value.

auto parameters_client = std::make_shared<rclcpp::SyncParametersClient>(this->shared_from_this());
ip_port_ = parameters_client->get_parameter("ip_port", 10940);

All the examples from the demos pkg that use rclcpp::SyncParametersClient, do it from the main and not inside the node.

Whereas for rclcpp::AsyncParametersClient, you can use it inside your node with this but there is no T get_parameter (const std::string &parameter_name, const T &default_value) function, you have to use a get_parameters(...) and then you don't even get the direct values but a vector of Parameter().

Am I missing something or is it just the way we have to get parameters for now ?


Edit : I can do something like :

template <class T>
rclcpp::Parameter get_param (rclcpp::Node* node, std::string param_name, T default_value) {
  auto param = rclcpp::Parameter(param_name, default_value);
  node->get_parameter(param_name, param);
  return param;

And then :

ip_port_ = get_param(this, "ip_port", "").as_int();

But I feel like it should be something that's already there.

Originally posted by Marc Testier on ROS Answers with karma: 203 on 2018-09-27

Post score: 1


1 Answer 1


Rosanswers logo

There's the get_parameter_or method:


Which would allow you to do something like this:

int ip_port_;
node->get_parameter_or("ip_port", ip_port_, 80);

And recently the get_parameter_or_set which will get it if set, and if not it will set the parameter to the "default" you gave and then return it.

Edit: remove & because it's pass by reference not a pointer.

Originally posted by William with karma: 17335 on 2018-09-28

This answer was ACCEPTED on the original site

Post score: 3

Original comments

Comment by Marc Testier on 2018-09-30:
Both get_parameter_or and get_parameter_or_set take a Parameter() in and not an int or string, so we can't do this. We would need to do :

Parameter ip_port_param;
this->get_parameter_or("ip_port", ip_port_param, Parameter("", 80));
ip_port_ = ip_port_param.as_int();

Comment by William on 2018-10-05:
Are you sure? The one I'm looking at takes ParameterT which is a template argument.

Comment by Marc Testier on 2018-10-07:
Ok, I had some errors and didn't look much further, my bad, it does work with:

int ip_port_;
this->get_parameter_or("ip_port", ip_port_, 80);

Need to remove the & since we pass by reference, otherwise we get an error.

Comment by William on 2018-10-08:
Awesome, glad you got it to work.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.