首先是安装
有两种可以选择,这里更加推荐使用cyclonedds。
sudo apt install ros-galactic-rmw-fastrtps-cpp
sudo apt install ros-galactic-rmw-cyclonedds-cpp
选择自己的ros版本即可
解答一下几个问题
- “不配置 DDS” = 用 ROS2 的默认 DDS 行为
- “配置 DDS” = 选 DDS 实现 + 写 DDS 配置文件(XML)+ 代码里调 QoS
- 怎么确认你写的配置真的生效了
配置 DDS 和不配置,有什么区别?
1)不配置:用的是“发行版默认 + DDS 默认配置”
ROS2 会自动选一个默认的 RMW(底层 DDS 实现),例如常见:
rmw_fastrtps_cpp(Fast DDS)
rmw_cyclonedds_cpp(Cyclone DDS)
DDS 的各种参数(发现机制、使用哪些网卡、是否用共享内存、队列大小等)如果你不写 XML 配置,就用库自带的默认。
对你来说的体现就是:
局域网内只要域 ID 一样、网络不特别奇怪,节点之间通常能互通;
但在复杂环境(多网卡、VPN、Docker、跨子网、带宽紧张)下,可能:
发现不到对方节点
丢包、延迟比较大
无意间广播到整个大网,网络噪声很多
对你这种做 SLAM / 训练 / 多机仿真的情况:
小规模、本机或简单局域网玩玩没问题,但一旦要多机、跨网段或上实验室大网,默认配置经常会出坑。
2)配置 DDS:你能控制这些东西
主要能做几类事:
选择哪种 DDS 实现
用环境变量:
export RMW_IMPLEMENTATION=rmw_fastrtps_cpp # Fast DDS
# 或
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp # Cyclone DDS
不同实现的特点不一样,比如 Cyclone 在多机发现上比较稳,Fast DDS 在 ROS2 里支持度很广。
通过 XML 配置底层通讯细节(核心)
指定使用哪块网卡(避免选到 VPN / Docker 的虚拟网卡)
限制只用 UDP / 只用共享内存 / 禁止多播
调 Discovery 参数(发现周期、超时时间)减少广播风暴
调缓冲区大小、可靠性、历史深度等
代码里配置 QoS(Reliability/Durability/Depth 等)
这个属于 ROS2 层的“逻辑 QoS”,比如:
SLAM map 话题用 reliable 和 transient_local
高频 IMU 可用 best_effort
这部分你大概已经在用,就不展开了。
总结一句话:
不配置 = “能跑就行”的默认模式
配置好 = “多机通信稳、延迟可控、网络不乱飞”的工程模式
2. 怎么配置 DDS?(以 Fast DDS 和 CycloneDDS 为例)
A. 选择 DDS 实现
在运行 ros2 之前设置环境变量:
# 例:使用 Fast DDS
export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
# 例:使用 CycloneDDS
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
可用 ros2 doctor --report 看当前实际使用的是哪个 RMW。
B. Fast DDS 配置(rmw_fastrtps_cpp)
新建一个 XML,比如 fastdds.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<dds>
<profiles>
<!-- 默认 Participant 配置 -->
<participant profile_name="ros2_participant" is_default_profile="true">
<rtps>
<!-- 指定 Domain ID -->
<domainId>0</domainId>
<!-- 限制使用某个网卡(可选) -->
<useBuiltinTransports>false</useBuiltinTransports>
<userTransports>
<transport_id>udp_transport</transport_id>
</userTransports>
<builtin>
<!-- 控制发现行为 -->
<use_SIMPLE_EndpointDiscoveryProtocol>true</use_SIMPLE_EndpointDiscoveryProtocol>
<leaseDuration>
<sec>5</sec>
<nanosec>0</nanosec>
</leaseDuration>
</builtin>
</rtps>
</participant>
</profiles>
</dds>
告诉 Fast DDS 使用这个配置:
export FASTRTPS_DEFAULT_PROFILES_FILE=/path/to/fastdds.xml
export RMW_IMPLEMENTATION=rmw_fastrtps_cpp
ros2 run demo_nodes_cpp talker
也可以在 XML 里为特定 Topic 定制 QoS,但一般先配置 Participant 就够你验证效果了。
C. CycloneDDS 配置(rmw_cyclonedds_cpp)
新建 cyclonedds.xml:
<?xml version="1.0" encoding="UTF-8"?>
<CycloneDDS>
<Domain id="any">
<General>
<!-- 关闭自动网卡发现,自行指定接口 (可选) -->
<NetworkInterfaceAddress>eth0</NetworkInterfaceAddress>
</General>
<Discovery>
<!-- 是否允许多播 -->
<AllowMulticast>true</AllowMulticast>
</Discovery>
<Tracing>
<!-- 打开调试日志,方便确认配置生效 -->
<Verbosity>config</Verbosity>
</Tracing>
</Domain>
</CycloneDDS>
设置环境变量:
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
export CYCLONEDDS_URI=file:///path/to/cyclonedds.xml
ros2 run demo_nodes_cpp talker
3. 如何确认配置“真的生效了”?
这里是重点,你可以按三个层次来确认:
① 环境变量层
echo $RMW_IMPLEMENTATION
echo $FASTRTPS_DEFAULT_PROFILES_FILE
echo $CYCLONEDDS_URI
用 ROS2 自检:
ros2 doctor --report | grep RMW
或者过滤一下:
ros2 doctor --report | grep -i ‘middleware name’
看到:

