Skip to content

Commit

Permalink
docs: 更新:ROS2-007-通信机制:参数服务
Browse files Browse the repository at this point in the history
简单介绍参数服务 (Parameters)
  • Loading branch information
JeacsonSnake committed Mar 5, 2025
1 parent 2fa80a2 commit b87006a
Showing 1 changed file with 254 additions and 0 deletions.
254 changes: 254 additions & 0 deletions docs/learningNote/Ros2_Note/2024_11_27.md
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) 来分别实现参数服务了。

## 总结

在这一节中,我们系统的阐述了参数服务。通过依据参数服务的相关原理自行操作,实现了节点参数服务的创建与使用。这一章节为止,我们就已经简单介绍完了四种通信方式,望能够提供参考。

0 comments on commit b87006a

Please sign in to comment.