跳到正文

Wiki

rosbag2

约 15 分钟阅读

1.基础概念

参考rosbag2教程

2.SLAM

2.1.功能包的职责

nav_bag_tools使用官方ros2 bag record和ros2 bag play,通过launch统一选择话题、QoS、输出位置、分卷和回放模式。现有C++ Writer/Reader demo保留为学习示例,正式使用不需要运行它们。

本页同时承担该包的使用说明,不再另建内容重复的README。

nav_bag_tools/
├── launch/
│   ├── record_slam.launch.py
│   └── play_slam.launch.py
├── config/
│   ├── slam_topics.yaml
│   └── slam_qos.yaml
├── recordings/               # 每次录制生成一个子目录,已被Git忽略
└── src/
    ├── demo01_writer.cpp
    └── demo02_reader.cpp

两份launch采用import os、generate_launch_description()、os.path.join(...)和return LaunchDescription([...])的直接写法,并为配置路径、启动参数和进程添加中文注释。DeclareLaunchArgument声明终端可传入的参数,LaunchConfiguration读取参数值,ExecuteProcess启动命令行程序;这里运行官方ros2 bag,所以不使用启动ROS节点的Node。

话题选择、路径和数值检查直接写在各自的launch中,不再使用额外的包装脚本。两份launch分别由start_record(context)和start_play(context)读取实际参数、选择YAML话题列表,再通过ExecuteProcess(cmd=['ros2', 'bag', ...])直接启动官方工具。

generate_launch_description()先声明参数,再用OpaqueFunction调用本文件中的启动函数。这里需要等终端传入的topics_file、include_debug、mode等参数确定后才能读取文件、选择话题,所以不能在声明参数之前就把命令固定下来。启动函数中的LaunchConfiguration('参数名').perform(context)就是读取这个参数的实际字符串值;OpaqueFunction本身不负责录制或回放。

record负责录数据,play负责发布已有消息;播放器本身不会重新计算SLAM,也不会自动启动Point-LIO、地形节点、机器人模型、雷达驱动或串口。 重跑算法需要另外启动对应的离线算法节点。

本版先完成官方工具的启动封装;参数、模型、版本、地图和pose graph按后文清单手动归档,尚未实现自动采集或自动完整性报告。

2.2.录制哪些数据

默认清单来自2026-10-21的实车检查,包含24路数据/诊断话题和3路事件话题,共27路,定义在config/slam_topics.yaml的record列表中。

数据组 实际完整topic名称 保存目的
原始雷达与IMU /livox/lidar、/livox/lidar/pointcloud、/livox/imu 当前Point-LIO订阅CustomMsg格式的/livox/lidar;PointCloud2副本便于分析和接入其他算法;MID360 IMU用于LIO估计
反馈与关节 /serial/gimbal_joint_state、/serial/imu、/joint_states 对比硬件反馈与模型实际收到的关节状态;串口IMU不能代替MID360 IMU
坐标与模型 /tf、/tf_static、/robot_description 保存当时的动态/静态坐标关系,以及模型文本
LIO及接口输出 /aft_mapped_to_init、/cloud_registered、/lidar_odometry、/registered_scan、/odometry、/sensor_scan 判断问题首先出现于LIO、坐标转换还是机器人里程计生成
地形 /terrain_map、/terrain_map_ext 检查地面估计、障碍提取和近远场处理
二维建图 /obstacle_scan、/map、/map_metadata、/pose 保留slam_toolbox实际输入与结果,供后续比较或单独重跑
诊断 /rosout、/parameter_events、/diagnostics 保存日志、参数变化和运行状态
状态事件 /joy、/map_clearing、/cloud_clearing 保存可能改变地形缓存的按钮或清图输入

正式清单如下,可与录制结束后的ros2 bag info逐项对照:

/livox/lidar
/livox/lidar/pointcloud
/livox/imu
/serial/gimbal_joint_state
/serial/imu
/joint_states
/tf
/tf_static
/robot_description
/aft_mapped_to_init
/cloud_registered
/lidar_odometry
/registered_scan
/odometry
/sensor_scan
/terrain_map
/terrain_map_ext
/obstacle_scan
/map
/map_metadata
/pose
/rosout
/parameter_events
/diagnostics
/joy
/map_clearing
/cloud_clearing

