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

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 ↩︎

<think>好的,用户想了解ROS2中的DOMAIN ID的用途和配置方法。我需要先回忆相关知识,然后结合提供的引用内容来组织回答。 首先,DOMAIN IDROS2中的作用是隔离不同网络环境下的通信。比如同一个局域网内的多个机器人,设置不同的DOMAIN ID可以让它们互不干扰。默认的DOMAIN ID是0,如果用户不设置的话,所有节点都会在同一个域里通信。 接下来,配置方法应该是通过环境变量来设置。用户需要设置ROS_DOMAIN_ID为一个0到232之间的整数。比如在终端里输入export ROS_DOMAIN_ID=42,这样之后启动的节点就会使用这个ID。不过要注意,不同组的机器人必须设置不同的ID才能隔离通信。 然后,查看当前DOMAIN ID的方法,可以用printenv命令或者echo $ROS_DOMAIN_ID。这样用户就能确认是否设置正确了。 另外,用户可能关心如何持久化配置,比如把环境变量写入.bashrc或者.profile文件,这样每次启动终端都会自动设置。这部分需要提到,但根据提供的引用,可能没有直接相关的内容,但可以结合一般Linux环境变量的配置方法来解释。 关于引用内容,用户提供的引用1提到了设置ROS_MASTER_URI和ROBOT=sim,这可能与ROS1的配置有关,但ROS2DOMAIN ID是类似的概念,用于隔离不同的通信域。引用2和3涉及ROS节点的初始化和安装插件,可能与通信配置相关,但可能不直接关联DOMAIN ID的设置。不过可以指出,正确设置DOMAIN ID是确保节点间通信的基础,类似ROS1中正确配置ROS_MASTER_URI的重要性[^1]。 用户可能还会遇到常见问题,比如设置了DOMAIN ID但节点无法通信,这时候需要检查ID是否一致,或者是否有防火墙阻挡了DDS的端口。通常DDS会使用UDP端口,范围根据DOMAIN ID计算,比如DOMAIN ID为n,端口号可能是7400+n*250到7400+n*250+249,所以需要确保这些端口开放。 最后,生成相关问题时要围绕DOMAIN ID的应用场景、如何验证是否生效、与ROS1的区别、网络要求以及调试工具等方面展开。</think>### ROS2 DOMAIN ID的用途及配置方法 #### 1. ROS2 DOMAIN ID的核心作用 ROS2的$DOMAIN\_ID$用于**隔离不同网络环境下的通信域**。当多个设备或开发者在同一物理网络中运行ROS2节点时,通过设置不同的$DOMAIN\_ID$,可以实现: - 逻辑隔离:相同$DOMAIN\_ID$的节点自动发现彼此 - 避免干扰:不同$DOMAIN\_ID$的节点互不可见 - 多环境并行:支持同时运行多个独立ROS系统(例如开发/测试/生产环境) 默认值为$DOMAIN\_ID=0$,取值范围为$0 \leq DOMAIN\_ID \leq 232$(由DDS协议限制)。 #### 2. 配置方法 ##### 2.1 临时设置(终端会话级) ```bash export ROS_DOMAIN_ID=<自定义数字> # 例如设置为42 ros2 run <包名> <节点名> ``` ##### 2.2 永久设置(用户级) 在`~/.bashrc`或`~/.zshrc`中添加: ```bash echo "export ROS_DOMAIN_ID=42" >> ~/.bashrc source ~/.bashrc ``` ##### 2.3 验证设置 ```bash echo $ROS_DOMAIN_ID # 显示当前值 printenv | grep ROS # 查看所有ROS环境变量 ``` #### 3. 网络端口映射 DOMAIN ID直接影响DDS使用的UDP端口范围: $$Port_{base} = 7400 + 250 \times DOMAIN\_ID$$ $$Port_{range} = [Port_{base}, Port_{base}+249]$$ 需确保防火墙开放对应端口范围[^2]。 #### 4. 典型应用场景 - **多机器人系统**:每个机器人设置不同ID - **开发测试隔离**:开发环境用ID=1,测试环境用ID=2 - **教学实验**:学生使用不同ID避免数据干扰 - **多版本并行**:同时运行不同版本ROS2节点 #### 5. 常见问题排查 - **节点无法发现**:检查所有设备的$DOMAIN\_ID$一致性 - **端口冲突**:使用`netstat -ulnp`查看端口占用 - **环境变量继承**:通过`systemd`启动服务时需显式设置环境变量 ```bash # 检查DDS发现包 export RMW_IMPLEMENTATION=rmw_fastrtps_cpp ros2 run demo_nodes_cpp talker --ros-args --log-level debug ``` #### 6.ROS1的区别对比 | 特性 | ROS1 | ROS2(使用DOMAIN ID) | |--------------|-------------------------|-----------------------------| | 发现机制 | 依赖ROS_MASTER_URI | 基于DDS的多播发现 | | 网络隔离 | 需不同MASTER_URI | 通过DOMAIN ID自动隔离 | | 配置复杂度 | 需配置多个环境变量 | 单变量控制 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值