ROS2 DDS通信漫谈
0. 前言
我们都知道ROS2比ROS1好很多,就比如说:
-
去中心化master,ROS和ROS2中间件不同之处在于,ROS2取消了master节点。在去中心化后,各个节点之间可以通过DDS的节点相互发现,各个节点都是平等的,且可以1对1、1对n、n对n进行互相通信。
-
不造通信的轮子,通信直接更换为DDS进行实现。通信采用采用DDS通信,使得ROS2的是实行、可靠性和连续性上都有了增强。
同时ROS2中也拥有了很多新的特性:
- 可用Python编写的Launch文件
- 多机器人协同通信支持
- 支持安全加密通信
- 同一个进程支持多个节点
- 使用ament进行包管理
- 支持Qos服务质量
- 支持节点生命周期管理
- 高效的进程间通信
我们发现这些特性都是基于通信模式从TCP/IP到DDS模式的转变,因此本文想从DDS出发,来带大家理解ROS2的DDS到底做了什么。
1. 多机通信DDS
DDS是一个被很多公司实现的工业标准,比如RTI的实现Connext和eProsima的实现Fast RTPS。ROS2 支持多种实现方式。在选择DDS实现的时候要考虑很多方面:法律上要考虑协议,技术上要考虑是否支持跨平台。不同的公司也许会为了适应不同的场景提出不止一种的DDS实现方式。比如RTI为了不同的目标就有很多种他们的Connext的变种。
DDS基于Domain ID在一个物理网络内切分为若干逻辑网络。在同一域(domain)中的ROS 2节点可以被自由发现并通信,在不同域中则不能互通。所有的ROS 2节点默认使用domain ID 0。为避免消息混淆,同网络内运行ROS 2的不同组的设备应该使用不同的domain ID。ROS_DOMAIN_ID有两种(short version / long version)。正常使用推荐short version,在[0, 101]之间进行选择即可。long version则可以在[0, 232]之间进行选择。
每个ROS节点在DDS中被称为参与者(participant)。对于在计算机上运行的每个ROS 2进程,都会创建一个DDS“参与者”。由于每个DDS参与者会占用计算机上的两个端口,因此在一台计算机上运行120多个ROS 2进程就可能会溢出到其他域ID或临时端口。
所以我们我们需要控制节点的数目或者通过一个进程控制多个节点的方法来避免溢出。
设置domain id就是在两台虚拟机中分别执行下面的指令(最好写到bashrc当中,当然不固定除外)
echo "export ROS_DOMAIN_ID=1">> ~/.bashrc
#export ROS_DOMAIN_ID=1
2. 中间件RMW
为了能够在ROS2中使用一个DDS实现,需要一个ROS中间件(RMW软件包),这个包需要利用DDS程序提供的API和工具实现ROS中间件的接口。为了在ROS2中使用一个DDS实现,有大量的工作需要做。但是为了防止ROS2的代码过于绑定某种DDS程序必须支持至少几种DDS程序。
C++和Python节点都支持环境变量 RMW_IMPLEMENTATION,该变量允许用户在运行ROS 2应用程序时选择要使用的RMW实现。
下面是常用的ROS2的RMW中间件。
我们也针对性的展示了换不同的RMW的操作
编译
- FastDDS:默认已经编译好了
- cycloneDDS: 默认已经编译好了
- RTI connext
sudo apt install rti-connext-dds-5.3.1
#执行colcon build 前做
export RTI_LICENSE_FILE=/opt/rti.com/rti_connext_dds-5.3.1/rti_license.dat
source /opt/rti.com/rti_connext_dds-5.3.1/setenv_ros2rti.bash
执行
- FastDDS:默认使用
- cycloneDDS
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
#然后执行ros2 run 等命令
#或者
RMW_IMPLEMENTATION=rmw_cyclonedds_cpp ros2 run ...
- RTI connext
export RTI_LICENSE_FILE=/opt/rti.com/rti_connext_dds-5.3.1/rti_license.dat
source /opt/rti.com/rti_connext_dds-5.3.1/setenv_ros2rti.bash
export RMW_IMPLEMENTATION=rmw_connext_cpp
#然后执行ros2 run 等命令
#或者
RMW_IMPLEMENTATION=rmw_connext_cpp ros2 run ...
3. 安全加密SROS
加密安全这部分正好作者zhangrelay的文章中提到了,也没有过多的介绍,而我们如何对我们的通讯进行加密,这一块在ROS中都有所体现,正好这次是DDS通讯漫谈,也把这一块拿出来一起讨论,网络消息安全性对多机器人系统非常重要。
从源代码编译时候,需要为fastrpts 打开 security 的支持
colcon build --symlink-install --cmake-args -DSECURITY=ON
创建 key store
ros2 security create_keystore demo_keys
为talker 和 listener两个node 创建key 和 certificate
ros2 security create_key demo_keys /talker
ros2 security create_key demo_keys /listener
有可能你会遇到如下错误
lxml.etree.XMLSchemaParseError: attribute use (unknown), attribute 'ref': The QName value '{http://www.w3.org/XML/1998/namespace}base' does not resolve to a(n) attribute declaration., line 34
修正这个问题如下
修改sros2 的代码
cd ros2_ws/src/ros2/sros2/sros2/sros2/policy/schemas
wget http://www.w3.org/2001/03/xml.xsd # 下载 xml.xsd
vim policy.xsd
#修改如下
@@ -4,7 +4,7 @@
xmlns:xml="http://www.w3.org/XML/1998/namespace"
elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:import namespace="http://www.w3.org/XML/1998/namespace"
- schemaLocation="http://www.w3.org/2001/03/xml.xsd" />
+ schemaLocation="xml.xsd" />
…详情请参照古月居
- 点赞
- 收藏
- 关注作者
评论(0)