最近写了一个无线网络环境下(比如WIFI)多机ROS通信的ROS包“swarm_ros_bridge”:

https://gitee.com/shu-peixuan/swarm_ros_bridge

该项目已被ROS index收录,ros wiki网址:

swarm_ros_bridge - ROS Wiki

本项目基于ZeroMQ,用于取代现有ROS1和ROS2多机通信配置,能够灵活地将任意本机ROS话题发送到其他机器人,或者读取其他机器人的话题。

目录

一、ROS多机通信现状

1、ROS1 自带的组网通信

2、ROS2自带的组网通信

3、自己写TCP/UDP的socket通信

二、基于ZeroMQ的通信中间件开发

三、swarm_ros_bridge

一、ROS多机通信现状

集群ROS机器人通过无线网络(WIFI、带网口的数传)进行多机通信,常用的应用层传输方法有:

1、ROS1 自带的组网通信

通过设置ROS_MASTER_URI使得所有机器人都连接到某一个主机的ROS master上,共享所有的ROS话题,底层是TCP协议和xmlRPC集中式节点发现机制)。缺点:

设置繁琐:每个机器人都要在/etc/hosts里设置IP, ~/.bashrc里设置ROS_MASTER_URI, ROS_HOSTNAME。不灵活:必须主机的roscore先启动,其他机器人的ROS节点后启动。

参考:

ROS/Technical Overview - ROS Wiki

ROS机器人操作系统底层原理及代码剖析_robinvista的博客-CSDN博客_ros源码分析

2、ROS2自带的组网通信

ROS2默认采用分布式的fast DDS通信架构。由于取消了ROS master中心节点,改用分布式的节点发现机制,ROS2的多机通信不需要设置主从机,设置简便了许多:

export ROS_DOMAIN_ID=5

保证同一局域网下的各个机器人的ROS_DOMAIN_ID相同即可。缺点:

不灵活:和ROS1一样,所有ROS话题都被传输,不能选择需要被传输的话题。不可靠:fast DDS 默认采用UDP通信协议,无线通信时不如TCP可靠(因为DDS一般是为本机多个进程间的数据交换开发的,而不是多机无线通信场景)。

参考:

ROS2之DDS问题汇集_zhangrelay的博客-CSDN博客_failed to find a free participant index for domain

 ROS2官方教程:ROS2中不同的DDS/RTPS vendors_P2Tree的博客-CSDN博客

 ZMQ vs eProsima Fast RTPS

3、自己写TCP/UDP的socket通信

采用sys/socket.h等库,自己写TCP或者UDP的socket通信代码,将ROS消息转换为TCP数据流发送到指定的机器人。其中TCP要求建立两者连接后才能收发数据,UDP则只负责发送数据和读取数据,而不管对方是否在线或接收到。缺点:

代码复杂:直接操作socket套件字过于底层,代码工作量很大,你要为每一个连接创建一个socket套接字,并全程管理绑定、监听、连接、接收等。”面向连接“而非”面向数据“:socket通信是面向连接的,而非ROS1/ROS2那样面向数据的,这意味着你需要为每两个机器人之间的通信都写一段连接的代码,不具有集群的扩展性。启动顺序有限制:和ROS1一样,TCP协议要求服务器端先启动,客户端后启动。而且不具备断线重连的功能。

C++ Socket实现TCP与UDP网络编程_C 语言_脚本之家

TCP socket通信

UDP socket通信

 为了避免重复造轮子,我调研了一些现有的把ros话题消息转换成TCP/UDP数据流的项目:

rosbridge_suite - ROS Wiki : Rosbridge provides a JSON API to ROS functionality for non-ROS programs.它主要是面向网页或者其他应用端和ros通信用,不是多机通信用。

rosserial - ROS Wiki :rosserial is a protocol for wrapping standard ROS serialized messages and multiplexing multiple topics and services over a character device such as a serial port or network socket. 它是读取串口的ROS包,也支持TCP端口读取,但是主要针对简单的读取一个固定TCP端口消息。

udp_com : 一个通用的以ROS形式读取和发送udp消息。提供了create_socket_service和send_service两个service用来创建接收套接字和发送消息,但是只能用他指定的ROS话题类型。

