在ROS1中参数全部都在一个Parameter Server上面,任意节点都可以随意的设置和读取其他节点的参数。但是在ROS2中,这部分发生了很大变化。首先由于ROS2没有了中心节点,所以也不存在一个Parameter Server了。每个节点的参数由节点本身去维护。所以要设置或获取其他节点的参数就要用调用服务的方法去调用其他节点设置参数,获取参数服务。下面是一个具体的例子
单个节点获取和设置自己的参数
import rclpy
node = None
def get_params():
global node
node.get_logger().info(node.get_parameter("test").get_parameter_value().string_value)
def main():
global node
rclpy.init()
node = rclpy.create_node("get_params_node")
# 声明参数,所有参数在使用之前都要声明一下
node.declare_parameter("test", "default")
# 设置参数
node.set_parameters([rclpy.Parameter("test", rclpy.Parameter.Type.STRING, "hello world")])
node.create_timer(1, get_params)
rclpy.spin(node)
if __name__ == "__main__":
main()
正常运行后输出如下
[INFO] [1677133156.500033082] [get_params_node]: hello world
[INFO] [1677133157.492551064] [get_params_node]: hello world
[INFO] [1677133158.492387209] [get_params_node]: hello world
[INFO] [1677133159.492404149] [get_params_node]: hello world
[INFO] [1677133160.492420371] [get_params_node]: hello world
设置其他节点的参数
import rclpy
from rcl_interfaces.srv import SetParameters
from rcl_interfaces.msg import Parameter, ParameterValue, ParameterType
index = 0
set_params = None
def get_params():
global set_params, index
index += 1
# 创建设置参数请求
req = SetParameters.Request()
# 设置参数数据
req.parameters = [Parameter(name="test", value=ParameterValue(string_value=f"{index}",type=ParameterType.PARAMETER_STRING))]
# 发送请求
set_params.call_async(req)
def main():
global set_params
rclpy.init()
node = rclpy.create_node("set_params_node")
# 创建设置参数服务客户端
set_params = node.create_client(SetParameters, "/get_params_node/set_parameters")
# 等待服务
set_params.wait_for_service(1)
node.create_timer(1, get_params)
rclpy.spin(node)
if __name__ == "__main__":
main()
总结
可以看到设置其他节点的参数相对于ROS1要复杂了很多。在ROS2的设计文档中提到了要做一个类似参数服务器的东西。但是目前这个东西还没有实现。