【ROS2】Beginner : CLI tools - record & play back data

记录与回放数据

目标:记录话题、服务和动作上发布的数据,以便随时回放和查看。
难度级别:初学者
预计时间:20 分钟

目录

  • 背景
  • 前提条件
  • 话题数据管理
    1. 设置
    2. 选择话题
    3. 记录话题
    4. 查看话题数据
    5. 回放话题数据
  • 服务数据管理
    1. 设置
    2. 检查服务可用性
    3. 记录服务
    4. 查看服务数据
    5. 回放服务数据
  • 动作数据管理
    1. 设置
    2. 检查动作可用性
    3. 记录动作
    4. 查看动作数据
    5. 回放动作数据
  • 总结

背景

ros2 bag 是一款命令行工具,用于记录 ROS 2 系统中话题、服务和动作上发布的数据。它会收集任意数量的话题、服务和动作传递的数据,并将其保存在数据库中。之后你可以回放这些数据,重现测试和实验结果。记录话题、服务和动作数据也是分享工作成果、让他人复现你的实验的有效方式。

前提条件

ros2 bag 通常会随 ROS 2 常规安装一起部署。若你尚未安装 ROS 2,请参考 安装指南 完成安装。

本教程涉及前序教程中介绍的节点、话题、服务和动作等概念,同时会使用 turtlesim 功能包、服务查看演示(Service Introspection Demo)和动作查看演示(Action Introspection Demo)。

和往常一样,每个新打开的终端都需先执行 ROS 2 的环境配置文件(source setup 文件)。

话题数据管理

1. 设置

我们将记录 turtlesim 系统中的键盘输入数据,以便后续保存和回放。首先启动 /turtlesim/teleop_turtle 节点:

  1. 打开新终端,运行 turtlesim 主节点:
    ros2 run turtlesim turtlesim_node
    
  2. 再打开一个新终端,运行键盘控制节点:
    ros2 run turtlesim turtle_teleop_key
    

为规范管理,建议创建一个新目录用于存储录制文件:

  • Linux / macOS
    mkdir bag_files
    cd bag_files
    
  • Windows
    md bag_files
    cd bag_files
    

2. 选择话题

ros2 bag 可记录话题上发布的消息数据。打开新终端,运行以下命令查看系统中的话题列表:

ros2 topic list

输出如下:

/parameter_events
/rosout
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose

在“话题”教程中你已了解到,/teleop_turtle 节点会在 /turtle1/cmd_vel 话题上发布控制指令,使 turtlesim 中的乌龟移动。

若要查看 /turtle1/cmd_vel 话题发布的数据,运行:

ros2 topic echo /turtle1/cmd_vel

初始状态下无数据输出,因为键盘控制节点未发布数据。返回运行 teleop_turtle 的终端并激活它,使用方向键移动乌龟,此时运行 ros2 topic echo 的终端会显示发布的数据:

linear:
  x: 2.0
  y: 0.0
  z: 0.0
angular:
  x: 0.0
  y: 0.0
  z: 0.0
---

3. 记录话题

3.1 记录单个话题

记录单个话题数据的命令格式如下:

ros2 bag record <话题名称>

在执行命令前,打开新终端并进入之前创建的 bag_files 目录(录制文件会保存在当前终端所在目录),然后运行:

ros2 bag record /turtle1/cmd_vel

终端输出如下,表明已开始记录话题数据:

[INFO] [rosbag2_storage]: Opened database 'rosbag2_2019_10_11-05_18_45'.
[INFO] [rosbag2_transport]: Listening for topics...
[INFO] [rosbag2_transport]: Subscribed to topic '/turtle1/cmd_vel'
[INFO] [rosbag2_transport]: All requested topics are subscribed. Stopping discovery...

在这里插入图片描述

返回键盘控制终端,再次移动乌龟(动作轨迹可任意,但建议形成易识别的图案,方便后续回放时观察)。完成后按 Ctrl+C 停止录制。

录制的数据会保存在一个新的 bag 目录中,目录名称格式为 rosbag2_年_月_日-时_分_秒,内部包含 metadata.yaml 元数据文件和对应格式的 bag 数据文件。

3.2 记录多个话题

ros2 bag 支持同时记录多个话题,也可自定义录制文件的名称。运行以下命令:

ros2 bag record -o subset /turtle1/cmd_vel /turtle1/pose

输出如下,确认两个话题均已开始录制:

