关于 Domain ID
如其他文档所述,ROS 2 用于通信的默认中间件是 DDS。在 DDS 中,使不同逻辑网络能够共享同一物理网络的主要机制是 Domain ID(域 ID)。同一域中的 ROS 2 节点可以自由地相互发现并发送消息,而不同域中的 ROS 2 节点则不能。所有 ROS 2 节点默认使用 Domain ID 0。为了避免在同一网络上运行的多组 ROS 2 计算机之间产生干扰,应为每组设置不同的 Domain ID。
选择 Domain ID(简短版本)
Section titled “选择 Domain ID(简短版本)”下文详细解释了 ROS 2 中可用 Domain ID 范围的推导过程。如果只想跳过背景知识、直接选择一个安全的数值,只需选择 0 到 101 之间(含边界)的 Domain ID 即可。
选择 Domain ID
Section titled “选择 Domain ID”DDS 使用 Domain ID 来计算用于发现和通信的 UDP 端口。有关端口计算方式的详细信息,请参阅 这篇文章。回顾一下网络基础知识:UDP 端口是一个 无符号 16 位整数。因此,可分配的最高端口号为 65535。根据上述文章中的公式进行计算,这意味着可分配的最高 Domain ID 为 232,最低为 0。
平台特定约束
Section titled “平台特定约束”为了最大限度地保证兼容性,在选择 Domain ID 时还应遵循一些平台特定的约束。特别是,应尽量避免在操作系统的 ephemeral port range(临时端口范围)内分配 Domain ID,以免 ROS 2 节点使用的端口与计算机上的其他网络服务发生冲突。
以下是各平台临时端口范围的说明。
默认情况下,Linux 内核使用端口 32768-60999 作为临时端口。这意味着 Domain ID 0-101 和 215-230 可以安全使用,不会与临时端口冲突。在 Linux 中,可以通过在 /proc/sys/net/ipv4/ip_local_port_range 中设置自定义值来配置临时端口范围。如果使用了自定义的临时端口范围,上述数值可能需要相应调整。
默认情况下,macOS 上的临时端口范围为 49152-65535。这意味着 Domain ID 0-166 可以安全使用,不会与临时端口冲突。在 macOS 中,可以通过设置 net.inet.ip.portrange.first 和 net.inet.ip.portrange.last 的自定义 sysctl 值来配置临时端口范围。如果使用了自定义的临时端口范围,上述数值可能需要相应调整。
Windows
Section titled “Windows”默认情况下,Windows 上的临时端口范围为 49152-65535。这意味着 Domain ID 0-166 可以安全使用,不会与临时端口冲突。在 Windows 中,可以 使用 netsh 来配置临时端口范围。如果使用了自定义的临时端口范围,上述数值可能需要相应调整。
Participant 约束
Section titled “Participant 约束”计算机上运行的每个 ROS 2 进程都会创建一个 DDS “participant”(参与者)。由于每个 DDS participant 会占用计算机上的两个端口,因此在一台计算机上运行超过 120 个 ROS 2 进程时,端口可能会溢出到其他 domain ID 或临时端口范围。
以 Domain ID 1 和 2 为例来说明原因:
- Domain ID 1 使用端口 7650 和 7651 进行 multicast。
- Domain ID 2 使用端口 7900 和 7901 进行 multicast。
- 在 Domain ID 1 中创建第 1 个进程(第 0 个 participant)时,使用端口 7660 和 7661 进行 unicast。
- 在 Domain ID 1 中创建第 120 个进程(第 119 个 participant)时,使用端口 7898 和 7899 进行 unicast。
- 在 Domain ID 1 中创建第 121 个进程(第 120 个 participant)时,使用端口 7900 和 7901 进行 unicast,与 Domain ID 2 重叠。
如果确定某台计算机同一时间只运行在一个 Domain ID 下,并且该 Domain ID 足够低,那么创建超过上述数量的 ROS 2 进程也是安全的。
当选择的 Domain ID 接近平台特定 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 个进程。类似地,在 Linux 上使用 Domain ID 230 时,最多应创建 63 个进程,因为最大端口号为 65535。
macOS 和 Windows 上的情况类似,但数值不同。在 macOS 和 Windows 上,当选择 Domain ID 为 166(范围上限)时,一台计算机上最多可以创建 120 个 ROS 2 进程,超过此数量就会进入临时端口范围。
Domain ID 到 UDP 端口计算器
Section titled “Domain ID 到 UDP 端口计算器”说明:原文提供了一个交互式计算器,用于根据 Domain ID 和 Participant ID 计算 Discovery Multicast Port、User Multicast Port、Discovery Unicast Port 和 User Unicast Port。由于静态 Markdown 无法运行 JavaScript,此处无法展示该交互式计算器。如需使用,请访问 ROS 2 官方文档 原页面。
计算公式如下(其中 PB = 7400,DG = 250,PG = 2):
- Discovery Multicast Port =
PB + (DG * domainID) + 0 - User Multicast Port =
PB + (DG * domainID) + 1 - Discovery Unicast Port =
PB + (DG * domainID) + 10 + (PG * participantID) - User Unicast Port =
PB + (DG * domainID) + 11 + (PG * participantID)