Ask Your Question

[ROS2][rclpy] how to set parameter hosted by another Node via service [closed]

asked 2020-02-05 01:09:44 -0600

lin404 gravatar image

updated 2020-02-05 18:15:42 -0600

I am looking for a solution to set the Parameter which is host by another node using rclpy.

I found there is a relavent post, but in rclcpp.

While, I tried below. But the error occurred. Any idea how I can fix it? Thank you very much!

import time

import rclpy
from rclpy.node import Node
import rclpy.qos as qos

from rclpy.parameter import Parameter
# from rcl_interfaces.msg import Parameter
from rcl_interfaces.msg import ParameterValue
from rcl_interfaces.srv import SetParameters, GetParameters, ListParameters
from rcl_interfaces.msg import ParameterDescriptor, ParameterValue

class MinimalClientAsync(Node):

    def __init__(self):

        self.cli = self.create_client(SetParameters, '/another_node/set_parameters')
        while not self.cli.wait_for_service(timeout_sec=1.0):
            self.get_logger().info('service not available, waiting again...')
        self.req = SetParameters.Request()

    def send_request(self):
        self.req.parameters = [Parameter(name='parameter_1', value=13)]
        self.future = self.cli.call_async(self.req)

def main(args=None):

    minimal_client = MinimalClientAsync()

    while rclpy.ok():
        if minimal_client.future.done():
                response = minimal_client.future.result()
            except Exception as e:
                    'Service call failed %r' % (e,))


if __name__ == '__main__':

The error is:

  File "/opt/ros/dashing/lib/python3.6/site-packages/rcl_interfaces/srv/", line 138, in parameters
    "The 'parameters' field must be a set or sequence and each value of type 'Parameter'"
AssertionError: The 'parameters' field must be a set or sequence and each value of type 'Parameter'

I also tried to use rcl_interfaces.msg.Parameter instead of rclpy.parameter.Parameter so it won't failed at rcl_interfaces/srv/ However it failed at rcl_interfaces/msg/ this time:

  File "/opt/ros/dashing/lib/python3.6/site-packages/rcl_interfaces/msg/", line 80, in __init__
    self.value = kwargs.get('value', ParameterValue())
  File "/opt/ros/dashing/lib/python3.6/site-packages/rcl_interfaces/msg/", line 149, in value
    "The 'value' field must be a sub message of type 'ParameterValue'"
AssertionError: The 'value' field must be a sub message of type 'ParameterValue'

Then I kept trying, used ParameterValue, like this:

Parameter(name='parameter_1', value=ParameterValue(integer_value=3))

It did not cause any error, but when I check the param, it shows Parameter not set.. I am confused. The parameter parameter_1 seems to be undeclared.

edit retag flag offensive reopen merge delete

Closed for the following reason duplicate question by lin404
close date 2020-02-05 18:18:44.228658

1 Answer

Sort by ยป oldest newest most voted

answered 2020-02-05 03:22:14 -0600

marguedas gravatar image

You're very close. As there is currently no helper in rclpy, the "easier" might be to use only rcl_interfaces type for now to avoid confusion

The 'parameters' field must be a set or sequence and each value of type 'Parameter'

This means that you need to pass a rcl_interfaces.msg.Parameter to this function.

Then I kept trying, used ParameterValue, like this:

That's the way to go. On top of defining the value, the type of the parameter needs to be set, as it is not detected automatically

Parameter(name='parameter_1', value=ParameterValue(integer_value=3, type=ParameterType.PARAMETER_INTEGER))

The send_request function will look like this:

def send_request(self):
    new_param_value = ParameterValue(type=ParameterType.PARAMETER_INTEGER, integer_value=13)
    self.req.parameters = [Parameter(name='parameter_1', value=new_param_value)]
    self.future = self.cli.call_async(self.req)

Note that you'll need to import ParameterType from rcl_interfaces.msg at the top of your file.

edit flag offensive delete link more


@marguedas Thank you very much! I have confirmed it, it works perfect!

lin404 gravatar image lin404  ( 2020-02-05 18:16:32 -0600 )edit

Does it work in foxy? I tried and get an error:

  File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/", line 127, in __init__
type_ = Parameter.Type.from_parameter_value(value)
  File "/opt/ros/foxy/lib/python3.8/site-packages/rclpy/", line 70, in from_parameter_value
    raise TypeError('The given value is not one of the allowed types.')
TypeError: The given value is not one of the allowed types.
dgarcialopez gravatar image dgarcialopez  ( 2021-05-23 10:38:59 -0600 )edit

It effectively works on foxy. I encountered the same issue and the problem was that my Parameter class was not imported from rcl_interface.msg. It shouldn't come from rclpy.parameter like the code above.

Lothea gravatar image Lothea  ( 2021-10-19 15:33:25 -0600 )edit

Question Tools



Asked: 2020-02-05 01:09:44 -0600

Seen: 954 times

Last updated: Feb 05 '20