-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
1 changed file
with
254 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,254 @@ | ||
--- | ||
title: ROS2-007-通信机制:参数服务 | ||
icon: 'warehouse' | ||
date: 2025-02-28 | ||
category: | ||
- Computer | ||
- robot | ||
- ROS | ||
--- | ||
|
||
## 简介 | ||
|
||
**参数(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 进行查看、修改等。 | ||
|
||
```bash | ||
ros2 param <related command> | ||
``` | ||
|
||
### 查看节点内拥有的 Parameters | ||
|
||
在一个 ROS2 程序运行时,你可以使用 `list` 查看该程序内所有节点下的所有 Parameters。 | ||
|
||
```bash | ||
ros2 param list | ||
``` | ||
|
||
在输出中,你可以看到以下结构(以 turtlesim package 运行时的相关输出为例子): | ||
|
||
```txt | ||
/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 的值. | ||
|
||
```bash | ||
ros2 param get <node_name> <parameter_name> | ||
``` | ||
|
||
例如,当你希望找到节点 `node_a` 中的 Parameters `height` 的值时: | ||
|
||
```bash | ||
ros2 param get /node_a height | ||
``` | ||
|
||
它会返回: | ||
|
||
```txt | ||
Integer value is: 186 | ||
``` | ||
|
||
这样你既可以知道其数据的值,也同时知道了其数据的类型。 | ||
|
||
### 在程序运行时修改某一节点内某一 Parameters 的值 | ||
|
||
在一个 ROS2 程序运行时,你可以使用 `set` 修改运行程序中某一节点内某一 Parameters 的值. | ||
|
||
```bash | ||
ros2 param set <node_name> <parameter_name> <value> | ||
``` | ||
|
||
例如,当你希望将节点 `node_a` 中的 Parameters `height` 的值修改为 `168` 时: | ||
|
||
```bash | ||
ros2 param set /node_a height 168 | ||
``` | ||
|
||
当其修改成功,它会弹出以下信息: | ||
|
||
```txt | ||
Set parameter successful | ||
``` | ||
|
||
### 在程序运行时输出某一节点内所有 Parameters 的值 | ||
|
||
在一个 ROS2 程序运行时,你可以使用 `dump` 输出某一节点内所有 Parameters 的值. | ||
|
||
```bash | ||
ros2 param dump <node_name> | ||
``` | ||
|
||
例如,当你希望输出节点 `node_a` 中所有 Parameters 的值时: | ||
|
||
```bash | ||
ros2 param dump /node_a | ||
``` | ||
|
||
它会在命令行窗口弹出以下信息: | ||
|
||
```txt | ||
/node_a: | ||
ros__parameters: | ||
height: 168 | ||
use_sim_time: false | ||
``` | ||
|
||
这些信息是该节点现在在运行时所拥有的 Parameters 数据,如果之前有进行过修改,这里会相对应的体现。当然,如果你希望保存为其他文件进行浏览,那么你可以将其保存至 `YAML 文件` 内。 | ||
|
||
例如,当你希望将节点 `node_a` 中所有 Parameters 的值输出至 `YAML 文件` 时,你可以执行如下代码: | ||
|
||
```bash | ||
ros2 param dump /node_a > node_a.yaml | ||
``` | ||
|
||
该命令执行后,ROS2 会在你的命令行所运行的文件夹路径下生成一个名称为 `node_a.yaml` 的文件。里面包括了之前输出至命令行窗口的所有信息。 | ||
|
||
### 在程序运行时将文件内的 Parameters 加载入运行中的节点 | ||
|
||
如果你希望将之前所保存的 Parameters 文件加载入运行中的对应节点,你可以在该节点重新运行时使用 `load` 进行加载。 | ||
|
||
```bash | ||
ros2 param load <node_name> <parameter_file> | ||
``` | ||
|
||
例如,当你希望将节点 `node_a` 中所有 Parameters 的值输出至 `YAML 文件` 时: | ||
|
||
```bash | ||
ros2 param load /node_a node_a.yaml | ||
``` | ||
|
||
你应该会得到以下回执: | ||
|
||
```txt | ||
Set parameter height successful | ||
Set parameter use_sim_time successful | ||
``` | ||
|
||
之后你可能会遇到出现以下回执的情况: | ||
|
||
```txt | ||
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 的值。 | ||
|
||
```bash | ||
ros2 run <package_name> <executable_name> --ros-args --params-file <file_name> | ||
``` | ||
|
||
::: note | ||
当你使用这个方法更新 Parameters 时,包括只读 Parameters 在内的所有相关 Parameters 都会得到更新。 | ||
::: | ||
|
||
## 参数服务的简单实现 | ||
|
||
当你使用自定义节点时,你可能会需要 Parameters。现在我们针对以下案例,通过使用 C++ 与 Python 进行分别实现,以更加深入了解参数服务。 | ||
|
||
### 案例需求&案例分析 | ||
|
||
需求:有两个节点,请编写参数服务,在参数服务端(节点A)中设置一些参数,使参数客户端(节点B)可以通过访问参数服务端(节点A)对这些参数实现查看与修改,并且参数服务端(节点A)自身可以对此进行增删改查。 | ||
|
||
分析:在上述需求中,我们需要关注以下三个要素: | ||
|
||
1. 参数服务端; | ||
2. 参数客户端; | ||
3. 参数本身。 | ||
|
||
### 流程简介 | ||
|
||
案例实现前需要先了解ROS2中参数的相关API,无论是客户端还是服务端都会使用到参数,而参数服务案例实现主要步骤如下: | ||
|
||
1. 编写参数服务端实现; | ||
2. 编写参数客户端实现; | ||
3. 编辑配置文件; | ||
4. 编译; | ||
5. 执行。 | ||
|
||
案例会采用 C++ 和 Python 分别实现,且二者都遵循上述实现流程。 | ||
|
||
### 准备工作 | ||
|
||
终端下创建工作空间: | ||
|
||
```shell | ||
mkdir -p ws01_plumbing/src | ||
cd ws01_plumbing/src | ||
colcon build | ||
``` | ||
|
||
进入工作空间的src目录: | ||
|
||
```shell | ||
cd src/ | ||
``` | ||
|
||
调用如下两条命令分别创建C++功能包、Python功能包及其所需服务端节点: | ||
|
||
**C++:** | ||
|
||
```shell | ||
ros2 pkg create cpp04_parameter --build-type ament_cmake --dependencies rclcpp --node-name demo01_parameter_server | ||
``` | ||
|
||
**Python:** | ||
|
||
```shell | ||
ros2 pkg create py04_parameter --build-type ament_python --dependencies rclpy --node-name demo01_parameter_server_py | ||
``` | ||
|
||
准备工作到此完毕。 | ||
|
||
--- | ||
|
||
接下来你便可以通过 [C++](./2025_03_06.md) 和 [Python](./2025_03_07.md) 来分别实现参数服务了。 | ||
|
||
## 总结 | ||
|
||
在这一节中,我们系统的阐述了参数服务。通过依据参数服务的相关原理自行操作,实现了节点参数服务的创建与使用。这一章节为止,我们就已经简单介绍完了四种通信方式,望能够提供参考。 |