ros_udp_bridge : 用poco net库里的socket创建ROS读取和发送话题,但只是读取一个特定话题的简单项目。

综上,现在并没有可以好用的针对集群无线通信的ROS包。

二、基于ZeroMQ的通信中间件开发

其实ROS1和ROS2里的话题机制就是一种通信中间件,“通信中间件”是介于通信架构“传输层”和”应用层“之间的一层,将传输层的socket通信连接等设置封装成一些简单的API供应用层调用,从而使得应用开发人员不需要关注繁琐的TCP/UDP socket设置。

通信的7层架构

中间件介于应用层和硬件层之间

 OSI 模型与TCP/IP、以太网、DDS - 知乎

 通讯协议篇(底层TCP/UDP;上层MQTT、HTTP、CoAP、DDS、AMQP、JMS) | 码农家园

ROS1是自己搭建了一套xmlRPC集中式机制来建立节点之间的TCP连接,ROS2则是直接用了fast DDS中的分布式fast RTPS机制。如果我们不用ROS1和ROS2自带的中间件,就意味着我们需要自己写一个通信中间件,来实现集群机器人之间的通信连接。

好在还有一些其他的通信中间件可供我们使用,其中比较著名的就是ZeroMQ:

ZeroMQ | Socket API

ØMQ中文翻译文档_我不掉头发的博客-CSDN博客

zmqpp: zmqpp Namespace Reference

zeroMQ是一个主要用于TCP通信的中间件,基于C但也提供C++、python等封装。它将socket通信连接全部封装好,而留出一些”面向数据“的API接口供我们调用。

ZeroMQ提供的接口延用了socket的名字,比如socket::bind(),socket::connect(),socket::send(), socket::receive(),但是没有socket::listen()和socket::accept(),因为它提供的socket不是面向连接而是面向数据的,为要传输的每一个数据创建一个套接字即可,而不需要关心底层的socket连接问题。因此它不要求服务器先启动、客户端后启动,而是会自动连接、断线重连。

ZeroMQ提供的几种socket模式很像ROS,比如Request-reply :类似于ROS的service。Pub-sub : 类似于ROS的topic。

Pipeline :类似于ROS的topic,但是其push/pull的模式会阻塞发送端,不会丢弃发送的数据。

将zeroMQ用于ROS消息传输的项目也有一些,比如:

zmqros : 2015年的项目,过于陈旧,功能不完善。

ros_zeromq_tutorial : 只是一个简单的zeromq使用示例,并没有转化成ros话题。

综上,现在并没有可以好用的zeroMQ来传输ROS消息的项目。

三、swarm_ros_bridge

swarm_ros_bridge: A lightweight middle interface that enables specified ROS message transmission among swarm robots through socket communication

针对以上问题,我基于ZeroMQ开发了一个轻量化的ROS包,可以将任意ROS话题发送到其他机器人实现多机通信。只需要将你需要发送或接收的ROS话题信息写在ros_topics.yaml文件里。

例如,两个机器人之间通信的示例如下图所示(可以扩展到多个机器人):

核心工作:

利用ROS1自带的serialization对ROS话题消息进行序列化和反序列化,然后利用zeroMQ的PUB/SUB模式将消息发送,并为每个ROS接收话题建立一个接收线程。

与ROS1多机器人无线通信相比,它具有以下优点:

鲁棒:无需先启动基站ROS主站。支持每个机器人以随机顺序启动并自主连接。灵活:您可以选择发送/接收 ROS 话题,而不是像 ROS1 那样传输所有话题。易于使用:在一个配置文件中指定所有IP和ROS话题。

与ROS2 DDS通信相比,它具有以下优点:

轻量化:是一个订阅和发送远程ROS主题的小型ROS桥接节点,因此很容易与其他ROS1节点对接。可靠:它使用基于TCP协议的zmq套接字通信,而ROS2基于DDS,其默认协议为UDP(不可靠)。事实上,DDS主要用于有线通信下的本机进程之间的数据交换,而不是远程无线通信。

未来改进:

动态RPC,包括动态节点发现、在线主题变更和地面站监控。支持UDP协议,用于视频流等大量数据传输。利用zeromq的request/reply模式,支持ROS service的传输。支持ROS2节点话题转发。

文章链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: