Skip to content

设计:为 rosbag2 添加快照服务

在 ros2/rosbag2#663 中,建议为 rosbag2 添加”快照(snapshot)“功能。

该功能旨在为用户提供一种机制:在指定话题上维护最近消息的临时缓存,只在用户触发时才写入永久存储。

例如,如果发生了罕见的异常行为,该功能允许你在观察到异常时才录制最近的 ROS 话题消息,而不必录制整个运行过程。

以指定的缓存大小在快照模式下启动 rosbag2:

$ ros2 bag record --max-cache-size 100000 --snapshot-mode [topics [topics ...]]

通过 CLI 触发快照:

$ ros2 service call /rosbag2_recorder/snapshot rosbag2_interfaces/Snapshot

用键盘快捷键触发快照: 例如,在打开的录制进程中按 s 键即可触发快照。

  • 在 ros2bag 的 record 子命令中添加 --snapshot-mode 标志,它将通过 StorageOptions 传递。

  • 创建一个新类 CircularMessageCache,它维护两个循环缓冲区,每个缓冲区在类 MessageCacheCircularBuffer 中单独实现,并根据现有的 --max-cache-size 参数调整大小。在快照模式下,CircularMessageCache 会持续向同一个循环缓冲区添加消息,直到被 Recorder 类触发切换到备用缓冲区。

  • 在 rosbag2_recorder 节点中创建一个服务 ~/snapshot,监听快照请求。收到服务调用后,它将触发 CircularMessageCache 中的缓冲区切换,并调用 SequentialWriter 中新的 take_snapshot 函数(详见下文)将快照消息写入存储。

  • 修改 SequentialWriter,在启用快照模式时使用 CircularMessageCache 而不是 MessageCache 和 CacheConsumer。

  • 在 SequentialWriter 中添加一个新的 take_snapshot 函数,由 rosbag2_recorder 节点的快照服务调用,将快照数据写入 rosbag。

  • 修改 BaseWriterInterface,加入纯虚函数 take_snapshot,确保所有未来的写入器都与快照模式兼容。

  • 在 rosbag2_interfaces 中把 ~/snapshot 服务接口实现为 Snapshot.srv。它不需要任何参数(类似于 Resume.srv)。

快照功能的实现可以分解为以下 PR:

  • 实现 CircularMessageCache 和 MessageCacheCircularBuffer。然后添加相应的测试。
  • 将 CircularMessageCache 集成到 SequentialWriter 中并更新其测试。
  • 在 Recorder 类中创建 ~/snapshot 服务,添加相应的测试,并创建 Snapshot.srv 服务接口。
  • 在 record 子命令中添加 --snapshot-mode 并更新 StorageOptions。
  • 在快照模式中添加用于触发快照的键盘快捷键。