[INFO] [rosbag2_storage]: Opened database 'subset'.
[INFO] [rosbag2_transport]: Listening for topics...
[INFO] [rosbag2_transport]: Subscribed to topic '/turtle1/cmd_vel'
[INFO] [rosbag2_transport]: Subscribed to topic '/turtle1/pose'
[INFO] [rosbag2_transport]: All requested topics are subscribed. Stopping discovery...
  • -o 选项用于指定录制文件的自定义名称(此处为 subset);
  • 记录多个话题时,只需用空格分隔各话题名称即可。

再次移动乌龟,完成后按 Ctrl+C 停止录制。

注意:命令中还可添加 -a 选项,用于记录系统中所有话题的数据。

4. 查看话题数据

通过以下命令可查看录制文件的详细信息:

ros2 bag info <bag 文件名称>

subset 文件为例,运行:

ros2 bag info subset

输出如下,包含文件大小、录制时长、消息数量及各话题的类型和数据量等信息:

Files:             subset.mcap
Bag size:          228.5 KiB
Storage id:        mcap
Duration:          48.47s
Start:             Oct 11 2019 06:09:09.12 (1570799349.12)
End                Oct 11 2019 06:09:57.60 (1570799397.60)
Messages:          3013
Topic information: Topic: /turtle1/cmd_vel | Type: geometry_msgs/msg/Twist | Count: 9 | Serialization Format: cdr
                   Topic: /turtle1/pose | Type: turtlesim_msgs/msg/Pose | Count: 3004 | Serialization Format: cdr

5. 回放话题数据

回放前,先在键盘控制终端中按 Ctrl+C 停止 teleop_turtle 节点,确保 turtlesim 窗口可见,以便观察回放效果。

执行以下命令开始回放:

ros2 bag play subset

输出如下,表明回放已启动:

[INFO] [rosbag2_storage]: Opened database 'subset'.

此时乌龟会沿录制时的轨迹移动(受系统时序微小差异影响,可能无法 100% 完全复现)。
在这里插入图片描述

由于 subset 文件记录了 /turtle1/pose 话题(turtlesim 节点活跃期间会定期发布该话题数据),即使录制时未移动乌龟,ros2 bag play 命令也会持续运行至录制时长结束。

ros2 bag info 的输出可观察到:/turtle1/cmd_vel 话题的消息数量(Count)仅为 9(对应录制时按下方向键的次数),而 /turtle1/pose 话题的消息数量超过 3000(对应录制期间该话题的持续发布)。

若要查看 pose 话题的发布频率,可运行:

ros2 topic hz /turtle1/pose

服务数据管理

1. 设置

我们将记录 introspection_client(服务客户端)和 introspection_service(服务服务器)之间的服务数据,后续查看并回放这些数据。需注意:要记录服务客户端与服务器之间的数据,必须先在节点上启用“服务查看”(Service Introspection)功能。

启动上述两个节点并启用服务查看功能(更多细节可参考 服务查看演示文档):

  1. 打开新终端,运行 introspection_service 并启用服务查看:
    ros2 run demo_nodes_cpp introspection_service --ros-args -p service_configure_introspection:=contents
    
  2. 再打开一个新终端,运行 introspection_client 并启用服务查看:
    ros2 run demo_nodes_cpp introspection_client --ros-args -p client_configure_introspection:=contents
    

2. 检查服务可用性

ros2 bag 仅能记录可用服务的数据。打开新终端,运行以下命令查看系统中的服务列表:

ros2 service list

输出如下(包含核心服务和参数相关服务):

/add_two_ints
/introspection_client/describe_parameters
/introspection_client/get_parameter_types
/introspection_client/get_parameters
/introspection_client/get_type_description
/introspection_client/list_parameters
/introspection_client/set_parameters
/introspection_client/set_parameters_atomically
/introspection_service/describe_parameters
/introspection_service/get_parameter_types
/introspection_service/get_parameters
/introspection_service/get_type_description
/introspection_service/list_parameters
/introspection_service/set_parameters
/introspection_service/set_parameters_atomically

运行以下命令,检查客户端和服务器是否已启用服务查看功能:

ros2 service echo --flow-style /add_two_ints

若能看到如下服务通信数据,说明功能已启用:

info:
  event_type: REQUEST_SENT
  stamp:
    sec: 1713995389
    nanosec: 386809259
  client_gid: [1, 15, 96, 219, 162, 1, 108, 201, 0, 0, 0, 0, 0, 0, 21, 3]
  sequence_number: 133
request: [{a: 2, b: 3}]
response: []
---

3. 记录服务

ros2 bag 支持多种服务记录方式,且可同时记录服务和话题数据:

  • 记录指定服务:ros2 bag record --service <服务名称>
  • 记录所有服务:ros2 bag record --all-services

