RK平台ROS2适配全指南:从编译到运行,手把手搞定嵌入式机器人开发 电子说
在嵌入式机器人与智能硬件领域,瑞芯微(Rockchip)的 RK356x、RK3588 等 arm64 芯片凭借高性能、低功耗的优势,成为众多开发者的首选硬件平台;而 ROS2(Robot Operating System 2)作为新一代机器人操作系统,在分布式通信、实时性、多语言支持上的升级,更是嵌入式机器人开发的核心框架。
但不少开发者在将 ROS2 适配到 RK 平台时,常会遇到 “SDK 与 ROS2 版本不兼容”“交叉编译报错”“板端运行缺失依赖” 等问题。本文基于瑞芯微官方《Rockchip Linux SDK 编译 ROS2 说明》文档,从适配逻辑、完整流程到避坑技巧,手把手教你搞定 RK 平台的 ROS2 适配。
在开始适配前,必须先明确硬件、系统、ROS2 版本的匹配关系,避免因版本不兼容走弯路。

RK 平台目前仅支持arm64 位芯片,已验证的型号包括:
•RK356x 系列(如 RK3562、RK3568)
•RK3588 系列
•其他同架构 arm64 芯片(内核版本无限制)
注意:32 位 arm 芯片的 rootfs 暂未支持 ROS2 编译,属于待完善项。
RK Linux SDK 基于 Buildroot 构建,ROS2 的编译依赖 SDK 提供的 Python、bullet、opencv 等基础包,且需与 Docker 镜像的 Python 版本严格一致(避免交叉编译时库版本冲突)。
已验证的 SDK 与 Docker 匹配关系如下:
|
Linux SDK 版本
|
Python 版本
|
匹配 Docker 镜像
|
额外要求
|
|
linux-5.10-stan-rkr1
|
3.10.5
|
jammy-ros2-build
|
需要添加 ros2_dep.config 补丁
|
|
linux-4.19-gen-rkr3
|
3.8.6
|
focal-ros2-build
|
需更新 lttng-tools 等依赖到指定版本
|
RK 平台已实测通过 4 个 ROS2 版本,源码可直接从 GitHub 下载,版本信息如下:
|
ROS2 发行版
|
版本号
|
下载链接(GitHub)
|
|
Foxy
|
ros2-release-foxy-20230620
|
https://github.com/ros2/ros2/releases/tag/release-foxy-20230620
|
|
Galactic
|
ros2-release-galactic-20221209
|
https://github.com/ros2/ros2/releases/tag/release-galactic-20221209
|
|
Humble
|
ros2-release-humble-20230724
|
https://github.com/ros2/ros2/releases/tag/release-humble-20230724
|
|
Iron
|
ros2-release-iron-20230912
|
https://github.com/ros2/ros2/releases/tag/release-iron-20230912
|
很多开发者会疑惑:直接在 RK SDK 里编译 ROS2 不行吗?为什么要引入 Docker?
这背后是 RK 团队为降低维护成本、提升版本灵活性设计的适配逻辑:
ROS2 官方虽提供了 arm64 交叉编译的 Docker 镜像(如Dockerfile_ubuntu_arm64_prebuilt),但仅支持 Ubuntu 18.04(Bionic)系统,而 RK Linux SDK 的 rootfs 基于 Buildroot 定制,与 Ubuntu 18.04 的库结构差异极大,直接使用会导致大量依赖冲突。
RK 采用 “SDK 提供依赖 + Docker 编译 ROS2” 的分离模式:
•RK Linux SDK:仅负责编译 ROS2 所需的基础依赖(如 Python、Eigen、OpenCV),不直接编译 ROS2 本体,避免 SDK 升级对 ROS2 的影响;
•Docker 容器:提供统一的 Ubuntu 编译环境,结合 SDK 的交叉工具链与 Sysroot,确保 ROS2 编译产物能适配 RK 的 rootfs;
•最终通过“重新打包 rootfs” 将 ROS2 集成到 RK 板端,实现灵活升级(换 ROS2 版本只需换 Docker 编译,无需重构 SDK)。
接下来进入实操环节,全程基于“RK3562 + Linux 5.10 SDK + ROS2 Iron” 示例,其他型号可参考适配。
先确保 SDK 已包含 ROS2 的基础依赖,关键是配置ros2_dep.config文件。
ros2_dep.config是 ROS2 依赖的配置文件,存放于buildroot/configs/rockchip/目录下,包含 LTTNG、Python 等必需依赖的开关。
•若存在该文件:检查是否包含LTTNG_TOOLS(ROS2 Iron 必需),若缺失则手动添加:
# 编辑ros2_dep.configtail -f buildroot/configs/rockchip/ros2_dep.config# 添加以下内容(支持tracetools功能)BR2_PACKAGE_LTTNG_TOOLS=yBR2_PACKAGE_LTTNG_LIBUST=y
•若不存在该文件:需给 SDK 打 2 个补丁(补丁文件可从RK 官方链接下载):
# 进入SDK的buildroot目录cd buildroot# 打补丁(添加libasio依赖和ros2_dep.config)patch -p1 < ../linux-sdk-patches/buildroot/0001-package-add-libasio.patchpatch -p1 < ../linux-sdk-patches/buildroot/0002-configs-rockchip-add-ros2-build-dependencies.patch
修改 SDK 的 defconfig 文件(如 RK356x 机器人方案的rockchip_rk356x_robot_defconfig),引入ros2_dep.config:
# 编辑defconfigvim buildroot/configs/rockchip/rockchip_rk356x_robot_defconfig# 在文件中添加一行(引入ROS2依赖配置)#include "ros2_dep.config"
执行 SDK 编译命令,生成包含 ROS2 依赖的 rootfs:
# 进入SDK根目录cd /path/to/rk-linux-sdk# 编译rootfs(根据芯片型号选择defconfig)./build.sh rockchip_rk356x_robot_defconfig# 编译完成后,rootfs输出在buildroot/output/rockchip_rk356x_robot/
基于匹配的 Docker 镜像,搭建 ROS2 的交叉编译环境。
在 Ubuntu PC(建议 20.04 及以上)上安装 Docker,避免每次执行需 sudo:
# 安装Dockersudo apt install docker.io# 将当前用户加入docker组(无需sudo)sudo usermod -aG docker $USERnewgrp docker # 生效用户组
先确认 SDK 编译的 Python 版本,再导入对应 Docker 镜像(镜像从RK 官方链接下载):
# 查看SDK的Python版本(示例输出:Python 3.10.5)./buildroot/output/rockchip_rk356x_robot/host/bin/python --version# 导入匹配的镜像(Python 3.10.5对应jammy-ros2-build)gunzip jammy-ros2-build.tar.gz # 解压镜像docker image load -i jammy-ros2-build.tar # 导入镜像
启动容器时,需将 SDK 的output目录(含交叉工具链、rootfs)挂载到容器内,确保编译时能调用 SDK 资源:
# 启动容器,挂载SDK的output目录(source替换为你的SDK output路径)docker run -it --mount type=bind,source=/home/yourname/rk-sdk/buildroot/output/rockchip_rk356x_robot/,target=/buildroot jammy-ros2-build# 进入容器后,默认用户为builder,密码:rockchip
从RK 官方链接下载ros2-build-scripts.tar.gz(编译脚本)和ros2-sources.tar.gz(ROS2 源码),拷贝到容器内并解压:
# 1. 在Ubuntu PC端,查找容器ID(示例容器ID:c519d9d668f9)docker container ls# 2. 拷贝文件到容器的/tmp目录docker container cp ros2-build-scripts.tar.gz c519d9d668f9:/tmp/docker container cp ros2-sources.tar.gz c519d9d668f9:/tmp/# 3. 在容器内解压文件到/opt/ros目录tar zxf /tmp/ros2-build-scripts.tar.gz -C /tar zxf /tmp/ros2-sources.tar.gz -C /# 解压后,/opt/ros下会有cross-compile(交叉编译配置)和各ROS2版本目录ls /opt/ros # 输出:cross-compile foxy galactic humble iron
确保编译脚本的 Python 版本与 SDK 一致(示例 SDK 为 3.10.5,无需修改;若为 3.8.6 则需将 “310” 改为 “38”):
编辑交叉编译配置文件vim /opt/ros/cross-compile/cross-compile.mixin检查Python版本相关配置(如3.10对应310)示例:将所有"3.10"改为"3.8"(若SDK为Python 3.8.6)
进入 ROS2 版本目录(如 Iron),执行编译脚本,重点处理 “TRY_RUN 手动配置” 问题。
# 进入ROS2 Iron目录cd /opt/ros/iron# 准备源码(脚本会检查源码完整性)./prepare-source.sh
# 开始编译ROS2(耗时约15-30分钟,取决于PC性能)./build-ros2.sh# 编译成功的标志:输出类似以下内容Summary: 317 packages finished [15min 37s]build ros quit & cleanup
交叉编译时,fastrtps和rosbag2_cpp会触发TRY_RUN报错(因无法在 PC 端运行 arm64 程序),需手动在 RK 板端执行程序并记录结果。
报错信息:
CMake Error: TRY_RUN() invoked in cross-compiling mode, please set SM_RUN_RESULT and SM_RUN_RESULT__TRYRUN_OUTPUT
解决步骤:
1.将容器内的测试程序(如/buildroot/build/ros/fastrtps/cmTC_4f573)拷贝到 RK 板端;
2.在 RK 板端执行程序,记录输出:
# RK板端执行/tmp/cmTC_4f573-SM_RUN_RESULT # 输出:PTHREAD_RWLOCK_PREFER_READER_NP
1.在容器内编辑TryRunResults.cmake,填入结果:
vim /buildroot/build/ros/fastrtps/TryRunResults.cmake# 添加以下内容set(SM_RUN_RESULT "0" CACHE STRING "PTHREAD_RWLOCK_PREFER_READER_NP" FORCE)set(SM_RUN_RESULT__TRYRUN_OUTPUT "0" CACHE STRING "PTHREAD_RWLOCK_PREFER_READER_NP" FORCE)
类似处理,在 RK 板端执行测试程序后,填入结果(示例输出为缺失 liblsan.so):
vim /buildroot/build/ros/rosbag2_cpp/TryRunResults.cmakeset(HAVE_SANITIZERS_EXITCODE "127" CACHE STRING "error while loading shared libraries: liblsan.so.0" FORCE)set(HAVE_SANITIZERS_EXITCODE__TRYRUN_OUTPUT "127" CACHE STRING "error while loading shared libraries: liblsan.so.0" FORCE)
若只需编译特定包(如demo_nodes_cpp),可使用colcon build --packages-select:
# 单独编译demo_nodes_cppcolcon build --packages-select demo_nodes_cpp --cmake-args -DCMAKE_TOOLCHAIN_FILE=/buildroot/share/buildroot/toolchainfile.cmake
编译完成后,ROS2 产物已存放在/buildroot/target/opt/ros目录,需重新打包 rootfs 并烧录到 RK 板端。
在 Ubuntu PC 的 SDK 根目录,执行打包命令:
# 进入SDK根目录cd /path/to/rk-linux-sdk# 重新打包rootfs(生成rootfs.img)./build.sh rootfs
将rootfs.img烧录到 RK 板端(使用 RK 烧录工具),启动后执行以下命令运行 ROS2 Hello World:
# 进入ROS2目录cd /opt/ros/iron# 设置环境变量(指定ROS2路径和工作目录)export COLCON_CURRENT_PREFIX=/opt/ros/ironexport ROS_HOME=/userdata/source ./local_setup.sh # 加载ROS2环境# 验证ROS2环境(列出已安装包)ros2 pkg list# 运行Hello World(启动listener后台进程,再启动talker)ros2 run demo_nodes_cpp listener &ros2 run demo_nodes_cpp talker# 成功输出(类似以下内容)[INFO] [1501839280.834017748] [talker]: Publishing: 'Hello World: 1'[INFO] [1501839280.839280957] [listener]: I heard: [Hello World: 1]
适配过程中难免遇到编译或运行报错,以下是 RK 官方已验证的 10 个高频问题及解决方案,按报错场景分类。
•现象:编译中途卡顿或报错“out of memory”;
•解决方案:开启 zram 交换空间(示例分配 12G):
sudo -i sumodprobe zramecho 12G > /sys/block/zram0/disksizemkswap /dev/zram0swapon /dev/zram0free -h # 验证交换空间已生效
•现象:编译 tracetools 时报错 “Could NOT find PkgConfig”;
•原因:Docker 中未安装pkgconf(非pkg-config),或 SDK 的 host-pkgconf 与 Docker 版本冲突;
•解决方案:在 Docker 中安装 pkgconf,并指定 SDK 的 pkgconfig 路径:
# Docker中安装pkgconfsudo apt install pkgconf# 设置PKG_CONFIG_PATH(指向SDK的sysroot)export PKG_CONFIG_PATH=/buildroot/host/aarch64-buildroot-linux-gnu/sysroot/usr/lib/pkgconfig
•现象:运行 ros2 命令时,提示libstdc++.so.6: version 'GLIBCXX_3.4.30' not found;
•原因:ROS2 编译使用的工具链与 SDK 的工具链版本不匹配;
•解决方案:必须使用 RK Linux SDK 自带的交叉工具链编译 ROS2(Docker 挂载的/buildroot目录已包含该工具链)。
•现象:ROS2 的 Python 库(如_rclpy_pybind11.cpython-310-x86_64-linux-gnu.so)是 x86 架构,无法在 arm64 板端运行;
•原因:pybind11 交叉编译时默认使用 PC 的 Python 路径;
•解决方案:修改 pybind11 配置,指定 arm64 的 Python 模块后缀:
# 1. 在pybind11_vendor/CMakeLists.txt中添加list(APPEND extra_cmake_args "-DPYBIND11_PYTHONLIBS_OVERWRITE=OFF")list(APPEND extra_cmake_args "-DPYTHON_MODULE_EXTENSION=.cpython-310-aarch64-linux-gnu.so")# 2. 在cross-compile.mixin中添加相同参数
•现象:编译 ament_cmake_vendor_package 时,报错 “Could not find exlibConfig.cmake”;
•原因:交叉工具链路径与 CMAKE_PREFIX_PATH 冲突;
•解决方案:编译时不指定CMAKE_TOOLCHAIN_FILE(依赖 Docker 与 SDK 挂载的环境自动识别)。
•现象:编译 foxy 版本时,报错 “‘numeric_limits’ is not a member of ‘std’”;
•原因:benchmark_register.h缺失
•解决方案:在该头文件中添加#include
•现象:编译 mimick_vendor 时,报错 “_FORTIFY_SOURCE requires compiling with optimization (-O)”;
•原因:SDK 工具链定义了_FORTIFY_SOURCE,但未开启编译优化;
•解决方案:删除工具链中的_FORTIFY_SOURCE定义,或在编译时添加-O2优化参数。
•现象:编译 orocos_kdl_vendor 时,报错 “EIGEN3_INCLUDE_DIR NOTFOUND”;
•原因:CMake 无法找到 SDK 中的 Eigen 头文件;
•解决方案:指定 CMAKE_INCLUDE_PATH 指向 SDK 的 sysroot:
export CMAKE_INCLUDE_PATH='/buildroot/host/aarch64-buildroot-linux-gnu/sysroot/usr/include/'
•现象:编译 tracetools 时,报错 “cannot find -llttng-ust-common”;
•原因:pkg-config 找到了 Docker 的 lttng,而非 SDK 的 lttng;
•解决方案:设置 PKG_CONFIG_PATH 指向 SDK 的 pkgconfig 目录(同问题 2 的解决方案)。
•现象:编译 action_msgs 时,警告 “unsafe header path: /usr/local/lib/python3.10/dist-packages/numpy/core/include”;
•原因:Python 使用 PC 端的 numpy 路径;
•解决方案:在 cross-compile.mixin 中预设 numpy 的 include 路径(指向 SDK 的 sysroot)。
目前 RK 平台的 ROS2 适配仍有 2 个待完善项,开发者需注意:
1.删除不必要的安装文件:编译后的 ROS2 目录包含 cmake、头文件、静态库等冗余文件,未来可优化为仅保留运行必需的动态库和脚本;
2.arm32 位 rootfs 支持:当前仅支持 arm64,32 位芯片(如 RK3288)的适配仍在开发中。
RK 平台的 ROS2 适配核心是 “SDK 提供依赖 + Docker 编译 + rootfs 集成”,既解决了官方 ROS2 镜像与 RK 系统的兼容性问题,又实现了 SDK 与 ROS2 的解耦维护。
给开发者的 3 点实操建议:
1.版本匹配是前提:务必确保 SDK 的 Python 版本、Docker 镜像、ROS2 版本三者对应,避免版本冲突;
2.交叉编译多检查:编译后通过file命令验证产物架构(如file _rclpy_pybind11.so应显示“aarch64”);
通过这套流程,你可以快速在 RK356x、RK3588 等芯片上跑通 ROS2,为嵌入式机器人开发打下基础。后续可基于此扩展激光 SLAM、运动控制等功能,充分发挥 RK 芯片的硬件性能与 ROS2 的软件生态优势。

全部0条评论
快来发表一下你的评论吧 !