扫地机器人这几年从"智商税"变成"真香"的过程,我算是完整经历了一遍。早些年那些随机碰撞、卡在沙发底下嗷嗷叫的机器,本质上就是个带轮子的振动马达;而现在能自己建图、规划路径、绕开拖鞋和宠物粪便的机器,背后是一整套SLAM(同步定位与建图)+ Nav2(导航栈)+ 运动控制的技术组合。很多人以为这东西只能买成品,其实自己攒一台完全可行,而且过程比想象中有意思得多——你会被迫搞懂激光雷达怎么出数据、ROS2 的话题和服务怎么串起来、STM32 怎么把轮子转起来。这篇就聊聊我理解的"三条路线":从纯买成品改造、到半自研、再到全栈从零攒机,以及一张我认为最务实的攒机路线图。适合想入门机器人开发但不知道从哪下手的朋友,也适合已经会点 STM32 或 ROS2、想找个完整项目练手的人。
1. 先想清楚你要的是"扫地"还是"机器人"
这个问题听起来像废话,但我见过太多人一上来就买激光雷达、买开发板,结果三个月后东西全在吃灰。核心原因是没分清自己的真实目标——你到底是想让家里地板干净,还是想搞明白机器人是怎么跑起来的?这两个目标对应的路线完全不同,投入的时间、金钱、踩坑密度差着数量级。
1.1 三条路线的本质区别
我把可行方案归成三类,你可以对号入座:
| 路线 | 核心动作 | 适合人群 | 时间投入 | 金钱投入 | 技术收获 |
|---|---|---|---|---|---|
| 路线一:成品改造 | 买整机,刷固件/接上位机 | 想快速用起来、轻度折腾 | 1-2 周 | 中 | 了解通信协议、上位机逻辑 |
| 路线二:半自研 | 买底盘+雷达,自己写导航 | 会点编程、想学 ROS2 | 1-3 个月 | 中高 | 掌握 SLAM、Nav2、话题服务 |
| 路线三:全栈攒机 | 从电机、驱动、主控到算法全自己搭 | 嵌入式+机器人双修 | 3-6 个月 | 高 | 完整机器人系统能力 |
路线一最省心,本质是"用别人的成熟产品当学习平台"。很多成品机器人支持串口或网络接口,你可以接一个上位机读它的传感器数据、甚至接管控制。这条路线的价值在于:你能在真实硬件上验证自己的算法想法,而不用先解决"轮子为什么不转"这种底层问题。
路线二是我最推荐的。买一个带编码器的差速底盘、一个 2D 激光雷达,主控用树莓派或 Jetson 这类能跑 Ubuntu 的板子,然后老老实实装 ROS2、跑 SLAM、配 Nav2。这条路线的甜点在于:底层运动控制已经被底盘厂商封装好了,你专注在感知和导航上,能快速看到"机器人自己绕开障碍物"的成就感,同时把 ROS2 的核心概念(节点、话题、服务、动作、TF 变换)全部过一遍。
路线三就是硬核玩家的选择了。STM32 负责电机闭环、编码器读取、超声波/IMU 数据采集,通过串口或 CAN 跟上位机通信;上位机跑 ROS2,做建图和导航。这条路线的坑最多,但你对整个系统的理解会深一个层次——比如你会真正明白为什么里程计会漂、为什么 TF 树不能有环、为什么定时器捕获测频率的精度直接影响轮速估计。
1.2 一个反直觉的建议:别一上来就全栈
我踩过的最大坑就是贪心。第一次搞的时候,我同时买了 STM32 开发板、激光雷达、电机驱动、一堆传感器,想着"一次到位"。结果光是把 STM32 的开发环境搭起来、把 ILI9341 屏幕点亮(读 ID 是 0xA1A1 那种经典问题)就花了一周,等真正想跑 SLAM 的时候已经没精力了。
正确的做法是先让机器人动起来,再让它聪明起来。具体说,先用现成的底盘和 ROS2 把"建图-导航"闭环跑通,哪怕底盘是买的、代码是抄的,只要你能看到机器人在 RViz2 里自己规划路径,你就有了正反馈。然后再回头把底盘换成自己做的 STM32 方案,这时候你是在"替换一个已知能工作的模块",而不是"从零搭一个不知道对不对的系统"。这个顺序能帮你省下大量调试时间。
提示:如果你连 Ubuntu 都没装过,先别碰硬件。花两天把 Ubuntu 装好、把 ROS2 装上、跑通官方的小乌龟例程,确认你的开发环境没问题,再动硬件。
2. 路线二详解:用 ROS2 + 激光雷达跑通建图导航
这条路线的核心是"站在巨人肩膀上"。ROS2 生态里 SLAM 和 Nav2 都有成熟实现,你要做的是把它们串起来,理解每个环节在干什么。
2.1 硬件清单与选型逻辑
先列一下我实际用过的配置,再说为什么这么选:
- 底盘:带编码器的两轮差速底盘(带万向轮)。差速底盘是最简单的运动学模型,SLAM 和 Nav2 对它的支持最好,调试成本最低。
- 激光雷达:2D 单线雷达,比如常见的 RPLIDAR 系列或国产替代。2D 雷达便宜、数据量小、SLAM 算法成熟,是入门首选。3D 雷达虽然能建八叉树地图、做三维导航,但数据量和算力要求高一个档次,不建议第一台就上。
- 主控:树莓派 4B 或 Jetson Nano/Orin Nano。树莓派够跑 2D SLAM,Jetson 适合以后加视觉 SLAM 或深度学习。
- 电机驱动:如果底盘自带驱动板就省事了,否则要自己配。注意驱动板要能接受上位机的速度指令(通常是串口协议)。
- 电源:锂电池组 + 稳压模块。雷达和主控对电压敏感,别用劣质电源,否则会出现雷达数据跳变、主控随机重启这种玄学问题。
选型的关键逻辑是降低变量数量。每多一个自己焊的模块,就多一个可能出问题的地方。入门阶段,能用成品就用成品,把精力留给算法和系统集成。
2.2 ROS2 环境搭建:避开那几个经典坑
装 ROS2 这件事,说简单也简单,说坑也真坑。我用的是 Ubuntu 22.04 + ROS2 Humble 这个组合,因为 Humble 是长期支持版本,社区资料最多。
安装流程大致是:配置软件源、安装 ros-humble-desktop、配置环境变量。但实际操作中你会遇到几个典型问题:
第一个是软件源报错。如果你看到类似获取:1 http://packages.ros.org/ros2/ubuntu jammy InRelease [4,682 B] 错误:1这种,八成是网络或者源地址的问题。解决办法是换用国内镜像源,或者检查你的系统版本代号是否匹配(jammy 对应 22.04,别搞错)。
第二个是环境变量没生效。装完之后ros2命令找不到,是因为没 source。记得在~/.bashrc里加上source /opt/ros/humble/setup.bash,然后source ~/.bashrc。
第三个是版本混乱。如果你之前装过其他版本的 ROS,可能会有冲突。建议用干净的 Ubuntu 环境,或者用 Docker 隔离。
装好之后,跑一下ros2 run turtlesim turtlesim_node和ros2 run turtlesim turtle_teleop_key,能看到小乌龟并且能用键盘控制它动,说明环境没问题。这一步别跳过,它是你后面所有调试的基础。
2.3 SLAM 建图:从"焦点乱跑"到一张干净的地图
SLAM 建图是机器人自己一边走一边画地图的过程。ROS2 里常用的是 slam_toolbox 这个包。启动之后,你在 RViz2 里会看到激光点云和逐渐生成的地图。
这里有个新手常见困惑:为什么地图上的机器人位置(焦点)会乱跑?这通常是因为里程计不准或者 TF 变换有问题。里程计来自轮子编码器,如果轮子打滑、编码器分辨率低、或者轮距参数设错,累积误差就会让机器人"以为"自己走到了别的地方。SLAM 的作用就是用激光雷达的观测来修正这个误差,但如果误差太大,修正就会失败,表现为地图扭曲或者焦点跳变。
我的经验是:先把里程计调准,再谈 SLAM。具体做法是让机器人直线走 1 米,看 RViz2 里它"以为"走了多少,如果差得多,就去调轮距和编码器参数。这个标定过程很枯燥,但省不得。
建图时的操作技巧:手动遥控机器人慢慢走,转弯要缓,别急停急转。走得太快激光雷达会有运动畸变,地图会糊。走完一圈回到起点,如果地图闭合得好,说明建图质量不错,可以用map_saver保存地图。
2.4 Nav2 导航:让机器人自己找路
有了地图,接下来就是 Nav2。Nav2 是一个导航框架,包含全局规划、局部规划、代价地图、恢复行为等模块。配置起来参数很多,但核心逻辑不复杂:
- 全局规划器:根据地图算一条从当前位置到目标点的路径,常用的是 A* 或 Dijkstra。
- 局部规划器:负责实时避障,根据当前传感器数据微调路径,常用的是 DWA 或 TEB。
- 代价地图:把地图和实时障碍物融合成"哪里能走、哪里不能走"的栅格。
配置 Nav2 最容易出问题的地方是参数文件。每个规划器、每个代价地图层都有一堆参数,比如膨胀半径、机器人半径、速度限制。膨胀半径设太小,机器人会贴着墙走然后卡住;设太大,窄通道就过不去。我的建议是从官方示例参数出发,一点点调,别自己从零写。
还有一个坑是TF 树。Nav2 依赖map -> odom -> base_link这条 TF 链。如果 SLAM 没在发布map -> odom,或者底盘没发布odom -> base_link,导航就会报错。用ros2 run tf2_tools view_frames可以生成 TF 树图,检查有没有断链或者环。
跑通之后,你在 RViz2 里点一个目标点,机器人就会自己规划路径、避开障碍、到达目标。那一刻的成就感,值得前面所有的折腾。
3. 路线三详解:STM32 底盘的硬核攒机
如果你不满足于"用别人的底盘",想自己掌控每一个轮子的转动,那就要进入 STM32 的世界了。这部分我踩的坑最多,也最有收获。
3.1 STM32 负责什么:运动控制的边界
在整套系统里,STM32 的角色是实时运动控制。上位机(跑 ROS2 的板子)负责重计算——SLAM、路径规划、决策;STM32 负责轻量但要求实时的事情——电机 PWM 输出、编码器计数、传感器采集、紧急停止。
为什么不让上位机直接控制电机?因为 Linux 不是实时系统,任务调度有抖动,直接控制电机会导致速度不稳。STM32 跑裸机或 FreeRTOS,定时器中断精确到微秒级,能保证控制环的稳定性。这就是典型的分层架构:上层管"去哪",下层管"怎么走"。
STM32 和上位机的通信通常用串口(UART)或 CAN。串口简单,适合入门;CAN 抗干扰强、支持多节点,适合复杂系统。协议可以自己定,比如简单的帧格式:帧头 + 命令字 + 数据 + 校验。上位机发速度指令(线速度、角速度),STM32 返回里程计数据(左右轮编码器计数)。
3.2 电机闭环:从 PWM 到 PID
让轮子转起来不难,难的是让它按你想要的速度转。这就需要一个闭环控制:
- 编码器读取:用定时器的编码器模式,或者外部中断计数。编码器分辨率决定了速度估计的精度。
- 速度计算:单位时间内的编码器脉冲数,换算成轮速。这里要注意定时器捕获测频率的精度问题。
- PID 调节:目标速度和实际速度的差值,经过 PID 算出 PWM 占空比。P 管响应,I 管消除稳态误差,D 管抑制超调。
调 PID 是个手艺活。我的经验是:先只加 P,慢慢加大到轮子开始振荡,然后退回一点;再加 I,消除稳态误差;D 一般给很小或者不给,因为编码器噪声会被 D 放大。差速底盘两个轮子的 PID 参数最好分别调,因为电机和机械阻力不可能完全一致。
注意:如果你用的是五线四相步进电机,控制逻辑和直流电机完全不同,需要按节拍发脉冲。步进电机低速扭矩好、定位准,但高速容易失步,适合对精度要求高、速度要求不高的场景。
3.3 传感器接入:超声波、IMU 和它们的坑
除了编码器,底盘上通常还要接一些传感器:
- 超声波测距:用于近距离避障或者悬崖检测。STM32 用定时器发触发信号、测回响时间。坑在于超声波有盲区、受温度影响、多个超声波会互相干扰。
- IMU:提供角速度和加速度,用于辅助里程计。坑在于零漂,需要静态校准,而且积分会累积误差。
- 红外/碰撞传感器:简单可靠,用于紧急停止。
这些传感器的数据要么在 STM32 上做预处理再上传,要么直接透传给上位机。我的建议是能在下层处理的就在下层处理,比如超声波测距直接算出距离值上传,而不是上传原始时间戳让上位机算,这样能减轻上位机负担、降低通信带宽。
3.4 通信协议设计:别小看这一层
上位机和 STM32 之间的协议,看起来简单,但设计不好会埋大坑。我总结几个要点:
- 帧同步:必须有明确的帧头和帧尾,否则数据错位后很难恢复。
- 校验:加个简单的校验和或者 CRC,能过滤掉大部分传输错误。
- 超时保护:如果上位机一段时间没发指令,STM32 应该自动停车,防止失控。
- 数据格式统一:注意字节序(大端小端)和数据类型(int16 还是 float),两边要对齐。我遇到过上位机发 float、STM32 按 int 解析,结果速度指令完全不对的情况。
调试通信的时候,先用串口助手手动发指令,确认 STM32 响应正确,再接入 ROS2。这样能把问题隔离在单侧,不用同时怀疑两边。
4. 那张攒机路线图:从零到能跑的完整顺序
说了这么多,最后给你一张我认为最务实的路线图。核心原则是每一步都有可验证的产出,不要憋大招。
4.1 阶段划分与验收标准
| 阶段 | 目标 | 验收标准 | 预计耗时 |
|---|---|---|---|
| 阶段零 | 环境准备 | Ubuntu + ROS2 装好,小乌龟能跑 | 2-3 天 |
| 阶段一 | 底盘动起来 | STM32 能控制电机正反转、调速 | 1-2 周 |
| 阶段二 | 里程计准确 | 直线走 1 米误差小于 5% | 1 周 |
| 阶段三 | 上位机通信 | ROS2 能收发速度指令和里程计 | 1 周 |
| 阶段四 | 建图 | 能生成闭合良好的 2D 地图 | 1-2 周 |
| 阶段五 | 导航 | 能自主规划路径并到达目标 | 2-3 周 |
| 阶段六 | 优化 | 加避障、调参数、提升鲁棒性 | 持续 |
这个顺序的关键是先底层后上层、先运动后感知。很多人反过来,先搞 SLAM 再搞底盘,结果 SLAM 调不通的时候不知道是算法问题还是底盘问题。
4.2 每个阶段最容易卡住的地方
阶段一卡在电机驱动。DRV8323 这类驱动芯片功能强但配置复杂,寄存器没配对电机就不转。建议先用简单的驱动模块(比如 L298N 之类)把逻辑跑通,再换高级驱动。
阶段二卡在编码器方向。左右轮编码器计数方向可能相反,导致机器人"以为"在前进实际在后退。解决办法是在代码里加方向标志,或者物理上调整接线。
阶段三卡在协议对齐。前面说过了,字节序和数据类型要对齐,建议先用固定测试数据验证。
阶段四卡在TF 树。SLAM 需要map -> odom -> base_link完整链路,缺一个就报错。用view_frames工具检查。
阶段五卡在参数调试。Nav2 参数多,建议从官方示例改,一次只改一个参数,改完测试。
4.3 一些省时间的经验
- 善用仿真:Gazebo 里可以先验证算法,不用等硬件。ROS2 Humble 配 Gazebo 能跑很多标准机器人模型。
- 版本要统一:ROS2 版本、Ubuntu 版本、Gazebo 版本之间有兼容性要求,别混用。
- 记录数据:ROS2 的 bag 功能可以录制话题数据,出问题后回放分析,比现场调试高效。
- 代码管理:用 Git 管理你的功能包,改坏了能回退。ROS2 创建 C++ 功能包有标准命令,别手动建目录。
- 社区资料:遇到问题先搜,ROS2 和 STM32 的坑基本都有人踩过。但注意版本差异,老版本的解决方案不一定适用。
5. 关于"值不值得自己攒"的一点个人看法
聊到最后,说点实在的。自己攒扫地机器人,从纯实用角度讲,大概率不如直接买成品——成品便宜、稳定、开箱即用。但如果你把这件事当成学习机器人系统的载体,那它的价值就完全不一样了。
我在这个过程中真正搞明白的东西,是书本上给不了的:为什么里程计会漂、为什么实时性重要、为什么分层架构是必要的、为什么通信协议设计不好会让人抓狂。这些认知,在你以后做任何机器人项目时都会用到。
如果你决定动手,我的建议是从路线二开始,用现成底盘把 ROS2 的建图导航跑通,建立信心和整体认知;然后再逐步替换成自己的 STM32 底盘,享受"每一行代码都归我管"的掌控感。别一上来就全栈,那不是勇敢,是给自己找罪受。
至于那些热搜词里提到的具体技术点——八叉树地图导航、视觉 SLAM、3D 雷达——等你把 2D 这条线跑通了,再往上加就是水到渠成的事。基础打牢了,上层的东西都是组合和调参。