运行以下命令,记录 /add_two_ints 服务数据:

ros2 bag record --service /add_two_ints

输出如下,表明已开始记录服务数据:

[INFO] [1713995957.643573503] [rosbag2_recorder]: Press SPACE for pausing/resuming
[INFO] [1713995957.662067587] [rosbag2_recorder]: Event publisher thread: Starting
[INFO] [1713995957.662067614] [rosbag2_recorder]: Listening for topics...
[INFO] [1713995957.666048323] [rosbag2_recorder]: Subscribed to topic '/add_two_ints/_service_event'
[INFO] [1713995957.666092458] [rosbag2_recorder]: Recording...

完成录制后按 Ctrl+C 停止,数据会保存在名称格式为 rosbag2_年_月_日-时_分_秒 的目录中,包含 metadata.yaml 和对应格式的 bag 文件。

4. 查看服务数据

运行以下命令查看服务录制文件的详细信息:

ros2 bag info <bag 文件名称>

以某次录制的文件为例,输出如下:

Files:             rosbag2_2024_04_24-14_59_17_0.mcap
Bag size:          15.1 KiB
Storage id:        mcap
ROS Distro:        rolling
Duration:          9.211s
Start:             Apr 24 2024 14:59:17.676 (1713995957.676)
End:               Apr 24 2024 14:59:26.888 (1713995966.888)
Messages:          0
Topic information:

Service:           1
Service information: Service: /add_two_ints | Type: example_interfaces/srv/AddTwoInts | Event Count: 78 | Serialization Format: cdr

5. 回放服务数据

回放前,先在 introspection_client 所在终端按 Ctrl+C 停止客户端。客户端停止后,introspection_service 也会停止输出结果(因无新请求传入)。

回放 bag 文件中的服务数据,会向 introspection_service 重新发送请求。执行以下命令:

ros2 bag play --publish-service-requests <bag 文件名称>

输出如下,表明回放已启动:

[INFO] [1713997477.870856190] [rosbag2_player]: Set rate to 1
[INFO] [1713997477.877417477] [rosbag2_player]: Adding keyboard callbacks.
[INFO] [1713997477.877442404] [rosbag2_player]: Press SPACE for Pause/Resume
[INFO] [1713997477.877447855] [rosbag2_player]: Press CURSOR_RIGHT for Play Next Message
[INFO] [1713997477.877452655] [rosbag2_player]: Press CURSOR_UP for Increase Rate 10%
[INFO] [1713997477.877456954] [rosbag2_player]: Press CURSOR_DOWN for Decrease Rate 10%
[INFO] [1713997477.877573647] [rosbag2_player]: Playback until timestamp: -1

此时 introspection_service 终端会再次输出服务请求处理信息:

[INFO] [1713997478.090466075] [introspection_service]: Incoming request
a: 2 b: 3

这是因为 ros2 bag play 会从 bag 文件中读取服务请求数据,并发送到 /add_two_ints 服务。

若要验证服务通信,可在回放前运行以下命令监听服务数据,此时能看到 bag 文件发送的请求和 introspection_service 返回的响应:

ros2 service echo --flow-style /add_two_ints

输出示例:

info:
  event_type: REQUEST_RECEIVED
  stamp:
    sec: 1713998176
    nanosec: 372700698
  client_gid: [1, 15, 96, 219, 80, 2, 158, 123, 0, 0, 0, 0, 0, 0, 20, 4]
  sequence_number: 1
request: [{a: 2, b: 3}]
response: []
---
info:
  event_type: RESPONSE_SENT
  stamp:
    sec: 1713998176
    nanosec: 373016882
  client_gid: [1, 15, 96, 219, 80, 2, 158, 123, 0, 0, 0, 0, 0, 0, 20, 4]
  sequence_number: 1
request: []
response: [{sum: 5}]

动作数据管理

1. 设置

我们将记录 fibonacci_action_client(动作客户端)和 fibonacci_action_server(动作服务器)之间的动作数据,后续查看并回放。需注意:要记录动作客户端与服务器之间的数据,必须先在节点上启用“动作查看”(Action Introspection)功能。

启动上述两个节点并启用动作查看功能(更多细节可参考 动作查看演示文档):

  1. 打开新终端,运行 fibonacci_action_server 并启用动作查看:
    ros2 run action_tutorials_py fibonacci_action_server --ros-args -p action_server_configure_introspection:=contents
    
  2. 再打开一个新终端,运行 fibonacci_action_client 并启用动作查看:
    ros2 run action_tutorials_cpp fibonacci_action_client --ros-args -p action_client_configure_introspection:=contents
    

