跳到正文

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