Skip to content

QoS 服务质量设置

ROS 2 提供了丰富的服务质量(Quality of Service,QoS)策略,允许你调整节点之间的通信。 通过正确的 QoS 策略组合,ROS 2 可以像 TCP 一样可靠,也可以像 UDP 一样尽力而为(best-effort),以及许多介于两者之间的选项。 与 ROS 1(主要只支持 TCP)不同,ROS 2 得益于底层 DDS 传输的灵活性,无论在有损无线网络环境中(更适合使用”尽力而为”策略),还是在需要恰当的 QoS 配置来满足截止时间要求的实时计算系统中,都能出色应对。

一组 QoS 策略(policies)构成一个 QoS 配置文件(profile)。 鉴于为特定场景选择合适的 QoS 策略较为复杂,ROS 2 为常见用例(如传感器数据)提供了一组预定义的 QoS 配置文件。 同时,开发者也可以灵活地控制 QoS 配置文件中的特定策略。

可以为发布者(publisher)、订阅者(subscription)、服务端(service server)和客户端(client)指定 QoS 配置文件。 QoS 配置文件可以独立地应用于上述每个实体实例,但如果发布者和订阅者使用了不兼容的配置文件,消息将无法传递。

基础 QoS 配置文件目前包含以下策略的设置:

  • History(历史)

    • Keep last(保留最新):仅存储最多 N 个样本,可通过队列深度选项进行配置。
    • Keep all(保留全部):存储所有样本,受底层中间件配置的资源限制约束。
  • Depth(深度)

    • Queue size(队列大小):仅在 “history” 策略设置为 “keep last” 时生效。
  • Reliability(可靠性)

    • Best effort(尽力而为):尝试传递样本,但如果网络不够健壮,可能会丢失样本。
    • Reliable(可靠):保证样本被传递,可能会重试多次。
  • Durability(持久性)

    • Transient local(瞬态本地):发布者负责为”后加入”的订阅者持久化样本。
    • Volatile(易失):不尝试持久化样本。
  • Deadline(截止时间)

    • Duration(持续时间):在向话题发布后续消息之间的预期最长时间间隔。
  • Lifespan(生命周期)

    • Duration(持续时间):从发布到接收消息之间的最长时间间隔,超过此时间消息被视为过期(过期消息会被静默丢弃,实际上永远不会被接收)。
  • Liveliness(活跃性)

    • Automatic(自动):当节点的任何一个发布者发布了消息时,系统会将该节点的所有发布者视为在另一个”租约期限”(lease duration)内仍然活跃。
    • Manual by topic(按话题手动):如果发布者手动断言它仍然活跃(通过调用发布者 API),系统会将其视为在另一个”租约期限”内活跃。
  • Lease Duration(租约期限)

    • Duration(持续时间):发布者表明其活跃状态的最大时间间隔,超过此时间系统将认为它失去了活跃性(失去活跃性可能是故障的迹象)。

对于每个非持续时间类型的策略,还有一个”system default”(系统默认)选项,即使用底层中间件的默认值。 对于持续时间类型的策略,也有一个”default”(默认)选项,表示持续时间未指定,底层中间件通常将其解释为无限长。

ROS 2 中的 “history” 和 “depth” 策略组合起来提供了类似于 ROS 1 中队列大小的功能。

ROS 2 中的 “reliability” 策略类似于 ROS 1 中使用 UDPROS(仅在 roscpp 中可用)实现”尽力而为”或使用 TCPROS(ROS 1 默认)实现”可靠”。 但请注意,即使是 ROS 2 中的 reliable 策略也是使用 UDP 实现的,这使得在适当时可以进行多播。

“durability” 策略 “transient local” 与任意深度组合,提供了类似于”锁存”(latching)发布者的功能。 ROS 2 中其余的策略在 ROS 1 中没有对应物,这意味着 ROS 2 在这方面比 ROS 1 功能更丰富。 未来 ROS 2 可能会提供更多的 QoS 策略。

配置文件让开发者可以专注于应用本身,而不必逐一调整每个 QoS 设置。 QoS 配置文件定义了一组预期适合特定用例的策略。

当前定义的 QoS 配置文件包括:

  • 发布者和订阅者的默认 QoS 设置

    为了让从 ROS 1 到 ROS 2 的过渡更加平滑,默认设置力求模拟类似的网络行为。 默认情况下,ROS 2 中的发布者和订阅者使用 “keep last” 作为 history 策略,队列大小为 10,“reliable” 作为 reliability 策略,“volatile” 作为 durability 策略,“system default” 作为 liveliness 策略。 Deadline、lifespan 和 lease duration 也都设置为 “default”。

  • 服务(Services)

    与发布者和订阅者类似,服务是可靠的。 对于服务来说,使用 volatile durability 尤为重要,否则重启的服务端可能会收到过期的请求。 虽然客户端有保护机制可以避免收到多个响应,但服务端没有这种保护,可能会受到过期请求的副作用影响。

  • 传感器数据(Sensor data)

    对于传感器数据,在大多数情况下,及时接收读数比确保所有读数都到达更重要。 也就是说,开发者希望尽快获取最新采集的样本,即使可能会丢失一些。 因此,传感器数据配置文件使用尽力而为的可靠性(best effort reliability)和较小的队列大小。

  • 参数(Parameters)

    ROS 2 中的参数基于服务,因此具有类似的配置文件。 区别在于参数使用更大的队列深度,这样当参数客户端无法连接到参数服务端时,请求不会丢失。

  • 系统默认(System default)

    使用 RMW 实现的所有策略的默认值。 不同的 RMW 实现可能有不同的默认值。