2. 检查动作可用性

ros2 bag 仅能记录可用动作的数据。打开新终端,运行以下命令查看系统中的动作列表:

ros2 action list

输出如下:

/fibonacci

运行以下命令,检查动作是否已启用动作查看功能:

ros2 action echo --flow-style /fibonacci

若能看到如下动作通信数据,说明功能已启用:

interface: GOAL_SERVICE
info:
  event_type: REQUEST_SENT
  stamp:
    sec: 1744917904
    nanosec: 760683446
  client_gid: [1, 15, 165, 231, 234, 109, 65, 202, 0, 0, 0, 0, 0, 0, 19, 4]
  sequence_number: 1
request: [{goal_id: {uuid: [81, 55, 121, 145, 81, 66, 209, 93, 214, 113, 255, 100, 120, 6, 102, 83]}, goal: {order: 10}}]
response: []
---
...

3. 记录动作

ros2 bag 支持多种动作记录方式,且可同时记录动作、话题和服务数据:

  • 记录指定动作:ros2 bag record --action <动作名称>
  • 记录所有动作:ros2 bag record --all-actions

运行以下命令,记录 /fibonacci 动作数据(包含目标、结果和反馈):

ros2 bag record --action /fibonacci

输出如下,表明已开始记录动作相关的话题和服务数据:

[INFO] [1744953225.214114862] [rosbag2_recorder]: Press SPACE for pausing/resuming
[INFO] [1744953225.218369761] [rosbag2_recorder]: Listening for topics...
[INFO] [1744953225.218386223] [rosbag2_recorder]: Event publisher thread: Starting
[INFO] [1744953225.218580294] [rosbag2_recorder]: Recording...
[INFO] [1744953225.725417634] [rosbag2_recorder]: Subscribed to topic '/fibonacci/_action/cancel_goal/_service_event'
[INFO] [1744953225.727901848] [rosbag2_recorder]: Subscribed to topic '/fibonacci/_action/feedback'
[INFO] [1744953225.729655213] [rosbag2_recorder]: Subscribed to topic '/fibonacci/_action/get_result/_service_event'
[INFO] [1744953225.731315612] [rosbag2_recorder]: Subscribed to topic '/fibonacci/_action/send_goal/_service_event'
[INFO] [1744953225.735061252] [rosbag2_recorder]: Subscribed to topic '/fibonacci/_action/status'
...

完成录制后按 Ctrl+C 停止,数据会保存在名称格式为 ros2 bag2_年_月_日-时_分_秒 的目录中,包含 metadata.yaml 和对应格式的 bag 文件。

4. 查看动作数据

运行以下命令查看动作录制文件的详细信息:

ros2 bag info <bag 文件名称>

以某次录制的文件为例,输出如下:

Files:             rosbag2_2025_04_17-22_20_40_0.mcap
Bag size:          20.7 KiB
Storage id:        mcap
ROS Distro:        rolling
Duration:          9.019568080s
Start:             Apr 17 2025 22:20:47.263125070 (1744953647.263125070)
End:               Apr 17 2025 22:20:56.282693150 (1744953656.282693150)
Messages:          0
Topic information:

Services:          0
Service information:

Actions:           1
Action information:
  Action: /fibonacci | Type: example_interfaces/action/Fibonacci | Topics: 2 | Service: 3 | Serialization Format: cdr
    Topic: feedback | Count: 9
    Topic: status | Count: 3
    Service: send_goal | Event Count: 4
    Service: cancel_goal | Event Count: 0
    Service: get_result | Event Count: 4

5. 回放动作数据

回放前,先在 fibonacci_action_client 所在终端按 Ctrl+C 停止客户端。客户端停止后,fibonacci_action_server 也会停止输出结果(因无新请求传入)。

回放 bag 文件中的动作数据,会向 fibonacci_action_server 重新发送目标请求。执行以下命令:

ros2 bag play --send-actions-as-client <bag 文件名称>

输出如下,表明回放已启动:

[INFO] [1744953720.691068674] [rosbag2_player]: Set rate to 1
[INFO] [1744953720.702365209] [rosbag2_player]: Adding keyboard callbacks.
[INFO] [1744953720.702409447] [rosbag2_player]: Press SPACE for Pause/Resume
[INFO] [1744953720.702423063] [rosbag2_player]: Press CURSOR_RIGHT for Play Next Message
[INFO] [1744953720.702431404] [rosbag2_player]: Press CURSOR_UP for Increase Rate 10%
[INFO] [1744953720.702437677] [rosbag2_player]: Press CURSOR_DOWN for Decrease Rate 10%
Progress bar enabled at 3 Hz.
Progress bar [?]: [R]unning, [P]aused, [B]urst, [D]elayed, [S]topped
[INFO] [1744953720.702577680] [rosbag2_player]: Playback until timestamp: -1

