概述
如前所述,ROS2用于通信的默认中间件是DDS。在DDS中,让不同的逻辑网络共享一个物理网络的主要机制被称为域ID(Domain ID)。同一域中的ROS2节点之间可以自由相互发现并发送消息,而不同域的ROS2节点则不能。默认情况下,所有的ROS2节点的域ID都为0。为了避免同一网络上运行的不同ROS2计算机组之间的干扰,应该为每组计算机设置不同的域ID。
快速选择域ID
下文解释了ROS2中域ID范围的推导。如果要直接跳过背景知识选择一个安全的数字,只需要选择一个介于0和101之间的域ID,这其中包括0和101。
域ID选择的详细说明
DDS使用域ID来计算用于发现和通信的UDP端口。有关如何计算端口的详细介绍,请参阅这篇文章(community.rti.com/content/for… 请记住这一点,我们基本网络的UDP端口是一个无符号16位整数。因此,可以分配的最大端口号是65535。当我们用上面文章中的公式做一些数学计算,就可以知道分配的最高域ID是232,而可以分配的最低域ID是0。
特定平台的约束
为了获得最大的兼容性,选择域ID时,应该遵循一些额外的特定于平台的约束。而且,最好避免在操作系统的临时端口范围内分配域ID。这避免了ROS2节点使用的端口与计算机上的其他网络服务之间发生冲突。
以下是一些平台特定的临时端口的说明
- Linux
默认情况下,Linux内核默认使用3276860999作为临时端口。这就是说我们可以安全地使用0101和215~232作为域ID,而不会与临时端口发生冲突。在Linux系统中,临时端口范围可以在/proc/sys/net/ipv4/ip_local_port_range中设置自定义值进行配置。如果使用自定义临时端口范围,则可能需要相应地调整上述数字。
- MacOS
默认情况下,macOS的临时端口范围为4915265535。这意味着可以安全地使用0166域ID,而不会与临时端口发生冲突。临时端口范围可以在MacOS中通过设置net.inet.ip.portrange.first和net.inet.ip.portrange.last中的sysctl值来配置。如果使用自定义临时端口范围,则可能需要相应地调整上述数字。
- Windows
默认情况下,Windows操作系统的临时端口范围为4915265535。这意味着可以安全地使用0166域ID,而不会与临时端口发生冲突。临时端口范围可以在Windows中使用netsh进行配置。如果使用自定义临时端口范围,则可能需要相应地调整上述数字。
参与者约束
计算机上运行的每个ROS2进程,都会创建一个DDS“参与者”。由于每个DDS参与者占用计算机上的两个端口,因此在同一台计算机上运行超过120个ROS2进程可能会溢出到其他域ID或临时端口。
下面来看一下原因,请考虑域ID取值为1和2的情况:
- 域ID为1的节点使用7650和7651端口进行组播。
- 域ID为2的节点使用7900和7901端口进行组播。
- 当域ID为1的节点创建第1个进程(第0个参与者)时,使用端口7660和7661进行单播。
- 当域ID为1的节点创建第120个进程(第119个参与者)时,使用端口7898和7899用于单播。
- 当域ID为1的节点创建第121个进程(120个参与者)时,使用端口7900和7901端口用于单播,这时就与域ID为2的节点重叠了。
如果我们知道计算机一次只使用一个域ID,并且域ID足够低,则创建比这更多的ROS2进程是安全的。
但是,当选择接近平台特定域ID范围顶部的域ID时,则应该考虑一个额外的约束。
例如,假设一台Linux计算机的域ID为101:
- 计算机上的第0个ROS2进程将连接到端口32650、32651、32660和32661。
- 计算机上的第1个ROS2进程将连接到端口32650、32651、32662和32663。
- 计算机上的第53个ROS2进程将连接到端口32650、32651、32766和32767。
- 计算机上的第54个ROS2进程将连接到端口32650、32651、32768和32769,这时就溢出到了临时端口范围。
因此,在Linux中如果选择101的作为域ID,那么允许创建的最大进程数是54。类似地,在Linux上使用域ID值为232时,因为最大端口号是65535,允许创建的最大进程数是63。
MacOS和Windows的情况类似,只是数字不同。在MacOS和Windows上,当选择166(范围的顶部)的域ID时,在溢出到临时端口范围之前,可以在计算机上创建的ROS2进程的最大数量是120。
关注【智践行】公众号,我们一起成长