拿到一块新的ARM开发板,兴冲冲刷好Ubuntu 22.04,按照网上的教程开始装ROS2 Humble,结果从换源开始就一路踩坑,装到深夜心态炸裂——这个场景我相信不少搞机器人、嵌入式的小伙伴都经历过。我最近在树莓派4B和一块RK3588的开发板上分别完整走了一遍ROS2 Humble的安装流程,中间踩过的坑、绕过的弯路,感觉值得整理成一份能直接照着抄的避坑指南。
这篇文章围绕ARM架构下Ubuntu 22.04安装ROS2 Humble的完整链路展开,重点解决三类问题:一是系统层面的软件源配置与基础环境准备,二是ROS2 Humble安装过程中ARM板特有的坑,三是装完之后如何验证环境、规避后续开发的隐患。如果你用的是树莓派、香橙派、RK3588这类ARM开发板,或者是在ARM云主机上折腾ROS2,这篇文章应该能帮你省下好几个晚上的时间。
1. 为什么是Ubuntu 22.04 + ROS2 Humble + ARM板这套组合
1.1 版本匹配关系:不是随便选的
ROS2的版本和Ubuntu系统版本有严格的对应关系,这一点和ROS1时期“一个ROS版本适配多个Ubuntu”的做法完全不同。ROS2 Humble Hawksbill是2022年5月发布的LTS版本,官方支持期限到2027年,它对应的操作系统是Ubuntu 22.04 Jammy。这个对应关系在ROS2的官方文档里写得很清楚,但很多人装的时候会忽略这一点。
如果你在Ubuntu 20.04上强行装Humble,依赖关系会乱成一锅粥;反过来,在Ubuntu 24.04上装Humble虽然部分能用,但官方并不保证所有功能正常,因为24.04对应的ROS2版本是Jazzy。所以选择Ubuntu 22.04 + ROS2 Humble并不是巧合,而是ROS2版本迭代机制决定的。
ARM开发板这块,情况要复杂一些。树莓派4B用的是ARMv8-A架构的Cortex-A72,属于64位ARM,可以跑arm64版本的Ubuntu。RK3588同样支持arm64。这里有一个关键点:ROS2官方对ARM架构的支持分为arm64和armhf,前者是64位,后者是32位。现在的开发板主流都是64位,建议直接选择arm64版本的Ubuntu镜像,性能和兼容性都更好。
1.2 不同ARM开发板的选型差异
我在树莓派4B(8GB版)和RK3588开发板上都实测过,两者装ROS2 Humble的流程基本一致,但有几个细微差别:
| 开发板 | 处理器架构 | 内存 | 系统镜像注意事项 | ROS2安装体验 |
|---|---|---|---|---|
| 树莓派4B | ARMv8-A (Cortex-A72) | 2/4/8GB | 建议官方Ubuntu Server 22.04.3 arm64 | 可用,但编译大包时偏慢 |
| 树莓派5 | ARMv8-A (Cortex-A76) | 4/8GB | 官方已支持,性能提升明显 | 体验较好 |
| RK3588系列 | ARMv8.2-A (Cortex-A76+A55) | 4~32GB | 各厂商镜像质量参差,建议选纯净版 | 性能充裕 |
| 香橙派5系列 | ARMv8-A | 4/8/16GB | 注意区分32位和64位固件 | 可用 |
对于内存只有2GB的开发板,装ros-humble-desktop会比较吃力,建议选择ros-humble-ros-base,后续缺什么包再单独补。内存4GB及以上的板子,直接上desktop版本问题不大。
1.3 为什么直接上ROS2而不是ROS1
现在还有一些教程推荐装ROS1 Noetic,但Noetic在2025年已经停止维护,而且对于新项目来说,ROS2的分布式通信、DDS中间件、生命周期节点等设计更符合现代机器人系统的需求。Humble作为ROS2的LTS版本,社区积累的教程和资料已经相当丰富,生态也逐渐成熟。如果你不是要复现一个老项目,没必要从ROS1开始了。
2. 系统准备阶段最容易翻车的三个细节
2.1 ARM版Ubuntu镜像怎么选才不坑
不管是树莓派还是RK3588,选系统镜像都要留个心眼。树莓派推荐直接去Ubuntu官网下载,选择Ubuntu Server 22.04.3 LTS (Jammy Jellyfish)的arm64版本,格式是ubuntu-22.04.3-preinstalled-server-arm64+raspi.img.xz,用官方的Raspberry Pi Imager烧录就行。
RK3588开发板的情况要复杂一些,不同厂商提供的Ubuntu镜像差异很大。有的厂商镜像预装了一堆东西,有的甚至不是标准Ubuntu,而是基于Debian魔改的。这里我的建议是:优先选厂商提供的“纯净版”Ubuntu 22.04镜像,尽量不要选带桌面环境的一体化镜像。因为开发板上很多预装环境会和ROS2的依赖产生冲突,到时候排查起来非常痛苦。
烧录工具方面,树莓派直接用Raspberry Pi Imager即可;RK3588一般用balenaEtcher或者dd命令。烧录完成后,首次开机建议连接显示器和键盘操作,避免一上来就折腾SSH——ARM板的网络配置经常会出现一些奇怪的问题。
2.2 换源之前先搞清楚架构:apt源的arm64坑
这是很多人忽略的问题。ARM开发板换源时,必须使用支持arm64架构的软件源。阿里云、清华、中科大的Ubuntu源都支持arm64,但在写sources.list的时候要注意格式。
apt源地址里的$ARCH或者直接路径必须正确。Ubuntu 22.04的软件源配置文件是/etc/apt/sources.list,从Ubuntu 22.04开始推荐使用.sources格式的DEB822源文件(/etc/apt/sources.list.d/ubuntu.sources)。
我用阿里云源的操作是这样的:
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak sudo bash -c 'cat > /etc/apt/sources.list << EOF deb https://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse deb https://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse deb https://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse deb https://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse EOF'但如果你用的是新版.sources文件格式,则需要这样写:
sudo nano /etc/apt/sources.list.d/ubuntu.sources把其中的URIs字段改为https://mirrors.aliyun.com/ubuntu/即可。
换源之后执行sudo apt update,注意观察是否有Error提示。如果输出里出现Ign(忽略)或者404 Not Found,通常是因为某些软件包在arm64架构下不存在,这属于正常现象,不影响核心安装。
2.3 pip源、git源、以及hostname的网络问题
换源不只是换apt源。安装ROS2过程中需要用到colcon等Python工具,pip默认源在国内安装速度很慢,建议一并换成阿里云pip源:
mkdir -p ~/.pip cat > ~/.pip/pip.conf << EOF [global] index-url = https://mirrors.aliyun.com/pypi/simple/ timeout = 120 EOFgit拉取ROS2源码时如果速度不理想,可以考虑使用ghproxy等加速服务,但注意Humble用apt方式安装其实不太需要走git拉源码,除非你要编译特定的功能包。
hostname方面,ARM板装上系统后默认主机名可能是ubuntu或者厂商设定的名称。ROS2分布式通信依赖DDS,而DDS对网络环境变化比较敏感。建议在装ROS2之前就把hostname改成有意义的名字,比如ros2master,并确保/etc/hosts中的解析正常:
sudo hostnamectl set-hostname ros2master echo "127.0.0.1 $(hostname)" | sudo tee -a /etc/hosts如果这一步偷懒,后面在多台开发板之间做ROS2分布式通信时,经常会出现节点互相发现不了的情况,排查起来会让人崩溃。
3. ROS2 Humble安装全程记录与关键踩坑点
3.1 官方推荐的安装方式:apt比源码香
ROS2的安装方式主要分两种:apt二进制包安装和源码编译安装。
对于ARM开发板,我的强烈建议是用apt方式安装。原因很简单:源码编译在ARM板上耗时太长,ros-humble-desktop如果从源码编译,在树莓派4B上可能要跑好几个小时甚至更久,而且过程中容易因为内存不足被kill掉,体验很差。
apt安装方式的核心步骤在ROS2官方文档里有详细说明,但有几个坑需要单独提示。
3.2 设置locale时不要跳过
官方文档的第一步是设置locale支持UTF-8:
sudo apt update && sudo apt install -y locales sudo locale-gen en_US en_US.UTF-8 sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 export LANG=en_US.UTF-8很多教程说这一步可以跳过,实际操作中发现如果locale设置不正确,后续rosdep和colcon工具运行时会报一些奇怪的字符编码错误。所以这一步别偷懒,一次执行到位。
3.3 添加ROS2源:阿里云ROS源的正确添加方式
官方源的地址是https://packages.ros.org/ros2/ubuntu,在国内访问偶尔会超时。这里可以换成阿里云的ROS2镜像源。
首先安装必要的工具并添加ROS2 GPG Key:
sudo apt update && sudo apt install -y curl gnupg lsb-release sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg这里有一个非常关键的坑:raw.githubusercontent.com在国内经常无法直接访问,导致curl这步失败。网上很多教程写到这一步就断了,解决方案有几种:
方案一:先想办法把ros.key文件下载到本地(比如用代理或者从国内镜像获取),然后手动放到位。如果你电脑上有这个文件,用U盘拷贝过去也行。
方案二:使用清华大学或者中科大提供的ROS2镜像源中带的key文件。清华源的地址是https://mirrors.tuna.tsinghua.edu.cn/ros2/ubuntu.key,可以尝试:
sudo curl -sSL https://mirrors.tuna.tsinghua.edu.cn/ros2/ubuntu.key -o /usr/share/keyrings/ros-archive-keyring.gpg拿到key之后添加软件源,以阿里云为例:
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] https://mirrors.aliyun.com/ros2/ubuntu jammy main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null注意这个源地址是https://mirrors.aliyun.com/ros2/ubuntu,不要和apt的https://mirrors.aliyun.com/ubuntu/搞混。添加完成后执行:
sudo apt update如果这一步能够正常获取到ROS2的包列表,说明软件源配置成功。
3.4 安装ROS2包:桌面版还是基础版
安装命令很简单,但选什么包取决于你的需求和使用场景:
# 基础版(不含GUI工具,适合服务器或资源受限的板子) sudo apt install -y ros-humble-ros-base # 桌面版(含rqt、rviz2等图形化工具,推荐) sudo apt install -y ros-humble-desktop # 开发工具(编译功能包时必备) sudo apt install -y ros-dev-tools这里补充说明一下ros-dev-tools,它是一个元包,会帮你装好colcon、rosdep、ament等一系列ROS2开发常用的命令行工具。如果不装这个,后续自己创建功能包、编译工作空间的时候会缺很多东西。
对于内存充足的开发板(4GB及以上),直接装ros-humble-desktop没错。2GB内存的板子建议先装ros-humble-ros-base,因为你大概率跑不动rviz2,装了反而吃内存。
3.5 环境变量配置与自动加载
安装完成后,需要把ROS2的环境变量加载到shell中:
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc source ~/.bashrc这个步骤人人都会做,但有一个高频错误:如果你用的是zsh而不是bash,这行要写入~/.zshrc。另外,如果同时装了ROS1和ROS2,环境变量会互相冲突,建议在~/.bashrc中做条件判断。
4. ARM板上独有的三个大坑:内存、中间件、权限
4.1 编译功能包时的OOM问题与swap配置
ARM开发板相比x86 PC,最大的弱势就是内存。我自己在树莓派4B上编译一些功能包时,遇到最多的问题就是编译器被OOM Killer干掉,终端直接提示Killed,没有任何报错信息,就像凭空消失了一样。
排查和解决思路如下:
先看当前内存和swap情况:
free -h如果swap为0或者很小,建议先扩容swap。创建一个4GB的swap文件(对于树莓派4B够用了):
sudo fallocate -l 4G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab同时降低编译时的并发度。很多人习惯用colcon build --parallel-workers 4来加速编译,但ARM板上4个并发编译进程很容易把2GB内存吃满。我的建议是:
colcon build --parallel-workers 2或者让系统根据可用内存自动调整:
colcon build --parallel-workers $(nproc --ignore 1)另一个技巧是使用MAKEFLAGS环境变量控制Make的并发数:
export MAKEFLAGS="-j2" colcon build这两个配合使用,能有效降低OOM的发生概率。
4.2 DDS中间件选型:Fast-DDS还是CycloneDDS
ROS2的通信底层基于DDS,默认使用的中间件实现是Eclipse CycloneDDS(Humble版开始在某些平台上默认)或者Fast-DDS(具体看发行版配置)。Humble默认推荐Fast-DDS,但实际使用中,两者在性能、资源占用、发现机制上各有差异。
在性能较弱的ARM板子上,Fast-DDS的资源占用偏高,而且它的默认discovery机制(通过多播发现节点)在某些网络环境下会变得非常慢。如果你发现两个节点运行起来之后要等好几秒才能互相发现,那问题大概率出在DDS的发现机制上。
可以尝试把默认中间件切换为CycloneDDS:
sudo apt install -y ros-humble-rmw-cyclonedds-cpp echo "export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp" >> ~/.bashrc source ~/.bashrcCycloneDDS在资源受限的嵌入式平台上通常表现更好,启动发现速度更快。切换中间件之后,记得重新运行你的节点测试,确认通信正常。
如果你要做多机通信,还需要注意DDS发现域的问题。ROS2默认的domain ID是0,多台设备在同一个局域网内如果都是一个ID,那么节点之间会自动发现并通信。但如果网络环境存在多个子网,或者有防火墙拦截了多播报文,就需要手动指定网卡:
export ROS_AUTOMATIC_DISCOVERY_RANGE=LOCALHOST或者设置ROS_DOMAIN_ID避免跨设备干扰。这部分展开讲很深,但作为安装后的头等注意事项,值得先了解一下。
4.3 用户组与设备权限:串口、摄像头、GPIO
开发板玩机器人必然要接串口、摄像头、雷达这些外设,而Linux下访问这些设备需要对应的权限。
把当前用户加入dialout组是ROS2嵌入式开发的惯用操作:
sudo usermod -aG dialout $USER sudo usermod -aG video $USER sudo usermod -aG i2c $USER sudo usermod -aG gpio $USER不同开发板用户组名称略有差异。树莓派上GPIO的组是gpio;RK3588的厂商镜像有的用的是gpio,有的直接root操作权限。加入用户组之后要重新登录或者重启才能生效,这是很多人容易忽略的一个环节——加完组立刻执行ls /dev/ttyUSB0发现没有权限,然后怀疑人生。
还有一个小坑是很多ARM板的串口设备名不是ttyUSB0而是ttyS0或者ttyAMA0,访问权限和性能表现都不一样。建议先执行ls /dev/tty*确认设备名,再配置串口权限。
5. 安装完成后的自检验证与常见错误处理
5.1 用talker/listener快速自检
装完之后我的习惯是,第一步先跑官方自带的C++和Python示例,确认通信链路通畅:
source /opt/ros/humble/setup.bash ros2 run demo_nodes_cpp talker新开一个终端:
source /opt/ros/humble/setup.bash ros2 run demo_nodes_py listener如果talker在发送,listener在接收,基本可以确认ROS2的核心机制没毛病。如果listener收不到消息,优先检查防火墙:
sudo ufw status如果防火墙是开启状态,要么临时关闭(不建议生产环境这么做),要么放行对应端口。ROS2默认使用多播和动态端口,最省事的做法是让DDS流量通过局域网网卡,而不是简单地把防火墙关闭了事。
5.2 排查工具:ros2 doctor和日志
如果出现问题,ros2 doctor是一个很实用的诊断命令。它会对系统环境、软件包状态、网络配置做一次全面体检:
ros2 doctor --report这个命令会输出很多信息,重点关注下面的System和ROS 2两部分。如果出现warning级别的提示,大部分不影响使用,但如果出现error级别的信息,就需要逐一排查了。
日志方面,ROS2把运行日志默认存储在~/.ros/log/目录下。排查节点崩溃、莫名退出的问题,去这个目录里找最新的log文件,往往比盯着终端输出有效得多。
5.3 创建第一个工作空间并编译一个功能包
自检通过之后,我建议再创建一个最小的C++功能包,完整走一遍编译流程,确保colcon和ament工具链正常工作:
mkdir -p ~/ros2_ws/src cd ~/ros2_ws colcon build source install/setup.bash ros2 pkg create --build-type ament_cmake test_pkg --node-name test_node colcon build --packages-select test_pkg如果编译过程中报错Package 'test_pkg' not found,检查一下是否忘了source install/setup.bash。这个失误非常常见,不管我自己还是身边朋友都跳过这个坑。
还有一个ARM板上比较常见的报错是undefined reference to ...,这通常跟编译器版本或者缺少某些依赖库有关。解决办法是先检查依赖是否装全:
rosdep install --from-paths src -y --ignore-src这个命令会自动分析src目录下所有功能包的依赖,并尝试通过apt安装缺失的库。注意第一次运行rosdep需要先初始化:
sudo rosdep init rosdep update如果rosdep update因为网络问题失败,可以考虑添加代理或者通过手动修改rosdep源的方式处理。
6. 把安装过程固化成脚本,以后刷机不怕重装
6.1 为什么建议写一个安装脚本
ARM开发板的好处是便宜,坏处是经不起折腾——系统刷坏了就重来一遍,重装一次ROS2的代价可不小。我第一次在RK3588上手动安装ROS2时花了大半天,第二次花了两个小时,第三次我已经可以在二十分钟内完成全新环境的搭设。
把安装过程固化成脚本,本质上是在编写“环境即代码”。下次换新板子或者系统被搞坏,执行一下脚本就能恢复到熟悉的ROS2环境,节省的时间相当可观。
6.2 我自己的安装脚本简化版
下面这个脚本我实测过在树莓派4B和RK3588上都能用,关键是它把前面提到的坑都绕开了:
#!/bin/bash set -e # 检查架构 ARCH=$(uname -m) if [ "$ARCH" != "aarch64" ]; then echo "当前架构为 $ARCH,本脚本仅支持aarch64(arm64)" exit 1 fi # 1. 设置locale sudo apt update sudo apt install -y locales sudo locale-gen en_US en_US.UTF-8 sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8 # 2. 换apt源为阿里云 sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak sudo bash -c 'cat > /etc/apt/sources.list << EOF deb https://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse deb https://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse deb https://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse deb https://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse EOF' # 3. 添加ROS2源(使用清华的key) sudo apt update && sudo apt install -y curl gnupg lsb-release sudo curl -sSL https://mirrors.tuna.tsinghua.edu.cn/ros2/ubuntu.key -o /usr/share/keyrings/ros-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] https://mirrors.aliyun.com/ros2/ubuntu jammy main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null # 4. 安装ROS2 sudo apt update sudo apt install -y ros-humble-desktop ros-dev-tools # 5. 配置环境变量 echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc source /opt/ros/humble/setup.bash # 6. 换pip源 mkdir -p ~/.pip cat > ~/.pip/pip.conf << EOF [global] index-url = https://mirrors.aliyun.com/pypi/simple/ timeout = 120 EOF # 7. 配置用户组(需重新登录后生效) sudo usermod -aG dialout $USER sudo usermod -aG video $USER echo "ROS2 Humble 安装完成!请重新登录系统使用。"这里有几个细节值得说明:
- 脚本最后加了
set -e,任何一步出错立即退出,方便定位问题; - key文件的获取用的是清华源,因为这个域名在国内访问比raw.githubusercontent.com稳定得多;
- 软件源用的是阿里云ROS2镜像,实测速度和稳定性都不错;
- 用户组配置完成后不会立即生效,脚本会提示重新登录,避免用户误以为已经生效。
6.3 脚本化安装的后续维护
有了脚本之后,还有一个很值得做的事:用git管理你的脚本和配置文件。ARM开发板上面做机器人开发,配置文件的版本管理同样很重要。我的做法是:
在PC上建立一个ros2-arm-setup仓库,把安装脚本、.bashrc自定义配置、DDS配置文件等放进去。每次修改配置后,提交并推送。新板子到手后,先执行安装脚本,再拉取配置文件覆盖,十分钟就能恢复到开发状态。
DDS配置文件也要单独说一下。如果你像我一样需要频繁在ARM板上调整中间件参数,建议把cyclonedds.xml放进仓库,启用时用环境变量指定:
export CYCLONEDDS_URI=file://$HOME/cyclonedds.xml这个配置文件可以控制发送缓冲区大小、网络接口、发现超时时间等参数,对嵌入式场景非常有帮助。
最后再分享一个小技巧:在ARM板上跑完安装脚本之后,登录到系统里会看到终端输出reboot的提示。别急着立刻重启,先把~/.bashrc里的内容单独打开看一眼,确认source /opt/ros/humble/setup.bash这行真的写进去了。我遇到过脚本执行成功但bashrc没写入的情况,排查半天发现是脚本里的重定向符号被转义错了。顺手检查一下,能帮你省掉重启后发现环境变量没加载的尴尬。