1. ROS1与ROS2数据包格式深度解析第一次接触ROS1和ROS2的数据包转换时我被它们完全不同的存储格式搞懵了。记得有次急着要分析一个旧项目的ROS1数据包结果发现新装的ROS2环境根本打不开那种抓狂的感觉至今难忘。ROS1的.bag文件就像是个打包好的压缩文件所有数据都整齐地塞在单个文件里。比如你录制的2021-05-19-19-10-18.bag直接就能用rosbag命令操作。这种设计简单直接但有个致命缺点——万一文件损坏整个数据包就废了。ROS2的存储方式则像是个精心整理的文件夹。我用ROS2 galactic录制测试数据时发现生成的是个名为rosbag2_2023_10_15-11_28_34的目录里面包含多个数据分片文件如_metadata.yaml和.db3文件索引文件时间戳信息这种设计让数据更安全部分损坏不影响整体也支持并行读写。但带来的麻烦就是ROS1的工具链完全无法识别这种结构。实测发现两种格式的消息序列化方式也不同。ROS1用的是简单的二进制序列化而ROS2采用了更现代的CDR格式。这就导致即使同一条/cmd_vel消息在两个系统中存储的字节流都不一样。2. 双环境配置避坑指南去年给团队搭建测试环境时我花了三天时间才搞定ROS1和ROS2的共存问题。这里分享几个血泪教训2.1 基础环境安装Ubuntu版本选择很关键ROS1 Noetic最好配Ubuntu 20.04ROS2 Humble需要Ubuntu 22.04如果想同时装建议用20.04ROS1 NoeticROS2 Foxy安装命令看似简单# ROS1 sudo sh -c echo deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main /etc/apt/sources.list.d/ros-latest.list sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 sudo apt update sudo apt install ros-noetic-desktop-full # ROS2 sudo apt install software-properties-common sudo add-apt-repository universe sudo apt update sudo apt install curl sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg echo deb [arch$(dpkg --print-architecture) signed-by/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main | sudo tee /etc/apt/sources.list.d/ros2.list /dev/null sudo apt update sudo apt install ros-foxy-desktop但实际会遇到各种依赖冲突。我的经验是先装ROS1再装ROS2用apt-cache depends检查冲突遇到问题就sudo apt --fix-broken install2.2 关键组件安装转换数据包需要这几个核心组件# ros1_bridge必须装 sudo apt install ros-foxy-ros1-bridge # 存储格式转换插件 sudo apt install ros-foxy-rosbag2-bag-v2-plugins \ ros-foxy-rosbag2-storage-default-plugins # 序列化库容易漏装 sudo apt install libroscpp-serialization0d特别提醒安装完成后一定要测试环境变量加载顺序。有次我直接source /opt/ros/foxy/setup.bash导致ROS1命令全部失效正确的做法是# 终端1 source /opt/ros/noetic/setup.bash roscore # 终端2 source /opt/ros/noetic/setup.bash source /opt/ros/foxy/setup.bash3. ROS1数据包在ROS2中播放实战上周刚用这个方法回放了一个2018年的旧数据包效果不错。具体操作3.1 准备工作首先检查数据包信息ROS1环境rosbag info old_data.bag确认包含的topic和消息类型比如常见的sensor_msgs/Image或geometry_msgs/Twist。3.2 跨系统播放关键命令就这两条# 在ROS2环境中播放ROS1包 ros2 bag play -s rosbag_v2 old_data.bag # 查看实际传输效果 ros2 topic list ros2 topic echo /your_topic但这里有个大坑环境变量加载顺序不对会报奇怪的错误。比如我就遇到过ImportError: /opt/ros/foxy/lib/librosbag2_storage.so: undefined symbol...解决方法是在播放前先加载ROS1库路径export LD_LIBRARY_PATH$LD_LIBRARY_PATH:/opt/ros/noetic/lib3.3 常见问题排查时间同步问题在play命令后加--rate 0.5可以降速播放消息类型不匹配用ros2 interface show对比ROS1和ROS2的消息定义时间戳异常加上--clock参数发布模拟时间实测案例转换一个包含/tf和/scan的导航数据包时发现ROS2中的坐标系名称需要调整。这时可以用ros2 run tf2_ros tf2_echo实时检查坐标系关系。4. 双向转换高级技巧4.1 ROS1→ROS2完整转换推荐使用rosbags工具链pip install rosbags rosbags-convert old_data.bag --dst new_data_folder转换后的目录结构new_data_folder/ ├── metadata.yaml ├── bag_0.db3 └── snapshots/4.2 ROS2→ROS1逆向转换需要先克隆工具仓库git clone https://gitlab.com/MapIV/rosbags.git cd rosbags pip install .转换命令rosbags-convert-2to1 rosbag2_folder -o output.bag4.3 自定义消息处理遇到自定义消息时比如公司内部的CustomMsg必须重新编译ros1_bridge。关键步骤创建专用工作空间mkdir -p ~/bridge_ws/src cd ~/bridge_ws/src git clone -b foxy https://github.com/ros2/ros1_bridge.git配置映射规则 在my_mapping_rules.yaml中定义消息对应关系ros1_package_name: custom_msgs ros1_message_name: CustomMsg ros2_package_name: custom_msgs ros2_message_name: CustomMsg编译时指定映射文件colcon build --packages-select ros1_bridge \ --cmake-args -DROS1_BRIDGE_MAPPING_FILEpwd/my_mapping_rules.yaml5. 实战案例与性能优化最近做自动驾驶数据回放时总结出几个实用技巧案例1大规模点云数据转换# 使用分片参数避免内存溢出 rosbags-convert lidar.bag --dst lidar_ros2 --chunk-size 100案例2多包连续转换# 保持时间序列连续 rosbags-convert-2to1 seq_1 seq_2 seq_3 -o merged.bag性能优化建议使用SSD硬盘存放数据包转换时关闭其他ROS节点对db3文件定期执行VACUUM命令需要sqlite3工具播放时加上--read-ahead-queue-size 100参数提升吞吐有个容易忽略的点转换后的数据包建议用ros2 bag reindex命令重建索引能显著提升后续播放效率。