ros_bridge实现ROS1,ROS2双向通信

📅 2026/7/18 18:53:30 👁️ 阅读次数 📝 编程学习
ros_bridge实现ROS1,ROS2双向通信

核心思想是:ros1_bridge本身同时链接 ROS1 和 ROS2 的消息库,把 ROS1 的 TCPROS 消息转换为 ROS2 DDS 消息,反方向也一样。

注意:ros_bridge需要同时加载ROS1和ROS2,一般我们使用docker创建个有ROS1,2的容器,在容器中编译ros_bridge。但是如果你的宿主机本身就有一个ROS环境,可以直接在宿主机源码编译另一版本ROS,让ros_bridge跑在宿主机,这样能够减少构建双ROS环境的时间

(ROS1) │ TCPROS ▼ ros1_bridge │ DDS ▼ (ROS2)

一、从零构建的复用流程

以下流程适用于当前环境:

  • Ubuntu 22.04
  • ROS2 Humble
  • ROS1 Noetic
  • Noetic 通过源码安装,因为 Ubuntu 22.04 没有标准 Noetic 二进制安装环境

1. 编译ROS1 Neotic

详情参照 Ubuntu22.04 编译 ROS1 Noetic-CSDN博客

2. 获取ROS2 Humble 兼容的 ros1_bridge

当前源码位于:

~/ros1_bridge_ws/bridge/src/ros1_bridge

一般获取方式:

cd ~/ros1_bridge_ws/bridge/src git clone https://github.com/ros2/ros1_bridge.git

对于稳定复用,建议固定到已经验证过的 commit,而不是以后一直跟随最新master

当前使用的 commit 是:

611755fd917285316051cbea80507e8b2f6b7ec1

固定版本:

cd ~/ros1_bridge_ws/bridge/src/ros1_bridge git checkout 611755fd917285316051cbea80507e8b2f6b7ec1

3. 按正确顺序 source 环境

这是最重要的一步:

source ~/ros1_bridge_ws/ros1_noetic/install_isolated/setup.bash source /opt/ros/humble/setup.bash

顺序是:

ROS1 Noetic → ROS2 Humble → 编译 ros1_bridge

终端可能出现:

ROS_DISTRO was set to 'noetic' before

这是因为 bridge 必须同时加载两个 ROS 环境。只要路径正确,这个提示本身不是错误。

编译前建议检查:

python3 -c "import rosmsg" which ros2 echo "$CMAKE_PREFIX_PATH" echo "$PYTHONPATH"

4. 编译 ros1_bridge

cd ~/ros1_bridge_ws/bridge colcon build \ --packages-select ros1_bridge \ --cmake-args \ -DCMAKE_BUILD_TYPE=Release \ -DBUILD_TESTING=OFF

如果之前配置环境错误,建议重新配置:

colcon build \ --packages-select ros1_bridge \ --cmake-force-configure \ --cmake-args \ -DCMAKE_BUILD_TYPE=Release \ -DBUILD_TESTING=OFF

编译完成后验证:

test -x install/ros1_bridge/lib/ros1_bridge/dynamic_bridge

5. 检查消息映射

source ~/ros1_bridge_ws/ros1_noetic/install_isolated/setup.bash source /opt/ros/humble/setup.bash source ~/ros1_bridge_ws/bridge/install/setup.bash ros2 run ros1_bridge dynamic_bridge --print-pairs \ | grep -E "Odometry|PointCloud2|TFMessage"

应该看到:

nav_msgs/msg/Odometry <=> nav_msgs/Odometry sensor_msgs/msg/PointCloud2 <=> sensor_msgs/PointCloud2 tf2_msgs/msg/TFMessage <=> tf2_msgs/TFMessage

三、跨电脑通信配置

假设:

Elevator-LIO 电脑:192.168.1.10 SCAN/bridge 电脑:192.168.1.20

ROS1 电脑:

export ROS_MASTER_URI=http://192.168.1.10:11311 export ROS_IP=192.168.1.10

bridge 电脑:

