Skip to content

Bobo2sky/ros2_bag_utils

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ros2_bag_utils

提供针对 ROS 2 bag 的实用工具,包含 frame_id 重写、topic 重命名、tf_static 写入等功能。

功能简介

  • rewrite_frame_id:根据配置,将已录制 rosbag2 中指定 topic 的 header.frame_id 批量替换,并生成新的 bag。
  • rewrite_tf_static_frame_id:对 /tf_static topic 中的 frame 名称进行批量改写,并生成新的 bag。
  • rename_topic:根据配置,将已录制 rosbag2 中的 topic 名称进行重命名,并生成新的 bag。
  • write_tf_static:根据外参配置文件,向 rosbag2 中写入 tf_static 变换信息。
  • filter_pointcloud_xyzi:将指定 PointCloud2 topic 的点云字段裁剪为常见的 x/y/z/intensity 四个字段。
  • export_assets:解析 rosbag2 中的点云、图像、/tf_static,并导出为 PCD/PNG/YAML 等通用格式
  • fuse_pointclouds: 将多个激光雷达 PCD 点云融合到统一坐标系。

安装与构建

colcon build --packages-select ros2_bag_utils
source install/setup.bash

依赖说明:请确保环境已安装 python-lzf(例如 pip install python-lzfsudo apt install python3-lzf),以便导出的 PCD 使用 LZF 压缩格式。

fuse_pointclouds

配置文件格式(fuse_pointclouds)

示例:config/fuse_pointclouds.example.yaml

input_root: /path/to/exported/data
base_frame: base_link
reference_lidar: lidar_name
time_tolerance_ms: 10.0
lidar_subdir: lidar
calib_subdir: calib
overwrite: false
  • input_root: 包含点云和外参的根目录。
  • base_frame: 目标基准坐标系。
  • reference_lidar: 参考时间轴的激光雷达名称。
  • time_tolerance_ms: 时间匹配容差(毫秒)。
  • lidar_subdir: 点云子目录(默认 lidar)。
  • calib_subdir: 外参子目录(默认 calib)。
  • overwrite: 是否覆盖现有输出目录。

命令行使用(fuse_pointclouds)

ros2 run ros2_bag_utils fuse_pointclouds --config /path/to/config.yaml

命令行参数可覆盖配置文件:

  • --input-root:输入根目录
  • --base-frame:基准坐标系
  • --reference-lidar:参考激光雷达名称
  • --time-tolerance-ms:时间容差(毫秒)
  • --lidar-subdir:点云子目录
  • --calib-subdir:外参子目录
  • --overwrite:覆盖输出目录

Launch 调用(fuse_pointclouds)

ros2 launch ros2_bag_utils fuse_pointclouds.launch.py \
  config_file:=/path/to/config.yaml

行为规范(fuse_pointclouds)

  • 读取指定目录下的 PCD 文件,根据时间戳匹配多个激光雷达的点云。
  • 使用外参文件中的四元数和平移,将点云变换到统一坐标系。
  • 输出融合后的点云到 input_root/lidar/base_frame/ 目录。
  • 支持 ASCII、二进制和压缩 PCD 格式。
  • 依赖 wind-pypcd、scipy、numpy、PyYAML。

rewrite_frame_id

配置文件格式(rewrite_frame_id)

示例:config/rewrite_frame_id.example.yaml

input_bag: /path/to/original_bag
output_bag: /path/to/output_bag  # 可选,缺省时自动追加后缀
mappings:
  /example/topic: base_link
  /another/topic: camera_link

命令行使用(rewrite_frame_id)

ros2 run ros2_bag_utils rewrite_frame_id --config /path/to/config.yaml

命令行参数可覆盖配置文件:

  • --input-bag:输入 bag 目录
  • --output-bag:输出 bag 目录(可选)
  • --topic-map topic:=frame:可重复指定,覆盖原配置

Launch 调用(rewrite_frame_id)

ros2 launch ros2_bag_utils rewrite_frame_id.launch.py \
  config_file:=/path/to/config.yaml \
  input_bag:=/override/input/bag \
  topic_map:="/topic:=new_frame;/topic2:=map"

行为规范(rewrite_frame_id)

  • 如配置中的 topic 不存在或没有消息,将直接报错退出。
  • 如消息缺少 header.frame_id 字段,同样报错。
  • 如果 bag 中存在 /tf_static,且变换中的 parent/child frame 命中被替换的旧 frame,会自动同步改写,保持 tf 树一致。
  • 当检测到同一 topic 的消息使用不同的 frame_id,或同一旧 frame 被要求映射到多个新 frame 时会报错提示。
  • 输出 bag 与输入 bag 采用相同的 storage/serialization 插件,并保存到新的目录中。

