ROS2-007-通信机制:参数服务
简介
参数(Parameters) 是 ROS2 中用于节点运行时动态配置的键值对(Key-Value)存储机制。参数并不需要中心化的仓库用于存储信息,其直接被归属于节点本身。参数允许通过服务接口在该节点运行期间读写其内部相关配置,而无需修改代码或重启该节点。与话题通信(Topics)和服务通信(Services)不同,参数的交互本质是 对节点内部状态的访问与控制,而非单纯的节点间数据流通。
具体而言:
- 参数直接存储在节点内部,每个节点维护独立的参数列表,通过命名空间(例如
/control_node/max_speed
)进行隔离。 - 参数通过 ROS2 内置的参数服务接口(如
/get_parameters
和/set_parameters
等)访问,其访问逻辑底层依赖于 ROS2 服务通信(Services)机制。 - 同一节点内的参数可被多个外部对象(如 CLI 工具、其他节点、RQT 界面等)同时访问,形成 单服务端(节点)对 多客户端 的交互模式。
参数(Parameters) 在节点中一般用于调整算法参数(如 PID 控制器的比例系数)、传感器阈值(如摄像头曝光时间)或操作模式(如调试模式开关)。当然,你可以通过脚本批量修改多个节点的参数(如同时设置所有激光雷达的扫描频率)以实现特殊操作。并且在实际应用中,将参数保存为 YAML 文件,可以在代码部署时通过调用该文件快速将节点内的配置恢复为 YAML 文件内的预设配置。
参数服务的命令行访问
在一个 ROS2 程序运行时,你可以在命令行窗口中使用指令对运行中节点内的 Parameters 进行查看、修改等。
ros2 param <related command>
查看节点内拥有的 Parameters
在一个 ROS2 程序运行时,你可以使用 list
查看该程序内所有节点下的所有 Parameters。
ros2 param list
在输出中,你可以看到以下结构(以 turtlesim package 运行时的相关输出为例子):
/teleop_turtle:
qos_overrides./parameter_events.publisher.depth
qos_overrides./parameter_events.publisher.durability
qos_overrides./parameter_events.publisher.history
qos_overrides./parameter_events.publisher.reliability
scale_angular
scale_linear
use_sim_time
/turtlesim:
background_b
background_g
background_r
qos_overrides./parameter_events.publisher.depth
qos_overrides./parameter_events.publisher.durability
qos_overrides./parameter_events.publisher.history
qos_overrides./parameter_events.publisher.reliability
use_sim_time
其中:
/teleop_turtle
是节点名- 节点名下的皆为其携带的 Parameters
- 在所有 Parameters 中,
use_sim_time
为所有节点都拥有的一种 Parameters。
获取某一节点内某一 Parameters 的值
在一个 ROS2 程序运行时,你可以使用 get
获取运行程序中某一节点内某一 Parameters 的值.
ros2 param get <node_name> <parameter_name>
例如,当你希望找到节点 node_a
中的 Parameters height
的值时:
ros2 param get /node_a height
它会返回:
Integer value is: 186
这样你既可以知道其数据的值,也同时知道了其数据的类型。
在程序运行时修改某一节点内某一 Parameters 的值
在一个 ROS2 程序运行时,你可以使用 set
修改运行程序中某一节点内某一 Parameters 的值.
ros2 param set <node_name> <parameter_name> <value>
例如,当你希望将节点 node_a
中的 Parameters height
的值修改为 168
时:
ros2 param set /node_a height 168
当其修改成功,它会弹出以下信息:
Set parameter successful
在程序运行时输出某一节点内所有 Parameters 的值
在一个 ROS2 程序运行时,你可以使用 dump
输出某一节点内所有 Parameters 的值.
ros2 param dump <node_name>
例如,当你希望输出节点 node_a
中所有 Parameters 的值时:
ros2 param dump /node_a
它会在命令行窗口弹出包含以下声明的信息:
/node_a:
ros__parameters:
height: 168
use_sim_time: false
这些信息是该节点现在在运行时所拥有的 Parameters 数据,如果之前有进行过修改,这里会相对应的体现。当然,如果你希望保存为其他文件进行浏览,那么你可以将其保存至 YAML 文件
内。
例如,当你希望将节点 node_a
中所有 Parameters 的值输出至 YAML 文件
时,你可以执行如下代码:
ros2 param dump /node_a > node_a.yaml
该命令执行后,ROS2 会在你的命令行所运行的文件夹路径下生成一个名称为 node_a.yaml
的文件。里面包括了之前输出至命令行窗口的所有信息。
在程序运行时将文件内的 Parameters 加载入运行中的节点
如果你希望将之前所保存的 Parameters 文件加载入运行中的对应节点,你可以在该节点重新运行时使用 load
进行加载。
ros2 param load <node_name> <parameter_file>
例如,当你希望将节点 node_a
中所有 Parameters 的值输出至 YAML 文件
时:
ros2 param load /node_a node_a.yaml
你应该会得到拥有以下声明的回执:
Set parameter height successful
Set parameter use_sim_time successful
之后你可能会遇到出现以下回执的情况:
Set parameter background_b successful
Set parameter background_g successful
Set parameter background_r successful
Set parameter qos_overrides./parameter_events.publisher.depth failed: parameter 'qos_overrides./parameter_events.publisher.depth' cannot be set because it is read-only
Set parameter qos_overrides./parameter_events.publisher.durability failed: parameter 'qos_overrides./parameter_events.publisher.durability' cannot be set because it is read-only
Set parameter qos_overrides./parameter_events.publisher.history failed: parameter 'qos_overrides./parameter_events.publisher.history' cannot be set because it is read-only
Set parameter qos_overrides./parameter_events.publisher.reliability failed: parameter 'qos_overrides./parameter_events.publisher.reliability' cannot be set because it is read-only
Set parameter use_sim_time successful
因为在里面有一些 Parameters 是只读的参数,这些只读参数只能在节点启动时修改,不能在启动后修改,这就是为什么 “qos_overrides” 相关的参数会出现一些警告。
在程序运行开始时将文件内的 Parameters 加载入即将运行的节点
如果你希望在程序运行开始时加载文件内的 Parameters,你可以在运行 ros2 程序时同时使用 --ros-args
和 --params-file
两个指示变量,来告诉 ROS2 你希望使用这个文件作为运行节点内 Parameters 的值。
ros2 run <package_name> <executable_name> --ros-args --params-file <file_name>
注
当你使用这个方法更新 Parameters 时,包括只读 Parameters 在内的所有相关 Parameters 都会得到更新。
参数服务的简单实现
当你使用自定义节点时,你可能会需要 Parameters。现在我们针对以下案例,通过使用 C++ 与 Python 进行分别实现,以更加深入了解参数服务。
案例需求&案例分析
需求:有两个节点,请编写参数服务,在参数服务端(节点A)中设置一些参数,使参数客户端(节点B)可以通过访问参数服务端(节点A)对这些参数实现查看与修改,并且参数服务端(节点A)自身可以对此进行增删改查。
分析:在上述需求中,我们需要关注以下三个要素:
- 参数服务端;
- 参数客户端;
- 参数本身。
流程简介
案例实现前需要先了解ROS2中参数的相关API,无论是客户端还是服务端都会使用到参数,而参数服务案例实现主要步骤如下:
- 编写参数服务端实现;
- 编写参数客户端实现;
- 编辑配置文件;
- 编译;
- 执行。
案例会采用 C++ 和 Python 分别实现,且二者都遵循上述实现流程。
准备工作
终端下创建工作空间:
mkdir -p ws01_plumbing/src
cd ws01_plumbing/src
colcon build
进入工作空间的src目录:
cd src/
调用如下两条命令分别创建C++功能包、Python功能包及其所需服务端节点:
C++:
ros2 pkg create cpp04_parameter --build-type ament_cmake --dependencies rclcpp --node-name demo01_parameter_server
Python:
ros2 pkg create py04_parameter --build-type ament_python --dependencies rclpy --node-name demo01_parameter_server_py
准备工作到此完毕。
接下来你便可以通过 C++ 和 Python 来分别实现参数服务了。
总结
在这一节中,我们系统的阐述了参数服务。通过依据参数服务的相关原理自行操作,实现了节点参数服务的创建与使用。这一章节为止,我们就已经简单介绍完了四种通信方式,望能够提供参考。