export ROS_MASTER_URI=http://192.168.1.10:11311 export ROS_IP=192.168.1.20 export ROS_DOMAIN_ID=0

ROS2电脑:

export ROS_DOMAIN_ID=0

注意:

  • 两台机器必须能互相ping
  • ROS1 不仅使用 11311,还会动态使用其他 TCP 端口。
  • ROS2 DDS 依赖 UDP、组播和动态端口。
  • 防火墙可能需要关闭或正确放行。
  • 所有 ROS2 机器的ROS_DOMAIN_ID必须一致。
  • 不要把ROS_HOSTNAME=127.0.0.1用在跨机器场景。

四、自定义消息的限制

标准消息现在都能桥接,但ros1_bridge不是运行时凭空理解自定义消息。

例如 Elevator-LIO 的:

lio/ElevatorState lio/CustomMsg

如果 ROS2 侧没有对应消`息包,它们不会出现在--print-pairs中。

自定义消息的流程是:

  1. ROS1 工作区编译 ROS1 消息包。
  2. ROS2 工作区创建字段一致的 ROS2 消息包。
  3. source ROS1 消息工作区。
  4. source ROS2 消息工作区。
  5. 重新编译ros1_bridge

这里只讲下需要特别注意的映射文件

1. 编写消息映射规则

创建:

/workspaces/ros2_msgs_ws/src/lio_msgs/mapping_rules.yaml

内容:

- ros1_package_name: lio ros2_package_name: lio_msgs - ros1_package_name: lio ros1_message_name: wheel_info ros2_package_name: lio_msgs ros2_message_name: WheelInfo

第一条是包级映射:

ros1_package_name: lio ros2_package_name: lio_msgs

它会尝试自动匹配同名消息:

lio/ElevatorState ↔ lio_msgs/msg/ElevatorState lio/CustomPoint ↔ lio_msgs/msg/CustomPoint lio/CustomMsg ↔ lio_msgs/msg/CustomMsg

第二条处理名称不同的消息:

wheel_info ↔ WheelInfo

字段名称不一致时

假设 ROS1 是:

float64 velocity

ROS2 改成:

float64 linear_velocity

则必须写字段映射:

- ros1_package_name: lio ros1_message_name: ElevatorState ros2_package_name: lio_msgs ros2_message_name: ElevatorState fields_1_to_2: header: header in_elevator: in_elevator displacement: displacement velocity: linear_velocity acceleration: acceleration

一旦使用fields_1_to_2,所有需要转换的字段都应明确列出;未列出的同名字段不会自动补充。这是官方映射规则中特别强调的行为。ros1_bridge 映射文档

因此,如果没有必要,最好保持字段名称完全一致,减少 YAML 映射。

五、常见故障判断

ROS2 看不到话题

检查:

ros2 topic list

然后看 bridge 是否输出:

created 1to2 bridge

可以加:

ros2 run ros1_bridge dynamic_bridge --bridge-all-1to2-topics

bridge 报无法连接 master

Failed to contact master Connection refused

检查:

echo "$ROS_MASTER_URI" rosparam list

确认roscore或 Elevator-LIO 的 ROS master 正在运行。

libroscpp.so => not found

说明 ROS1 环境没有 source:

source ~/ros1_bridge_ws/ros1_noetic/install_isolated/setup.bash

libros1_bridge.so => not found

说明 bridge 安装环境没有 source:

source ~/ros1_bridge_ws/bridge/install/setup.bash

No module named rosmsg

source ~/ros1_bridge_ws/ros1_noetic/install_isolated/setup.bash python3 -c "import rosmsg"

如果仍失败,说明 ROS1rosmsg没有编译安装,或者PYTHONPATH不正确。

有话题但没有消息

分别检查:

# ROS1 rostopic hz /LIO/odom_vehicle # ROS2 ros2 topic hz /LIO/odom_vehicle

还要检查 ROS2 QoS:

ros2 topic info /LIO/clouds_lidar --verbose

点云常使用 Best Effort QoS;如果订阅端 QoS 不兼容,也可能出现“有话题但收不到数据”。