目标
记录发布在话题和服务上的数据,以便随时回放和检查。
背景知识
ros2 bag
是一个命令行工具,主要用于记录ROS2系统中使用话题和服务发布的数据。它会收集任意数量的话题和服务传递的数据,然后将其保存到数据库中。之后你可以回放这些数据,重现测试和实验的结果。记录话题和服务也是分享你的工作并让他人重现实验的好方法。
前提条件
和往常一样,每次打开新终端时,别忘了对ROS2进行环境配置。
bash
# Replace ".bash" with your shell if you're not using bash
# Possible values are: setup.bash, setup.sh, setup.zsh
source /opt/ros/jazzy/setup.bash
管理话题数据
1. 准备工作
你将在 turtlesim
系统中记录键盘输入,以便稍后保存和回放。因此,首先启动 /turtlesim
和 /teleop_turtle
节点。
打开一个新终端并运行:
bash
ros2 run turtlesim turtlesim_node
再打开另一个终端并运行:
bash
ros2 run turtlesim turtle_teleop_key
为了养成良好的习惯,我们再创建一个新目录来存储保存的记录:
- Linux / macOS:
bash
mkdir bag_files
cd bag_files
- Windows:
powershell
md bag_files
cd bag_files
2. 选择话题
ros2 bag
可以记录发布到话题的消息数据。要查看系统中的话题列表,打开一个新终端并运行以下命令:
bash
ros2 topic list
这将返回:
bash
/parameter_events
/rosout
/turtle1/cmd_vel
/turtle1/color_sensor
/turtle1/pose
在学习话题的时候,你应该已经了解到 /turtle_teleop
节点会在 /turtle1/cmd_vel
话题上发布命令,以使 turtlesim
中的海龟移动。
要查看 /turtle1/cmd_vel
正在发布的数据,运行以下命令:
bash
ros2 topic echo /turtle1/cmd_vel
一开始不会有任何显示,这是因为遥控操作节点没有发出任何数据。回到运行遥控操作节点的终端并激活它,使用方向键移动海龟,你会在运行 ros2 topic echo
的终端上看到数据发布情况:
yaml
linear:
x: 2.0
y: 0.0
z: 0.0
angular:
x: 0.0
y: 0.0
z: 0.0
---
3. 记录话题
3.1 记录单个话题
要记录发布到某个话题的数据,可以使用以下命令:
bash
ros2 bag record <topic_name>
在运行这个命令之前,打开一个新终端,然后进入之前创建的 bag_files
目录,ROS的 bag 文件将保存在你运行该命令的目录中。
运行命令:
bash
ros2 bag record /turtle1/cmd_vel
你将在终端中看到以下消息(日期和时间会有所不同):
less
[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...
现在,ros2 bag
正在记录 /turtle1/cmd_vel
话题上发布的数据。回到遥控操作终端,再次移动海龟。移动方式无关紧要,但尽量形成一个容易识别的模式,以便稍后回放数据时能看到效果。

按 Ctrl+C
停止记录。
数据将被收集到一个新的 bag 目录中,目录名称的格式为 rosbag2_year_month_day-hour_minute_second
。该目录将包含一个 metadata.yaml
文件以及以记录格式保存的 bag 文件。
3.2 记录多个话题
你还可以记录多个话题,并且可以更改 ros2 bag
保存的文件名。
bash
ros2 bag record -o subset /turtle1/cmd_vel /turtle1/pose
-o
选项允许你为 bag 文件选择一个唯一的名称。后面的字符串(在本例中为 subset
)就是文件名。
要一次性记录多个话题,只需用空格分隔每个话题名称即可。
你将看到以下消息,提示确认两个话题都正在被记录:
less
[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...
你可以移动海龟,完成后按 Ctrl+C
。
另外,你还可以在命令中添加另一个选项 -a
,它会记录系统中的所有话题。
4. 检查话题数据
你可以通过运行以下命令查看记录的详细信息:
bash
ros2 bag info <bag_file_name>
对 subset
bag文件运行此命令将返回该文件的信息列表:
yaml
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/msg/Pose | Count: 3004 | Serialization Format: cdr
5. 回放话题数据
在回放 bag 文件之前,先在运行遥控操作节点的终端中按 Ctrl+C
。然后确保 turtlesim
窗口可见,这样你就可以看到 bag
文件的回放效果。
输入命令:
bash
ros2 bag play subset
终端将返回消息:
css
[INFO] [rosbag2_storage]: Opened database 'subset'.
你的海龟将沿着你记录时输入的路径移动(不过不会完全精确,因为 turtlesim
对系统时间的微小变化很敏感)。

由于 subset
文件同时也记录了 /turtle1/pose
话题,所以当你的海龟停止移动之后,ros2 bag play
命令并没有立即停止回放。
这是因为记录期间,只要 /turtlesim
节点处于活动状态,它会定期在 /turtle1/pose
话题上发布数据。你可能已经注意到,在上面的 ros2 bag info
示例结果中,/turtle1/cmd_vel
话题的 Count
信息只有 9,这是我们在记录时按下方向键的次数。而/turtle1/pose
的 Count
值超过了 3000,这意味着在我们记录时,该话题发布了 3000 次数据。
要了解位置数据的发布频率,你可以运行以下命令:
bash
ros2 topic hz /turtle1/pose
管理服务数据
1. 准备工作
你将记录 introspection_client
和 introspection_service
之间的服务数据,稍后显示和回放这些数据。要记录服务客户端和服务器之间的服务数据,必须在节点上启用服务内省(introspection)功能。
让我们启动 introspection_client
和 introspection_service
节点并启用服务内省功能。细节就不在这里展开了,你可以在服务内省Demo中查看更多详细信息。
打开一个新终端并运行 introspection_service
,同时启用服务内省功能:
bash
ros2 run demo_nodes_cpp introspection_service --ros-args -p service_configure_introspection:=contents
再打开另一个终端并运行 introspection_client
,同时启用服务内省功能:
bash
ros2 run demo_nodes_cpp introspection_client --ros-args -p client_configure_introspection:=contents
2. 检查服务可用性
ros2 bag
只能记录可用服务的数据。要查看系统中的服务列表,打开一个新终端并运行以下命令:
bash
ros2 service list
这将返回:
bash
/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
要检查客户端和服务上是否启用了服务内省功能,运行以下命令:
bash
ros2 service echo --flow-style /add_two_ints
你应该会看到类似以下的服务通信信息:
yaml
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. 记录服务
记录服务数据支持以下选项。另外,服务数据可以与话题数据同时记录。
要记录特定的服务:
bash
ros2 bag record --service <service_names>
要记录所有服务:
bash
ros2 bag record --all-services
运行命令记录/add_two_ints服务:
bash
ros2 bag record --service /add_two_ints
你将在终端中看到以下消息(日期和时间会有所不同):
ini
[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...
现在,ros2 bag
正在记录 /add_two_ints
服务上发布的服务数据。要停止记录,在终端中按 Ctrl+C
。
数据将被收集到一个新的 bag 目录中,目录名称的格式为 rosbag2_year_month_day-hour_minute_second
。该目录将包含一个 metadata.yaml
文件以及以记录格式保存的 bag 文件。
4. 检查服务数据
你可以通过运行以下命令查看记录的详细信息:
bash
ros2 bag info <bag_file_name>
运行此命令将返回该文件的信息列表:
yaml
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. 回放服务数据
在回放 bag 文件之前,在运行 introspection_client
的终端中按 Ctrl+C
。当 introspection_client
停止运行时,introspection_service
也会停止打印结果(注意它并没有停止运行),因为没有传入的请求了。
输入命令将从 bag 文件中回放服务数据,开始向 introspection_service
发送请求:
bash
ros2 bag play --publish-service-requests <bag_file_name>
终端将返回消息:
ini
[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
终端将再次开始打印以下服务消息:
less
[INFO] [1713997478.090466075] [introspection_service]: Incoming request
a: 2 b: 3
这是因为 ros2 bag play
将 bag
文件中的服务请求数据发送到了 /add_two_ints
服务。
我们还可以在 ros2 bag play
回放服务数据时进行服务通信内省,以验证 introspection_service
。
在运行 ros2 bag play
之前运行以下命令,查看 introspection_service
的情况:
bash
ros2 service echo --flow-style /add_two_ints
你可以看到来自 bag
文件的服务请求和来自 introspection_service
的服务响应。
yaml
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}]
总结
你可以使用 ros2 bag
命令记录ROS 2系统中通过话题和服务传递的数据。无论你是要与他人分享工作,还是对自己的实验进行内省,这都是一个非常实用的工具。
关注【智践行】公众号,发送 【机器人】 获得机器人经典学习资料