话题名称采用完整绝对名称,不会因为给launch换一个命名空间就自动替换。若实际namespace/remap已变化,需要同时调整话题清单与QoS文件的键。可通过topics_file、qos_file指定自己的配置副本。

话题出现在ROS graph里不代表有有效消息。 三路状态事件在上次检查时没有发布者;录制器允许发现无发布者的话题,并继续等待后来出现的发布者,整个实验未触发时没有消息是正常情况。仅仅启动录制器不构成完整性证明。

include_debug:=true会追加以下8路:

/cloud_registered_body
/cloud_effected
/Laser_map
/path
/slam_toolbox/graph_visualization
/slam_toolbox/scan_visualization
/slam_toolbox/update
/slam_toolbox/feedback

前4路在上次检查中有发布端但未收到消息,部分发布开关关闭;要先确认对应功能确实出数据。控制响应实验可在自己的配置中补录/cmd_vel、/cmd_gimbal_joint、/cmd_spin,这些命令不属于默认清单。

2.3.编译与录制

在已安装ROS 2 Humble的环境中执行:

cd /home/tungchiahui/UserFolder/MySource/ysu2026_rm_sentry/ysu2026_rm_sentry_nav
source /opt/ros/humble/setup.bash
colcon build --packages-select nav_bag_tools --symlink-install
source install/setup.bash

实车录制需要和被录节点使用一致的ROS域、网络和接口环境。2026-10-21实车的域为6,以下仅按该次配置举例:

export ROS_DOMAIN_ID=6
ros2 launch nav_bag_tools record_slam.launch.py

默认保存到当前工程源码包下的src/nav_bag_tools/recordings/,每次录制在里面生成一个独立的bag目录。未指定bag_name时,目录名为slam_年月日_时分秒_微秒,启动时会打印绝对路径。该目录已加入工程的Git忽略规则。

默认路径通过--symlink-install安装后的launch链接定位源码目录,不依赖终端当前工作目录。在工控机上编译运行时,指向工控机自己的源码工程;应尽量在运行驱动的容器/机器本地录制。仍可通过output_dir:=/data/recordings改存到其他磁盘;使用源码目录作为默认位置时,按上面的命令保留--symlink-install编译选项。

也可以指定实验名称:

ros2 launch nav_bag_tools record_slam.launch.py \
  bag_name:=gimbal_yaw_01 \
  include_debug:=false

这个例子会生成src/nav_bag_tools/recordings/gimbal_yaw_01/,目录内包含metadata.yaml和SQLite的.db3分卷。

同名bag目录已存在时拒绝覆盖;下一次换新名称。录制不会自动启动/重启SLAM,可先启动录制器,再启动驱动和算法,让录制覆盖初始化阶段;中途接入运行中的SLAM,需要在实验说明中记下开始时间与此前已经运行的情况。

录制参数 默认值 含义
output_dir 源码包内的recordings/ bag父目录;可覆盖,支持~和相对路径,启动时解析成绝对路径
bag_name 自动生成 新bag目录名;不能填写多级路径
topics_file 包内slam_topics.yaml 话题列表配置
qos_file 包内slam_qos.yaml 官方rosbag2 QoS覆盖配置
include_debug false 追加8路调试话题
use_sim_time false 实车使用系统时间;设为true时,录制器等待/clock后才写消息
max_bag_size 2147483648 单卷约2 GiB;单位字节,0关闭按大小分卷
max_bag_duration 300 单卷300秒;0关闭按时长分卷;不是录5分钟自动停止
max_cache_size 104857600 每个缓存约100 MiB;官方使用双缓冲,最坏仅缓存部分就可能接近200 MiB

两种分卷条件同时启用,先满足的条件触发切换。本版固定使用Humble现有的sqlite3插件,不启用压缩;存储文件是.db3。旧学习demo中的Jazzy/MCAP数据不用于证明这份Humble配置已经可用。

结束时按一次Ctrl+C,等待官方录制器完成写盘并退出,再操作或复制文件。launch为结束清理保留了更长的信号等待时间,但不能保证强制断电或强杀后当前分卷仍完整。

2.4.QoS为何单独配置

slam_qos.yaml是rosbag2的覆盖文件,顶层是topic名称,不是节点的ros__parameters。

话题 本版覆盖策略 原因
两种Livox点云、MID360 IMU Best Effort、Volatile,有限Keep Last队列 减少新增可靠高带宽读端对驱动的影响;不保证无丢包
/obstacle_scan Best Effort、Volatile 匹配上次实测的Best Effort发布者
/tf_static Reliable、Transient Local、深度100 晚启动的录制器需要取得所有静态发布者的快照;回放合并为一个发布者后也保留多条静态消息
/map、/map_metadata、/robot_description Reliable、Transient Local、深度1 晚加入时仍取得已有的地图/模型
/rosout Reliable、Volatile、深度1000 兼容不同节点提供的Volatile/Transient Local日志发布者,避免只按最先发现的发布者选择持久性
其他话题 官方工具自适应 本版没有把所有发现结果机械复制为覆盖值

队列深度是本版选择的初始配置,需要实测;不能照抄上次DDS发现返回的UNKNOWN/0。录制和播放目前默认使用同一份文件;若某个实验需要不同策略,分别通过两份launch的qos_file传入不同文件即可。

2.5.历史查看与原始输入重算

播放器默认发布100 Hz的/clock。使用独立的回放ROS域,并让RViz/算法终端使用同一个域;以下用106演示,不要与仍在运行的实车系统混用。

2.5.1.查看历史现场

source install/setup.bash
export ROS_DOMAIN_ID=106
ros2 launch nav_bag_tools play_slam.launch.py \
  bag_path:="$PWD/src/nav_bag_tools/recordings/gimbal_yaw_01" \
  mode:=view \
  rate:=1.0

view发布record列表中的历史消息,include_debug:=true再增加调试列表。默认不播放清单外的话题,因此即使bag里另外存过控制命令,也不会自动把它们全部播出。此模式不需要启动新算法;需要可视化时另开RViz并使用仿真时间。

对于清单中bag没有录到的可选话题,播放器不会凭空生成数据。view包含原始输入和历史结果,不应与正在重算的算法同时运行。

2.5.2.重跑算法时只提供输入

source install/setup.bash
export ROS_DOMAIN_ID=106
ros2 launch nav_bag_tools play_slam.launch.py \
  bag_path:="$PWD/src/nav_bag_tools/recordings/gimbal_yaw_01" \
  mode:=reprocess \
  start_paused:=true

reprocess只选择这6路:

/livox/lidar
/livox/imu
/joint_states
/joy
/map_clearing
/cloud_clearing

其中当前Point-LIO使用CustomMsg输入,因此不同时播放PointCloud2副本。选择记录的/joint_states作为模型输入后,不同时启动另一个JointState发布器,也不再让原串口反馈链生成第二份同名关节消息。

此launch只启动播放器。 继续重算还需要在相同回放域中,使用归档参数、URDF及外参,另外启动所需的Point-LIO、loam_interface、sensor_scan_generation、terrain_analysis、terrain_analysis_ext、pointcloud_to_laserscan、slam_toolbox、robot_state_publisher和静态变换发布者,并确保每个算法节点实际use_sim_time=true。

静态TF从归档模型和静态变换配置重建;动态TF、里程计、点云和地图由新算法生成,所以reprocess不播放旧的/tf、/tf_static、/robot_description和算法输出。缺少模型、静态变换或算法节点时,仅启动播放器不会得到新地图。

已有实车总入口会启动真实驱动等硬件节点,不应直接当作完整离线重跑入口。离线算法组合的自动启动尚未包含在本版中;需要分别确认模型来源、关节发布者、参数替换和时钟之后再接入。

播放器暂停就绪后,在算法及模型已准备好的同域终端执行:

ros2 service call /rosbag2_player/resume rosbag2_interfaces/srv/Resume "{}"

launch关闭了播放器的终端键盘控制,以免依赖子进程能否收到空格键。可通过/rosbag2_player/pause、/rosbag2_player/resume服务控制播放;命令里的ROS域要与播放器一致。

回放参数 默认值 含义
bag_path 必填 含metadata.yaml的bag目录,不是其中一个.db3文件
mode view 历史查看或reprocess输入重算
rate 1.0 播放倍率,必须为有限正数;调试可设0.5
clock_hz 100.0 发布/clock的频率,必须为有限正数
start_paused false 暂停启动,供准备算法;通过服务恢复
include_debug false 仅view可启用;重算模式禁止混入调试输出
topics_file、qos_file 包内对应配置 覆盖话题清单和QoS

2.6.bag以外还要保存什么

资产 保存内容
运行参数 关键节点开始/结束时的有效参数dump;不能只拿仓库默认YAML代替
启动配置 启动命令、namespace/remap、实际参数文件和launch替换结果
模型与外参 运行中的完整URDF、雷达安装外参、LiDAR/IMU外参、MID360配置JSON
软件环境 Git commit/diff、必要的未跟踪配置、自定义消息定义、ROS包版本、ROS域/RMW及网络配置
ROS graph 话题类型、发布订阅者、QoS,关键TF边与发布者的对应关系
地图与状态 地图图片及YAML;需要继续二维建图时保存slam_toolbox的.posegraph与.data
先验资产 本次确实启用并读取的PCD/地图;保存路径、内容及校验值
实验说明 运动部件、动作顺序、已知距离、起终点、异常时间、时钟同步状态

/parameter_events不补齐录制前参数,/map不替代pose graph,PCD不替代逐点时间和IMU历史。slam_toolbox state也不包含Point-LIO全部滤波器/地图缓存;从中途开始的bag不能保证恢复启动以来的所有内部状态。

这些资料目前需要手动保存。本次没有实现自动dump、地图保存服务调用、state序列化或归档同步,避免把“录制进程启动成功”误写成“实验资产已全部保存”。

2.7.建议的首轮验证

先在本地回放ROS域录一份低负载测试数据,核对bag info中的类型、数量和时间范围;再短时进行实车静止、底盘静止而云台yaw缓慢转动、已知距离直行往返等独立实验。每次记录真实动作,算法输出的里程计不能作为自己的独立真值。

ros2 bag info "$PWD/src/nav_bag_tools/recordings/gimbal_yaw_01"

对必要原始输入检查是否有实际数据,核对时间戳是否有异常间隔;检查多个静态TF发布者的关键边是否都保存。事件话题未触发和关键传感器断流需要区别记录。实车高带宽话题避免叠加远程hz/echo/RViz订阅,用短时试录确认驱动和算法没有明显受影响,再延长录制。

2.8.本次验证范围(2026-10-24)

本机Humble环境已完成包编译、资源安装与两份launch参数展开检查。随后在隔离ROS域中使用合成小消息完成以下检查:

  • 默认27路均录到实际消息,包含启动后才出现发布者的事件话题;单独保留的地图、模型和两份静态TF也被录到。
  • 测试将分卷时间临时设为1秒,生成5个SQLite分卷并能连续读回。
  • reprocess暂停启动、通过服务恢复,收到6路选定输入及/clock;未收到历史/tf、/map和/cloud_registered。
  • view能播放历史TF、地图及点云;在静态消息已播过后才加入的Transient Local监听者仍取得两条测试静态边。
  • 混合持久性的/rosout发布者在加入显式Volatile配置后,最终测试未再出现该QoS不兼容告警。
  • 移除独立包装脚本后,重新验证以上流程;另验证默认时间戳命名、含空格的输出及配置路径、debug追加、仿真时间录制、同名目录拒绝覆盖,以及重算模式禁止混入debug输出。

这些检查验证的是官方命令封装、配置与模式选择。尚未验证实车全带宽长期录制、真实点云内容质量、异常断电恢复或完整离线SLAM重算效果。

2.9.参考