刷 GitHub 的时候看到有人把整套扫地机器人方案开源了,第一反应确实是“离谱”两个字。再仔细翻了下仓库,发现这还真不是单纯在造玩具——现在从零做一台能扫会拖、能自动回充的小车,门槛已经被开源生态压得非常低了。整套方案以 ROS 2 为核心机器人框架,配合开源激光雷达驱动、Cartographer 建图算法、Navigation2 导航栈,再加一块普通 Linux 开发板和几个直流减速电机,硬件成本甚至可以控制在千元级别。
这篇内容适合想入门移动机器人的嵌入式爱好者、正在做毕业设计的学生,以及纯粹好奇“扫地机器人到底怎么工作”的人。我把整套开源方案从架构到落地拆开讲一遍,包括怎么选硬件、怎么接线、怎么在 GitHub 上把代码拉下来跑通,以及我实际踩过的那些坑。如果你也想攒一台“自己会扫地”的机器,这篇文章可以直接当成起步手册。
1. 扫地机器人开源方案的整体思路拆解
1.1 为什么“整套开源”这件事值得关注
过去扫地机器人是家电厂商的封闭产品,软硬件全锁在黑色盒子里,用户只知道它会转、会扫,不知道它背后的感知、建图、规划、控制到底是怎么协作的。而开源方案的意义,不只是让你省了几千块买成品机器的钱,而是把整条技术链路摊开给你看:激光雷达数据怎么变成地图、地图怎么变成路径、路径怎么变成电机转速。
这个思路在 GitHub 上已经形成了完整的生态链条。底层有 ROS 2 提供通信骨架,上层有 Cartographer 或 slam_toolbox 这类建图算法,中间还有 Navigation2 负责全局路径规划和局部避障。每个模块都是活跃维护的独立开源项目,彼此之间用标准消息接口对接,这就让“攒一台扫地机器人”变成了“拼积木”式的工作。
更关键的一点是,开源方案的决策层逻辑非常透明。扫地机的“随机碰撞清扫”和“规划式清扫”完全是两个时代的东西,开源项目里能看到代价地图、膨胀层、恢复行为这些原本藏在家电固件里的策略。理解了这套机制,你甚至能自己改清扫逻辑——比如让它在某块区域反复清扫、给禁区画多边形、按房间分区规划任务。
1.2 开源方案的分层架构:五层模型
我习惯把整套开源扫地机方案分成五个层次,每一层都有对应的开源组件和硬件模块:
| 层次 | 职责 | 常见开源组件 / 硬件 |
|---|---|---|
| 感知层 | 获取环境数据和机器人自身状态 | RPLIDAR 雷达、碰撞开关、悬崖红外、IMU、电机编码器 |
| 决策层 | 建图、定位、路径规划、清扫策略 | Cartographer、slam_toolbox、Navigation2、Behavior Tree |
| 控制层 | 把速度指令变成 PWM,闭环控制电机 | ros2_control、PID 控制器、Arduino/ESP32 固件 |
| 执行层 | 驱动车轮实际转动 | 带霍尔编码器的直流减速电机、TB6612/L298N 驱动模块 |
| 交互层 | App 控制、状态显示、语音提醒 | Rosbridge、MQTT、Android/iOS 客户端、小爱同学等接入 |
这套分层的核心价值是解耦。你在决策层换一个建图算法,不需要动电机接线;你在执行层从差速轮换成全向轮,也不需要重写路径规划。实际项目里,最稳的做法是“Linux 主控 + MCU 双芯片”:Linux 主控跑建图、导航、通信这些重任务,MCU 专门负责编码器采集和电机关环控制,两边通过串口或 USB 通信。这样即使导航进程卡死,小车也不会失控狂奔。
2. 核心模块拆解与关键技术点
2.1 感知模块:低成本激光雷达与传感器组合
扫地机器人最核心的感知设备是单线激光雷达。开源项目里最常见的是 RPLIDAR A1M8,价格大概在三四百元级别,采用三角测距原理,每秒能采样几千到几万个点,测量半径 8 米,360 度旋转扫描。三角测距的原理可以理解成“已知基线和角度算距离”:激光器发射一束光到障碍物上,反射光经过透镜投射到传感器上,根据光点在传感器上的偏移位置,用几何关系反推出障碍物距离。
除了雷达,一套能正常跑起来的方案还要配齐这几类传感器:
- 碰撞传感器:装在底盘前部,通常用机械微动开关,碰到物体后触发回退和转向。
- 悬崖传感器:用朝下的红外对管,检测是否有台阶边缘,防止从楼梯掉下去。
- IMU 惯性测量单元:一般用 MPU6050 这类六轴模块,提供加速度计和陀螺仪数据,辅助定位和航向判断。
- 电机编码器:装在减速电机尾部,通过霍尔传感器输出 A/B 两相脉冲,用来计算车轮转速和行进里程。
在这套组合里,激光雷达负责“看清环境”,编码器负责“知道自己走了多远”,IMU 负责“知道自己转了多少度”,碰撞和悬崖传感器负责“兜底”。它们的数据经过融合,才是建图和导航算法能吃进去的输入。
2.2 运动控制:差速底盘与编码器里程计
绝大多数开源扫地机方案采用差速驱动底盘,也就是左右两个独立驱动的轮子加一个或两个万向支撑轮。差速底盘的运动学非常直观:两个轮子同速同向转动就直行,转速差产生角速度从而转向,完全相反就原地旋转。设左右轮线速度分别为 vl 和 vr,轮距为 L,则机器人线速度 v = (vl + vr) / 2,角速度 w = (vr - vl) / L。
为什么不用全向轮或者麦克纳姆轮?扫地机的使用场景是家里地板,需要跨越门框、地垫和细小杂物,全向轮的小滚轮在复杂地面上容易卡滞,而且成本更高。差速轮结构简单、越障能力强、控制逻辑成熟,是家用地面清洁场景里最可靠的选择。
电机选型上,最常见的配置是带霍尔编码器的 N20 微型直流减速电机。减速比通常在 30:1 到 50:1 之间,减速后空载转速控制在每分钟 100 到 300 转,配合直径 65 毫米左右的轮子,能让小车达到约 0.3 到 0.5 米/秒的清扫速度。扭矩不需要太大,能推动自身加上电池和雷达的重量就够。
电机驱动模块我推荐 TB6612FNG 而不是 L298N。TB6612 是 MOSFET 结构,导通压降低,发热小,体积也小,工作电压适合 2.7V 到 5.5V 的逻辑电源。实际项目中给它供电机电源 6V 到 12V,逻辑电源接 3.3V 或 5V,输出 PWM 频率建议设在 10kHz 以上,能明显减少电机运转时的啸叫声。L298N 的问题是压降大,满载时发热严重,还容易把板载的 5V 稳压芯片搞烧。
2.3 建图与导航:Cartographer 和 Navigation2 的配合
扫地机器人能“认识房间”靠的是 SLAM 算法。开源生态里最常用的两个方案是 Cartographer 和 slam_toolbox。Cartographer 是 Google 开源的 2D/3D SLAM 库,核心优势是带有回环检测,能修正长时间扫描累积的漂移误差,特别适合中小户型这种闭环较多的场景。slam_toolbox 则更适合纯 2D 激光、计算资源有限的平台,参数调节更直观。
建图完成后就进入导航阶段。Navigation2 是 ROS 2 下的官方导航框架,它的工作流程分为三层:全局代价地图用于存储已知障碍物和膨胀区域,全局规划器(通常用 A* 算法)在地图上找出一条从当前位置到目标点的无碰撞路径,局部规划器(常用 DWA 算法)再根据实时激光数据做短距离避障和速度控制。
参数调优是按照开源方案复现时的重头戏。几个影响最明显的参数:
- robot_radius:机器人半径,设置过小会导致导航路径贴着墙走,实际通过时撞上障碍物。
- inflation_radius:膨胀半径,影响障碍物周围的“危险区域”范围,太大会让狭窄通道无法通过,太小则容易剐蹭。
- max_vel_x:最大线速度,建议初始调到 0.3 米/秒左右,速度和建图质量、避障成功率是负相关的。
依赖这套算法,扫地机才能实现“弓字形清扫”“沿墙清扫”“指定区域清扫”这些功能。市面上很多老式随机碰撞清扫机并不是没有导航算法,而是为了压低成本把决策模块砍了,清扫效率自然差一个量级。
2.4 电源系统:锂电池、BMS 与降压电路
电源设计是整个项目里最容易被低估的部分,但我也见过不少人在这里栽跟头。一套典型的方案是用 4 节 18650 锂电池组供电。如果采用 4 节串联,标称电压 14.8V,能量密度高,但需要配套一块成熟的锂电池保护板(BMS),负责过充、过放和过流保护。如果采用 2 串 2 并方案,标称 7.4V,容量翻倍,安全性更好,也更适合 12V 评级的电机驱动模块。
整机供电要考虑分压问题。电机和驱动模块直接用电池电压,主控板、雷达、传感器则通过 DC-DC 降压模块取电。我常用的降压模块是 MP1584,支持 4.5V 到 28V 输入,输出可调,效率能到 90% 以上;相比之下 LM2596 虽然也很常见,但线性降压工作在压差大的场景下发热严重,散热不好容易烫手。
选电池容量时可以用一个简单的功率估算。假设整机平均工作电流在 1.5A 左右,一块 2500mAh 的 2 串 2 并电池组容量是 5000mAh,理论上能跑 3.3 个小时,实际因为雷达、主控、电机的动态波动,打八折也有 2.5 小时左右,足够一次全屋清扫。
3. 实操:从零开始搭建一台开源扫地机器人
3.1 物料清单与预算参考
按照开源方案里最常见的配置,我给出一份参考物料清单。价格是市场波动范围内的估算,主要看你在闲鱼捡漏还是全新购买。
| 组件 | 型号/方案参考 | 预算参考 | 说明 |
|---|---|---|---|
| 主控板 | 树莓派 4B 或香橙派 Zero3 | 300 元 | 跑 ROS 2、建图和导航,建议 2GB 内存以上 |
| MCU 底层控制板 | Arduino Nano 或 ESP32 | 20-30 元 | 采集编码器、输出 PWM、关环控制 |
| 激光雷达 | RPLIDAR A1M8 | 400-500 元 | 单线 360 度,8 米测距 |
| 电机 | 带霍尔编码器 N20 减速电机 x2 | 50-70 元 | 减速比 1:30 左右,配 65mm 轮子 |
| 电机驱动 | TB6612FNG 模块 | 15-20 元 | 两路电机驱动,内置稳压 |
| 电池 | 18650 电池 4 节 + BMS 保护板 | 80-100 元 | 推荐 2 串 2 并,7.4V |
| 降压模块 | MP1584 x2 | 10-15 元 | 一路给 5V,一路给雷达/传感器 |
| 底盘 | 亚克力板 + 3D 打印件 | 50-100 元 | 网上有很多开源的底盘图纸 |
| 传感器 | 碰撞开关、悬崖红外、MPU6050 | 80-100 元 | 按需选购 |
| 充电座 | 红外信标或普通无线充电模块 | 50-100 元 | 自动回充的物理设备 |
算下来整套硬件成本在 1100 元到 1500 元之间,比买一台主打规划清扫的成品扫地机便宜不少。如果你手头有旧机器人、旧无人机拆下来的电机和电池,成本还能再降。
3.2 底盘组装与接线避坑
底盘组装看起来是纯机械活,但有几个细节直接决定后面能不能顺利建图。
第一,接线前先画一张完整的接线图。主控板、MCU、电机驱动、雷达、传感器之间的电源线和信号线要明确区分,避免通电后才发现接错。电源线用粗一点的硅胶线,信号线用排线或杜邦线,尽量缩短电机驱动到电机之间的线长,减少电磁干扰。
第二,电机编码器接线要接到 MCU 的外部中断引脚上。霍尔编码器输出 A/B 两相方波信号,通过两相之间的相位差可以判断旋转方向。如果接到普通 GPIO 上做轮询,高速转动时会丢脉冲,里程计就不准了。
第三,电机电源和逻辑电源必须共地。电机启动瞬间电流很大,会在电源线上产生压降,如果不把电机电源的 GND 和主控逻辑电源的 GND 接在一起,MCU 收到的编码器信号会出现乱跳,严重时直接复位。
第四,激光雷达尽量安装在底盘中心轴线上,且位置要高于底盘边缘,否则建图时雷达扫描线会打到车身上,产生一圈“假墙”。
第五,电池要平铺在底盘中央偏下的位置,降低整机重心。踩过的教训是:重心过高会导致快速转向时小车侧倾,雷达也跟着晃动,建图效果会变得很不稳定。
3.3 软件环境搭建与驱动节点部署
软件部分我按 ROS 2 框架来说。ROS 2 的长期支持版本 Humble 是当前最稳定的选择,对 Ubuntu 22.04 支持也最好;如果你的板子资源紧张,也可以考虑更精简的方案,直接跑节点编排。
先装基础系统,然后安装 ROS 2 核心包:
sudo apt update sudo apt install ros-humble-desktop source /opt/ros/humble/setup.bash创建工作区,把开源方案的代码克隆到 src 目录:
mkdir -p ~/sweeper_ws/src cd ~/sweeper_ws colcon build source install/setup.bash雷达驱动的部署是最先要验证的环节。RPLIDAR 官方提供了 rplidar_ros 驱动包,连接 USB 后通过 launch 文件启动,正常情况下ros2 topic echo /scan会持续输出激光数据。这里最容易踩的坑是 USB 串口权限问题,报错Permission denied时执行:
sudo chmod 666 /dev/ttyUSB0更专业的做法是写一个 udev 规则,在/etc/udev/rules.d/下新建规则文件,让系统自动给雷达串口赋予权限。
底盘驱动节点负责把编码器读数换算成里程计信息,发布 odom 话题,同时接收 cmd_vel 速度指令,换算成左右轮的 PWM 输出。这一步是整个系统里最机械但也最关键的环节,odom 数据不准,后面建图和导航全白搭。
所有节点跑起来后,用ros2 run tf2_tools view_frames检查 TF 树,正常情况下应该有一条完整的链路:odom → base_link → laser。链路中间任何一环缺失,导航程序都会直接报错退出。
3.4 建图、清扫模式与自动回充调试
建图是第一个能看到“成就感”的环节。用游戏手柄或者键盘控制节点发布 cmd_vel 速度指令,让小车以很慢的速度绕房间走一圈,重点走墙角、门框这些特征明显的区域,同时避免过快旋转导致雷达扫描不连贯:
ros2 launch cartographer_ros cartographer.launch.py ros2 run teleop_twist_keyboard teleop_twist_keyboard ros2 run nav2_map_server map_saver_cli -f ~/map地图保存下来后,就可以用 Navigation2 做自主导航了。一个比较顺滑的调试顺序是:先让机器人手动走到充电座旁边,记录充电座在地图中的坐标;之后每次清扫结束,导航到该坐标,再通过红外信标或者激光雷达的精确匹配做最后几厘米的对准。
自动回充的常见实现有两种。第一种是红外引导方案,充电座上放一个红外发射器,机器人装多个红外接收管,靠信号强度差来判断方向和距离,成本低、实现快。第二种是纯导航方案,完全依赖建图时记录的充电座坐标,用 Navigation2 导航过去,再用缓慢的直线微调对准充电触点。实际项目里两者可以结合:远场用导航,近场用红外精确对准,稳定性最好。
清扫模式在导航框架之上实现。最简单的是弓字形覆盖:从房间的一角出发,沿一条直线走到边界,旋转 180 度,平移一个机身宽度后往回走,循环覆盖整个区域。高级方案里还可以实现基于地图分割的房间分区清扫,以及根据充电座电量自动中断清扫并返回充电。
4. 常见问题与排查技巧实录
4.1 电机不转、抖动或转速不一致
电机问题是最先暴露的坑,排查顺序建议按这条路线走:先确认供电电压正常,再确认驱动模块输入逻辑,最后检查 PWM 频率和编码器反馈。
- 电压正常但电机不转:大概率是驱动模块的使能引脚(EN)没拉高,或者 PWM 占空比设置为 0。
- 电机抖动:PWM 频率太低,通常在几百赫兹时会出现明显的步进感或啸叫,把频率调到 10kHz 以上可以解决。
- 左右轮转速不一致:检查两个电机的减速比是否一致,编码器线数是否相同,对应驱动通道的 PWM 分辨率是否有差异。如果硬件都没问题,可以在控制节点里给每个轮子单独校准比例系数。
4.2 建图重影、漂移或地图缺角
建图效果出问题,大多数情况不是算法不行,而是输入数据不干净。
- 重影:雷达扫描数据不连续,或者底盘电机打滑导致里程计丢步。可以先用硬纸板把雷达线固定住,避免旋转时线缆拉扯。
- 地图漂移:IMU 没有做校准,或者里程计参数不对。MPU6050 首次上电要静止 10 秒以上,让陀螺仪完成零偏校准;轮距和编码器线数这两个参数,必须实际测量后写进配置。
- 地图缺角:建图时机器人车速太快,或者转弯太猛,导致某些区域激光扫描不完整。建图阶段把最大线速度限制在 0.2 米/秒以内,转弯角速度限制在 0.5 弧度/秒以内,就会好很多。
里程计校准有一个实用的土办法:让机器人贴墙走一段精确距离(比如 2 米),看编码器算出来的位移和实际差多少;再让它原地旋转 360 度,看角度误差。通过这两个误差值反推轮距和脉冲数参数,通常调一两次就能把误差控制在 2% 以内。
4.3 ROS 2 通信连不上、话题数据断流
多机通信和话题断流是玩 ROS 2 最头疼的一类问题,但排查思路相对固定。
- 确保开发板和电脑在同一个网段,并且
/etc/hosts里写清楚主机名和 IP 的映射。 - 全系统使用相同的 RMW 实现,比如都用默认的 Fast DDS,混用不同中间件会导致节点之间互相发现不了。
- 用
ros2 doctor检查环境,用ros2 node list和ros2 topic list确认节点和话题是否正常注册。 - 雷达话题掉线,先排除 USB 供电不足。雷达的瞬时电流接近 500mA,如果用一个供电能力弱的 USB HUB 给雷达供电,就会出现间歇性断流。
4.4 依赖拉不下来:GitHub 访问与镜像加速的常规操作
这是把开源方案从“收藏”变为“本地可运行”时人人都会遇到的一道坎。GitHub 的直连访问有时候不稳定,git clone 大仓库或者拉取 submodule 时经常超时。我总结了几条不依赖特殊工具的常规操作,按优先级排列:
- 优先用国内开源软件镜像站。清华大学开源软件镜像站(TUNA)和阿里巴巴开源镜像站都提供了 GitHub 代码仓库的同步入口,把仓库地址的域名前缀替换成镜像站域名,就可以通过国内服务器拉代码,速度稳定很多。
- 去 Gitee 上搜索同名的开源项目。很多高星项目在 Gitee 上有官方或社区维护的同步镜像,直接
git clone即可。 - 对于只需要源码包、不需要 git 历史的情况,进入项目主页的 Releases 页面,下载对应的源码压缩包附件,走浏览器直连通常比
git clone可靠。 - ROS 2 的依赖用 rosdep 安装时,偶尔会因为源的问题卡住。可以把 rosdep 的源地址替换为国内镜像,具体配置方法在 ROS 官方文档和镜像站帮助页都有说明。
提示:在 GitHub 上找开源项目时,注意核对仓库的 star 数、最近提交时间和 license 文件。高仿项目很容易混进搜索结果里,携带修改过的 launch 配置或者不明来源的第三方二进制,尽量选择维护活跃、文档完善的仓库。
4.5 导航时反复撞墙、原地打转或规划失败
导航行为异常,本质上是在问:代价地图到底看到了什么?规划器到底在算什么?
- 反复撞墙:机器人半径和膨胀半径设置不当,路径规划认为能通过,实际却过不去。用
ros2 run nav2_util lifecycle_bringup打开可视化工具,把代价地图和实际雷达点云叠在一起看,能直接找到问题。 - 原地打转:局部规划器在找不到可行路径时,会不断尝试旋转寻找方向,这是恢复行为(Recovery Behavior)在起作用。检查激光雷达是否被遮挡、膨胀层是否把整个区域都标成了障碍物。
- 规划失败:全局路径规划找不到路径时,优先查地图是否有缺口或者不连续区域。可以用地图编辑器把通道加宽,或者把 nav2 参数文件里的
allow_unknown设为 true,允许路径穿过未探索区域。
写在最后的一点经验
我自己在从零搭建这套开源方案的时候,最大的感悟是:建图和导航算法本身其实没那么难调,真正浪费时间的是“数据质量”问题。编码器标定不准、雷达供电不稳、底盘重心偏高,这些硬件层面的小问题,会以离奇的方式反映在软件结果上。所以我的建议是,一开始就把轮式里程计标定好、把供电系统理顺、把每个传感器单独验证过,再开始跑整套导航,能帮你省下至少一周的排查时间。
如果你也想动手试,后续还可以继续折腾很多方向:给底盘加拖地模组、用视觉识别做地毯检测、通过语音助手远程控制、把清扫记录同步到手机 App。开源方案只是起点,真正有意思的部分是你根据自己的需求把它改造成你想要的样子。反正 GitHub 上整套方案都摆在那了,动手就完事了。