docs(nav): 阅读路径导航 + 数字统一

This commit is contained in:
xs
2026-08-04 16:10:27 +08:00
parent 549d6b337e
commit 6338f3d36a
95 changed files with 3838 additions and 1260 deletions
+107 -52
View File
@@ -1,77 +1,132 @@
# cpp_qos_demo
# cpp_qos_demo — C++ QoS 9 种组合演示
ROS2 QoS 9 种组合演示包(C++)。属于 Level 1 基础机制第 13 块
> 生产级 ROS2 必学:**QoS(Quality of Service)** 消息传输质量策略
>
> 预计学习时间:1-2 小时。
## 功能
---
- **`qos_demo_publisher_cpp`**: 参数化 QoS 发布者
- **`qos_demo_subscriber_cpp`**: 参数化 QoS 订阅者
## 这是什么?
每个节点支持以下参数:
**QoS(服务质量)** 控制 Topic 消息的传输行为。9 种组合 = 3 个维度叉乘:
| 参数 | 可选值 | 默认 |
| 维度 | 选项 | 含义 |
|---|---|---|
| `reliability` | `reliable` / `best_effort` | `reliable` |
| `durability` | `volatile` / `transient_local` | `volatile` |
| `history` | `keep_last` / `keep_all` | `keep_last` |
| `depth` | int | 10 |
| `publish_rate_hz` | float | 1.0 |
| **Reliability(可靠性)** | `reliable` / `best_effort` | 保证送达 vs 丢了就算了 |
| **Durability(持久性)** | `volatile` / `transient_local` | 不保存历史 vs 为晚加入者保留 |
| **History(历史)** | `keep_last(N)` / `keep_all` | 只保留最后 N 条 vs 保留所有 |
## 9 种常用组合
**兼容性要求**:Publisher 和 Subscriber 的 QoS 必须**兼容**,否则它们看不到对方!
| Reliability | Durability | History | 适用场景 |
|---|---|---|---|
| RELIABLE | VOLATILE | KEEP_LAST(10) | 默认 / 跨语言互通基线 |
| RELIABLE | VOLATILE | KEEP_LAST(1) | 控制指令(只关心最新) |
| RELIABLE | TRANSIENT_LOCAL | KEEP_LAST(1) | 参数 / 配置(晚订阅者也能拿到) |
| BEST_EFFORT | VOLATILE | KEEP_LAST(1) | 视频流(丢一帧无所谓) |
| BEST_EFFORT | VOLATILE | KEEP_LAST(10) | Lidar / 雷达 |
| RELIABLE | VOLATILE | KEEP_ALL | 日志(必须投递,不丢) |
---
## 兼容性矩阵
## 🎯 学完之后你能做什么?
| Publisher ↓ \ Subscriber → | RELIABLE | BEST_EFFORT |
|---|---|---|
| RELIABLE | ✅ | ❌ |
| BEST_EFFORT | ✅ | ✅ |
1. ✅ 理解 3 维 QoS 模型(Reliability / Durability / History)
2. ✅ 用 `rclcpp::QoS` 构造 QoS profile
3. ✅ 知道 9 种组合的兼容性矩阵
4. ✅ 在生产环境正确选 QoS(传感器用 best_effort,关键控制用 reliable)
**关键**:`RELIABLE → BEST_EFFORT` 不兼容!sub 不发 ACK,pub 报错:
```
[WARN] ... New subscription discovered on this topic with incompatible QoS ...
```
---
## 运行
## 🚀 跑起来
### 启动 Subscriber
**终端 1**(容器内):
```bash
# 默认 QoS(RELIABLE + VOLATILE + KEEP_LAST(10))
ros2 launch cpp_qos_demo qos_launch.py
source /opt/ros/humble/setup.bash
source /root/ros2_ws/install/setup.bash
# BEST_EFFORT 视频流
ros2 run cpp_qos_demo qos_demo_publisher_cpp --ros-args \
-p reliability:=best_effort -p history:=keep_last -p depth:=1
# TRANSIENT_LOCAL(晚订阅者能拿到历史)
ros2 run cpp_qos_demo qos_demo_subscriber_cpp --ros-args \
-p durability:=transient_local
# 默认(reliable + volatile + keep_last(10))
ros2 run cpp_qos_demo qos_demo_subscriber_cpp
```
## 测试
### 启动 Publisher(另开终端)
**终端 2**:
```bash
source /opt/ros/humble/setup.bash
source /root/ros2_ws/install/setup.bash
# 默认(reliable + volatile + keep_last(10))
ros2 run cpp_qos_demo qos_demo_publisher_cpp
# 或用参数切换 QoS
ros2 run cpp_qos_demo qos_demo_publisher_cpp --ros-args \
-p reliability:=best_effort \
-p durability:=transient_local \
-p history:=keep_all \
-p depth:=10
```
### 试不兼容的组合
**终端 3**(Subscriber 用 reliable,Publisher 用 best_effort):
```bash
ros2 run cpp_qos_demo qos_demo_subscriber_cpp --ros-args -p reliability:=reliable
ros2 run cpp_qos_demo qos_demo_publisher_cpp --ros-args -p reliability:=best_effort
```
**预期结果**:**看不到对方的消息**(QoS 不兼容)。
---
## 📖 兼容性矩阵
| Publisher\Subscriber | Reliable | Best Effort |
|---|---|---|
| **Reliable** | ✅ 互通 | ✅ 互通(reliable ≥ best_effort) |
| **Best Effort** | ❌ 不兼容 | ✅ 互通 |
**口诀**:**reliable 可以向下兼容 best_effort**(reliable 一定能发出 best_effort 也能接收的消息),反之不行。
---
## 📖 核心代码
```cpp
// 构造 QoS
rclcpp::QoS qos(depth);
qos.reliable(); // 或 qos.best_effort()
qos.transient_local(); // 或 qos.durability_volatile()
qos.keep_last(depth); // 或 qos.keep_all()
// 用 QoS 创建 Publisher
publisher_ = this->create_publisher<std_msgs::msg::String>("/topic", qos);
```
---
## 🧪 跑测试
```bash
colcon test --packages-select cpp_qos_demo
colcon test-result --all --verbose
```
测试覆盖(在 `test/test_qos_profiles.cpp`):
**预期**:`cpp_qos_demo: gtest 4/4 ✓` 全部通过。
| 用例 | 内容 |
|---|---|
| `DefaultProfileValues` | 默认 QoS profile 字段 |
| `PublisherConstructsWithDefaultQoS` | Publisher 默认参数 |
| `PublisherConstructsWithBestEffort` | BEST_EFFORT 构造 |
| `SubscriberConstructsWithTransientLocal` | TRANSIENT_LOCAL 构造 |
---
## 深度学习
## 📚 深入学习
- 编程规范:[`doc/CODING_STYLE.md`](../doc/CODING_STYLE.md)
- QoS 深度:[`doc/19-qos.md`](../doc/19-qos.md)
- OMG DDS 规范:[`DDS 1.4 spec`](https://www.omg.org/spec/DDS/1.4/)
- [doc/19-qos.md](../../doc/19-qos.md) — QoS 深度(全部 9 种组合详解)
- [ROS2 QoS 设计稿](https://design.ros2.org/articles/qos.html)
---
## ⏭️ 下一个包
继续学 **[py_lifecycle_composable](../py_lifecycle_composable/README.md)** — Lifecycle Node(节点生命周期管理)。
---
## 📍 学习路径导航
| ⏮ 上一个 | 🏠 当前位置 | ⏭ 下一个 |
|---|---|---|
| [cpp_robot_tf2 — C++ TF2 + URDF](../cpp_robot_tf2/README.md) | **cpp_qos_demo — C++ QoS** | [py_lifecycle_composable — Python Lifecycle + Composable](../py_lifecycle_composable/README.md) |
📍 完整 12 包学习顺序见 [主 README](../../README.md#-12-包推荐学习顺序)