尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

ROS2国产化迁移实战:DDS选型、ros2_control适配与实时性调优

ROS2国产化迁移实战:DDS选型、ros2_control适配与实时性调优 1. 机器人操作系统与国产化-ROS2生态全景1.1 为什么这个话题现在值得认真聊我在机器人行业摸爬滚打这些年亲眼看着ROS1从如日中天到2025年正式停止维护也看着ROS2从2017年第一个正式版本Ardent发布时的玩具状态一路走到今天Jazzy Jalisco成为LTS版本。说实话2020年之前你要跟我提用ROS2做产品我大概率会劝你再等等——生态不成熟、DDS选型混乱、实时性没保障。但现在情况完全变了。与此同时国产化替代这件事从政策层面到产业层面都在加速推进。工业机器人、轨道交通AFC系统、电力巡检机器人、农业自动化设备这些领域对操作系统的自主可控要求越来越高。我最近参与的几个项目甲方明确要求核心软件栈必须能在国产芯片和国产操作系统上跑通。这就带来一个非常现实的问题ROS2这套源自欧美的机器人中间件怎么在国产化环境下落地这篇文章我想把ROS2的生态全景拆开来讲清楚同时把国产化迁移这条路上我踩过的坑、验证过的方案、以及一些不太方便写在官方文档里的经验都分享出来。不管你是刚接触ROS2的新手还是正在做国产化适配的资深工程师应该都能从中找到有用的东西。1.2 ROS2到底解决了什么问题很多人刚接触ROS2的时候会问ROS1用得好好的为什么要换我通常用这样一个类比来解释ROS1像是一个老式办公室所有人共用一条走廊传文件谁嗓门大谁先说话一旦有人堵在走廊里整个办公室就瘫痪了。ROS2则像是给每个人配了对讲机还分了不同的频道你可以选择只收听你关心的频道也可以设置优先级。具体来说ROS1的核心痛点包括单点故障roscore挂了整个系统全挂无实时性保障TCP-based的通信机制在需要确定性延迟的场景下完全不可控网络穿透能力差跨网段、跨设备通信配置极其痛苦不支持多机器人协同命名空间和话题冲突问题难以根治ROS2基于DDSData Distribution Service重构了通信层把这些问题从架构层面解决了。DDS本身是一个成熟的工业级发布-订阅中间件标准在航空、国防、金融交易等领域已经用了二十多年。ROS2选择DDS作为底层通信相当于站在了巨人的肩膀上。1.3 国产化为什么绕不开ROS2这里需要说清楚一个逻辑国产化不是目的自主可控才是。ROS2本身是开源的Apache 2.0协议不存在授权风险。真正的风险在于DDS实现的选择默认的Fast DDS是eProsima公司的产品虽然开源但商业支持依赖海外团队依赖库的供应链ROS2依赖大量第三方库如OpenCV、PCL、Eigen等这些库在国产平台上的编译适配需要逐一验证工具链的完整性从编译工具链到调试工具国产平台上的支持成熟度参差不齐实时OS的配合很多国产化场景要求搭配国产实时操作系统ROS2需要做相应的实时性适配所以ROS2国产化这件事本质上是在开源生态的基础上构建一套从芯片到操作系统到中间件到应用框架的完整自主技术栈。2. ROS2核心架构深度拆解2.1 DDS层ROS2的心脏DDS是ROS2最核心的底层通信机制理解DDS是理解ROS2的关键。我见过太多人学ROS2只学API调用结果遇到通信问题就抓瞎根本原因就是没搞懂DDS的工作原理。DDS的核心概念包括Domain域一个虚拟的通信空间不同Domain之间的节点互相不可见。默认Domain ID是0。在多机器人场景下给每个机器人分配不同的Domain ID是最简单的隔离方式。Participant参与者每个ROS2节点在启动时会创建一个或多个DDS Participant它是DDS通信的入口点。Participant之间通过发现协议Discovery Protocol互相发现。Topic话题数据的逻辑通道发布者往Topic写数据订阅者从Topic读数据。ROS2中的Topic名称会被映射为DDS的Topic名称。QoS服务质量这是DDS最强大的特性之一也是ROS2区别于ROS1的核心优势。QoS策略决定了通信的可靠性、持久性、历史记录等行为。我整理了一个常用QoS策略的对照表实际项目中经常需要根据场景调整QoS策略可选值适用场景注意事项ReliabilityRELIABLE / BEST_EFFORT控制指令用RELIABLE传感器数据用BEST_EFFORTRELIABLE会增加延迟DurabilityTRANSIENT_LOCAL / VOLATILE地图、参数用TRANSIENT_LOCAL占用内存更多HistoryKEEP_LAST / KEEP_ALL通常用KEEP_LAST(depthN)KEEP_ALL可能耗尽内存Deadline时间段实时控制场景需要DDS实现支持Lifespan时间段有时效性的数据过期数据自动丢弃注意QoS不匹配是ROS2通信失败最常见的原因。发布者和订阅者的QoS策略如果不兼容数据根本不会传输而且默认情况下不会有任何报错。我建议在调试阶段用ros2 topic info --verbose命令检查QoS配置。2.2 DDS实现选型Fast DDS vs Cyclone DDS vs 其他ROS2支持多种DDS实现目前主流的包括Fast DDS默认eProsima开发功能最全面文档最完善社区最活跃。缺点是资源占用相对较高在嵌入式场景下需要调优。Cyclone DDSEclipse基金会项目轻量级性能优秀特别适合嵌入式和高实时场景。Eclipse Cyclone DDS在国产化场景中值得重点关注因为它的代码结构清晰便于审计和定制。RTI Connext商业DDS功能最强但需要商业授权。在国产化场景中基本不会考虑。GurumDDS韩国公司开发在亚洲市场有一定份额。在国产化场景下我的建议是如果目标是快速迁移先用Fast DDS跑通再考虑替换如果对实时性和资源占用有严格要求优先评估Cyclone DDS如果需要完全自主可控可以考虑基于开源DDS实现做深度定制切换DDS实现的方法很简单通过环境变量或RMW_IMPLEMENTATION指定# 使用Cyclone DDS export RMW_IMPLEMENTATIONrmw_cyclonedds_cpp # 使用Fast DDS export RMW_IMPLEMENTATIONrmw_fastrtps_cpp但实际切换时远没有这么简单不同DDS实现的默认配置差异很大需要针对性地调整XML配置文件。2.3 ros2_control机器人控制的标准化框架ros2_control是ROS2生态中负责机器人控制的框架它定义了一套标准接口把硬件驱动、控制器、状态发布解耦开来。我个人的评价是这是ROS2生态中设计最优雅的子系统之一。它的核心架构分为三层Hardware Interface层负责与真实硬件或仿真器通信提供read()和write()接口。你需要为每种硬件实现对应的Hardware Interface插件。Controller Manager层管理控制器的生命周期负责在合适的时机加载、配置、激活、停用控制器。Controller层实现具体的控制算法如关节轨迹控制、力控制、差分驱动等。一个典型的ros2_control配置流程controller_manager: ros__parameters: update_rate: 100 # Hz joint_state_broadcaster: type: joint_state_broadcaster/JointStateBroadcaster diff_drive_controller: type: diff_drive_controller/DiffDriveController diff_drive_controller: ros__parameters: left_wheel_names: [left_wheel_joint] right_wheel_names: [right_wheel_joint] wheel_separation: 0.3 wheel_radius: 0.05 publish_rate: 50.0实操心得update_rate的设置非常关键。设太高会导致CPU占用飙升设太低会影响控制精度。我的经验是对于差分驱动移动机器人100Hz足够对于机械臂关节控制建议至少500Hz对于力控场景可能需要1000Hz以上。但前提是你的硬件接口能跟上这个频率。2.4 国产化适配的核心挑战把ROS2迁移到国产平台核心挑战集中在以下几个方面编译工具链国产CPU架构如龙芯的LoongArch、飞腾的ARMv8、申威的SW64需要对应的GCC工具链。ROS2的构建系统colcon对交叉编译的支持还在完善中很多包的CMake配置需要手动调整。依赖库适配ROS2依赖的第三方库在国产平台上的可用性参差不齐。我遇到过最典型的问题是某些数学库如Eigen在特定架构上的SIMD指令集支持不完整导致性能下降甚至编译失败。实时性保障国产实时操作系统如SylixOS、RT-Thread等与ROS2的集成需要额外工作。主要是DDS层需要适配实时OS的网络栈和线程模型。工具链完整性rviz2、gazebo等可视化工具在国产平台上的GPU驱动支持是个大问题。很多国产GPU的OpenGL驱动不完整导致这些工具无法正常运行。3. 国产化迁移实操全流程3.1 环境准备与基础平台搭建国产化迁移的第一步是搭建基础环境。以Ubuntu 22.04 ROS2 Humble为例这是目前最成熟的组合迁移到国产平台的基本流程如下第一步确认目标平台信息# 查看CPU架构 uname -m # 龙芯: loongarch64 # 飞腾: aarch64 # 兆芯: x86_64 # 查看操作系统版本 cat /etc/os-release # 查看内核版本 uname -r第二步安装基础编译工具链# 更新包列表 sudo apt update # 安装编译工具 sudo apt install -y \ build-essential \ cmake \ git \ python3-pip \ python3-colcon-common-extensions \ python3-rosdep \ python3-vcstool第三步初始化rosdepsudo rosdep init rosdep update注意在国产平台上rosdep update可能会因为网络问题失败。我的做法是提前下载好rosdep的数据库文件手动放到/etc/ros/rosdep/sources.list.d/目录下。另外某些依赖包在国产平台的软件源中可能不存在需要手动编译安装。第四步安装ROS2基础包# 添加ROS2 apt源 sudo apt install -y software-properties-common sudo add-apt-repository universe # 安装ROS2 Humble sudo apt install -y ros-humble-desktop如果apt源中没有对应架构的ROS2包就需要从源码编译。源码编译ROS2是个体力活我建议用ros2.repos文件来管理依赖mkdir -p ~/ros2_humble/src cd ~/ros2_humble wget https://raw.githubusercontent.com/ros2/ros2/humble/ros2.repos vcs import src ros2.repos然后逐个编译遇到编译失败的包就单独处理。这个过程可能需要几个小时甚至几天取决于平台适配的成熟度。3.2 DDS层国产化替换方案DDS层的替换是国产化迁移中最关键也最复杂的环节。我推荐的分步策略是阶段一保持Fast DDS验证基础功能先不换DDS用默认的Fast DDS把ROS2的基础通信跑通。这一步的目的是确认ROS2核心功能在国产平台上是否正常。# 终端1启动talker ros2 run demo_nodes_cpp talker # 终端2启动listener ros2 run demo_nodes_cpp listener如果能看到消息正常收发说明基础通信没问题。阶段二切换到Cyclone DDS验证兼容性# 安装Cyclone DDS sudo apt install -y ros-humble-rmw-cyclonedds-cpp # 设置环境变量 export RMW_IMPLEMENTATIONrmw_cyclonedds_cpp # 重新测试 ros2 run demo_nodes_cpp talker阶段三定制DDS配置Cyclone DDS的配置文件格式与Fast DDS不同需要重新编写。一个典型的Cyclone DDS配置?xml version1.0 encodingUTF-8 ? CycloneDDS xmlnshttps://cdds.io/config Domain idany General NetworkInterfaceAddressauto/NetworkInterfaceAddress AllowMulticasttrue/AllowMulticast /General Internal Watermarks WhcHigh500kB/WhcHigh /Watermarks /Internal /Domain /CycloneDDS通过CYCLONEDDS_URI环境变量指定配置文件路径export CYCLONEDDS_URIfile:///path/to/cyclonedds.xml实操心得在国产平台上网络接口的自动发现经常出问题。如果遇到节点之间无法互相发现的情况尝试在配置中明确指定网络接口地址而不是用auto。另外某些国产网卡的组播支持不完整可能需要关闭组播改用单播发现。3.3 ros2_control在国产硬件上的适配ros2_control的硬件接口适配是另一个重点。以国产运动控制卡为例适配流程如下第一步实现Hardware Interface#include hardware_interface/system_interface.hpp class MyRobotHardware : public hardware_interface::SystemInterface { public: hardware_interface::CallbackReturn on_init( const hardware_interface::HardwareInfo info) override { // 初始化硬件通信 // 打开设备文件或建立网络连接 return hardware_interface::CallbackReturn::SUCCESS; } hardware_interface::CallbackReturn on_activate( const rclcpp_lifecycle::State previous_state) override { // 激活硬件 return hardware_interface::CallbackReturn::SUCCESS; } hardware_interface::return_type read( const rclcpp::Time time, const rclcpp::Duration period) override { // 从硬件读取关节位置和速度 return hardware_interface::return_type::OK; } hardware_interface::return_type write( const rclcpp::Time time, const rclcpp::Duration period) override { // 向硬件写入控制指令 return hardware_interface::return_type::OK; } };第二步编写URDF描述文件ros2_control nameMyRobotSystem typesystem hardware pluginmy_robot_hardware/MyRobotHardware/plugin param namedevice/dev/my_robot/param /hardware joint namejoint1 command_interface nameposition/ state_interface nameposition/ state_interface namevelocity/ /joint /ros2_control第三步配置控制器controller_manager: ros__parameters: update_rate: 500 joint_state_broadcaster: type: joint_state_broadcaster/JointStateBroadcaster joint_trajectory_controller: type: joint_trajectory_controller/JointTrajectoryController joint_trajectory_controller: ros__parameters: joints: - joint1 command_interfaces: - position state_interfaces: - position - velocity constraints: stopped_velocity_tolerance: 0.01 goal_time: 0.5注意update_rate的设置需要与硬件通信周期匹配。如果硬件通信周期是1ms那么update_rate设为1000Hz是合理的。但如果硬件通信周期是10ms设1000Hz就是浪费CPU资源。我见过有人把update_rate设成10000Hz结果CPU直接跑满系统卡死。3.4 国产化工具链的补充与替代在国产化环境中一些常用的ROS2工具可能需要替代方案工具原版国产化替代方案备注可视化rviz2基于Qt自研可视化工具需要适配国产GPU仿真Gazebo国产仿真平台或自研物理引擎可复用构建colcon保持colcon适配工具链需处理交叉编译调试gdb国产调试器或保持gdb需适配目标架构包管理apt/rosdep国产包管理或离线源需自建软件源我个人的经验是rviz2的替代是最麻烦的。很多国产GPU的OpenGL驱动只支持到OpenGL ES 2.0而rviz2需要OpenGL 3.3以上。如果实在跑不起来可以考虑用Web-based的可视化方案比如Foxglove Studio的Web版本通过rosbridge把数据转发到浏览器中显示。4. 常见问题与排查技巧实录4.1 通信类问题排查问题一节点之间无法发现这是国产化迁移中最常见的问题。排查思路# 检查ROS_DOMAIN_ID是否一致 echo $ROS_DOMAIN_ID # 检查RMW实现是否一致 echo $RMW_IMPLEMENTATION # 检查网络接口 ip addr show # 查看DDS发现流量 sudo tcpdump -i any port 7400 -c 10如果发现流量正常但节点仍然无法发现大概率是QoS不匹配或DDS配置问题。问题二消息延迟大或丢包# 查看话题统计信息 ros2 topic hz /topic_name # 查看QoS配置 ros2 topic info /topic_name --verbose如果延迟大检查是否使用了RELIABLE QoS但网络质量差是否消息体过大导致序列化开销高是否DDS的History深度设置不合理问题三ros2 command not found# 检查ROS2环境是否source source /opt/ros/humble/setup.bash # 检查安装是否完整 dpkg -l | grep ros-humble在国产平台上如果是从源码编译的ROS2需要source的是~/ros2_humble/install/setup.bash。4.2 编译类问题排查问题一找不到依赖包# 使用rosdep安装依赖 rosdep install --from-paths src --ignore-src -r -y # 如果rosdep失败手动查找 apt search ros-humble-package_name问题二链接错误国产平台上常见的链接错误包括缺少特定架构的库文件符号版本不匹配静态库和动态库混用排查方法# 查看库文件依赖 ldd /path/to/binary # 查看符号表 nm -D /path/to/library.so | grep symbol_name问题三编译时内存不足ROS2的某些包如rviz2编译时需要大量内存。如果国产平台内存有限可以使用# 限制并行编译任务数 colcon build --parallel-workers 2 # 或者使用ccache加速重复编译 sudo apt install ccache export CCACHE_DIR~/.ccache colcon build --cmake-args -DCMAKE_C_COMPILER_LAUNCHERccache -DCMAKE_CXX_COMPILER_LAUNCHERccache4.3 实时性调优技巧在国产化场景中实时性往往是硬指标。以下是我总结的调优清单系统层调优# 设置CPU隔离 # 在/etc/default/grub中添加 # GRUB_CMDLINE_LINUXisolcpus2,3 nohz_full2,3 rcu_nocbs2,3 # 设置实时优先级 sudo setcap cap_sys_niceep /path/to/ros2_node # 调整网络缓冲区 sudo sysctl -w net.core.rmem_max2097152 sudo sysctl -w net.core.wmem_max2097152ROS2层调优使用BEST_EFFORTQoS减少确认开销减小消息体大小避免传输大图像使用Intra-process通信减少进程间开销合理设置update_rate不要盲目追求高频率DDS层调优调整WhcHigh水位线平衡内存和延迟关闭不必要的发现协议开销使用共享内存传输如果DDS实现支持实操心得实时性调优是一个系统工程不要指望改一个参数就能解决问题。我的经验是先测量再优化。用ros2 topic delay测量端到端延迟用perf或ftrace定位瓶颈然后有针对性地调整。另外国产平台的实时性表现差异很大同样的配置在不同芯片上效果可能完全不同一定要在目标平台上实测。4.4 国产化认证相关注意事项如果项目需要通过国产化认证以下几点需要特别注意操作系统认证确保使用的国产操作系统版本在认证目录中。常见的包括麒麟、统信UOS、中科方德等。芯片认证确认目标芯片型号在认证范围内。龙芯、飞腾、鲲鹏、兆芯、海光等都有各自的认证体系。软件栈认证ROS2本身是开源软件但基于ROS2开发的应用软件需要单独认证。认证过程中需要提供完整的软件物料清单SBOM。安全合规确保不包含任何未经授权的加密算法或通信协议。DDS的某些安全插件可能需要替换或移除。5. 生态全景与未来演进5.1 ROS2生态的层次结构把ROS2生态画成一个金字塔从下到上依次是底层DDS通信层。这是ROS2的根基负责所有数据传输。国产化替代的核心就在这一层。中间层RMW和核心库。RMWROS Middleware Interface是ROS2与DDS之间的抽象层它让ROS2可以灵活切换不同的DDS实现。核心库包括rclcpp、rclpy、rcl等。上层功能包和工具。包括导航Nav2、运动规划MoveIt2、仿真Gazebo、可视化rviz2等。顶层应用框架。基于ROS2构建的具体机器人应用如自动驾驶、工业机械臂、服务机器人等。国产化迁移的策略应该是底层重点突破中间层保持兼容上层逐步替代。5.2 值得关注的新兴方向Micro-ROS把ROS2带到微控制器上。在国产MCU如GD32、CH32等上运行Micro-ROS是一个很有前景的方向。我最近在STM32H7上跑Micro-ROS结合DMA双缓冲和DDS技术实现高精度波形生成效果不错。ROS2与AI的融合ROS2正在成为AI算法落地的标准框架。国产AI芯片如寒武纪、地平线等与ROS2的集成是一个热点。云边端协同ROS2的DDS天然支持分布式部署结合国产云平台可以构建云边端一体化的机器人系统。安全ROS2DDS的安全插件如SROS2在国产化场景中需要特别关注因为加密算法可能需要替换为国密算法。5.3 学习路径建议如果你是刚接触ROS2的新手我建议的学习路径是基础入门安装ROS2 Humble跑通小乌龟turtlesim理解节点、话题、服务、动作的基本概念通信深入学习QoS、DDS原理、RMW机制工具链掌握熟练使用colcon、ros2 CLI、rviz2、gazebo控制框架学习ros2_control实现一个简单的硬件接口导航与规划学习Nav2和MoveIt2国产化适配在国产平台上复现上述所有内容解决适配问题对于有ROS1基础的开发者迁移到ROS2最大的思维转变是从中心化到去中心化从TCP可靠传输到QoS可配置从单一机器人到多机器人协同。5.4 我个人的一些判断ROS2的生态成熟度在2024年已经跨过了一个临界点。Jazzy Jalisco作为LTS版本支持到2029年这给了工业界足够的信心做产品化。国产化方面虽然目前还没有一个完全国产化的ROS2发行版但各个层面的替代方案都在快速成熟。我的建议是不要等完全准备好再动手。国产化迁移是一个渐进的过程先从非关键模块开始积累经验逐步替换。同时积极参与开源社区把国产化适配中遇到的问题和解决方案反馈回去这本身就是对生态的贡献。最后分享一个我在实际项目中验证过的经验国产化迁移最大的成本不是技术而是测试。同样的代码在不同国产平台上的表现可能完全不同必须建立完善的自动化测试体系才能在迁移过程中保证质量。我通常会在目标平台上跑一套包含通信、控制、导航的完整测试用例每次修改后都重新跑一遍确保没有回归。这套测试用例的投入在后期会节省大量的调试时间。
返回列表