Ask Your Question
1

[ROS2] using dynamic parameters in Python

asked 2020-06-22 02:02:06 -0600

lmiller gravatar image

updated 2020-07-30 02:43:13 -0600

I want to use dynamic parameters in my ROS2 code. I defined a callback function, if a parameter is changed with following line:

self.add_on_set_parameters_callback(self.cb_params)

I wrote a little example to test it:

import rclpy
from rclpy.node import Node
from rclpy.exceptions import ParameterNotDeclaredException

class MinimalParam(Node):

def __init__(self):
    super().__init__('minimal_param_node')
    timer_period = 2  # seconds
    self.timer = self.create_timer(timer_period, self.timer_callback)
    self.declare_parameter("name", "world")

    self.add_on_set_parameters_callback(self.cb_params)
    self.name = self.get_parameter("name").get_parameter_value().string_value

def cb_params(self, data):

    self.get_logger().warn("parameter changed...")
    self.successful = True
    self.name = self.get_parameter("name").get_parameter_value().string_value
    return self


def timer_callback(self):

    self.get_logger().info('Hello %s!' % self.name)

def main():
    rclpy.init()
    node = MinimalParam()
    rclpy.spin(node)

if __name__ == '__main__':
    main()

I changed the parameter over the ros2 command in a terminal with:

ros2 param set /minimal_param_node name "earth"

With the log message I can see that the callback is working, but the parameter is not changed the first time. When I call the ros2 command again, the parameter changed to the value set before.

FYI: The line:

self.successful = True
return self

is needed, because without them the code is crashing with an Error:

AttributeError: 'NoneType' object has no attribute 'successful'

I'm working with Foxy on Ubuntu 20.04 . Unfortunately I could not find any documentation/tutorial on this. What did i wrong?

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
2

answered 2020-06-22 06:07:03 -0600

ahcorde gravatar image

change you callback function

   from rcl_interfaces.msg import SetParametersResult
   from rclpy.parameter import Parameter
   ...
   def cb_params(self, data):
        for parameter in data:
        if parameter.name == "name":
            if parameter.type_ == Parameter.Type.STRING:
                self.name = parameter.value
    self.get_logger().warn("parameter changed... {}".format(self.name))
    return SetParametersResult(successful=True)
edit flag offensive delete link more

Comments

Thats it! Thanks

lmiller gravatar image lmiller  ( 2020-06-22 06:17:24 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

2 followers

Stats

Asked: 2020-06-22 02:02:06 -0600

Seen: 1,075 times

Last updated: Jul 30 '20