【ROS2概念】系列(十四)——ROS 1 和 ROS 2 之间的桥接通信

目录

一、ROS1和RO2之间的桥接概述

ROS2提供了一个ROS2 package,这个包提供了一个桥(bridge),可以在 ROS 1 和 ROS 2 之间交换消息。

该桥目前在 C++ 中实现,因为当时 ROS 2 的 Python API 尚未开发。因此,它的支持仅限于桥编译时可用的消息/服务类型。

目前ros1_bridge这个包的功能有限,还不提供python实现,预构建 ROS 2 二进制文件提供的桥包括对通用 ROS 接口(消息/服务)的支持,仅支持ros2_common_interfaces中列出的通讯类型和tf2_msgs

如果想使用自定义类型的ros1_bridge,则必须在单独的 ROS 1 和 ROS 2 工作区中构建自定义类型后,从源代码构建ros1_bridge

出于效率原因,只有当匹配的发布者-订阅者对在ros1_bridge的任一侧都处于活动状态时,才会桥接topic。因此,如果没有其他订阅者存在,使用命令行工具ros2 topic echo <topic-name>不起作用,但会失败并显示错误消息Could not determine the type for the passed topic,因为dynamic_bridge尚未桥接topic。

作为解决方法,可以明确指定topic类型ros2 topic echo <topic-name> <topic-type>,这会触发topic的桥接,因为该echo命令表示必要的订阅者。

但在 ROS 1 端rostopic echo没有明确指定topic类型的选项。因此,如果没有其他订阅者,它不能与ROS2的dynamic_bridge一起使用。作为替代方案,可以使用ros2 run ros1_bridge dynamic_bridge --bridge-all-2to1-topics选项把所有 ROS 2的topic桥接到 ROS 1,以便即使没有匹配的 ROS 1 订阅者,rostopic echorostopic listrqt这些工具也会看到topic。运行ros2 run ros1_bridge dynamic_bridge -- --help以获得更多选项。

注意,ROS2官方提示目前ros1_bridge已经存在的一些问题:

  • 可能需要 ros2 run ros1_bridge dynamic_bridge --bridge-all-topics 才能正确桥接。 经过测试并报告说,当至少一种自定义消息类型在 ROS 2 中发布并在 ROS 1 中订阅时,--bridge-all-topics是必需的。还有非正式地报告说,在相同条件下,内置消息类型需要--bridge-all-topics选项
  • 最后ros1_bridge一旦与 ROS 1 主服务器建立了映射,就可以在没有 --bridge-all-topics的情况下重新运行ros1_bridge,以便有选择地桥接主题。 但是,这不能保证。

二、桥接流程

桥接过程至少需要开启四个终端:

Terminal 1 Terminal 2 Terminal 3 Terminal 4
ROS环境变量 source ros1 source ros1 source ros1, source ros2 source ros2
命令 roscore 运行你需要使用的ros1的包 export ROS_MASTER_URI=http://localhost_IP:11311
ros2 run ros1_bridge dynamic_bridge
运行你需要使用的ros2的包

注意:当运行这些demo时,确保仅提供指定ROS版本的环境变量。如果在某些节点中有两个ROS工作区,将收到错误消息。

三、ROS 1 talker -> ROS 2 listener

3.1 运行命令

Terminal 1 Terminal 2 Terminal 3 Terminal 4
ROS环境变量 source ros1 source ros1 source ros1, source ros2 source ros2
命令 roscore rosrun rospy_tutorials talker export ROS_MASTER_URI=http://localhost_IP:11311
ros2 run ros1_bridge dynamic_bridge
ros2 run demo_nodes_cpp listener

首先启动roscore(左上角),接着运行自己的ROS1节点(左下角),ROS 1 节点开始将发布的消息打印到控制台。

然后启动ros1_bridge(右上角),它将监视可用的 ROS 1 和 ROS 2 主题,一旦检测到匹配的主题,它就会开始桥接关于该主题的消息。ros1_bridge开始定期输出 ROS 1 和 ROS 2 中当前可用的主题。

最后运行自己的ROS2节点(右下角),ROS 2 节点开始将收到的消息打印到控制台。

3.2 输出结果

在桥接的过程中,Terminal 3(右上角)有一行说明该topic的bridge已创建:

