# ROS2基础教程 - 9 分布式通信

在 ROS2 中,节点是基本的计算单元,每个节点可以在独立的计算机上运行。通过 DDS 的自动发现功能,ROS2 的节点在启动时会自动找到同一网络中的其他节点。这样,你无需手动配置网络设置,只需确保所有节点在同一网络环境中,不需要做任何配置,即可实现跨主机的通信,使得分布式系统能够灵活地部署和扩展。

例如,你可以在一台计算机上运行传感器节点,实时收集数据;在另一台计算机上运行处理节点,接收传感器数据进行处理和分析。两者通过同一主题进行数据传输。通过分布式通信,可以分摊各个节点的计算压力。

在机器人编队场景中,机器人可能需要获取周边机器人的速度、位置、运行轨迹等相关信息。这些信息可以通过ROS2的分布式通信机制进行传输和共享。

# 9.1 分布式通信演示

例如,我有两台设备,这里我使用两台虚拟机演示,两台虚拟机都部署了 ROS2,网络配置需要使用桥接模式

两台设备的 IP 是:192.168.0.104 、192.168.0.105 。

在一台虚拟机中,打开终端,启动小海龟的窗口节点:

# 启动小海龟窗口节点
ros2 run turtlesim turtlesim_node
1
2

在另一台虚拟机中,打开终端,启动小海龟的控制节点:

# 启动小海龟控制节点
ros2 run turtlesim turtle_teleop_key
1
2

直接操作控制节点,发现可以直接控制小海龟窗口中的小海龟运动。

两台主机没有做任何的配置,就可以实现通信。


同样,ROS2 还有一个自带的 demo 程序,就是话题通信的 demo,一个节点定时发布信息,一个节点订阅消息。

可以在两台主机上分别启动下面两个节点:

# 第一个主机启动发布节点
ros2 run demo_nodes_py talker

# 第二个主机启动订阅节点
ros2 run demo_nodes_py listener
1
2
3
4
5

可以发现两个节点就可以实现通信了,在实际的开发中,我们自己开发的节点也可以部署到不同的设备上,只要这些设备处于同一个网络即可。

# 9.2 DDS域

DDS域是一个逻辑上的分组,它将各个节点绑定在一起进行通信。只有处于同一个DDS域中的节点才能互相通信,不同DDS域中的节点则无法直接通信。这种机制有助于避免无用数据占用资源,同时提高了系统的安全性和可管理性。

例如:如果一个网络中,可能有很多的设备,有很多的节点,我们又不希望每个设备中的节点都实现通信,那么我们可以将设备进行分组。

配置方法也很简单,只需要在环境变量中配置 ROS_DOMAIN_ID 即可,ROS_DOMAIN_ID 相同的主机才能实现通信,默认不配置的情况下,ROS_DOMAIN_ID 的值是0,所以都能实现通信。

编辑 ~/.bashrc 文件,添加如下配置:

# 编辑~/.bashrc文件
vim ~/.bashrc

# 添加如下配置
export ROS_DOMAIN_ID=1
1
2
3
4
5

ROS_DOMAIN_ID 的值自己定义,值可以设置为 0 到 232,在同一域 ID 中才能相互通信。如果节点在不同的域 ID 中,它们将无法互相发现和通信。

了解一下:

  • 端口占用:根据DDS协议规定,以7400作为起始端口,每个域默认占用250个端口。因此,在局域网内,域的数量最多为(65535-7400)/250=232个(端口号最大为65535,是一个16位的无符号整数)。
  • 节点端口:每个ROS2节点需要占用两个端口,一个是用于组播的Discovery Multicast端口,另一个是用于单播的User Unicast端口。在DDS协议中,每个域ID的端口段内,第1、2个端口是域内组播端口,从第11、12个端口开始是域内第一个节点的单播端口,后续节点的单播端口依次顺延。
  • 节点数量限制:由于每个域ID默认占用250个端口,且每个ROS2节点需要占用两个端口,因此一个域ID中的最大节点个数为(250-10)/2=120个(需要减去组播端口和预留的端口)。特殊情况下,如果域ID值为101,其后半段端口属于操作系统的预留端口,因此该域的节点总数需要小于等于54个。