docs(nav): 阅读路径导航 + 数字统一
This commit is contained in:
+107
-52
@@ -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-包推荐学习顺序)
|
||||
|
||||
Reference in New Issue
Block a user