created 1to2 bridge for topic '/chatter' with ROS 1 type 'std_msgs/String' and ROS 2 type 'std_msgs/String'

在停止了 talker 或 listener 中的任何一个,就会有一行表明桥已被拆除:

removed 1to2 bridge for topic '/chatter'

四、ROS 2 talker -> ROS 1 listener

4.1 运行命令

Terminal 1 Terminal 2 Terminal 3 Terminal 4
ROS环境变量 source ros1 source ros1 source ros1, source ros2 source ros2
命令 roscore rosrun roscpp_tutorials listener export ROS_MASTER_URI=http://localhost_IP:11311
ros2 run ros1_bridge dynamic_bridge
ros2 run demo_nodes_py talker

首先启动roscore(左上角),接着运行自己的ROS2节点(左下角),ROS 2 节点开始将发布的消息打印到控制台。

然后启动ros1_bridge(右上角),它将监视可用的 ROS 1 和 ROS 2 主题,一旦检测到匹配的主题,它就会开始桥接关于该主题的消息。ros1_bridge开始定期输出 ROS 1 和 ROS 2 中当前可用的主题。

最后运行自己的ROS1节点(右下角),ROS 1 节点开始将收到的消息打印到控制台。

4.2 输出结果

在桥接的过程中,Terminal 3(右上角)有一行说明该topic的bridge已创建:

created 2to1 bridge for topic '/chatter' with ROS 2 type 'std_msgs/String' and ROS 1 type 'std_msgs/String'

在停止了 talker 或 listener 中的任何一个,就会有一行表明桥已被拆除:

removed 2to1 bridge for topic '/chatter'

五、ROS 2 拍摄图像 -> ROS 1 显示图像

ros1_bridge也可以传输大数据消息,如图像数据。

ROS 2 节点发布相机图像,ROS 1 使用rqt_image_view在 GUI 中渲染图像。

5.1 运行命令

Terminal 1 Terminal 2 Terminal 3 Terminal 4
ROS环境变量 source ros1 source ros1 source ros1, source ros2 source ros2
命令 roscore rqt_image_view /image export ROS_MASTER_URI=http://localhost_IP:11311
ros2 run ros1_bridge dynamic_bridge
ros2 run image_tools cam2image

首先启动roscore(左上角),接着运行自己的ROS1节点(左下角)。

然后启动ros1_bridge(右上角),它将监视可用的 ROS 1 和 ROS 2 主题,一旦检测到匹配的主题,它就会开始桥接关于该主题的消息。ros1_bridge开始定期输出 ROS 1 和 ROS 2 中当前可用的主题。

最后运行自己的ROS2节点(右下角)。

5.2 输出结果

六、传输Service

在这个例子中,我们将桥接来自 ros/roscpp_tutorials的服务 TwoInts和来自 ros2/roscpp_examples 的 AddTwoInts

在构建时,ros1_bridge 会查找所有已安装的 ROS 和 ROS2 服务。通过比较请求和响应中的包名称、服务名称和字段来匹配找到的服务。如果 ROS 和 ROS2 服务中的所有名称都相同,则将创建网桥。也可以通过创建包含相应服务名称的 yaml 文件来手动配对服务。

为了使这个示例正常运行,请确保在构建 ros1_bridge 时系统上安装了 roscpp_tutorials 包并且环境设置正确。

6.1 运行命令

Terminal 1 Terminal 2 Terminal 3 Terminal 4
ROS环境变量 source ros1 source ros1 source ros1, source ros2 source ros2
命令 roscore rosrun roscpp_tutorials add_two_ints_server export ROS_MASTER_URI=http://localhost_IP:11311
ros2 run ros1_bridge dynamic_bridge
ros2 run demo_nodes_cpp add_two_ints_client

首先启动roscore(左上角),接着运行自己的ROS1节点(左下角)。

然后启动ros1_bridge(右上角),它将监视可用的 ROS 1 和 ROS 2 服务,一旦检测到匹配的服务,它就会开始桥接关于该服务的消息。ros1_bridge开始定期输出 ROS 1 和 ROS 2 中当前可用的服务。

最后运行自己的ROS2节点(右下角)。

6.2 输出结果