rewrite_tf_static_frame_id

配置文件格式(rewrite_tf_static_frame_id)

示例:config/rewrite_tf_static_frame_id.example.yaml

input_bag: /path/to/original_bag
output_bag: /path/to/output_bag  # 可选,缺省时自动追加后缀
frames:
  old_frame_a: new_frame_a
  old_frame_b: new_frame_b

命令行使用(rewrite_tf_static_frame_id)

ros2 run ros2_bag_utils rewrite_tf_static_frame_id --config /path/to/config.yaml

命令行参数可覆盖配置文件:

  • --input-bag:输入 bag 目录
  • --output-bag:输出 bag 目录(可选)
  • --frame-map old:=new:可重复指定,覆盖原配置

Launch 调用(rewrite_tf_static_frame_id)

ros2 launch ros2_bag_utils rewrite_tf_static_frame_id.launch.py \
  config_file:=/path/to/config.yaml \
  input_bag:=/override/input/bag \
  frame_map:="old:=new;foo:=bar"

行为规范(rewrite_tf_static_frame_id)

  • 仅对 /tf_static topic 进行处理,其余 topic 原样拷贝。
  • 同时改写 TransformStampedheader.frame_id(parent)与 child_frame_id
  • 当旧 frame 在 bag 中未出现时给出警告但不会中断,仍会输出新 bag。
  • 改写成功后输出改写统计,包括映射列表及修改前后的 tf 连线摘要。

rename_topic

配置文件格式(rename_topic)

示例:config/rename_topic.example.yaml

input_bag: /path/to/original_bag
output_bag: /path/to/output_bag  # 可选,缺省时自动追加后缀
mappings:
  /old/topic: /new/topic
  /another/old: /another/new

命令行使用(rename_topic)

ros2 run ros2_bag_utils rename_topic --config /path/to/config.yaml

命令行参数可覆盖配置文件:

  • --input-bag:输入 bag 目录
  • --output-bag:输出 bag 目录(可选)
  • --topic-map old:=new:可重复指定,覆盖原配置

Launch 调用(rename_topic)

ros2 launch ros2_bag_utils rename_topic.launch.py \
  config_file:=/path/to/config.yaml \
  input_bag:=/override/input/bag \
  topic_map:="/old:=/new;/foo:=/bar"

行为规范(rename_topic)

  • 若旧 topic 不存在或无消息,将直接报错终止。
  • 若新 topic 已存在于原 bag 或多个旧 topic 指向同一新 topic,同样报错。
  • 输出 bag 使用与输入相同的 storage/serialization 插件并写入新目录,metadata 中的 topic 名称会同步更新。

write_tf_static

配置文件格式(write_tf_static)

示例:config/write_tf_static.example.yaml

input_bag: /path/to/original_bag
output_bag: /path/to/output_bag  # 可选,缺省时自动追加后缀

lidars:  # 可选,存在则处理
  lidar0:
    topic: "/sensing/lidar/lidar0/pointcloud_raw"
    extrinsics: "/absolute/path/to/lidar0_extrinsics.yaml"
  lidar1:
    topic: "/sensing/lidar/lidar1/pointcloud_raw"
    extrinsics: "/absolute/path/to/lidar1_extrinsics.yaml"

cameras:  # 可选,存在则处理
  cam0:
    topic: "/sensing/camera/cam0/image_ptr"
    extrinsics: "/absolute/path/to/cam0_extrinsics.yaml"

外参文件格式:

parent_frame: base_link
child_frame: lidar_lidar0
transform:
  translation:
    x: 1.250
    y: 0.000
    z: 1.600
  rotation_quaternion:
    x: 0.000
    y: 0.000
    z: 0.000
    w: 1.000

命令行使用(write_tf_static)

ros2 run ros2_bag_utils write_tf_static --config /path/to/config.yaml

Launch 调用(write_tf_static)

ros2 launch ros2_bag_utils write_tf_static.launch.py \
  config_file:=/path/to/config.yaml \
  input_bag:=/override/input/bag

行为规范(write_tf_static)

  • 外参文件不存在或格式错误时发出警告并跳过该设备,不会终止程序。
  • 检查 frame 名称是否符合 ROS 规范,不规范时跳过。
  • 若原 bag 已存在 /tf_static topic,会发出警告并合并变换。
  • 使用原 bag 第一条消息的时间戳作为 tf_static 的时间戳。

filter_pointcloud_xyzi

配置文件格式(filter_pointcloud_xyzi)

示例:config/filter_pointcloud_xyzi.example.yaml