能看到类似:
RMW implementation: rmw_cyclonedds_cpp
说明 DDS 实现已经切换成功。
② 日志 / 行为层
做几个“明显可见”的配置,来验证:
改 Domain ID
在 XML 里把 0 改成 10;
一个终端用 Domain 0,另一个终端用 Domain 10;
启动 talker 和 listener:
如果配置正确,不同 Domain 的 talker / listener 互相看不到;
再把 Domain 改为一样,应该马上能互通。
指定网卡 / 关闭多播
在 CycloneDDS 里只允许某一个网卡:
eth0
然后在另一台机器上拔/禁掉其他网卡,看节点是否还互相发现;
或者在 false 时,多机之间会依赖 Unicast,行为会有变化。
开启 DDS 调试日志
CycloneDDS 配置里 config,启动时会在终端打印使用的配置文件、网卡、端口等信息;
Fast DDS 也可以通过 env / XML 开启 log(比如 节点),看到它加载了哪个 profile。
实际配置
实际使用时的配置如下:
sudo apt install ros-galactic-rmw-cyclonedds-cpp
echo "export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp" >> ~/.bashrc
source ~/.bashrc
nano ~/cyclonedds.xml
<?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">
<General>
<NetworkInterfaceAddress>auto</NetworkInterfaceAddress>
<MaxMessageSize>104857600</MaxMessageSize> </General>
<Internal>
<MinimumSocketReceiveBufferSize>26214400</MinimumSocketReceiveBufferSize> <Watermarks>
<WhcHigh>50MB</WhcHigh> <WhcLow>1MB</WhcLow> </Watermarks>
</Internal>
</Domain>
</CycloneDDS>
echo "export CYCLONEDDS_URI=file://$HOME/cyclonedds.xml" >> ~/.bashrc
source ~/.bashrc
注意,以上所有的配置都是学习dds过程中相关教程的建议。但是经过我实际验证发现,并不能直接通过这样的方式来配置好dds,所以我的建议是不配置dds,export CYCLONEDDS_URI=file://$HOME/cyclonedds.xml和export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp也是完全没有必要指定的。真正影响udp通信的,还是直接去配置linux的内核缓冲区的空间大小。
修改 Linux 内核缓冲区
sudo gedit /etc/sysctl.d/10-cyclone-max.conf
# ------------- 雷达 UDP 缓冲区优化 -------------
# UDP 接收缓冲区(读缓冲区,工控机收雷达数据)
net.core.rmem_default = 26214400 # 默认 25MB
net.core.rmem_max = 67108864 # 最大 64MB
# UDP 发送缓冲区(写缓冲区,DDS 发点云数据)
net.core.wmem_default = 26214400 # 默认 25MB
net.core.wmem_max = 67108864 # 最大 64MB
sudo sysctl -p /etc/sysctl.d/10-cyclone-max.conf
# 默认接收缓冲区大小(全局)
sysctl net.core.rmem_default
# 最大接收缓冲区大小(全局上限)
sysctl net.core.rmem_max
# 默认发送缓冲区大小(全局)
sysctl net.core.wmem_default
# 最大发送缓冲区大小(全局上限)
sysctl net.core.wmem_max

1695

被折叠的 条评论
为什么被折叠?