====== Playback Progress ======
[1744953656.281683207] Duration 9.02/9.02 [R]

此时 fibonacci_action_server 终端会再次输出动作执行信息(目标处理、反馈和结果):

[INFO] [1744953720.815577088] [fibonacci_action_server]: Executing goal...
[INFO] [1744953720.815927050] [fibonacci_action_server]: Feedback: array('i', [0, 1, 1])
[INFO] [1744953721.816509658] [fibonacci_action_server]: Feedback: array('i', [0, 1, 1, 2])
[INFO] [1744953722.817220270] [fibonacci_action_server]: Feedback: array('i', [0, 1, 1, 2, 3])
[INFO] [1744953723.817876426] [fibonacci_action_server]: Feedback: array('i', [0, 1, 1, 2, 3, 5])
[INFO] [1744953724.818498515] [fibonacci_action_server]: Feedback: array('i', [0, 1, 1, 2, 3, 5, 8])
[INFO] [1744953725.819182228] [fibonacci_action_server]: Feedback: array('i', [0, 1, 1, 2, 3, 5, 8, 13])
[INFO] [1744953726.820032562] [fibonacci_action_server]: Feedback: array('i', [0, 1, 1, 2, 3, 5, 8, 13, 21])
[INFO] [1744953727.820738690] [fibonacci_action_server]: Feedback: array('i', [0, 1, 1, 2, 3, 5, 8, 13, 21, 34])
[INFO] [1744953728.821449308] [fibonacci_action_server]: Feedback: array('i', [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55])

这是因为 ros2 bag play 会从 bag 文件中读取动作目标请求数据,并发送到 /fibonacci 动作。

若要验证动作通信,可在回放前运行以下命令监听动作数据,此时能看到 bag 文件发送的目标请求和 fibonacci_action_server 返回的响应:

ros2 action echo --flow-style /fibonacci

输出示例:

interface: STATUS_TOPIC
status_list: [{goal_info: {goal_id: {uuid: [34, 116, 225, 217, 48, 121, 146, 36, 240, 98, 99, 134, 55, 227, 184, 72]}, stamp: {sec: 1744953720, nanosec: 804984321}}, status: 4}]
---
interface: GOAL_SERVICE
info:
  event_type: REQUEST_RECEIVED
  stamp:
    sec: 1744953927
    nanosec: 957359210
  client_gid: [1, 15, 165, 231, 190, 254, 1, 50, 0, 0, 0, 0, 0, 0, 19, 4]
  sequence_number: 1
request: [{goal_id: {uuid: [191, 200, 153, 122, 221, 251, 152, 172, 60, 69, 94, 20, 212, 160, 40, 12]}, goal: {order: 10}}]
response: []
---
interface: GOAL_SERVICE
info:
  event_type: RESPONSE_SENT
  stamp:
    sec: 1744953927
    nanosec: 957726145
  client_gid: [1, 15, 165, 231, 190, 254, 1, 50, 0, 0, 0, 0, 0, 0, 19, 4]
  sequence_number: 1
request: []
response: [{accepted: true, stamp: {sec: 1744953927, nanosec: 957615866}}]
---
interface: STATUS_TOPIC
status_list: [{goal_info: {goal_id: {uuid: [191, 200, 153, 122, 221, 251, 152, 172, 60, 69, 94, 20, 212, 160, 40, 12]}, stamp: {sec: 1744953927, nanosec: 957663383}}, status: 2}]
---
interface: FEEDBACK_TOPIC
goal_id:
  uuid: [191, 200, 153, 122, 221, 251, 152, 172, 60, 69, 94, 20, 212, 160, 40, 12]
feedback:
  sequence: [0, 1, 1]
---
...

总结

通过 ros2 bag 命令,你可以记录 ROS 2 系统中话题、服务和动作传递的数据。无论是与他人分享工作,还是深入分析自己的实验过程,ros2 bag 都是一款实用工具。

下一步

至此,你已完成“初学者:CLI 工具”系列教程!接下来可以开始学习“初学者:客户端库”系列教程,首先从《创建工作空间》(Creating a workspace)开始。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ray.so

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值