本文介绍内容: ROS 用户在创建发布者、订阅者等时,可以通过 QoS 配置结构指定历史、深度、可靠性和持久性。
虽然 DDS 提供了许多设置来实现对实体的服务质量 (QoS) 的细粒度控制,但 ROS 只为其中的少数提供本机支持。 ROS 用户在创建发布者、订阅者等时,可以通过 QoS 配置结构指定历史、深度、可靠性和持久性。
这留下了很多 QoS 设置,只有在 DDS 供应商可以通过配置文件加载其他默认设置时才能设置。如果用户想要将他们的代码挂接到这些额外的 QoS 设置中,那么他们需要获取对 rmw 实现的引用,并针对供应商特定的 API 进行编程。如果没有 ROS 提供的抽象层,它们的代码就变得不那么可移植了。
随着用户开始构建更强大的应用程序,他们将需要更多地控制何时交付数据以及有关系统何时发生故障的信息。为了满足这些需求,建议我们首先添加对以下新 DDS QoS 设置的支持。
截止日期策略为消息之间允许的时间量建立了合同。对于订阅,它确定了接收消息之间允许经过的最长时间。对于发布者,它确定了发送消息之间允许传递的最长时间。主题将支持截止日期跟踪仅到 rmw 层。这意味着如果 rmw 层在指定时间内没有收到消息,则认为错过了最后期限。为了让订阅者收听发布者的主题,他们请求的截止日期必须大于或等于发布者设置的截止日期。截止
活力政策为实体如何报告他们仍然活着建立了一个合同。对于订阅,它确定了他们需要从他们订阅的发布者那里获得的报告级别。对于发布者,它确定了他们将向订阅者提供的报告级别,即他们还活着。
主题将支持以下级别的活跃度:
为了让订阅者收听发布者的主题,他们请求的活跃度跟踪级别必须等于或低于发布者提供的跟踪级别,并且订阅者设置的直到被认为不活跃的时间必须大于时间由发布者设置。
生命周期策略为消息保持有效的时间建立了合同。对于订阅,它确定消息被视为有效的时间长度,在此时间之后将不会被接收。对于发布者,它确定消息被视为有效的时间长度,在此时间之后,它将从主题历史记录中删除并且不再发送给订阅者。生命周期时间为 0 将禁用生命周期跟踪。默认寿命时间为 0。
这些新策略都基于 DDS QoS 策略,但它们不需要 DDS 来支持 rmw 实现。有关这些政策的 DDS 细节的更多详细信息,请参见下面的附录 A。
这些是 ROS 中需要进行的各种更改,以便原生支持 Deadline 和 Liveliness。
1)资源状态事件处理程序
Deadline 和 Liveliness 策略都从需要通知应用程序的 rmw 层生成事件。对于截止日期,如果订阅者在截止日期内未收到任何内容,则订阅者将收到事件通知,如果在截止日期内未发布任何内容,发布者将收到事件通知。对于 Liveliness,当不再有任何 Publisher 活动时,订阅者会收到事件来断言主题是活动的。当客户端和服务器违反定义的策略时,服务会生成类似的事件。这两个都属于“资源状态事件”的类别。
为了处理这些通知,用户可以提供新的回调函数,在特定主题的任何事件发生时都会调用这些回调函数。它将接收一个结构值作为参数,其中包含有关事件的信息,例如事件发生的时间和与事件相关的其他元数据。当用户的应用程序为发布者和订阅者调用 create 函数时,这些回调函数将可选地提供。构造函数和创建函数将被重载以使这个新的处理程序成为可选的。
不会为每个状态事件调用一次状态事件处理程序。相反,只有在为回调提供服务的 Executor 检查时存在尚未处理的状态更改事件时,才会调用事件处理程序。
2)服务质量结构
在当前版本的 ROS 中,有一个 QoS 结构,用于在创建发布者和订阅者时指定 QoS 策略。通过这些新的 QoS 设置,支持的主题和服务的 QoS 策略集会有所不同。尽管如此,我们将坚持为 Topics 和 Services 使用单个结构,而不是切换到两种不同的结构类型,以便将更改保持在最低限度并在客户端库接口中保持尽可能多的向后兼容性。
现有的 QoS 策略结构将添加新字段,以指定 Deadline、Liveliness 和 Lifespan 所需的 QoS 设置。这些新字段实例将是枚举和时间值的组合。
3)断言活力函数
需要添加新功能,应用程序可以使用这些新功能来明确断言活力。一个函数在节点级别断言活跃度,一个在主题级别断言它。虽然仅基于发送消息也会隐式假设活跃性,但应用程序将使用这些函数来显式声明资源是活跃的。这些功能需要在从 rmw 到 rcl 和特定语言的客户端库(例如 rclcpp)的每一层中实现。
4)rcl_wait 和 rmw_wait
rcl 层当前正在使用 WaitSet 来通知来自 rmw 层的事件,例如传入的消息。这些 WaitSet 包含多种条件的列表,例如计时器触发或订阅接收数据。为了支持新的主题状态事件,将在现有的 WaitSet 中添加一个新类型,并且 rmw 层将在这些事件发生时设置它们。
5)rcl_take_status 和 rmw_take_status
需要添加名为 rcl_take_status 和 rmw_take_status 的新函数,它们可以直接查询主题的状态。它将以与用于检索订阅消息的 rcl_take 和 rmw_take 函数类似的方式运行。当执行者通过上面提到的等待集收到一个资源有一个新的状态事件可用的通知时,它将被执行者使用。
所有这些新的 QoS 策略都需要在 rmw 实现中得到支持。当我们添加新的 QoS 策略时,很可能并非所有 rmw 供应商都会为 ROS 定义的每个 QoS 策略提供支持。对于尚未对这些功能提供本机支持的基于非 DDS 的实现尤其如此。因此,我们需要一种方法让应用程序知道正在使用的 rmw 供应商是否支持指定级别的指定策略。在这种情况下,rmw 供应商应该通过返回一个错误代码来使操作失败,该错误代码指定所请求的 QoS 策略不受支持。显式失败将确保请求应用程序正在接收定义的行为并且不会在意外条件下运行。
除了阻止应用程序使用不受支持的策略运行之外,应用程序能够查询 rmw 供应商支持的 QoS 策略也很有用。最好的方法是提供一个 API,允许应用程序检查是否支持特定策略并获取所有支持的设置。此 API 的设计和实现超出了本文档的范围,应考虑作为未来工作的一部分。