# 19 · QoS (服务质量) 完全指南 > **目标**: 理解 ROS2 QoS 的 5 个维度、兼容规则、9 种常用组合、能独立为节点选 QoS。 --- ## 目录 - [1. 是什么](#1-是什么) - [2. 5 大维度](#2-5-大维度) - [3. 兼容规则](#3-兼容规则) - [4. 9 种常用组合](#4-9-种常用组合) - [5. Python API](#5-python-api) - [6. C++ API](#6-c-api) - [7. rclpy QoSProfile 详解](#7-rclpy-qosprofile-详解) - [8. 调试 QoS 不兼容](#8-调试-qos-不兼容) - [9. 推荐阅读](#9-推荐阅读) --- ## 1. 是什么 **QoS (Quality of Service)** 控制 DDS 通信的可靠性、实时性、持久性等。 ROS2 默认 QoS = `RELIABLE + VOLATILE + KEEP_LAST(10)`,适合大多数场景。 但**高频传感器流** / **控制指令** / **参数发布**等场景需要**自定义 QoS**。 ## 2. 5 大维度 | 维度 | 取值 | 默认 | 含义 | |---|---|---|---| | **Reliability** | RELIABLE / BEST_EFFORT | RELIABLE | 必须投递 / 丢一帧无所谓 | | **History** | KEEP_LAST(N) / KEEP_ALL | KEEP_LAST(10) | 队列策略 | | **Durability** | VOLATILE / TRANSIENT_LOCAL | VOLATILE | 晚订阅者是否收到旧数据 | | **Deadline** | Duration | ∞ | 最长多久发一次 | | **Lifespan** | Duration | ∞ | 多旧的消息失效 | ## 3. 兼容规则 **关键规则** — RELIABLE ↔ BEST_EFFORT 单向兼容: | Publisher ↓ \ Subscriber → | RELIABLE | BEST_EFFORT | |---|---|---| | RELIABLE | ✅ | ❌ | | BEST_EFFORT | ✅ | ✅ | **为什么 RELIABLE → BEST_EFFORT 不兼容**: - RELIABLE pub 等 ACK(确保投递) - BEST_EFFORT sub 不发 ACK - pub 等不到 ACK → 报 "QoS incompatible" **报错样例**: ``` [WARN] ... New subscription discovered on this topic with incompatible QoS ... ``` ## 4. 9 种常用组合 | Reliability | Durability | History | 适用场景 | |---|---|---|---| | RELIABLE | VOLATILE | KEEP_LAST(10) | **默认 / 跨语言互通基线** | | RELIABLE | VOLATILE | KEEP_LAST(1) | 控制指令(只关心最新) | | RELIABLE | TRANSIENT_LOCAL | KEEP_LAST(1) | 参数 / 配置(晚订阅者也能拿到) | | RELIABLE | VOLATILE | KEEP_ALL | 日志(必须投递,不丢) | | RELIABLE | TRANSIENT_LOCAL | KEEP_ALL | 启动期参数 | | BEST_EFFORT | VOLATILE | KEEP_LAST(1) | 视频流(丢一帧无所谓) | | BEST_EFFORT | VOLATILE | KEEP_LAST(10) | Lidar / 雷达 | | BEST_EFFORT | TRANSIENT_LOCAL | KEEP_LAST(1) | 较老的状态快照 | | SYSTEM_DEFAULT | VOLATILE | KEEP_LAST(10) | 由 RMW 决定 | ## 5. Python API ```python from rclpy.qos import ( QoSProfile, ReliabilityPolicy, HistoryPolicy, DurabilityPolicy, ) # 视频流:BEST_EFFORT + 深度 1 sensor_qos = QoSProfile( reliability=ReliabilityPolicy.BEST_EFFORT, history=HistoryPolicy.KEEP_LAST, depth=1, ) # 控制指令:RELIABLE + 深度 1 control_qos = QoSProfile( reliability=ReliabilityPolicy.RELIABLE, history=HistoryPolicy.KEEP_LAST, depth=1, ) # 参数:TRANSIENT_LOCAL(晚订阅者能拿历史) param_qos = QoSProfile( reliability=ReliabilityPolicy.RELIABLE, durability=DurabilityPolicy.TRANSIENT_LOCAL, depth=1, ) # 用 publisher_ = self.create_publisher(String, 'topic', sensor_qos) ``` ## 6. C++ API ```cpp #include "rclcpp/qos.hpp" using namespace rclcpp; // 视频流 auto sensor_qos = QoS(1) .reliability(RMW_QOS_POLICY_RELIABILITY_BEST_EFFORT) .history(RMW_QOS_POLICY_HISTORY_KEEP_LAST); // 参数 auto param_qos = QoS(1) .reliability(RMW_QOS_POLICY_RELIABILITY_RELIABLE) .durability(RMW_QOS_POLICY_DURABILITY_TRANSIENT_LOCAL); // 用 publisher_ = this->create_publisher("topic", sensor_qos); ``` ## 7. rclpy QoSProfile 详解 完整参数: ```python QoSProfile( # Reliability reliability=ReliabilityPolicy.RELIABLE, # or BEST_EFFORT, SYSTEM_DEFAULT # History history=HistoryPolicy.KEEP_LAST, # or KEEP_ALL depth=10, # 仅 KEEP_LAST 时有效 # Durability durability=DurabilityPolicy.VOLATILE, # or TRANSIENT_LOCAL # Deadline(可省) deadline=Duration(seconds=0), # 0 = 无 # Lifespan(可省) lifespan=Duration(seconds=0), # 0 = 无 # Liveliness(可省) liveliness=LivelinessPolicy.SYSTEM_DEFAULT, liveliness_lease_duration=Duration(seconds=0), ) ``` ## 8. 调试 QoS 不兼容 **症状**: `ros2 topic echo` 没输出,`ros2 topic info -v` 显示 QoS incompatible 警告。 **调试步骤**: ```bash # 1) 看 pub/sub 各自 QoS ros2 topic info /topic -v # 2) 检查 pub/sub 是否在同 domain echo $ROS_DOMAIN_ID # 3) 看具体 incompatibility # 错误信息: PolicyKind=RMW_QOS_POLICY_RELIABILITY ``` **修法**: 改一边 QoS 匹配,或用 SYSTEM_DEFAULT。 ## 9. 推荐阅读 - [ROS2 QoS 设计稿](https://design.ros2.org/articles/qos.html) - [ROS2 Humble QoS 文档](https://docs.ros.org/en/humble/Concepts/About-Quality-of-Service.html) - [OMG DDS 规范 v1.4](https://www.omg.org/spec/DDS/1.4/) — QoS 源头 - [FastDDS QoS 配置](https://fast-dds.docs.eprosima.com/) - [`cpp_qos_demo` 包](../src/cpp_qos_demo/README.md) --- --- ## 📖 阅读路径导航 > 💡 这是仓库 `doc/` 下所有文档的推荐阅读顺序。[返回 README 总导航](../README.md#-23-篇文档怎么读) > > ⏱ **本文预计阅读时间**: 25 分钟 > 📍 **当前位置**: 第 10 / 24 篇 - ⏮ **上一篇**: [Composable Node](../18-composable.md) - ⏭ **下一篇**: [Topic pub/sub 深度](../20-topics.md)