我手里这块树莓派4B(8GB版)在抽屉里躺了大半年,前阵子翻出来想着不能继续吃灰,干脆搭一套ROS2 Humble开发环境。整个过程走下来,其实没有太多玄学,但网上的教程东一句西一句,很多还是拿x86电脑上的命令直接搬到ARM上跑,最后各种报错找不着北。这篇文章就是把我从烧录Ubuntu 22.04、装桌面、配ROS2 Humble、搭colcon工作空间,到跑通小乌龟和RViz2的完整过程整理出来,重点是讲清楚每一步背后的原因和踩过的坑,给想在树莓派4B上玩ROS2的同学一条能直接照抄的路。
这套组合的定位也很明确:树莓派4B是ARM64架构的真实硬件,ROS2 Humble是目前资料最全、生态最稳的长期支持版,Ubuntu 22.04又是官方对应版本。三样凑在一起,既能当学习平台,也够支撑小型机器人原型验证。适合完全没碰过ROS2的小白,也适合在虚拟机里装过但想在真机上跑一遍的中手。
1. 为什么是树莓派4B + ROS2 Humble:这套组合的真实价值
1.1 树莓派4B在机器人入门场景里的生态地位
很多人纠结要不要直接在电脑上装虚拟机跑ROS2,我个人的答案是:虚拟机适合快速试水,但你要是真想往机器人方向走,迟早得在真机上装一遍。原因很直接——ROS2归根结底是给机器人用的,机器人的主控板上跑的就是Linux系统,你在虚拟机上可以方便地做网络隔离、快照恢复,但到了真实场景里,GPIO、串口、CAN总线、电机驱动板这些硬件接口,虚拟机一概给不了你。
树莓派4B在入门级机器人主控里几乎是绕不开的选择。四核Cortex-A72,最高8GB内存,32GB以上的SD卡或者SSD硬盘,跑一个轻量桌面加ROS2 Humble完全够用。更关键的是它用的是ARM64架构,很多量产机器人主控(像NVIDIA Jetson系列、各种RK3588开发板)也是这个体系,你在树莓派上积累的编译习惯、依赖管理经验,换到别的ARM板子上基本无缝迁移。
当然,2GB版树莓派4B我不建议用来跑桌面版ROS2,内存会非常紧张。如果手里只有2GB版,要么老老实实装Server系统、不装桌面,通过SSH操作;要么就去整一块4GB以上的板子。8GB版目前价格已经稳定,性价比很合适。
1.2 Humble版本选型与Ubuntu 22.04的对应关系
ROS2从Foxy开始已经有了好几个发行版,很多人一上来就懵:到底装哪个?先看一张对应关系表就清楚了。
| ROS2发行版 | 对应Ubuntu版本 | 维护状态 |
|---|---|---|
| Foxy Fitzroy | 20.04 | 已停止维护 |
| Galactic Geochelone | 20.04 | 已停止维护 |
| Humble Hawksbill | 22.04 (Jammy) | 长期支持,维护到2027年 |
| Iron Irwini | 22.04 | 短期支持,已过支持期 |
| Jazzy Jalisco | 24.04 | 新一代LTS,生态还在沉淀 |
Humble对应Ubuntu 22.04 Jammy,这个版本号锁定关系不是随便配的,ROS2官方在每个发行版发布前会做大量CI测试,确保特定Ubuntu版本下软件依赖不出问题。选Humble的原因特别实际:它是目前教程覆盖最广、第三方硬件驱动兼容性最好的版本,很多传感器、激光雷达、IMU的SDK都优先适配Humble。Jazzy虽然新,但24.04在树莓派4B上的资源占用更高,不少老教程还来不及更新,新手踩坑的代价更大。
另外提醒一句:树莓派4B上一定要装64位系统,对应软件架构是arm64。别为了兼容旧项目去装32位系统,ROS2 Humble的很多包在32位源里已经停止更新了,后面装依赖会各种缺胳膊少腿。
2. 把Ubuntu装进树莓派4B:从烧录到首次启动
2.1 镜像选择:为什么推荐Server镜像配合手动装桌面
标题写的是Ubuntu Desktop,但我实际操作时推荐的是另一条路线:先烧Ubuntu Server镜像,装系统后再手动装桌面环境。原因很简单,树莓派4B的硬件性能摆在那里,完整版Ubuntu Desktop默认带着GNOME桌面,内存占用动不动就上2GB,再叠加RViz2这种吃内存的图形工具,板子会卡到你怀疑人生。
更好的方案是装Ubuntu Server 22.04官方树莓派镜像,这个镜像是arm64架构,先从树莓派官方下载。烧录完成后,用SSH远程登录系统,再执行命令安装轻量桌面。我选择的是Xfce桌面(对应软件包是xubuntu-desktop),它比GNOME轻得多,在4GB内存的树莓派上跑RViz2也能保持可用帧率。
如果你确实想直接装Desktop,树莓派官方也提供过Ubuntu Desktop镜像,但那个是给树莓派5或更高性能设备准备的,4B跑起来风扇狂转、界面掉帧,没有必要自己折腾自己。
2.2 烧录、首登与基础配置三步走
烧录工具直接用树莓派官方的Raspberry Pi Imager,纯图形界面,选择自定义镜像文件后,把下载好的Ubuntu Server镜像路径填进去就行。烧录之前,Imager会让你设置几个关键参数:Wi-Fi的SSID和密码、是否开启SSH、默认用户名和密码,这些一定要在这个阶段就配置好,否则第一次启动后无头设备(没接屏幕和键盘)很难处理。
烧录完成后,把SD卡插进树莓派4B,通电启动。Ubuntu Server首次启动默认用户名是ubuntu,密码是ubuntu,系统会强制你改密码。如果你在Imager里自定义过用户名密码,就直接用自己设置的登录。
SSH连接成功后,第一件事是更新软件源。这里有个坑我特意说一下:树莓派上的Ubuntu Server用的是ports.ubuntu.com这个源地址,不是普通x86机器上的archive.ubuntu.com,很多人换源时没意识到这一点,把源配置改错了,后面apt更新一堆报错。
编辑/etc/apt/sources.list.d/ubuntu.sources文件(22.04已经改成deb822格式),把其中的ports.ubuntu.com地址替换成国内镜像站地址。替换完执行:
sudo apt update && sudo apt upgrade -y系统更新完,安装桌面环境:
sudo apt install xubuntu-desktop -y这个包会拉入Xfce桌面、LightDM登录管理器等一整套组件,体积不小,安装过程在树莓派上可能要等十几分钟。装完执行sudo reboot,重启后接上显示器,或者用VNC远程访问,就能看到桌面登录界面了。
这里额外说一个与电源相关的坑:树莓派4B对供电质量很敏感,官方建议5V/3A。如果用了劣质充电头或者线材太细,高负载安装阶段就会突然重启,非常折磨。我建议直接上官方电源适配器,别在这上面省那几十块钱。
3. ROS2 Humble安装两条路线:官方二进制源与社区脚本的取舍
3.1 官方二进制源安装的完整命令
在树莓派上安装ROS2 Humble,有两种主流方式:一是添加官方二进制源然后apt安装,二是用社区的一键安装脚本。这部分我先把官方二进制源命令整套贴出来,后面再细说两条路线的差异。
首先安装基础工具并添加ROS2软件源:
sudo apt update && sudo apt install curl gnupg lsb-release -y sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key \ -o /usr/share/keyrings/ros-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] \ http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" | \ sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null执行完源配置,更新并安装核心包:
sudo apt update && sudo apt upgrade -y sudo apt install ros-humble-desktop -yros-humble-desktop这个包里包含了ROS2核心、常用消息类型、RViz2可视化工具、demo例程、turtlesim小乌龟等等,一套装完就能直接开始体验。如果想更精简一点,也可以装ros-humble-ros-base,只保留最基础的功能,之后的图形化组件按需零散安装。不过对于大多数新手,desktop一次到位更省心,结束时也更容易和教程里的命令对得上。
安装完成后设置环境变量:
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc source ~/.bashrc然后再补几个必备的Python开发工具:
sudo apt install python3-colcon-common-extensions python3-argcomplete python3-rosdep -ycolcon是编译ROS2功能包的工具,argcomplete提供命令行自动补全,rosdep负责自动解析功能包的依赖关系。这三个工具后边建工作空间和编译功能包都会用到,现在装好省得以后再补。
验证一下安装结果:
ros2 pkg list | head如果能看到一大串包名输出,说明ROS2命令已经可以用了。装完环境确实没有问题,但这里要提醒:如果ros2命令找不到,八成是source没写进~/.bashrc,或者终端没有重开。
3.2 “一键安装”的实际体验与风险控制
社区里流行的“一键安装”脚本(比如鱼香ROS的一键安装命令)本质上就是把上面这些配置步骤封装成一段shell脚本自动执行。方便是真方便,适合你已经对流程烂熟于心、需要快速重装环境的场景。
但我对新手有个建议:第一次装,强烈建议手动敲一遍命令。原因不是脚本本身不好,而是你要知道每一步到底做了什么。脚本一旦运行,它会自动下载ros.key、写入源、安装一堆文件,中间任何一个环节出问题,报错信息是打包输出的,你根本不知道瓶颈在哪儿。我自己第一次装的时候也偷懒用了脚本,结果树莓派上网络拉取超时,脚本报了段错误信息,我足足折腾了一个多小时才定位到是ros.key下载环节的问题。
另外要留意的是,一键脚本通常会替换你的源配置文件,有的还会往~/.bashrc里追加几条环境变量。如果你的树莓派上还装了Anaconda或其他需要管理PATH的软件,这种自动追加可能会引起冲突。所以用它之前至少大致扫一眼脚本内容,确认没有做奇怪的操作。
3.3 环境变量与ROS_DOMAIN_ID的配置逻辑
ROS2用的环境变量不算多,最核心的是source脚本那一行,但还有一个很容易忽略的变量——ROS_DOMAIN_ID。ROS2在不同设备之间通信时,靠这个ID区分不同机器人系统。所有节点都使用默认的0,一般单机跑没问题;但如果屋里有好几套ROS2设备同时开机,同一网络的节点可能会彼此干扰,这时候给不同设备设不同的域ID就能隔离。
echo "export ROS_DOMAIN_ID=1" >> ~/.bashrc我一般习惯在一开始就把这个变量写进~/.bashrc,省得以后搭建多机器人通信时再回头查。除了这个,ROS2还依赖DDS(数据分发服务中间件)做底层通信,树莓派上默认安装的是Fast DDS,这部分先知道有这么回事,后面排错的章节我再细讲。
4. 创建和编译自己的ROS2工作空间:colcon实战
4.1 colcon的工作空间结构
ROS2里推荐用colcon来管理项目编译,它替代了ROS1时期的catkin。工作区是colcon默认的目录结构,标准做法是这样:
mkdir -p ~/ros2_ws/src cd ~/ros2_ws创建出来的目录结构里会包含src(源码目录)、build(中间编译产物)、install(安装好的功能包)、log(编译日志)。其中install目录里的内容才是最终被调用的,所以每次编译完都要source install/setup.bash,让系统能找到新的功能包。
4.2 创建一个Python功能包并编译
进入src目录,用ros2 pkg create创建一个功能包:
cd ~/ros2_ws/src ros2 pkg create --build-type ament_python my_py_node这个命令会生成一个包含package.xml、setup.py、setup.cfg和src目录的Python功能包骨架。接下来我直接在my_py_node目录下写一个简单的发布者节点,文件放在my_py_node/my_py_node/talker.py:
import rclpy from rclpy.node import Node from std_msgs.msg import String class Talker(Node): def __init__(self): super().__init__('talker') self.pub = self.create_publisher(String, '/chatter', 10) self.timer = self.create_timer(1.0, self.tick) self.count = 0 def tick(self): msg = String() msg.data = f'Hello from 树莓派: {self.count}' self.pub.publish(msg) self.count += 1 def main(args=None): rclpy.init(args=args) node = Talker() rclpy.spin(node) rclpy.shutdown() if __name__ == '__main__': main()写完代码还不能直接运行,需要在setup.py的entry_points里注册这个脚本。打开setup.py,找到类似这部分:
entry_points={ 'console_scripts': [ 'talker = my_py_node.talker:main', ], },保存后回到~/ros2_ws目录编译:
cd ~/ros2_ws colcon build --symlink-install这里用--symlink-install是给Python开发用的:它会以软链接方式把源码连接到install目录,后续改代码不用重新编译,直接就能生效。对树莓派这种编译耗时偏长的设备来说,这个参数非常友好。
编译完成后激活工作空间,然后运行节点:
source install/setup.bash ros2 run my_py_node talker再开一个终端,用话题监听工具看看数据有没有发出来:
source /opt/ros/humble/setup.bash source ~/ros2_ws/install/setup.bash ros2 topic echo /chatter能看到不断刷新的字符串,说明自己的工作空间已经能正常发布和订阅消息了。这一步跑通,基本可以认为你的ROS2环境已经真正能用于开发。
4.3 ARM设备上编译的注意事项
树莓派上编译功能和x86电脑有一个非常大的区别:内存和CPU都很有限。如果你一次性在工作空间里放了多个功能包,然后直接colcon build,colcon默认会尽可能多地并行编译,很快内存就见底,轻则编译速度骤降,重则直接OOM(内存溢出)卡死。
碰到这种情况,我一般会调整并行度:
colcon build --parallel-workers 1牺牲一点编译速度,换取稳定性。另外建议给系统配置一点swap或者zram,给内存加个缓冲。安装命令很低成本:
sudo apt install zram-tools -y sudo systemctl enable zramswap sudo systemctl start zramswapzram本质上是用压缩内存做交换空间,比传统磁盘swap快得多,树莓派这种SD卡IO不强的设备上体验尤其明显。
5. 跑通小乌龟和RViz2:用可视化验证ROS2核心通信能力
5.1 小乌龟:快速验证发布订阅机制
小乌龟(turtlesim)是ROS2自带的教学示例,本身不复杂,但用它验证ROS2的核心通信机制非常高效。ROS2里所有节点之间通信都靠话题(Topic)、服务(Service)、动作(Action)这三种机制,小乌龟能覆盖前面两种。
安装和启动很简单:
sudo apt install ros-humble-turtlesim -y ros2 run turtlesim turtlesim_node会弹出一个蓝色背景的仿真窗口,里面有一只小乌龟。然后另开一个终端,启动键盘控制节点:
source /opt/ros/humble/setup.bash ros2 run turtlesim turtle_teleop_key在这个终端里按方向键,小乌龟就会移动、画线。此时再开一个终端,执行:
ros2 node list ros2 topic list ros2 topic echo /turtle1/cmd_velros2 node list能看到两个节点,topic list能看到/turtle1/pose、/turtle1/cmd_vel等话题,topic echo能实时看到键盘控制节点发布的线速度和角速度消息。别看这几个命令简单,它们就是后续调试机器人运动控制的老本行,熟记绝对不亏。
树莓派4B跑小乌龟的体验整体流畅,如果感觉画面掉帧,大概率是桌面特效占用了太多CPU,可以在Xfce的“设置-窗口管理器微调”里关掉部分合成特效。
5.2 RViz2:可视化工具启动与软件渲染优化
RViz2是ROS2里最常用的3D可视化工具,激光雷达点云、机器人模型、导航路径、代价地图都要靠它来看。安装命令:
sudo apt install ros-humble-rviz2 -y ros2 run rviz2 rviz2启动后第一次打开,窗口里只有地面网格和坐标轴,默认Fixed Frame是map。如果之后要显示机器人模型,就把Fixed Frame改成odom或者base_link,再点击Add添加相应显示组件。树莓派上跑RViz2最大的问题是没有独立GPU,默认的硬件加速在树莓派上其实走的是软件渲染,大点云场景下会很吃力。
一个小技巧是通过环境变量强制走软件渲染,并降低渲染质量:
LIBGL_ALWAYS_SOFTWARE=1 ros2 run rviz2 rviz2在RViz2的Display面板里,把渲染相关的抗锯齿关掉,也能帮上不少忙。我实际测试下来,在Xfce桌面下,禁用抗锯齿后的RViz2即使显示了个把万级的点云,帧率也还能保持在可交互范围。
树莓派上RViz2的主要用途是调demo和看教学数据。真到了要跑导航建图那一步,比如打算玩SLAM建图、octomap八叉树地图、Nav2导航,RViz2基本都是主力观察窗口。这些场景对性能要求更高,到那时候就得考虑换更好的散热方案,或者干脆把采集端(树莓派)和可视化端(PC)分离,这也是后面可以扩展的方向。
5.3 树莓派上的性能观察与内存检查
跑图形界面之前,建议先确认系统资源余量。用htop或者最简单的:
htop free -h看几个核心指标——CPU占用率、内存剩余、zram的交换量。我实测过:8GB版树莓派,Xfce桌面加一个RViz2窗口加两三个ROS2节点,内存占用大概稳定在3GB上下,还有富余。4GB版也可以接受。但如果你是2GB版,建议只跑ros-humble-ros-base加上ros2 run rviz2,能起来但会很吃力。
如果内存经常爆红,检查一下是不是跑了一堆不用的服务节点。ROS2开发中对比调试很常见,开着开着终端里就堆了很多node,这时候用ros2 node list看看当前所有节点,及时Ctrl+C关掉不用的。
6. 树莓派上的常见坑与答案:从镜像拉取失败到DDS通信异常
6.1 ros.key下载超时与软件源连接不稳定
很多人在添加ROS2源时,卡在ros.key那个curl命令上,各种超时。这个文件本质是用于apt校验包完整性的公钥,如果一直超时,有几个办法可以处理:
第一,用curl时加上重试参数,网络波动大的时候能提高成功率:
sudo curl -sSL --retry 5 --retry-delay 3 https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg第二,如果你的网络环境跟海外服务器连接本身就很差,可以先从其他渠道(比如国内镜像站同步的ros仓库)下载ros.key文件,再放到/usr/share/keyrings/目录,效果一样。
第三,添加源文件时,确认写入的仓库地址能正常访问。如果官方源连不上,可以把packages.ros.org那一行替换成国内维护的镜像仓库地址,这类镜像通常在网络可达性和速度上都更好。
这个问题的核心思路是:apt源没有就必须换一个可达的源,别死磕。
6.2 拉取micro-ROS agent镜像失败的定位
玩micro-ROS(让ESP32这类单片机接入ROS2的框架)时,一个常见命令是:
sudo docker pull microros/micro-ros-agent:humble如果本机没有这个镜像,Docker会尝试从Docker Hub拉取。报错unable to find image 'microros/micro-ros-agent:humble' locally,字面意思就是本地确实没有该镜像,需要从远程仓库下载。如果你看到这个报错后命令卡住,或者反复拉取失败,问题就出在Docker拉取源的网络连接上。此时给Docker配置镜像加速器是常规做法,在/etc/docker/daemon.json里加上registry-mirrors配置,重启Docker后再拉。这个报错本身不是ROS2的问题,但因为它出现得很频繁,我专门提一下。
6.3 节点发现不了彼此:DDS多播与ROS_DOMAIN_ID
这是树莓派上跑ROS2最容易困惑的报错之一:你在终端A里启动了一个节点,终端B里ros2 node list却看不到它。ROS2的节点发现依赖DDS协议,默认使用多播(Multicast)在同一局域网内互相发现。如果树莓派连的是Wi-Fi,路由器开了AP隔离(客户端之间禁止访问),多播包就会被拦掉,节点自然互相看不见。
排查思路按顺序来:
- 确认两个终端的ROS_DOMAIN_ID一致。不一致是头号原因。
- 确认两台设备在同一网段,并且网络层可以互通,直接用ping测。
- 检查防火墙(UFW或iptables),尤其是树莓派默认不装防火墙,但如果你之前手动开过,就要注意有没有阻挡DDS端口。
- 如果Wi-Fi下实在不通,直接把树莓派和电脑接在同一台交换机/路由器网口,用有线方式测试。有线网络的多播支持比Wi-Fi稳定得多。
我个人的经验是:树莓派做机器人主控,能接有线网线就接有线,不仅是DDS发现,数据传输延迟也会好看很多。
6.4 硬件层面的坑:供电、散热与SD卡
树莓派跑ROS2高负载编译时,对硬件稳定性要求一下就上来了。遇到莫名重启,先怀疑供电。5V/3A是底线,线材也要用够粗的,USB口直接给树莓派供电时,如果拖了太多外设,电压跌落就会触发重启保护。
散热问题也容易忽略。树莓派4B在满负载编译时,CPU温度能轻松飙到85摄氏度以上,一旦触达温度墙就会降频,表现出来就是“编译到一半突然变慢”。加个散热片加个小风扇,成本很低,效果立竿见影。查看温度命令:
vcgencmd measure_temp超过80摄氏度,基本就是散热不够了。
SD卡的选用也直接影响体验。尽量选A2规格的卡,持续写入速度比普通卡快不少。树莓派整个系统包括编译中间文件都跑在SD卡上,卡的速度决定了安装软件和编译功能的整体节奏。有条件甚至可以USB外接SSD启动,那是另一个话题了,但对4B来说,SD卡确实是性能短板之一。
还有一个容易被忽视的问题:SD卡损坏。树莓派跑ROS2,各种日志和缓存频繁写入,劣质SD卡很容易在几个月之内出现坏块,表现就是系统无缘无故卡死、文件损坏。建议装完系统、配好环境之后,用dd命令把整个SD卡备份成一个镜像,之后万一卡坏了可以直接回刷。
最后分享一个个人习惯:每次在树莓派上跑通一个功能包,我会顺手把当时的系统状态、依赖版本、关键命令记到本地笔记里,然后在安装成功那一刻用Win32DiskImager之类工具备份一次整卡镜像。这套环境搭建一次不算难,但重装一次也是实打实的几个小时。环境备份真的是树莓派开发里最值得花的几分钟,尤其是你后面还打算往SD卡里塞micro-ROS、Nav2这类重量级组件的时候,一张干净的备份卡能救你很多次。