目录
一、DDS的域(Domain)ID
1.1 域内最大进程数目
DDS基于Domain ID将一个物理网络切分为若干逻辑网络。在同一域(domain)中的ROS 2节点可以被自由发现并通信,在不同域中则不能互通。
所有的ROS 2节点默认使用域ID 0,如果要修改ROS2中节点运行所在的域,可以在~/.bashrc
中添加指令:export ROS_DOMAIN_ID=1
计算机上运行的每个ROS 2进程,将创建一个DDS participant,每个DDS域内会分配两个固定端口用于多播,分别是发送和接收端口,剩余端口分配给各个participant用于单播。
每个participant的单播会占用计算机上的两个端口,分别是发送和接收端口,因此在一台计算机上运行120个以上的ROS 2进程可能会溢出到其他域ID或临时端口。
为了解释原因,考虑域ID编号1和2。
域ID 1使用端口7650和7651进行多播。
域ID 2使用端口7900和7901进行多播。
在域ID 1中创建第一个进程 (第0个参与者) 时,端口7660和7661用于单播。
在域ID 1中创建第120个进程 (第119个参与者) 时,端口7898和7899用于单播。
在域ID 1中创建第121个进程 (第120个参与者) 时,端口7900和7901用于单播,则与域ID 2的多播地址冲突。
因此,一个域内的运行的ROS 2节点的进程数目最大为120。
注意:一个进程可以运行多个ROS2节点。
1.2 域的范围
由于网络中TCP/UDP端口是无符号16位整型,可以分配的最大端口号是65535,因此域ID是有范围大小的。
为了实现Windows、Linux和MacOS最大的兼容性,在选择Domain ID时应遵循一些特定于平台的附加约束,并且避免在操作系统的临时端口范围中分配域ID。
以下是一些关于特定平台临时端口的提示。
- Linux
默认情况下,Linux内核使用端口32768-60999作为临时端口。这意味着域ID 0-101 和 215-232 可以安全使用,而不会与临时端口发生冲突。临时端口范围可在Linux中通过在 /proc/sys/net/ipv4/ip_local_port_range 中设置自定义值进行配置。如果使用自定义临时端口范围,则可能需要相应地调整上述数字。
在选择特定平台域 ID 范围顶部的域 ID 时,还有一个限制因素需要考虑。例如,假设一台ID为101的Linux计算机,多播端口为32650、32651,计算机上的第0个ROS 2进程将连接到端口32660和32661。计算机上的第1个ROS 2进程将连接到32662和32663。计算机上的第53个ROS 2进程32766和32767。计算机上的第54个ROS 2进程将连接到端口32768和32769,则32768和32769运行在Linux临时端口范围内,易与系统发生冲突。
因此,在Linux上使用域ID为101时应创建的最大进程数为54。同样,在Linux上使用域ID为232时应创建的最大进程数为63,因为最大端口号为65535。
所以,如果一台计算机上只设置一个域ID时,这个域ID最好足够低,确保participant数目可以达到最大120!
- macOS
默认情况下,macOS上的临时端口范围为49152-65535。这意味着域ID 0-166可以安全使用,而不会与临时端口发生冲突。通过为 net.inet.ip.portrange.first 和 net.inet.ip.portrange.last 设置自定义sysctl值,临时端口范围可在macOS中配置。如果使用自定义临时端口范围,则可能需要相应地调整上述数字。
- Windows
默认情况下,Windows上的临时端口范围为49152-65535。这意味着域ID 0-166可以安全使用,不会与临时端口发生冲突。临时的端口范围可通过 使用netsh 在窗口中配置。如果使用自定义临时端口范围,则可能需要相应地调整上述数字。
一般而言,ROS_DOMAIN_ID有两种(short version / long version)。正常使用推荐short version,在[0, 101]之间进行选择,使用顺序从小到大;通过修改各个平台的自定义临时端口范围,long version则可以在[0, 232]之间进行选择。
1.3 总结
一台Linux机器上一般最多存在102个DDS域,每个域最多有120个运行ROS 2节点的进程!
二、多机通信DDS
ROS1多机通信配置较为繁琐,需要配置MASTER等参数,但是ROS2非常简单,只需要一行命令,即可实现。
ROS2的多机原理是利用DDS域实现,同一域内的ROS2节点之间可以自由发现和发送消息,而不同域内的ROS2节点之间则不能,只需要确保不同机器设备在同一网络内能相互ping通。
多机通信DDS参数设置:
永久设置域ID,在两台设备上的~/.bashrc
中都添加下面的指令,使ROS2节点处于同一个DDS通信域中:
export ROS_DOMAIN_ID=0
临时设置域ID,在两台设备上的终端上都执行下面指令,使ROS2节点处于同一个DDS通信域中:
export ROS_DOMAIN_ID=0
三、安全加密SROS2
在 ROS 2 中,术语“SROS 2”指的是 ROS 2 各个部分中用于实现与 DDS-Security 集成的一组功能和工具,ROS2是通过合理利用DDS-Security规范获得安全能力。
SROS2功能已经通过跨平台(Linux、macOS 和 Windows)以及不同语言(C++ 和 Python)的测试。SROS2 不支持DDS供应商之间的安全通信。
3.1 DDS-Security
DDS-Security规范在DDS规范的基础上进行了扩展,通过定义服务插件接口SPI(Service Plugin Interface)架构、一系列SPI内置实现以及由SPI强制执行的安全模型来添加增强型安全功能。具体来说,DDS-Security定义了以下五个SPI:
身份验证(Authentication):对给定域参与者的身份进行验证。
访问控制(Access control):对经过身份验证的域参与者能够执行的DDS相关操作强制实行各种限制。
加密(Cryptographic):对所有必需的加密、签名和散列操作进行处理。
日志记录(Logging):提供审计DDS-Security相关事件的能力。
数据标记(Data tagging):提供向数据样本添加标记的能力。
ROS 2的安全功能目前仅使用了前三个SPI。这是由于为符合DDS-Security规范,既不需要日志记录也不需要数据标记(参见该规范2.3节),因此并非所有DDS实现都支持后两个SPI。
下面来深入研究一下前三个插件。
3.1.1 身份验证
身份验证插件(参见DDS-Security规范8.3节)是整个SPI架构的核心,因为身份验证插件提供了经确认的身份这一概念,没有经确认的身份就不可能进一步执行其它安全操作(例如,如果无法安全地确定其具体身份,则很难确保某个给定的ROS身份只会访问某些特定话题)。
SPI架构允许有多种潜在的身份验证方案,但ROS 2使用的是内置身份验证插件(称为“DDS:Auth:PKI-DH”,请参阅DDS-Security规范9.3节),该插件使用经过验证的公钥基础设施PKI(Public Key Infrastructure)。该插件需要每个域参与者的一个公钥和一个私钥,以及将该参与者的公钥绑定到某个特定名称的x.509证书。每个x.509证书都必须由该插件配置为信任的某个特定证书颁发机构CA(Certificate Authority)签名(或者具有一个签名链)。
使用该内置插件的理由有两个:
这是DDS-Security规范中详细描述的唯一方法。
所有兼容的DDS实现都必须互操作地支持该内置插件(请参阅DDS-Security规范2.3节),这使得ROS 2的安全功能可以以最小工作量跨不同DDS供应商正常工作。
3.1.2 访问控制
这允许将细粒度的策略应用到经过身份验证的网络参与者。它允许只有批准的参与者才能被发现,并通过预先批准的网络接口进行通信。SROS2有用于生成这些配置的命令行工具。
访问控制插件(参见DDS-Security规范8.4节)处理某个给定域参与者DDS相关功能限制的定义和实施。例如,该插件可以允许用户将某个特定参与者限制在某个特定的DDS域中,或者只允许该参与者读取或写入某些特定的DDS话题,等等。
同样地,SPI架构允许在插件如何完成此任务方面具有一定的灵活性,但ROS 2使用的又是内置的访问控制插件(称为“DDS:Access:Permission”,参见DDS-Security规范9.4节),该插件也使用PKI。
该插件需要每个域参与者的下面这两个文件:
治理(Governance)文件:一个签名的XML文档,用于指定该域应如何保障安全。
权限(Permissions)文件:一个签名的、包含域参与者各项权限的XML文档,该文件会被绑定至身份验证插件定义的参与者名称(这是通过x.509证书完成的,正如前面所讨论的那样)。
这两个文件都必须由该插件配置为信任的证书颁发机构CA签名。该CA可能是身份验证插件信任的同一个CA,但这并不是必需的。
使用该内置插件的理由:
这是DDS-Security规范中详细描述的唯一方法。
所有兼容的DDS实现都必须互操作地支持该内置插件(请参阅DDS-Security规范2.3节),这使得ROS 2安全功能可以以最小的工作量跨不同供应商正常工作。
3.1.3 加密
加密插件(参见DDS-Security规范8.5节)是处理所有与加密相关操作的地方,包括:加密、解密、签名、散列等。
身份验证和访问控制插件都会利用加密插件的功能以便进行签名验证等,加密DDS话题通信的功能也位于加密插件中。
虽然SPI架构允许加密插件有多种可能性,但ROS 2使用的是内置的加密插件(称为“DDS:Crypto:AES-GCM-GMAC”,请参阅DDS-Security规范9.5节),该内置插件可以提供经过身份验证的、使用高级加密标准AES(Advanced Encryption Standard)Galois计数器模式GCM(Galois Counter Mode)即AES-GCM加密算法的加密。
使用该内置插件的理由:
这是规范中详细描述的唯一方法。
所有兼容的DDS实现都必须互操作地支持该内置插件(请参阅DDS-Security规范2.3节),这使得ROS 2安全功能可以以最小的工作量跨不同供应商正常工作。
3.2 DDS-Security与ROS 2的集成:SROS 2
ROS 2中用于启用DDS安全功能的特性和工具集统称为“安全(Secure) ROS 2”,简写即为SROS 2。,默认情况下,ROS 2中并没有启用DDS的任何安全功能。
ROS 2中使用ROS2客户端库(RCL)和 命令行接口(CLI)支持安全功能。
3.2.1 ROS2客户端库RCL中的安全功能
面向用户层的SROS 2功能接口大部分已经包含在ROS客户端库中,通过ROS客户端库(RCL)即可为受支持的DDS实现Security配置。
RCL中包括以下三个 SROS 2功能:
(1) 对每个域参与者安全文件的支持
(2) 同时对宽松和严格的安全措施进行支持
(3) 对用于所有SROS 2功能的一个主“开/关”开关功能的支持
下面来依次讨论这三个安全功能。
(1)对每个域参与者安全文件的支持
如前所述,DDS-Security插件需要每个域参与者的一系列安全文件(如密钥、治理文件和权限文件等)。域参与者会映射到ROS 2的进程内环境(context)中,因此每个进程都需要一组这些文件。
RCL支持以两种不同的方式指向包含安全文件的目录:
- 1) 所有安全文件的目录树
- 2) 手动指定
1)所有安全文件的目录树
RCL支持在预留的enclaves子文件夹内的某个目录中查找安全文件,在根密钥库内,该目录对应于每个安全飞地(enclave)的完全合格路径。例如, /front/camera飞地的目录结构如下图所示:
每个飞地实例目录中预期的文件集为:
identity_ca.cert.pem:身份验证插件信任的CA(“身份”CA)的x.509证书。
cert.pem:本飞地实例的x.509证书(由身份CA签名)。
key.pem:本飞地实例的私钥。
permission_ca.cert.pem:访问控制插件信任的CA(“权限”CA) 的x.509证书。
government.p7s:用于向访问控制插件指定应如何保护域安全的XML文档(由权限CA签名),即治理文件。
permission.p7s:用于向访问控制插件指定本特定飞地实例权限的XML 文档(也由权限 CA 签名),即权限文件。
这可以通过将ROS_SECURITY_KEYSTORE环境变量设置为指向密钥库目录树的根目录路径来完成,然后使用--ros-args运行时参数-e或者--enclave来指定该飞地的路径,例如:
export ROS_SECURITY_KEYSTORE="/home/bob/.ros/sros2_keystore"
ros2 run <package> <executable> --ros-args --enclave="/front/camera"
2)手动指定
RCL还支持为需要使用覆盖环境变量启动的进程指定飞地路径。这可以通过将ROS_SECURITY_ENCLAVE_OVERRIDE环境变量设置为密钥库中的备用飞地路径来完成。请注意,这种设置方式的优先权要高于使用--enclave参数的ROS_SECURITY_KEYSTORE环境变量设置方式。
请注意,下面这两个示例加载的飞地路径与前面演示中的飞地路径相同(笔者注:第二个示例中虽然使用--enclave参数指定了不同的飞地实例/spam,但由于ROS_SECURITY_ENCLAVE_OVERRIDE环境变量会覆盖该参数,因此加载的还是/front/camera飞地实例):
export ROS_SECURITY_KEYSTORE="/home/bob/.ros/sros2_keystore"
export ROS_SECURITY_ENCLAVE_OVERRIDE="/front/camera"
ros2 run <package> <executable>
export ROS_SECURITY_KEYSTORE="/home/bob/.ros/sros2_keystore"
export ROS_SECURITY_ENCLAVE_OVERRIDE="/front/camera"
ros2 run <package> <executable> --ros-args --enclave="/spam"
(2)同时对宽松和严格的安全措施进行支持
启用了安全功能的参与者将不会与未启用安全功能的参与者进行通信,但是如果有人尝试启动一个带有密钥/权限/等文件的不可识别飞地的参与者,RCL应该怎么办?RCL可以有以下两个选择:
宽容模式(Permissive mode):会尝试查找各个安全文件,如果找不到这些安全文件,则会在不启用任何安全功能的情况下启动该参与者。这是RCL的默认行为。
严格模式(Strict mode):会尝试查找各个安全文件,如果找不到这些安全文件,则无法运行该参与者。
指定期望模式的方法为:通过将ROS_SECURITY_STRATEGY环境变量设置为“Enforce”(区分大小写)来指定严格模式,而将该环境变量设置为任何其他值来指定宽容模式。
(3)对用于所有SROS 2功能的一个主“开/关”开关功能的支持
除了前面刚讨论的两项受支持的功能之外,RCL还支持安全功能的主关闭以便于实验。如果关闭(默认选项),则不会启用上述任何安全功能。
为了启用SROS 2,请将ROS_SECURITY_ENABLE环境变量设置为“true”(区分大小写)。若要禁用SROS 2,则请将该环境变量设置为任何其他值。
3.2.2 ROS2命令行接口CLI中的安全功能
在RCL中对ROS 2系统进行安全配置涉及到许多新技术(如PKI、DDS治理文件和权限文件以及它们的语法等)。如果用户熟悉这些技术,则上述信息应该是正确配置SROS 2所必需的全部信息。
SROS 2命令行界面(CLI )包含一个工具ros2 security来帮助那些不想完全由自己来设置ROS 2安全功能的人,该工具应包括以下几项功能:
创建身份CA和权限CA
创建包含所有安全文件的目录树
为某个给定的安全飞地创建一个新身份,生成密钥对并使用身份CA签署其x.509证书
创建一个默认情况下会加密所有DDS数据流的治理文件
支持以熟悉的ROS术语指定飞地权限,然后自动将该飞地权限转换为底层DDS权限
支持从正在运行的ROS系统中自动发现所需的各项权限
3.2.3 测试SROS2
SORS2加密依赖SSL,需要安装最新版本的 openssl。
sudo apt update
sudo apt install libssl-dev
Fast DDS 需要一个额外的 CMake 标志来构建安全插件,因此需要修改 colcon 调用以通过:
colcon build --symlink-install --cmake-args -DSECURITY=ON
(1) 为安全文件创建一个文件夹
mkdir ~/sros2_demo
(2) 生成密钥库
cd ~/sros2_demo
ros2 security create_keystore demo_keystore
(3) 生成密钥和证书
ros2 security create_enclave demo_keystore /talker_listener/talker
ros2 security create_enclave demo_keystore /talker_listener/listener
(4) 配置环境变量
export ROS_SECURITY_KEYSTORE=~/sros2_demo/demo_keystore
export ROS_SECURITY_ENABLE=true
export ROS_SECURITY_STRATEGY=Enforce
(5) 运行talker/listener
演示
通过启动talker 节点开始演示。
ros2 run demo_nodes_cpp talker --ros-args --enclave /talker_listener/talker
在另一个终端中,执行相同操作以启动listener节点。此终端中的环境变量必须按照上述步骤 4 中的说明正确设置。
ros2 run demo_nodes_py listener --ros-args --enclave /talker_listener/listener
这些节点将使用身份验证和加密进行通信!
如果查看数据包内容(如使用tcpdump或Wireshark),可以看到消息已加密。
四、ROS2中的QoS策略
4.1 Qos策略
ROS2中引⼊了Quality of Service,QoS(服务质量)的策略⽤于配置节点间通信,进⽽提升了ROS2适应于不同应⽤场景的灵活性。
ROS 2提供了丰富的服务质量(QoS)策略,允许我们对节点之间的通信进行调优。在QoS的不同策略下,ROS 2可以像TCP一样可靠,或者像UDP一样提供尽力服务,当然也可以调整为两者之间任意可能的服务质量状态。
ROS2提供的八种QoS 策略种类如下:
QoS 策略含义:
- 历史History
保留最后Keep last:只存储N个数据,可通过队列深度选项变更相关配置。
保留所有Keep all:存储所有数据,根据底层中间件的配置进行资源限制。 - 深度Depth
队列深度Queue size:仅当“历史”策略为“保持最后”时生效。 - 可靠性Reliability
- 尽力服务Best effort:尝试发送数据,但若网络不够健壮,则可能会丢失。
- 可靠Reliable:通过多次重试保证数据送达。
- 耐用性Durability
- 暂存本地Transient local:发布者将负责对数据进行持久化,以便“迟加入”的订阅者可获取数据。
- 挥发性Volatile:不尝试保存数据。
- 截止时间Deadline
- 持续时间Duration:将连续消息发布到主题时的预期最大时间。
- 寿命Lifespan
- 持续时间Duration:在发布和接收消息之间的最长时间,在此时间内,消息不会被认为是过期的(过期的消息会被安静地丢弃,永远不会再被接收到)。
- 活跃程度Liveliness
- 自动Automatic:若任意节点发布了一条消息,系统将认为所有节点在接下来的租赁周期(Lease Duration)中都是活跃的。
- 按主题手动Manual by topic:若任意节点发布了一条消息,系统仅将认为该节点在接下来的租赁周期(Lease Duration)中是活跃的(通过调用发布的API)。
- 租赁周期Lease Duration
- 持续时间Duration:系统认为发布者失活的最大周期时间(失活将会导致失败)。
ROS2的 History和Depth结合起来类似于ROS的队列大小功能。
ROS2的Reliability取Best-effort类似于Ros1的UDPROS(仅 roscpp包含此功能),取 Reliable类似于ROS1的TCPROS。
ROS2的Durability和队列深度为1的 Depth结合起来类似于ROS 1中的latching订阅器。
4.2 Qos配置文件
一组 QoS 策略组合起来形成一个 QoS 配置文件,ROS2读取Qos配置文件,并根据其中参数配置Qos策略。
配置文件允许开发人员专注于他们的应用程序,而不必担心每一个可能的 QoS 设置。QoS 配置文件定义了一组策略,这些策略预计可以很好地用于特定用例。
ROS2内部预设了几种对Qos要求不同的配置文件,这些QoS配置⽂件为策略的集合,⽤⼾可以通过选择不同的QoS配置⽂件以实现不同的通信表现,如下所⽰:
发布-订阅机制的QoS设定
服务 (Service) 的QoS设定
传感器数据的QoS设定
参数的QoS设定
DDS中间层默认的QoS设定
rclcpp中Qos配置的相关接口维护在rclcpp模块中的qos.cpp和qos.hpp文件中。
预设的Qos结构数据在/opt/ros/galactic/include/rmw/qos_profiles.h中。
总结:Qos策略形成Qos配置文件,并被ROS2调用来设置通信质量;ROS2对不同的通信机制预设了不同的Qos配置文件!
4.3 Qos兼容性
每个节点的Qos是可以单独配置的,所以如果配置的Qos互相不兼容,节点间的通信将无法建立。
QoS配置文件基于“Request vs Offered”模型来确定兼容性。
订阅者Request一个它可接受的最低质量的QoS配置文件,发布者提供一个它可Offer的最高质量的QoS配置文件,只有当Request的QoS配置文件的每个策略,都松于Offer的QoS配置文件的对应策略时,连接才会被建立。
发布者A和订阅者B之间的兼容性不受发布者A和订阅者C的存在影响,这意味着,即使多个订阅者请求的配置文件不同,它们也可以同时连接到同一个发布者。
不同策略的配置兼容性如下表所示:
4.4 Qos事件
在某些QoS策略下,ROS2将提供相关的QoS事件,回调函数由前述的QoS事件触发,可以在回调函数中书进行相应的处理,典型的例如如何处理接收到的主题消息。
4.4.1 发布者相关事件
发布者过期(Offered deadline missed)
发布者未能在deadline QoS策略期望的时间内发布相应的消息。失活(Liveliness lost)
发布者未能在周期内声明其活跃性。QoS设置不兼容(Offered incompatible QoS)
发布者的QoS配置不能满足订阅者请求的相关配置要求,导致二者无法连接。
4.4.2 订阅者相关事件
订阅者过期(Requested deadline missed)
订阅者未能在deadline QoS策略期望的时间内收到相应的消息。活跃性变化(Liveliness changed)
订阅者发现任意发布者未能在周期内声明其活跃性。QoS设置不兼容(Requested incompatible QoS)
发布者的QoS配置不能满足订阅者请求的相关配置要求,导致二者无法连接。
在某些QoS策略下,系统将提供相关的事件,我们可以对发布者和订阅者提供回调函数。回调函数由前述的QoS事件触发,我们可以在回调函数中书写相应的处理,典型的例如如何处理接收到的主题消息。
五、DDS调优
DDS调优应将这样一条建议作为起点;这些调优适用于特定的系统和环境,但调优可能会因多种因素而异。在调试时,可能需要增大或减小与消息大小、网络拓扑等因素相关的值。
5.1 跨供应商调优
问题:当某些IP片段(fragments)被丢弃时,通过有损网络连接(通常是WiFi)发送数据会出现问题,可能会导致接收端的内核缓冲区变满。
解决方案一: 使用“尽力而为(best-effort)”的QoS设置而不是“可靠(reliable)”的设置。
“尽力而为”设置会减少网络流量,因为DDS实现不必承担可靠通信的开销,在可靠通信情况下,发布者要求对发送给订阅者的消息进行确认,并且必须重新发送未正确接收的数据样本。但是,如果IP片段的内核缓冲区已满,则症状仍然相同(阻塞30 秒)。该解决方案应该可以在一定程度上改善问题,而无需调整参数。
解决方案二: 减小ipfrag_time参数的值。
net.ipv4.ipfrag_time / /proc/sys/net/ipv4/ipfrag_time参数 (默认值为30s) : 将IP片段保留在内存中的时间,单位为秒。
例如,通过运行以下命令将该参数值减小到3秒:
sudo sysctl net.ipv4.ipfrag_time=3
减小此参数的值也会减少没有接收到片段的时间窗口。该参数是用于所有正在进入的片段的全局参数,因此需要针对每个具体环境考虑减小此参数值的可行性。
解决方案三: 增大ipfrag_high_thresh参数的值。
net.ipv4.ipfrag_high_thresh / /proc/sys/net/ipv4/ipfrag_high_thresh参数(默认值为262144字节):用于重组IP片段的最大内存。
例如,通过运行以下命令将此参数值增加到128MB:
sudo sysctl net.ipv4.ipfrag_high_thresh=134217728 # (128MB)
显著地增大此参数的值是为了确保缓冲区永远不会完全被填满。但是,假设每个UDP数据包都缺少一个片段,该参数值可能必须非常大才能保存ipfrag_time参数设置的时间窗口内接收到的所有数据。
5.2 Fast DDS调优
问题: 通过WiFi连接时,Fast RTPS会用大量数据或快速发布的数据淹没(floods)网络。
解决方案: 请参阅前面“跨供应商调优”中的解决方案。
5.3 Cyclone DDS调优
问题: 即使使用“可靠(reliable)”设置并通过有线网络传输,但Cyclone DDS仍无法可靠地传送大型消息。
解决方案: 增大Cyclone使用的最大Linux内核接收缓冲区大小和最小套接字接收缓冲区大小。
进行以下调整以解决9MB大小的消息传送:
通过运行以下命令设置最大接收缓冲区大小rmem_max
:
sudo sysctl -w net.core.rmem_max=2147483647
或者通过编辑/etc/sysctl.d/10-cyclone-max.conf文件以包含下面一行内容来永久设置该参数:
net.core.rmem_max=2147483647
接下来,为了设置Cyclone请求的最小套接字接收缓冲区大小,请编写一个配置文件供Cyclone在启动时使用,该配置文件内容应该如下所示:
<?xml version="1.0" encoding="UTF-8" ?>
<CycloneDDS xmlns="https://cdds.io/config" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://cdds.io/config
https://raw.githubusercontent.com/eclipse-cyclonedds/cyclonedds/master/etc/cyclonedds.xsd">
<Domain id="any">
<Internal>
<MinimumSocketReceiveBufferSize>10MB</MinimumSocketReceiveBufferSize>
</Internal>
</Domain>
</CycloneDDS>
然后,每当要运行一个节点时,要设置以下环境变量(记得要用xml格式的配置文件的绝对路径替换absolute/path/to/config_file.xml):
CYCLONEDDS_URI=file:///absolute/path/to/config_file.xml
5.4 RTI Connext调优
问题:尽管使用了“best-effort”的设置并通过有线网络传输,Connext 仍不能可靠地传递大型消息。
解决方案一:这个Connext QoS profile,随着rmem_max
参数的增加。
通过运行以下命令设置最大接收缓冲区大小rmem_max
:
sudo sysctl -w net.core.rmem_max=4194304
通过在 Linux 内核中调整net.core.rmem_max到 4MB,QoS 配置文件可以产生真正可靠的行为。
此配置已被证明可以通过 SHMEM|UDPv4 可靠地传递消息,并且仅在单台机器上使用 UDPv4。rmem_max还以 4MB 和 20MB(两台机器连接 1Gbps 以太网)测试了多机配置,没有丢失消息,平均消息传递时间分别为 700 毫秒和 371 毫秒。
在不配置内核的情况rmem_max下,相同的 Connext QoS 配置文件最多需要 12 秒才能交付数据。但是,它总是至少设法完成交付。
解决方案二:使用Connext QoS 配置文件 而不调整rmem_max
.
ROS2TEST_QOS_PROFILES.xml 文件是使用 RTI 关于配置流控制器的文档配置的。它具有慢速、中速和快速流控制器(参见 Connext QoS 配置文件链接)。
中等流量控制器为我们的案例产生了最好的结果。然而,控制器仍然需要针对它们运行的特定机器/网络/环境进行调整。Connext 流量控制器可用于调整带宽及其发送数据的积极性,尽管一旦特定设置的带宽被调整通过,性能将开始下降。
参考:
DDS域ID和进程数计算:https://blog.csdn.net/qq_27865227/article/details/123794699
SROS设计思路:https://zhuanlan.zhihu.com/p/454262080
SORS2论文:https://aliasrobotics.com/files/SROS2.pdf
SROS2 github:https://github.com/ros2/sros2
SROS的两层解释:https://ubuntu.com/blog/what-is-sros-2
SROS2功能测试代码:https://docs.ros.org/en/rolling/Tutorials/Advanced/Security/Introducing-ros2-security.html
Qos官方文档:https://docs.ros.org/en/humble/Concepts/About-Quality-of-Service-Settings.html
Qos翻译:https://blog.csdn.net/amuro_ray027/article/details/118102624