记录与回放数据
目标:记录话题、服务和动作上发布的数据,以便随时回放和查看。
难度级别:初学者
预计时间:20 分钟
目录
- 背景
- 前提条件
- 话题数据管理
- 设置
- 选择话题
- 记录话题
- 查看话题数据
- 回放话题数据
- 服务数据管理
- 设置
- 检查服务可用性
- 记录服务
- 查看服务数据
- 回放服务数据
- 动作数据管理
- 设置
- 检查动作可用性
- 记录动作
- 查看动作数据
- 回放动作数据
- 总结
背景
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 节点:
- 打开新终端,运行
turtlesim主节点:ros2 run turtlesim turtlesim_node - 再打开一个新终端,运行键盘控制节点:
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)功能。
启动上述两个节点并启用服务查看功能(更多细节可参考 服务查看演示文档):
- 打开新终端,运行
introspection_service并启用服务查看:ros2 run demo_nodes_cpp introspection_service --ros-args -p service_configure_introspection:=contents - 再打开一个新终端,运行
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)功能。
启动上述两个节点并启用动作查看功能(更多细节可参考 动作查看演示文档):
- 打开新终端,运行
fibonacci_action_server并启用动作查看:ros2 run action_tutorials_py fibonacci_action_server --ros-args -p action_server_configure_introspection:=contents - 再打开一个新终端,运行
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)开始。

被折叠的 条评论
为什么被折叠?



