赞
踩
最近写了一个无线网络环境下(比如WIFI)多机ROS通信的ROS包“swarm_ros_bridge”:
https://gitee.com/shu-peixuan/swarm_ros_bridge
该项目已被ROS index收录,ros wiki网址:
本项目基于ZeroMQ,用于取代现有ROS1和ROS2多机通信配置,能够灵活地将任意本机ROS话题发送到其他机器人,或者读取其他机器人的话题。
目录
集群ROS机器人通过无线网络(WIFI、带网口的数传)进行多机通信,常用的应用层传输方法有:
通过设置ROS_MASTER_URI使得所有机器人都连接到某一个主机的ROS master上,共享所有的ROS话题,底层是TCP协议和xmlRPC集中式节点发现机制)。缺点:
参考:
ROS/Technical Overview - ROS Wiki
ROS机器人操作系统底层原理及代码剖析_robinvista的博客-CSDN博客_ros源码分析
ROS2默认采用分布式的fast DDS通信架构。由于取消了ROS master中心节点,改用分布式的节点发现机制,ROS2的多机通信不需要设置主从机,设置简便了许多:
export ROS_DOMAIN_ID=5
保证同一局域网下的各个机器人的ROS_DOMAIN_ID相同即可。缺点:
参考:
ROS2之DDS问题汇集_zhangrelay的博客-CSDN博客_failed to find a free participant index for domain
ROS2官方教程:ROS2中不同的DDS/RTPS vendors_P2Tree的博客-CSDN博客
采用sys/socket.h等库,自己写TCP或者UDP的socket通信代码,将ROS消息转换为TCP数据流发送到指定的机器人。其中TCP要求建立两者连接后才能收发数据,UDP则只负责发送数据和读取数据,而不管对方是否在线或接收到。缺点:
C++ Socket实现TCP与UDP网络编程_C 语言_脚本之家
为了避免重复造轮子,我调研了一些现有的把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包。
其实ROS1和ROS2里的话题机制就是一种通信中间件,“通信中间件”是介于通信架构“传输层”和”应用层“之间的一层,将传输层的socket通信连接等设置封装成一些简单的API供应用层调用,从而使得应用开发人员不需要关注繁琐的TCP/UDP socket设置。
通讯协议篇(底层TCP/UDP;上层MQTT、HTTP、CoAP、DDS、AMQP、JMS) | 码农家园
ROS1是自己搭建了一套xmlRPC集中式机制来建立节点之间的TCP连接,ROS2则是直接用了fast DDS中的分布式fast RTPS机制。如果我们不用ROS1和ROS2自带的中间件,就意味着我们需要自己写一个通信中间件,来实现集群机器人之间的通信连接。
好在还有一些其他的通信中间件可供我们使用,其中比较著名的就是ZeroMQ:
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消息的项目。
针对以上问题,我基于ZeroMQ开发了一个轻量化的ROS包,可以将任意ROS话题发送到其他机器人实现多机通信。只需要将你需要发送或接收的ROS话题信息写在ros_topics.yaml文件里。
例如,两个机器人之间通信的示例如下图所示(可以扩展到多个机器人):
核心工作:
利用ROS1自带的serialization对ROS话题消息进行序列化和反序列化,然后利用zeroMQ的PUB/SUB模式将消息发送,并为每个ROS接收话题建立一个接收线程。
与ROS1多机器人无线通信相比,它具有以下优点:
与ROS2 DDS通信相比,它具有以下优点:
未来改进:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。