ROS2学习(五).ROS概念 - ROS_DOMAIN_ID

毛景曜
2023-12-01

ROS2 默认使用的通信中间件是DDS。
DDS基于Domain ID在一个物理网络内切分为若干逻辑网络。
在同一域(domain)中的ROS 2节点可以被自由发现并通信,在不同域中则不能互通。
所有的ROS 2节点默认使用domain ID 0。
为避免消息混淆,同网络内运行ROS 2的不同组的设备应该使用不同的domain ID1

domain ID的选择

ROS_DOMAIN_ID有两种(short version / long version)。
正常使用推荐short version,在[0, 101]之间进行选择即可。
long version则可以在[0, 232]之间进行选择。

Domain Participant

每个ROS节点在DDS中被称为参与者(participant)。默认情况下,每个Domain Participant需要打开四个UDP/IP端口:其中两个端口是组播端口,在同一个DomainId的所有Domain Participant之间共享;另外两个是单播端口,对于计算机中的每个参与者都不相同。
根据DDS-RTPS规范,用于发现的组播的IP地址默认为239.255.0.1。

端口号的计算2

在DDS中,端口号由DDS的domain ID以及通信域中的参与者数量决定。包括:
Multicast Ports (通常用于基于同一domainID的所有应用的广播通信):

DiscoveryMulticastPort = PB + DG * domainId + d0
UserMulticastPort = PB + DG * domainId + d2

Unicast Ports (对每个参与者不同,用于点对点通信):

DiscoveryUnicastPort = PB + DG * domainId + d1 + PG * participantId
UserUnicastPort = PB + DG * domainId + d3 + PG * participantId

上述公式依赖于两个变量 domainId和participantId

domainId      	DDS的Domain ID
participantId  	从0开始的的参与者的编码,在一个操作系统(虚拟机或者实际的计算机)内进行排序给出;
				第一个参与者为0,第二个为1,以此类推。

公式还涉及到一些常量,遵循OMG的DDS-RTPS标准,常量如下:

d0 (builtin_multicast_port_offset) = 0
d2 (user_multicast_port_offset) = 1
d1 (builtin_unicast_port_offset) = 10
d3 (user_unicast_port_offset) = 11
PB (port_base) = 7400
DG ( domain_id_gain) = 250
PG (participant_id_gain) = 2

注意:
按照上述公式,我们可以算出当participant Id到达120时,两个UnicastPort会与下一个domain ID的MulticastPort重叠,我们在使用时要注意ID的重叠情况。
如果您不能确定局域网内的domainId的情况,请不要在一个Domain中使用超过120个[0, 119]的节点。

例一

在domainId=0下进行运行,如果我们的计算机中有两个参与者,则使用的端口如下:
所有节点共用

DiscoveryMulticastPort = 7400
UserMulticastPort = 7401

第一个ROS节点

DiscoveryUnicastPort = 7410
UserUnicastPort = 7411

第二个ROS节点

DiscoveryUnicastPort = 7412
UserUnicastPort = 7413

例二

如果我们在domainId=0上进行通信,那么UDP端口范围[7400, 7649]将可以映射到各参与者使用。
其中7400是participantId=0使用的最低端口,7649是participantId=119使用的最高端口。
如果我们再domainId=10上通信,那么相应的UDP端口范围则为[9900, 10149]。

平台限制

基于上述,为了使DDS在不同系统中获得兼容性,选择域ID时应遵循附加于平台的一些约束。特别要注意避免在操作系统的临时端口范围分配domain Id,从而避免ROS 2节点使用的端口与计算机上其他网络服务冲突。

Linux

默认情况下,Linux内核使用端口32768-60999作为临时端口。
这意味我们可以安全地使用的domain id范围是[0-101]和[215-232]。
当然,如果有需要,在Linux中,可以通过在/proc/sys/net/ipv4/ip_local_port_range中调整临时端口范围。

macOS

默认情况下,macOS上的临时端口范围为49152 ~ 65535。
这意味着可以安全地使用的domain id的范围是[0-166]。
通过设置net.inet.ip.portrange.first和net.inet.ip.portrange.last的自定义sysctl值,可以在macOS中配置临时端口范围。

Windows

Windows系统默认的临时端口范围与macOS一致,为49152 ~ 65535。
这意味着可以安全地使用的domain id的范围是[0-166]。
临时端口范围可以在Windows中使用netsh进行配置。 如果使用自定义临时端口范围,则可能需要相应地调整上述数字。

基于上述限制,若我们要构建跨平台的ROS网络,则可选择的domain ID范围应该是[0, 101]。

参与者限制

对计算机上运行的每个ROS 2节点,将创建一个DDS participant。

domain端口重叠

由于每个DDS参与者都使用了计算机上的两个端口,因此在一台计算机上运行超过120个ROS 2进程可能会溢出到其他域id所对应的端口,或系统临时端口。

例如,我们考虑domain ID 1和2:

  • Domain ID 1使用端口7650和7651作为组播使用;
  • Domain ID 2使用端口7900和7901作为组播使用;
  • domain ID 1的0号参与者,使用端口7660和7661作为单播使用;
  • domain ID 1的119号参与者,使用端口7898和7899作为单播使用;
  • domain ID 1的120号参与者,使用端口7900和7901作为单播使用;这两个端口同domain ID 2组播使用的端口冲突了。

当然,若我们在计算机上一次仅使用一个domain ID,且这个domain ID取的是一个较小的值,那么我们就可以使用超过120个的ROS2节点。

平台预留端口重叠

当我们选择了一个接近平台限制上限的domain ID,那么我们需要考虑一些额外的限制。

例如,我们考虑在Linux平台上使用domain ID 101

  • 0号ROS 2参与者将会使用端口32650, 32651, 32660和32661;
  • 1号ROS 2参与者将会使用端口32650, 32651, 32662和32663;
  • 53号ROS 2参与者将会使用端口32650, 32651, 32766和32767;
  • 54号ROS 2参与者将会使用端口32650, 32651, 32768和32769;此时,这里用到的端口就同平台的预留端口冲突了。

因此,在Linux上,当我们使用domain ID 101时,最多只能使用54个ROS2 节点。
在macOS和Windows上也是同样的情况,仅仅是数字可能不同。当我们选择domain ID 166时,ROS 2的最大进程数不要超过120,以免同预留端口冲突。

参考


  1. The ROS_DOMAIN_ID ↩︎

  2. Ports used by DDS Discovery ↩︎

 类似资料: