ros2基础向--DDS配置与作用

首先是安装
有两种可以选择,这里更加推荐使用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,所以我的建议是不配置ddsexport CYCLONEDDS_URI=file://$HOME/cyclonedds.xmlexport 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白云千载尽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值