!QoS(Quality of Service,服务质量)策略 是 ROS 2 中非常重要的一部分,它决定了节点之间通信的质量和行为。你可以把它理解为“通信规则”,告诉系统在发布消息或接收消息时应该如何处理数据。
🧠 为什么需要 QoS 策略?
ROS 2 使用 DDS(Data Distribution Service) 作为底层通信机制,而 DDS 是一个面向实时系统的中间件协议。为了适应不同场景的需求(比如传感器数据、控制指令、日志信息等),DDS 提供了多种可配置的通信策略。
ROS 2 对这些策略进行了封装,让开发者可以用更简单的方式设置通信质量。
✅ QoS 策略的作用
QoS 策略影响以下方面:
功能 | 说明 |
---|---|
数据可靠性 | 消息是否必须送达 |
数据持久性 | 新订阅者是否能收到之前的消息 |
数据优先级 | 某些数据是否应被优先处理 |
队列长度 | 发布/订阅队列中最多缓存多少条消息 |
传输方式 | 是否使用多播还是单播 |
数据生命周期 | 数据保存多久 |
📦 常见的 QoS 策略(ROS 2 中常用的)
ROS 2 定义了一些标准的 QoS 配置,我们可以直接使用它们,也可以自定义组合。
🔹 1. QoSProfile(depth=10)
这是最常见的一种写法,表示创建一个队列深度为 10 的 QoS 策略。
from rclpy.qos import QoSProfile
qos = QoSProfile(depth=10)
这个 depth
实际上设置了以下两个策略:
- history:
HistoryPolicy.KeepLast
- depth:保留最近的 10 条消息
也就是说,如果消息太多来不及处理,只保留最新的 10 条。
🔹 2. 常用 QoS 设置(ROS 2 内置预设)
ROS 2 提供了一些内置的 QoS 设置,方便你快速选择适合当前用途的策略:
🟢 QoSProfile.system_default
默认策略,大多数时候使用这个即可。
🟡 QoSProfile.sensor_data
适用于传感器数据(如摄像头、激光雷达),允许丢弃旧数据。
from rclpy.qos import QoSProfile, QoSPresetProfiles
qos = QoSPresetProfiles.SENSOR_DATA.value
🔵 QoSProfile.services_default
适用于服务(Service)通信,保证可靠传输。
🟣 QoSProfile.parameters
用于参数服务器通信,通常要求可靠性和持久化。
🟥 QoSProfile.action_status_default
用于 Action 接口的状态更新。
🔧 可配置的 QoS 参数详解
你可以手动设置每一个 QoS 参数来定制自己的策略:
from rclpy.qos import QoSProfile
from rclpy.qos import HistoryPolicy, ReliabilityPolicy, DurabilityPolicy
qos = QoSProfile(
history=HistoryPolicy.KeepLast,
depth=10,
reliability=ReliabilityPolicy.BestEffort,
durability=DurabilityPolicy.Volatile,
deadline=(0, 100000000), # 100ms
lifespan=(0, 3000000000), # 3秒
liveliness=LivelinessPolicy.Automatic,
liveliness_lease_duration=(0, 1000000000),
avoid_ros_namespace_conventions=False
)
各个参数含义如下:
参数名 | 类型 | 描述 |
---|---|---|
history | HistoryPolicy | 消息存储策略: • KeepLast(n) - 保留最近 n 条• KeepAll - 保留所有 |
depth | int | 当 history=KeepLast 时,保留多少条消息 |
reliability | ReliabilityPolicy | 消息传输可靠性: • BestEffort - 尽力而为(可能丢包)• Reliable - 必须送达(重传机制) |
durability | DurabilityPolicy | 消息持久性: • Volatile - 不保留(新订阅者收不到旧消息)• TransientLocal - 保留(新订阅者能收到旧消息) |
deadline | Duration | 要求每两次消息之间的时间间隔不能超过这个时间 |
lifespan | Duration | 消息的最大存活时间,超过则失效 |
liveliness | LivelinessPolicy | 判断节点是否活跃的机制 |
avoid_ros_namespace_conventions | bool | 是否避免 ROS 命名空间约定 |
🧪 示例:如何在代码中使用 QoS 策略
假设你想创建一个发布者,使用 TransientLocal
策略,确保新订阅者也能收到最新消息:
from rclpy.qos import QoSProfile, DurabilityPolicy
# 创建一个 QoS 策略,保留最后一条消息,并持久化
qos = QoSProfile(
depth=1,
durability=DurabilityPolicy.TRANSIENT_LOCAL
)
self.publisher_ = self.create_publisher(String, 'chatter', qos)
这样即使有新的订阅者加入,也能立即收到上一条消息。
📌 总结一句话:
QoS 策略是 ROS 2 中用来控制节点之间通信质量的一组参数集合,它决定了消息的可靠性、持久性、传输方式等关键行为。
🧩 应用建议
场景 | 推荐 QoS 策略 |
---|---|
实时传感器数据(如摄像头、IMU) | QoSPresetProfiles.SENSOR_DATA |
控制指令(如机器人运动) | QoSProfile(reliability=Reliable) |
日志或调试信息 | QoSProfile(reliability=BestEffort) |
参数服务 | QoSPresetProfiles.PARAMETERS |
新节点也需要历史数据 | durability=TRANSIENT_LOCAL |