一、QoS 介绍
ROS2的QoS机制源于对实时性网络通信的优化需求。传统ROS1基于TCP协议实现数据传输,虽可靠性高,但在无线网络等不稳定环境中易出现丢包问题。而ROS2采用DDS(数据分发服务)作为底层传输协议,支持UDP传输并引入QoS策略,允许开发者根据场景在可靠传输与实时性之间灵活平衡
例如:在机器人传感器数据传输中,激光雷达的实时性优先级高于数据完整性,此时可配置Best effort策略;而在关键指令传输(如紧急停止)时则需Reliable策略确保数据必达
二、QoS 核心策略
1. 数据可用性策略
历史记录(History)
1.Keep Last:仅保留最近的N个样本(通过Depth参数配置),适用于高频数据(如传感器)
2.Keep All:存储所有数据,受限于系统资源,适合需完整回溯的场景(如调试)
持久性(Durability)
1.Volatile:不保留历史数据,新订阅者无法获取连接前的信息。
2.Transient Local:发布者保留最后一条数据,类似ROS1的Latching机制
2. 数据交付策略
可靠性(Reliability)
策略 | 适用场景 | 特点 |
---|---|---|
Best Effort | 传感器数据、视频流 | 允许丢包,优先实时性 |
Reliable | 控制指令、服务通信 | 重传确保数据必达 |
所有权(Ownership)
允许多个发布者竞争写入权限,通过“强度”值决定优先级,适用于冗余传感器切换
3. 数据时效性策略
1.Deadline:约束消息发布的周期,若超时则触发事件告警
2.Liveliness:通过心跳机制检测节点活跃性,若超时则认为节点失效
3.Latency Budget:控制端到端最大延迟,超时数据可能被丢弃以保证实时性
4. 资源管理策略
1.队列深度(Depth):与Keep Last配合,控制缓存大小(如默认传感器配置Depth=5)
2.资源限制(Resource Limits):限制内存分配,防止系统过载
三、QoS 配置文件
3.1 使用方式
ROS2为常见场景提供标准化配置,简化开发复杂度:
配置文件 | 适用场景 | 策略组合 |
---|---|---|
Sensor Data | 传感器数据 | Best Effort + Keep Last(5) + Volatile |
Services Default | 服务通信 | Reliable + Keep Last(10) + Volatile |
Parameters | 参数服务器 | Reliable + Keep Last(1000) + Volatile |
System Default | 默认配置 | 由底层DDS实现定义(如Fast DDS或RTI) |
代码示例(Python):
from rclpy.qos import QoSProfile, qos_profile_sensor_data
# 使用传感器预设配置
sub = node.create_subscription(LaserScan, '/scan', callback, qos_profile=qos_profile_sensor_data)
3.2 配置文件介绍
配置文件让开发人员可以专注于他们的应用程序,而不必担心每个可能的 QoS 设置。QoS 配置文件定义了一组策略,这些策略有望很好地配合特定用例。
当前定义的 QoS 配置文件包括:
3.2.1 发布者和订阅者的默认 QoS 设置
为了使从 ROS 1 过渡到 ROS 2 更加容易,最好采用类似的网络行为。默认情况下,ROS 2 中的发布者和订阅者将“保留最后”用于历史记录,队列大小为 10,“可靠”用于可靠性,“易失性”用于持久性,“系统默认”用于活跃性。截止期限、使用寿命和租约期限也全部设置为“默认”。
3.2.2 服务
与发布者和订阅者一样,服务也是可靠的。服务使用易失性持久性尤为重要,否则重新启动的服务服务器可能会收到过时的请求。虽然客户端可以避免接收多个响应,但服务器无法避免接收过时请求的副作用。
3.2.3 传感器数据
对于传感器数据,在大多数情况下,及时接收读数比确保所有读数都到达更重要。也就是说,开发人员希望在捕获最新样本后立即获得它们,但代价是可能会丢失一些样本。因此,传感器数据配置文件使用尽力而为的可靠性和较小的队列大小。
3.2.4 参数
ROS 2 中的参数基于服务,因此具有类似的配置文件。不同之处在于参数使用更大的队列深度,以便在参数客户端无法到达参数服务服务器等情况下不会丢失请求。
3.2.5 系统默认
这将对所有策略使用 RMW 实现的默认值。不同的 RMW 实现可能具有不同的默认值。
四、QoS兼容性规则
发布者与订阅者需满足策略兼容性才能建立连接,核心规则包括:
1. 可靠性兼容性
发布者策略 | 订阅者策略 | 是否兼容 | 结果策略 |
---|---|---|---|
Best Effort | Best Effort | ✅ | Best Effort |
Best Effort | Reliable | ❌ | - |
Reliable | Best Effort | ✅ | Best Effort |
Reliable | Reliable | ✅ | Reliable |
2. 持久性兼容性
发布者策略 | 订阅者策略 | 是否兼容 |
---|---|---|
Volatile | Volatile | ✅ |
Transient Local | Volatile | ✅ |
Transient Local | Transient Local | ✅ |
注:任一策略不兼容均会导致连接失败
五、与 ROS 1 的比较
ROS 2 中的“history”和“depth”策略结合起来提供了类似于 ROS 1 中的队列大小的功能。
ROS 2 中的“reliability”策略类似于使用 UDPROS(仅在 中roscpp)表示“尽力而为”,或使用 TCPROS(ROS 1 默认)表示“best effort”。但请注意,即使 ROS 2 中的可靠策略也是使用 UDP 实现的,这允许在适当的情况下进行多播。
“durability”策略“transient local”与任意深度相结合,提供与“latching”发布者类似的功能。ROS 2 中的其余策略与 ROS 1 中提供的任何策略都不相似,这意味着 ROS 2 在这方面比 ROS 1 功能更丰富。将来,ROS 2 中可能会提供更多 QoS 策略。
从历史上看,在 ROS 1 中,任何具有相同消息类型且涉及同一主题的发布者和订阅者都会连接起来。使用 ROS 2 时,需要注意请求和提供的 QoS 配置文件可能不兼容