七、仅桥接选定的主题和服务

ros1_bridge通过配置文件可以选择性桥接自己需要的主题和服务。

ros1_bridge包使用dynamic_bridge节点来桥接所有主题和服务,使用parameter_bridge节点通过ROS1的参数服务器来选择桥接哪些主题和服务。

桥接所有主题和服务
ros2 run ros1_bridge dynamic_bridge

通过ROS1的参数服务器来选择桥接指定的主题和服务
ros2 run ros1_bridge parameter_bridge

注意:service的bridge是单向的,必须相应地使用services_2_to_1桥接 ROS 2 -> ROS 1 和services_1_to_2来桥接 ROS 1 -> ROS 2 的service。

例如,使得主题/chatter时双向桥接的,而服务/add_two_ints service仅从 ROS 2 -> ROS 1,可以创建如下配置文件bridge.yaml

topics:
  -
    topic: /chatter  # Topic name on both ROS 1 and ROS 2
    type: std_msgs/msg/String  # Type of topic to bridge
    queue_size: 1  # Queue size
services_2_to_1:
  -
    service: /add_two_ints  # ROS 1 service name
    type: roscpp_tutorials/TwoInts  # The ROS 1 service type name

7.1 运行命令

Terminal 1 Terminal 2 Terminal 3 Terminal 4 Terminal 5 Terminal 6
ROS环境变量 source ros1 source ros1 source ros1 source ros2 source ros2 source ros2
命令 roscore rosparam load bridge.yaml;
rosrun rospy_tutorials talker
rosrun roscpp_tutorials add_two_ints_server ros2 run ros1_bridge parameter_bridge ros2 run demo_nodes_cpp listener ros2 service call /add_two_ints example_interfaces/srv/AddTwoInts "{a: 1, b: 2}"

首先启动roscore,接着加载 bridge.yaml 配置文件,然后启动 talker和server。

启动ros1_bridge中的parameter_bridge,日志显示它正在为主题和服务创建桥梁,如果一切顺利,就能够调用该服务并从 ROS 2 收听 ROS 1 talker。

对于ROS2的listener,这时应该输出I heard: [hello world ...]带有时间戳的文本。

对于ROS2的client,这时应该输出example_interfaces.srv.AddTwoInts_Response(sum=3)

八、参数化服务质量

ROS 2 优于 ROS 1 的一个优势是可以为每个主题定义不同的服务质量设置。

parameter_bridge 也可以通过ROS 1的参数配置文件修改ROS2相应的话题的服务质量(Qos)。

ROS 1 中的/tf_static话题用来描述不同静态坐标系的变换关系,在ROS1中只会发布一次,若ROS2节点需要该数据,可以通过ROS 2 中parameter_bridge设置Qos中的history参数来获取数据,该/tf_static的主题配置为:

topics:
  -
    topic: /tf_static
    type: tf2_msgs/msg/TFMessage
    queue_size: 1
    qos:
      history: keep_all
      durability: transient_local

所有其他 QoS 选项(如https://docs.ros.org/en/foxy/Concepts/About-Quality-of-Service-Settings.html中所述)均可用:

topics:
  -
    topic: /some_ros1_topic
    type: std_msgs/msg/String
    queue_size: 1
    qos:
      history: keep_last  # OR keep_all, then you can omit `depth` parameter below
      depth: 10  # Only required when history == keep_last
      reliability: reliable  # OR best_effort
      durability: transient_local  # OR volatile
      deadline:
          secs: 10
          nsecs: 2345
      lifespan:
          secs: 20
          nsecs: 3456
      liveliness: liveliness_system_default  # Values from https://design.ros2.org/articles/qos_deadline_liveliness_lifespan.html, eg. LIVELINESS_AUTOMATIC
      liveliness_lease_duration:
          secs: 40
          nsecs: 5678

请注意,该qos部分可以完全省略,未设置的选项保留为默认值。

参考:
ros1_bridge官方:https://github.com/ros2/ros1_bridge
ros1_bridge无法建立通讯解决办法:https://blog.csdn.net/weixin_37669024/article/details/122348311
ros1_bridge运行结果不成功,报错No executable found:https://blog.csdn.net/wsc820508/article/details/81408251

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343

推荐阅读更多精彩内容