点击此处查看上述配置文件使用的具体策略。 这些配置文件中的设置可能会根据社区的反馈进一步调整。

注意:本节讨论的是发布者和订阅者,但内容同样适用于服务端和客户端。

可以为发布者和订阅者独立配置 QoS 配置文件。 只有在发布者和订阅者具有兼容的 QoS 配置文件时,它们之间才会建立连接。

QoS 配置文件的兼容性基于”请求 vs 提供”(Request vs Offered)模型确定。 订阅者请求一个 QoS 配置文件,这是它愿意接受的”最低质量”;发布者提供一个 QoS 配置文件,这是它能够提供的”最高质量”。 只有当请求方的每个 QoS 策略都不比提供方的更严格时,才会建立连接。 多个订阅者可以同时连接到单个发布者,即使它们请求的 QoS 配置文件不同。 发布者和订阅者之间的兼容性不受其他发布者和订阅者的影响。

以下表格展示了不同策略设置的兼容性及结果:

可靠性(reliability)QoS 策略的兼容性:

发布者订阅者兼容
Best effortBest effort是
Best effortReliable否
ReliableBest effort是
ReliableReliable是

持久性(durability)QoS 策略的兼容性:

发布者订阅者兼容结果
VolatileVolatile是仅新消息
VolatileTransient local否无法通信
Transient localVolatile是仅新消息
Transient localTransient local是新旧消息

要实现”锁存”(latched)话题(使后加入的订阅者也能收到之前发布的消息),发布者和订阅者都必须使用 ‘Transient Local’。

截止时间(deadline)QoS 策略的兼容性:

假设 x 和 y 是任意有效的持续时间值。

发布者订阅者兼容
DefaultDefault是
Defaultx否
xDefault是
xx是
xy(其中 y > x)是
xy(其中 y < x)否

活跃性(liveliness)QoS 策略的兼容性:

发布者订阅者兼容
AutomaticAutomatic是
AutomaticManual by topic否
Manual by topicAutomatic是
Manual by topicManual by topic是

租约期限(lease duration)QoS 策略的兼容性:

假设 x 和 y 是任意有效的持续时间值。

发布者订阅者兼容
DefaultDefault是
Defaultx否
xDefault是
xx是
xy(其中 y > x)是
xy(其中 y < x)否

要建立连接,所有影响兼容性的策略都必须兼容。 例如,即使双方的 reliability 策略兼容,如果 durability 策略不兼容,仍然无法建立连接。

当连接未建立时,发布者和订阅者之间不会传递任何消息。 有一些机制可以检测这种情况,将在后面的章节中介绍。

在 ROS 1 中,同一话题上具有相同消息类型的发布者和订阅者都会自动建立连接。 请求方与提供方 QoS 配置文件不兼容是 ROS 2 引入的新情况,使用时需要特别注意。

某些 QoS 策略可能有关联的事件。 开发者可以为每个发布者和订阅者注册回调函数,由 QoS 事件触发,按需处理,类似于处理话题上接收到的消息。

开发者可以订阅以下与发布者关联的 QoS 事件:

  • Offered deadline missed(提供的截止时间未满足)

    发布者未在 deadline QoS 策略设定的预期持续时间内发布消息。

  • Liveliness lost(活跃性丢失)

    发布者未能在租约期限内表明其活跃性。

  • Offered incompatible QoS(提供了不兼容的 QoS)

    发布者在同一话题上遇到了一个订阅者,该订阅者请求的 QoS 配置文件无法被提供的 QoS 配置文件满足,导致发布者与该订阅者之间无法建立连接。

开发者可以订阅以下与订阅者关联的 QoS 事件:

  • Requested deadline missed(请求的截止时间未满足)

    订阅者未在 deadline QoS 策略设定的预期持续时间内接收到消息。

  • Liveliness changed(活跃性变化)

    订阅者注意到所订阅话题上的一个或多个发布者未能在租约期限内表明其活跃性。

  • Requested incompatible QoS(请求了不兼容的 QoS)

    订阅者在同一话题上遇到了一个发布者,该发布者提供的 QoS 配置文件不满足订阅者请求的 QoS 配置文件,导致订阅者与该发布者之间无法建立连接。

除了 QoS 事件之外,当任何发布者和订阅者之间建立或断开连接时,还可以生成匹配事件(matched events)。 开发者可以为每个发布者和订阅者注册回调函数,由匹配事件触发,按需处理,类似于处理话题上接收到的消息。

开发者可以通过发布者或订阅者来订阅此事件。

  • 发布者:当发布者找到一个话题匹配且 QoS 兼容的订阅者时,或一个已连接的订阅者断开连接时,触发此事件。
  • 订阅者:当订阅者找到一个话题匹配且 QoS 兼容的发布者时,或一个已连接的发布者断开连接时,触发此事件。

以下是一些展示如何使用该事件的示例: