跳到正文

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.參考