Skip to content

设计:rosbag2 录制与回放服务

在 ros2/rosbag2#773 中,建议为 rosbag2 添加录制服务请求的功能。

本设计描述如何基于当前架构实现该功能,以及如何扩展现有命令参数。

服务自省(service introspection,ros2/ros2#1285)已经实现。所有服务消息(请求和响应)都会发布到服务事件话题上,该话题是隐藏在服务名称下的 _service_event 话题(例如 /add_two_ints/_service_event)。因此,该话题中的所有消息可以像普通话题一样被录制。

如何在所有录制的话题中区分服务事件话题

Section titled “如何在所有录制的话题中区分服务事件话题”

服务事件话题与普通话题一样保存,但读取录制文件后,它们需要走不同的处理流程,因此需要通过话题名称来区分。

  • 普通话题
    [NameSpace/]TopicName

  • 隐藏话题
    [NameSpace/]_TopicName

  • 服务事件话题
    [NameSpace/]ServiceName/_service_event

以下标准用于判定服务事件话题:

  1. 话题以 /_service_event 结尾
  2. 话题类型名称匹配 */srv/*_Event(例如 example_interfaces/srv/AddTwoInts_Event)

新增或修改的参数:

  • --services ServiceName1 [ServiceName2 ...]

    指定要录制哪些服务。必须至少指定一个服务。

  • --all-topics

    录制所有话题(包括服务事件话题),排除隐藏话题。

  • --all-services

    录制所有服务事件话题。

  • --exclude-regex

    由 --exclude 重命名而来。排除与给定正则表达式匹配的话题和服务。

  • --exclude-topics

    不录制的话题列表。

  • --exclude-services

    不录制的服务列表。

相关参数的行为说明如下:

参数描述
—services ServiceName1 [ServiceName2 …]录制指定名称的服务(服务事件话题)。
—all录制所有话题和服务事件话题,排除其他隐藏话题。
—all-topics录制所有话题,排除隐藏话题(包括服务事件话题)。
—all-services只录制所有服务事件话题。
—include-hidden-topics录制所有隐藏话题(包括服务事件话题)。
—exclude-regex排除与给定正则表达式匹配的话题和服务。
—exclude-topics不录制的话题列表。
—exclude-services不录制的服务列表。
-e REGEX, —regex REGEX只录制与给定正则表达式匹配的话题和服务。

新增一个参数。

  • -v 或 --verbose

    如果设置了 -v 或 --verbose,info 命令会额外显示两条信息:话题和服务的字节数贡献,以及每个服务基于服务事件统计的请求和响应数量。否则,只显示话题的消息计数和服务的总体事件数量。注意,解析消息需要时间,耗时与录制的话题消息和服务事件数量成正比。

不带 -v 或 --verbose 参数时,info 命令的输出示例如下:

Files: 123_0.mcap
Bag size: 28.2 KiB
Storage id: mcap
Duration: 15.59s
Start: May 19 2023 13:22:25.340 (1684473745.340)
End: May 19 2023 13:22:40.400 (1684473760.400)
Messages: 60
Topic information: Topic: /chatter | Type: std_msgs/msg/String | Count: 16 | Serialization Format: cdr
Topic: /events/write_split | Type: rosbag2_interfaces/msg/WriteSplitEvent | Count: 0 | Serialization Format: cdr
Topic: /parameter_events | Type: rcl_interfaces/msg/ParameterEvent | Count: 0 | Serialization Format: cdr
Topic: /rosout | Type: rcl_interfaces/msg/Log | Count: 44 | Serialization Format: cdr
>>>> The below is new added items for service event topic <<<<<<<
Service : XX <== The number of service
Service information: Service: /xxx/xxx | Type: xxx/xxx/xxx | Event Count: XX | Serialization Format: XX
Service: /xxx/xxx | Type: xxx/xxx/xxx | Event Count: XX | Serialization Format: XX

带 -v 或 --verbose 参数时,info 命令的输出示例如下:

Files: 123_0.mcap
Bag size: 28.2 KiB
Storage id: mcap
Duration: 15.59s
Start: May 19 2023 13:22:25.340 (1684473745.340)
End: May 19 2023 13:22:40.400 (1684473760.400)
Messages: 60
Topic information: Topic: /chatter | Type: std_msgs/msg/String | Count: 16 | Size Contribution XX xxB | Serialization Format: cdr
Topic: /events/write_split | Type: rosbag2_interfaces/msg/WriteSplitEvent | Count: 0 | Size Contribution 0 B | Serialization Format: cdr
Topic: /parameter_events | Type: rcl_interfaces/msg/ParameterEvent | Count: 0 | Size Contribution 0 B | Serialization Format: cdr
Topic: /rosout | Type: rcl_interfaces/msg/Log | Count: 44 | Size Contribution XX xxB | Serialization Format: cdr
>>>> The below is new added items for service <<<<<<<
Service : XX <== The number of service
Service information: Service: /xxx/xxx | Type: xxx/xxx/xxx | Request Count: XX | Response Count: XX | Size Contribution XX xxB | Serialization Format: XX
Service: /xxx/xxx | Type: xxx/xxx/xxx | Request Count: XX | Response Count: XX | Size Contribution XX xxB | Serialization Format: XX

新增或修改的参数:

  • --publish-service-requests

    根据录制的服务自省消息发送服务请求。默认情况下,录制的服务自省消息会通过服务事件话题发布。

  • --service-requests-source {service_introspection, client_introspection}

    确定要回放的服务请求的来源。默认情况下,服务请求来自录制的服务自省消息。 该选项仅在设置了 --publish-service-requests 选项时才有意义。

  • --services ServiceName1 [ServiceName2 ...]

    指定回放哪些服务的请求。

  • --exclude-topics topic1 [topic2 ...]

    不回放的话题列表。

  • --exclude-services ServiceName1 [ServiceName2 ...]

    不回放的服务列表。

  • --exclude-regex REGEX

    由 --exclude 重命名而来。排除与给定正则表达式匹配的话题和服务。

-e REGEX, --regex REGEX 同时影响话题和服务。

实施分为两个阶段。 第一阶段预计实现与服务事件录制相关的所有功能。 第二阶段实现与服务请求回放相关的其余功能。 服务请求回放并不容易实现,因为 rclcpp 层目前没有提供 API 来发布具有动态创建类型支持的服务请求。需要在 rclcpp 层创建一个类似 GenericPublisher 的 GenericClient 才能做到这一点。为了实现 GenericClient,可能需要更新 get_typesupport_handle() 以支持服务 ros2/rclcpp#2209。 因此,第二阶段将在所需的新 rclcpp API 就绪后实施。