我手头这块树莓派4B,从买回来到现在折腾ROS2,前后刷了不下十次系统。网上教程很多,但大部分要么只讲树莓派,要么只讲ROS2,把两者放到一起按真实项目流程走的文章其实不多。这篇就把我从零开始,用树莓派跑ROS2,再到接摄像头、控制舵机、做小车、尝试建图导航的完整经历写出来,包括踩过的坑、试错的路径,以及最后沉淀下来的稳定方案。文章适合两类人:一是手里有树莓派但不知道从哪下手的零基础玩家,二是已经能跑通例程、想往实际机器人方向推进的初学者。
1. 先想清楚一个问题:你的树莓派真的要装ROS2吗
很多人上来就问“树莓派怎么装ROS2”,但很少有人先问“我的树莓派适不适合装ROS2”。这个前置问题不解决,后面会走很多弯路。我见过有人在树莓派Zero上折腾ROS2,编译到一半卡死,最后跑来问是不是命令错了——不是命令错,是板子本身跑不动。
1.1 树莓派4B和5的真实性能差距
树莓派4B(4GB版)是跑ROS2的入门底线。我自己主力用的是4B,实测跑Ubuntu 22.04 + ROS2 Humble,再挂一个USB摄像头节点和一个激光雷达节点,CPU占用在60%到80%之间浮动,内存大约占用2.5GB左右。这个负载下,树莓派的散热片温度能到65度上下,如果不加风扇、长时间跑,降频是必然的。所以如果你是4B且只有2GB内存,我的建议是老老实实跑Ubuntu Server版,不要装桌面,省下来的内存对ROS2这种多节点通信框架来说,意义非常大。
树莓派5我后来也上手试了。它的CPU性能比4B强不少,尤其在编译ROS2功能包的时候,5代编译同样的包,时间差不多是4B的一半。如果你预算允许,直接上树莓派5可以说是在硬件层面把后面三年的折腾成本都压低了。但要注意,树莓派5的供电要求是5V/5A,老款电源和普通充电宝大概率喂不饱,跑高负载时系统会直接重启,这个现象非常容易让新手误判成“系统没装好”。
1.2 什么时候该选Pico这样的轻量方案
如果你的目标不是跑完整的ROS2,只是想用树莓派Pico控制一个舵机,或者做一个简单的传感器采集,那完全没必要套ROS2。Pico这类MCU的定位是执行层,跑的是micro-ROS——这是ROS2官方为资源受限设备设计的方案,通过串口或者WiFi和上位机通信。我后来做舵机控制就想通了:Pico负责高频PWM控制,树莓派4B负责决策和通信,两者各干各的,比在树莓派上硬接舵机更稳。
具体到micro-ROS的搭建,有个很顺手的组合:树莓派上开Docker跑micro-ROS Agent,然后通过VS Code的PlatformIO插件往ESP32或Pico里烧micro-ROS固件。这套流程在GitHub上有现成的模板可以看。我第一次把Pico发出的话题在树莓派上用ros2 topic echo接收到的时候,一种“数据链路打通了”的实感非常强烈,而不是像跑例程那样只是图个亮。
1.3 系统烧录时最容易忽略的细节
树莓派系统的烧录工具,官方叫Raspberry Pi Imager。这个工具有两个地方新手容易卡:一是烧录时可以选择预配置SSH和WiFi,很多人不知道直接跳过了,结果板子起来后没法远程连接,又得拿显示器键盘去重弄;二是Imager默认会把安装程序装到C盘,如果你想把软件本体放到别的盘,安装过程中是能选路径的,别一路点“下一步”到最后才发现C盘满了。
烧录报错是另一个高频问题。如果你用的TF卡是那种杂牌扩容卡,烧录到一半报错特别正常。我的建议是:烧录失败先换一张卡,别反复重烧同一张卡。做过一次完整镜像校验比烧十次都省时间。
2. ROS2系统版本对照,以及换源和安装顺序的讲究
ROS2的版本和Ubuntu版本是严格绑定的。很多人装不上,不是操作不对,而是Ubuntu版本和ROS2版本对不上。比如ROS2 Jazzy只支持Ubuntu 24.04,你拿22.04去装,官方源里根本没有这个包。
2.1 树莓派上最常见的三组搭配
我列一下我实际用过的搭配,你可以直接照着选:
| 树莓派型号 | Ubuntu版本 | ROS2版本 | 我的评级 |
|---|---|---|---|
| 树莓派4B 2GB | Ubuntu Server 22.04 | Humble | 勉强能用,别开桌面 |
| 树莓派4B 4GB/8GB | Ubuntu 22.04 Desktop | Humble | 舒适,适合学习 |
| 树莓派5 | Ubuntu 24.04 Desktop | Jazzy | 当前最优选择 |
树莓派5如果想装旧一点的Humble,其实也能跑,但需要自己从源码编译。我没走这条路,因为Ubuntu 24.04 + Jazzy在树莓派5上的表现已经足够稳定,没必要为了“情怀”去编译一晚上。
2.2 安装步骤里的关键顺序
ROS2的安装步骤看着简单,但顺序错了很折腾。完整的流程应该是:先改软件源,再更新系统,然后装 locales 和 curl 之类的基础依赖,接着添加ROS2官方的源和密钥,最后才执行apt install ros-humble-desktop。
很多时候问题出在改了软件源但没有执行apt update,或者添加ROS2源之后没有把密钥配好。还有一个很典型的坑:在树莓派上安装ROS2的deb包时,ros-humble-desktop太大了,包含可视化工具,下载时间很长,不少人在这个环节以为卡死了。实际上放那等十来分钟很正常,实在担心的话,可以先装ros-humble-ros-base这样的小集合,之后缺什么功能再按需装。
2.3 换镜像源的边界问题
在树莓派上跑Ubuntu,默认连的是官方源,国内网络环境下速度很感人。换源是必须做的一步。这里我多说一句:换的是Ubuntu的apt源,把国内的镜像站地址替换掉/etc/apt/sources.list里的默认地址就行。操作前备份一下原文件,万一替换错了还能改回来。
树莓派OS的源和Ubuntu的源位置不一样,树莓派OS是/etc/apt/sources.list.d/下的多个文件。如果你刷的是树莓派OS而不是Ubuntu,换源方式别照搬Ubuntu教程,否则改错文件,不会报错但也不会生效。
3. 跑通第一个ROS2程序:小乌龟到rviz2再到摄像头的跳跃
ROS2装完之后,第一个验证程序当然是ros2 run turtlesim turtlesim_node。这个例程的意义在于验证发布订阅、话题通信和服务调用是否正常,不是让你做游戏。很多人跑完小乌龟就不知道该干嘛了,实际上ROS2入门有一条非常清晰的路径:先让小乌龟动起来,再用rviz2看机器人模型,最后接上真实传感器。这条链走通,你才算真正入门。
3.1 小乌龟验证的三种通信机制
跑小乌龟的时候,建议顺便验证三种基本通信机制。第一种是话题,终端里执行ros2 topic list看有哪些话题,然后ros2 topic echo /turtle1/cmd_vel就能看到速度指令的数据。第二种是服务,执行ros2 service list能看到服务列表,比如/spawn,调用一下就能在窗口里生成新乌龟。第三种是参数,ros2 param list能查看节点参数。
这一套下来,你对ROS2的“话题、服务、参数”三个基本概念会有直观理解,比看一百页概念定义都管用。
3.2 rviz2无法启动的常见原因
rviz2是ROS2里的三维可视化工具,跑起来之后能看到机器人模型、传感器点云、地图这些内容。但rviz2在树莓派上有一个很常见的问题:窗口起不来,或者起来之后全黑。如果你用的是无桌面版系统,那不用想了,rviz2这类GUI工具必须配合桌面环境才能运行。如果你用的是Desktop版但仍打不开,大概率是显卡驱动的问题。树莓派的GPU驱动在Ubuntu下默认用的是软件渲染,rviz2在这种模式下降频特别严重,简单来说就是“能跑但拖不动”。我的解决办法是给/boot/firmware/cmdline.txt增加GPU内存分配,或者在启动rviz2之前先关掉一些不必要的后台节点,把显存腾出来。
3.3 树莓派摄像头模块的接入方式
树莓派的官方摄像头模块,型号是OV5647,也就是常说的800万像素摄像头,CSI接口是它区别于USB摄像头的最大特点。CSI摄像头在ROS2里不是即插即用的,你需要安装raspicam2或者使用camera_ros这类驱动节点。我实测下来,直接用ROS2的usb_cam驱动是识别不到CSI摄像头的,必须走专用的CSI封装节点。
如果你的摄像头是USB接口的,那简单得多,用usb_cam功能包,改一下设备路径和像素格式就能发布图像话题。我在树莓派上遇到的一个问题是USB摄像头打开后画面颜色偏绿,后来发现是白平衡参数没设置对,在usb_cam的配置里把白平衡模式改成自动就正常了。
如果想快速验证摄像头本身有没有问题,可以装一个叫luvcview的小工具——它是Linux下通用的USB摄像头查看工具,不需要ROS2就能直接看画面。这个工具特别适合排查“是不是摄像头硬件坏了”这种问题。先确认摄像头硬件本身能出图,再去排查ROS2驱动,排查思路就清晰得多。
4. 从舵机到四轮小车:树莓派实际控制执行器的几条路线
前面这些环节都是软件层的验证,到了这里才真正进入“机器人”的范畴:让硬件动起来。热词里提到“树莓派Pico控制舵机”和“树莓派四轮小车”,这其实代表了两种完全不同的控制思路,用错方向会浪费很多时间。
4.1 树莓派Pico控制舵机的接线和代码思路
Pico控制舵机走的是PWM信号,舵机的角度由脉冲宽度决定。常见的SG90舵机需要50Hz的频率,也就是20毫秒周期,其中0.5ms对应0度,2.5ms对应180度。用MicroPython代码实现的话,先去构造PWM对象,设置频率为50Hz,然后控制占空比来改变脉宽。硬件接线上,舵机三根线分别为信号线、正极和地线。我最初接的时候没注意外部供电这回事,直接用Pico的3.3V输出带动SG90,结果舵机抖动、复位,后来才明白舵机启动时电流瞬间能到几百毫安甚至更高,Pico的引脚根本供不住。正确的做法是舵机的电源用5V外部供电,信号线连Pico的GPIO输出,地线共地。
4.2 四轮小车摄像头的开启方式
四轮小车涉及的摄像头,要先分清用的什么型号。如果是带摄像头的4WD小车,一般有两种情况:一种是树莓派单独跑了ROS2,摄像头直接连树莓派,那么摄像头的开启方式和上一节讲的完全一样;另一种是摄像头连的是别的控制板,树莓派只负责算法层。我调试这类小车时发现,很多人说“摄像头打不开”其实是没给权限。Linux下访问摄像头设备,需要让当前用户加进video用户组,否则会提示权限不足。执行sudo usermod -aG video $USER然后重新登录,问题就解决了。
4.3 小车运动控制里最容易忽略的供电问题
四轮小车比单纯一个舵机复杂在系统层面。四个电机同时启动的电流非常可观,如果你给树莓派和电机驱动芯片用的是同一个电源,电机一转,电压跌落,树莓派直接重启。这个问题几乎每个玩小车的人都会遇到,区别只是重启的时机早晚。解决方法是分开供电:电机一路,树莓派一路,共地但别共电源。我后来测过,用两节18650电池专门给电机供电,再用一块稳压模块给树莓派供电,整套系统就稳定了,再没出现过一动就重启的情况。
5. 车能动了之后:建图导航、雷达配置和ROS2目录结构
能把车开动,说明基础通信已经通了。接着往高阶走,就是建图和导航。这里面的关键词是“八叉树地图”和“Livox雷达”,这俩凑一块儿,属于比较硬核的方向了。
5.1 八叉树地图导航到底在做什么
传统的地图表示方法是占据栅格地图,就是一张二维图片,黑色是障碍物、白色是空地。八叉树地图(OctoMap)是三维的,它把空间递归切块,如果一个块内部全是空的或者全是实的,就不再细分。这样做的好处是内存消耗比体素地图小得多,而且能表达复杂的三维结构,比如室内天花板、悬空障碍物。导航时使用八叉树地图,能够做真正意义上的三维路径规划,而不是只在平面图上避障。
在ROS2生态里,构建八叉树地图通常借助octomap_server这类功能包,它订阅激光雷达或深度相机的数据,实时生成八叉树地图并通过rviz2展示。如果你的传感器是2D激光雷达,那就只能用二维占据栅格地图了;想玩8叉树,至少得有个3D数据源,比如Livox雷达或者RGB-D深度相机。
5.2 Livox雷达在ROS2下的配置经验
Livox是国产的固态激光雷达品牌,在户外机器人场景用得多。Livox Avia这类雷达在ROS2下的配置,比常规雷达要费劲一点。首先要装厂商提供的livox_ros_driver2功能包,新版本对ROS2 Humble和Jazzy都有支持。其次,雷达的IP地址和电脑网卡的IP地址要配到同一个网段,这是最容易被忽略的一步。我调试的时候发现点云话题始终没有数据,排查了一个多小时才发现雷达默认IP是192.168.1.5,而树莓派网卡IP是192.168.0.10,跨网段了,数据根本收不到。
5.3 ROS2功能包的目录结构
说到这里得提一下ROS2的目录结构,因为后面你自己写功能包时,这个绕不开。一个标准的ROS2功能包目录大致是这样的:
my_robot/ ├── package.xml # 包描述文件,记录依赖 ├── CMakeLists.txt # 编译配置(C++包) ├── setup.py # 编译配置(Python包) ├── setup.cfg ├── resource/ ├── launch/ # 存放launch文件 ├── src/ # 源码目录 └── config/ # 配置文件(yaml等)我最早犯的错是把编译好的Python包直接丢进src目录就跑,当然找不到,因为ROS2的功能包必须按上述结构组织好,然后执行colcon build完成编译,再source工作空间才能被识别。
ROS2里常用的命令,其实核心就那么几条:ros2 node list看节点,ros2 topic list看话题,ros2 topic echo看数据,ros2 service list看服务,ros2 action list看动作。真正复杂的是Action机制。Action在ROS2里的地位很像“带反馈的异步服务”,适合那些执行时间长的任务,比如导航到某个点。它由目标、反馈、结果三个部分组成,客户端发起目标后,服务端可以异步反馈进度,最后返回结果。写导航代码时,用Action比用Service合理得多,因为导航是一个持续过程,不是一问一答。
还有一个进阶概念是FastDDS,它是ROS2默认的DDS实现,负责节点之间的底层通信。FastDDS不是独立于ROS2之外的东西,它本身就是ROS2的通信底座。理解这一点就够了,除非你要做性能调优或者跨设备通信,否则不需要深入它的内部封装结构。
6. 从数据采集到应用场景:树莓派ROS2的实际项目方向
装了ROS2,跑通了小乌龟和摄像头,那接下来能做什么?这个问题比“怎么装”更值得思考。我整理几个自己实操过或深入研究过的方向。
6.1 ADS-B航空数据接收项目
树莓派接收ADS-B信号,是用来获取附近飞机信息的。ADS-B是飞机自动广播自身位置、高度、速度等信息的系统,地面用专门的SDR接收棒就能捕获这些广播,再配合软件解码,就能在电脑上看到周边空域的情况。这个项目的典型链路是:树莓派插上RTL-SDR接收棒,装上dump1090之类的解码软件,再通过网页界面或者ROS2节点来读取数据。
和ROS2结合的一个玩法是把接收到的飞机信息包装成自定义话题,发给下游做数据处理。这个项目特别适合练手,因为硬件成本低,数据获取简单,而且涉及串口或USB设备读取、数据解析、话题通信,这些都是机器人项目的通用技能。
6.2 无桌面环境下ROS2的日常使用技巧
既然前面强调了Server版省内存,那你得掌握一套纯命令行的操作习惯。树莓派Ubuntu Server版启动后默认不装桌面,SSH连接过去就是黑底白字的终端。对于ROS2来说这完全够用,因为大部分操作都可以在命令行完成。
唯一不方便的是可视化验证。解决办法有两个方向:一是通过SSH的X11转发,把rviz2这种GUI程序显示到本地电脑上。这个方案要求本地电脑跑Linux或者装Xming,Windows下也可以用,但延迟高,展示效果一般。二是使用Web端的可视化方案,比如Foxglove Studio,树莓派上把ROS2数据桥接出去,本地浏览器打开看图像和点云。我后来一直用这种方法,比X11转发顺滑得多。
6.3 自定义话题与语音交互的扩展
热词里出现了“小智语音聊天”和别的一些语音方案。把语音接入ROS2,本质上是写两个节点:一个是语音识别节点,把声音转成文本后发布成字符串话题;另一个是语音合成节点,订阅字符串话题转成声音播放。这个架构最直接的价值是让你理解“节点职责单一”的设计思想,后面不管接什么外设,都是往话题总线里加节点。
做中文语音交互时,还涉及一个问题:树莓派默认没有中文字体和中文字库,你如果是装桌面版然后想输入中文,需要帮忙安装输入法框架。五笔用户则可以再添加五笔输入法支持。这些都是系统层的坑,和ROS2本身无关,但会实实在在影响使用体验。
7. 装机之后的三件小事:U盘挂载、SSH保活、时间同步
最后写几个装完系统、跑起ROS2之后,实际使用中绕不开的小问题。这些小问题单独看都不难,但遇到一个卡一次,非常消磨耐心。
7.1 U盘自动挂载位置与权限
树莓派OS和Ubuntu Server对U盘的处理不同。树莓派OS桌面版插上U盘会自动挂载到/media/pi/设备名,而Ubuntu Server默认不做自动挂载,需要手动挂载。手动挂载的第一步是要先看lsblk找到U盘的设备名,比如/dev/sda1,然后执行sudo mount /dev/sda1 /mnt/usb。这里有个不太优雅的细节:如果U盘是NTFS格式,直接挂载只有只读权限,需要安装ntfs-3g并加参数挂载;如果是exFAT,Ubuntu自带支持,不会有大问题。
7.2 SSH连接不稳定对ROS2多机通信的影响
树莓派用得久了你会发现,WiFi连接的SSH会偶发断连。这在平时无所谓,重连一下就好,但在ROS2多机通信时影响很大。ROS2节点之间的通信走的是DDS,基于UDP,网络抖动会导致话题数据卡顿或丢失。我在树莓派和电脑双机通信时就遇到过:订阅端时不时掉话题,一连查了几天代码,最后发现是WiFi下网络延迟不稳定。
解决思路有两个:一是优先用网线直连树莓派和路由器,把网络抖动降到最低;二是调FastDDS的配置。简单来说,在fastdds.xml里合理设置端口和网卡绑定。这个文件能配置节点使用的网卡、端口复用、心跳间隔等参数。如果只有一块网卡,配置不配置差别不大;但多网卡环境(比如同时连着WiFi和网线),不指定网卡的话,ROS2可能自己选错网络接口导致节点发现不了,这是个很容易踩的深坑。
7.3 时间同步问题
ROS2的TF坐标变换对时间戳很敏感。如果你的树莓派没有连网,系统时间和真实时间偏差很大,那么跑地图或者导航时会出现各种奇怪的“转换失败”报错,看起来像是代码写错了,实际上是时间基准不对。装完系统第一步养成习惯:检查时间是否正确,如果不对就配置网络时间同步服务。就这么一个操作,能帮你避免后面排查问题的弯路。
树莓派+ROS2这条路,说难不难,说容易也不容易。它难在涉及的层次太多:硬件、系统、网络、通信框架、传感器、执行器,每一层都有各自的坑。但它也正因为层次多而适合学习——每跨过一个坑,你对整个机器人系统从底层到上层的理解都会深一层。我的经验是别想着一步到位,先把系统装干净,把小乌龟跑起来,再一个传感器一个传感器地接,最后当你把传感器数据、控制指令、可视化界面串起来的那一刻,对这套体系才算真正有感觉。