ROS2学习(七) Foxy版本ros2替换中间件。

在ros2使用的过程中,一开始选用的foxy版本,后来发现,foxy版本的ros2有很多问题。一个是foxy版本已经停止维护了。另一个问题是这个版本有很多bug, 后续的版本在功能实现上做了很大的改动,甚至说进行了重写。修复的一些问题,foxy版本上的问题也没有修复。

最近遇到的问题是,service有时候没有应答,根据输出的log看是中间件出的问题,错误的的日志如下

bash 复制代码
E0229 15:04:57.981310  2354 main.cpp:43] [me] rclcpp::exception::RCLError caught! failed to send response: client will not receive response, at /tmp/binarydeb/ros-foxy-rmw-fastrtps-shared-cpp-1.3.2/src/rmw_response.cpp:127, at /tmp/binarydeb/ros-foxy-rcl-1.1.14/src/rcl/service.c:356

后面查看源码发现如下的内容,看到这个if条件是Maybe就很崩溃了。

遇到节点启动时,负载很高,通过perf工具查看,是启动的时候共享内存一直创建失败。抛出异常,

然后进入某种死循环,一直在创建共享内存。一直在find_segment()函数中转。

目前没有从网上找到很好的处理方法,其实也无法确定是ros2的问题导致的,还是中间件导致的。

所以采取的方式是换中间件。

ros2 中间件

foxy版本的中间件使用的是fast-rtps, 这个版本默认是使用共享内存的。也就是遇到了上面的问题。通过查一些资料,用的比较多的是cyclone-dds. 所以决定先替换中间件。

替换方法比较简单。

直接apt安装,再加声明环境变量RMW_IMPLEMENTATION就可以。

安装方法:

bash 复制代码
sudo apt install ros-foxy-rmw-cyclonedds-cpp

安装完后使用export声明变量。

bash 复制代码
export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp

然后启动ros2工程,使用的就是cyclone dds了。

Foxy版本ROS2使用 cyclonedds_ccp遇到的一些问题

  1. 默认使用UDP通信,不支持共享内存

    cyclonesdds_cpp对应的foxy版本默认使用的是udp通信,二进制安装是不只是共享内存的。从网上看一些资料说源码编译应该可以,不过我试过没有编译成功,提示有一些接口变了。这个也是foxy版本的ros2比较麻烦的一点。后面的ros2版本和以前的版本兼容性不好。

    所以只能用udp的方式通信。

  2. 关于upd通信单播和组播的问题

    cyclonesdds_cpp对应的foxy版本默认是组播方式,会根据网卡质量选择一个比较好的网卡进行组播。我遇到到的情况是,我自己的设备有有线网卡eth0, 连接的是激光,无线网卡wlan0. ros2默认选择了质量比较好的eth0进行组播,导致eth0的负载非常高,影响了激光的通信。

    可以看到eth0的负载拉满了。

    所以此时需要通过中间件的配置文件去控制网络。

    在本地机器任一位置创建一个名为cyclonedds.xml的文件。

    添加如下内容:

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>wlan0</NetworkInterfaceAddress>
            <AllowMulticast>true</AllowMulticast>
        </General>
        <Discovery>
            <ParticipantIndex>auto</ParticipantIndex>
            <MaxAutoParticipantIndex>30</MaxAutoParticipantIndex>
            <Peers>
                <Peer address="localhost"/>
            </Peers>
        </Discovery>
    </Domain>
</CycloneDDS>

然后声明环境变量

bash 复制代码
export CYCLONEDDS_URI=file:///etc/systemd/system/cyclonedds.xml

再启动工程的时间,就会根据xml的配置,组播数据走wlan0, eth0上的负载降下来了。当然也可以完全关闭,修改xml只使用本地回环,也是没有问题的。只是注意使用本地回环lo的时候是不支持组播的,要设置成false.

其他关于配置文件的设置,可以参考官网文档。

参考

cyclonedds官网配置文件
foxy安装中间件

相关推荐
poemyang5 分钟前
“一切皆文件”:揭秘LINUX I/O与虚拟内存的底层设计哲学
linux·rpc·i/o 模式
im_AMBER11 分钟前
数据结构 04 栈和队列
数据结构·笔记·学习
尘似鹤28 分钟前
微信小程序学习(六)--多媒体操作
学习·微信小程序·小程序
大聪明-PLUS31 分钟前
GPIO 也是一个接口,还有 QEMU GPIODEV 和 GUSE
linux·嵌入式·arm·smarc
UpYoung!1 小时前
无广技术贴!【PDF编辑器】Solid Converter PDF保姆级图文下载安装指南——实用推荐之PDF编辑软件
学习·数学建模·pdf·编辑器·运维开发·个人开发
达瓦里氏1231 小时前
重排反应是什么?从分子变化到四大关键特征解析
数据库·学习·化学
LiJieNiub2 小时前
基于 PyTorch 实现 MNIST 手写数字识别
pytorch·深度学习·学习
Geek攻城猫2 小时前
02117 信息组织【第六章】
学习
流***陌2 小时前
线上教学小程序:构建高效互动的云端学习空间
学习·小程序
来自嵌入式的zyz2 小时前
STM32项目实战/PID算法学习:编码电机闭环控制实现控速+位置控制、倒立摆实现
stm32·嵌入式硬件·学习·控制·pid