input_bag: /path/to/original_bag
output_bag: /path/to/output_bag  # 可选,缺省时自动追加后缀
topics:
  - /sensing/lidar/front/pointcloud_raw
  - /sensing/lidar/rear/pointcloud_raw

命令行使用(filter_pointcloud_xyzi)

ros2 run ros2_bag_utils filter_pointcloud_xyzi --config /path/to/config.yaml

命令行参数可覆盖配置文件:

  • --input-bag:输入 bag 目录
  • --output-bag:输出 bag 目录(可选)
  • --topic /foo/points:可重复指定,覆盖原配置

Launch 调用(filter_pointcloud_xyzi)

ros2 launch ros2_bag_utils filter_pointcloud_xyzi.launch.py \
  config_file:=/path/to/config.yaml \
  input_bag:=/override/input/bag \
  topics:="/topic_a;/topic_b"

行为规范(filter_pointcloud_xyzi)

  • 仅当目标 topic 的所有消息同时包含 xyzintensity 且类型为 float32 时会执行裁剪。
  • 如任意目标 topic 的任意消息缺失上述字段或字段类型不符合要求,将立即报错并终止。
  • 输出 bag 与输入 bag 使用相同的 storage/serialization 插件,并写入新的目录,目标 topic 的消息仅保留 xyzi 字段。

export_assets

配置文件格式(export_assets)

示例:config/export_assets.example.yaml

input_bag: /path/to/rosbag2_directory
output_root: /path/to/export_root  # 可选,缺省时自动生成 *_exported
base_frame: base_link              # 可选,外参统一到的基准坐标系
filename_style: ns                  # 默认纳秒命名,可设置为 datetime
filename_time_source: header        # 默认使用 header.stamp,可改为 bag
# filename_time_format: "%Y%m%d_%H%M%S"  # 仅当 filename_style=datetime 时有效

lidar:
  topics:
    - /sensing/lidar/front/points_raw
  output_subdir: lidar

camera:
  topics:
    - /sensing/camera/front/image_raw
  output_subdir: camera

tf_static:
  enabled: true
  output_subdir: calib

filename_time_format: "%Y%m%dT%H%M%S_%f"
overwrite: false

命令行使用(export_assets)

ros2 run ros2_bag_utils export_assets --config /path/to/config.yaml

常用覆盖参数:

  • --input-bag:输入 bag 目录
  • --output-root:导出根目录
  • --base-frame:外参统一到的基准 frame
  • --lidar-topic /topic:可重复指定点云 topic
  • --camera-topic /topic:可重复指定图像 topic
  • --disable-lidar:跳过点云导出(等同于在配置中将 lidar.enabled: false
  • --disable-tf-static:跳过外参导出
  • --overwrite:若输出目录已存在则清空后重建
  • --filename-style {ns,datetime}:选择文件命名样式;datetime 可结合 24 小时制格式
  • --filename-time-source {header,bag}:选择时间来源,默认 header

Launch 调用(export_assets)

ros2 launch ros2_bag_utils export_assets.launch.py \
  config_file:=/path/to/config.yaml \
  input_bag:=/path/to/bag \
  output_root:=/path/to/export \
  lidar_topics:="/lidar_a;/lidar_b" \
  camera_topics:="/cam/image" \
  overwrite:=true

行为规范(export_assets)

  • 自动识别 sensor_msgs/msg/PointCloud2sensor_msgs/msg/Imagesensor_msgs/msg/CompressedImage 以及 /tf_static
  • 点云导出为 .pcd,采用 PCD v0.7 格式。输出的 PCD 存储格式可通过 pcd_format 配置控制(取值:uncompressedasciicompressed,默认 uncompressed)。点云字段保留由 pointcloud_format 控制(取值:auto/xyz/xyzi/xyzit,默认为 auto)。
  • 图像统一保存为 .png,原始图像根据编码解码,压缩图像先解压再保存。
  • tf_static 将尝试构建到 base_frame 的变换链,缺失时给出警告;如 bag 中不存在 base_frame,会报错并停止写入外参。
  • 点云、图像分别按 frame_id 归档到 lidar/camera/ 子目录,每帧以采样时间命名;外参写入 calib/frame_extrinsics.yaml 文件。
  • 可通过配置项 lidar.enabled: false 或 CLI --disable-lidar 显式禁用点云导出,避免解析 PointCloud2(加速仅导出相机数据的流程)。
  • 默认使用消息 header.stamp 的纳秒值作为文件名;可通过配置切换为 24 小时制时间字符串。
  • 处理过程中使用 rich 进度条展示点云与图像的处理进度;若环境缺少 rich 会降级为日志提示。

测试

colcon test --packages-select ros2_bag_utils

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published