做机器人这几年,我越来越确信一件事:开源SLAM方案的选型,本质上不是比谁论文里的精度数字更好看,而是比谁更懂自己的场景和需求。社区里开源SLAM方案满天飞,ORB-SLAM、VINS、LOAM、LIO-SAM、cartographer,随手就能列出一长串,可真到要往自家机器人上装、要让它稳定跑起来的时候,很多人第一步就懵了——这么多方案到底该怎么选、怎么评?
我最早接触开源SLAM,是在给一台小型轮式机器人做室内自主导航的时候。当时面对一大堆开源项目,我也走了不少弯路:看哪个star多就装哪个,看哪篇论文新就试哪个,结果要么编译失败,要么跑起来效果跟论文里完全对不上。后来踩坑踩多了,我慢慢形成了一套自己的评估方法论:先定场景,再列维度,最后用统一的数据集和工具做横向对比。这套方法帮我省下了大量试错时间,今天分享出来,希望能帮正准备入坑或正在选型的同学少走弯路。这篇内容适合想给机器人加“眼睛”的工程师、做算法评估的研究生,以及所有想从一堆开源方案里选出“够用且好落地”方案的爱好者。
1. 为什么我劝你先建一套评估标准,再谈选型
1.1 方案不是越新越好,先明确你的机器人形态和使用场景
先聊一个我自己踩过的坑。有段时间我特别迷信新方案,看到哪个项目star涨得快、论文发得新,就往机器上装。结果在室内小车场景里,一圈试下来才发现,很多号称精度很高的开源视觉方案,在纹理不足的白墙环境里根本跑不起来,反而是被我嫌弃“老土”的激光方案稳稳当当。
所以评估任何开源SLAM方案之前,第一个要回答的问题不是“它精度多高”,而是“你的机器人长什么样、在什么环境里跑”。是带激光雷达的轮式机器人,还是带相机的无人机?是室内结构化环境,还是室外植被丰富的场景?搭载平台有多少CPU、内存和算力?这些问题直接决定了候选方案的集合,也能帮你少浪费好几个周末在编译上。
我自己习惯把应用场景归成几类:室内低速导航、室外高速移动、无人机空中定位、AR/VR手持设备。不同类型的运动特性对SLAM算法的要求完全不一样。比如快速旋转运动对视觉SLAM来说几乎是灾难,但激光雷达基本不受影响;反过来,激光方案在几何特征少的长走廊里定位容易飘,而视觉方案却能靠远处的纹理救回来。先明确自己的场景,选型才有方向。
1.2 我常用的六个评估维度与打分框架
我把SLAM方案评估拆成六个维度,每个维度按0到10打分,最后做加权比较。这六个维度分别是:定位精度、鲁棒性、实时性、资源占用、易用性、社区活跃度。
定位精度是SLAM方案的核心KPI,但不是唯一KPI。鲁棒性看的是在光照突变、快速运动、遮挡、空旷场景这些“刁钻条件”下还能不能稳住;实时性看单帧处理耗时,能不能满足机器人的控制频率;资源占用看CPU、内存,放到移动端还要考虑功耗和发热;易用性看编译安装、参数调优、数据集适配的整体成本;社区活跃度看Issue回复速度、更新频率、资料丰富程度,这直接决定你踩坑后能不能快速爬出来。
打分的时候不用特别精确,关键是同一套标准要统一应用到所有候选方案上。我的做法是:先把每个维度的原始数据收集齐,比如用evo跑出来的APE数值、用top命令观察的CPU占用率、从GitHub Issues看平均响应时间,然后按表格中的参考线给分。下面是我常用的一套打分参照表。
| 评估维度 | 9-10分 | 6-8分 | 3-5分 | 0-2分 |
|---|---|---|---|---|
| 定位精度 | 公开数据集上APE RMSE极低,稳定复现论文水平 | 精度好但需要调参才能达到 | 能跑但误差明显 | 无法获得有效轨迹 |
| 鲁棒性 | 多种恶劣场景下仍能持续定位 | 常规场景稳定,个别场景会丢 | 对运动或环境变化非常敏感 | 普通场景都无法稳定运行 |
| 实时性 | 远低于传感器帧率 | 能跟上帧率,偶有卡顿 | 处理速度明显不足 | 完全无法实时运行 |
| 资源占用 | 占用很低,嵌入式可用 | 占用中等,主流工控机流畅 | 占用偏高,发热明显 | 资源消耗不可接受 |
| 易用性 | 一条命令编译运行 | 按文档能跑通,但有一些坑 | 需要大量调参和补丁 | 极难复现,依赖严重冲突 |
| 社区活跃度 | Issue响应快,持续更新 | 有维护者,资料较多 | 基本停更,靠网友问答 | 无活跃社区,无资料 |
1.3 六个维度在典型场景下的权重模板
打分归打分,每个项目对维度的重视程度不一样,所以还得加权重。比如室内轮式机器人,定位精度和鲁棒性排在前面;而无人机上,实时性可能比易用性重要得多。我自己总结了几套常用权重模板,你可以直接参考,也可以按自己的需求调整。
- 室内轮式机器人:精度0.35,鲁棒性0.30,实时性0.10,资源占用0.10,易用性0.10,社区活跃度0.05
- 无人机空中定位:精度0.30,鲁棒性0.25,实时性0.25,资源占用0.10,易用性0.05,社区活跃度0.05
- 室外无人车:精度0.35,鲁棒性0.30,实时性0.15,资源占用0.05,易用性0.05,社区活跃度0.10
- 低成本嵌入式设备:精度0.20,鲁棒性0.20,实时性0.20,资源占用0.25,易用性0.10,社区活跃度0.05
权重这东西没有标准答案,它的意义在于逼你把“我觉得A好像更好”变成可复现的比较过程。特别是当要在两三个方案之间做决定时,打分数值一算,往往比印象流靠谱得多。
2. 主流开源SLAM方案盘点:按场景对号入座
2.1 视觉SLAM三巨头:ORB-SLAM3、VINS-Mono/Fusion、DSO
视觉SLAM是开源社区最热闹的领域,这里绕不开的就是ORB-SLAM系列。ORB-SLAM3支持单目、双目、RGB-D,还支持视觉+惯导(VI),在公开数据集上的精度数据相当亮眼。它基于ORB特征点做稀疏建图,回环检测稳定、地图复用能力强,在室内特征丰富的环境里表现极佳。缺点也很明显:计算量偏大,低算力嵌入式平台上帧率很难拉满,而且对光照突变比较敏感。你可以把ORB-SLAM3理解为“全能型选手”,但全能意味着它不是任何单项最顶尖的。
VINS-Mono/Fusion是港科大开源的方案,采用单目+IMU紧耦合架构,IMU预积分和视觉特征的融合让它在快速运动、纹理单调的场景下依然能稳住姿态。VINS-Fusion在单目基础上扩展了双目和GPS融合,室外场景非常实用。我自己在无人机上跑VINS-Fusion的体感是,它比纯视觉方案更抗造,尤其在大机动飞行时能明显感受到IMU补足了视觉的短板。
DSO是直接法的代表,它不走特征提取路线,直接对像素灰度进行优化。在纹理丰富且光照稳定的环境里精度很高,但缺点也致命——对环境光照极其敏感。我试过在室外阴影斑驳的地方跑,很快就跟丢了。所以DSO更适合室内恒定光源下的算法研究和演示类应用,拿来做产品主方案风险很大。想系统理解这些方案的差异,高翔的《视觉SLAM十四讲》依然是很合适的入门地图,里面的ORB特征、图优化等基础概念能帮你建立真正的理解框架。
2.2 激光SLAM双线作战:从cartographer到LOAM系再到LIO-SAM
激光SLAM这些年从2D走向3D,方案丰富度比早期高了不少。室内2D场景,谷歌开源的cartographer是我用得最顺手的。它采用子图(submap)加回环检测的思路,建图时能明显感觉到闭环修正的效果,画出来的地图横平竖直、边界清晰,配合ROS的navigation栈做自主导航非常顺滑。如果你的机器人只做室内平面导航,cartographer+move_base基本是无脑首选。
3D激光方向,LOAM系是绕不开的经典。从最原始的LOAM到轻量化的A-LOAM,再到带线特征的FLOAM,核心思路都是激光里程计:高频扫描匹配输出里程计,低频优化构建地图。纯LOAM系的问题是缺少IMU辅助,在剧烈颠簸和快速旋转时容易退化。LIO-SAM就是为解决这个问题而来的,它在激光里程计基础上加入IMU紧耦合,用因子图把激光里程计、IMU预积分和GPS(如果有的话)统一优化。我在带坡度的园区道路上试过LIO-SAM,精度确实比纯LOAM系高一个档次。
2.3 视觉+激光+IMU多传感器融合:为什么成了新趋势
现在的新趋势是激光、视觉、IMU三者融合。原因不复杂:单一传感器都有自己的死穴——视觉怕黑暗和快速运动,激光怕几何特征缺失,纯IMU漂移快。融合方案通过不同传感器的互补,能大幅提升整体鲁棒性。
代表方案如LVI-SAM、LIO-VIS等,它们把视觉特征、激光点云和IMU预积分放进同一个因子图或滑窗里联合优化。效果好,但对传感器标定和时间同步的要求也高得多。一套未校准好的系统,融合反而可能把各传感器的误差叠加在一起,效果不如单传感器。所以我给大家的建议是:如果预算和精力有限,先玩好单传感器方案;等基础流程稳定了,再考虑融合方案。多传感器融合不是万能的,但确实是未来几年的主流演进方向。
3. 评估方法实操:从数据集到evo跑分一条龙
3.1 公开数据集选型标准:TUM、KITTI、EuRoC各测什么
评估开源SLAM方案,第一步不是装到自己的机器人上,而是先用公开数据集跑通。公开数据集的好处是自带真值轨迹、评测指标公认、结果可以横向对比。三个主流数据集各有侧重,我根据自己的目标场景来选择。
TUM RGB-D是慕尼黑工业大学采集的室内数据集,包含大量手持相机的快速运动、动态物体场景,测的是视觉方案在“折腾型”运动下的表现。KITTI是室外驾驶数据集,图像分辨率高、场景尺度大,适合无人车方向。EuRoC是无人机室内数据集,同步采集双目图像和IMU数据,特别适合测视觉+惯导方案。我的经验是:先根据目标场景选最接近的数据集,然后让所有候选方案在同一数据集上跑,确保比较口径一致。真值轨迹文件一般在数据集目录里,比如TUM的groundtruth.txt,格式是“时间戳 位置xyz 四元数xyzw”,评估前先确认你读懂了这条格式。
3.2 Kalibr相机标定:这步不做好,评估结果全是虚的
相机标定不直接属于SLAM评估,但它的质量直接决定SLAM评估的准确性。如果用未标定或标定不准的相机跑视觉SLAM,内参误差会被算法逐渐放大,最后的轨迹误差可能比真实水平高出一个数量级。我见过一个项目,换成高质量标定参数后,精度直接翻了一倍,不是算法进步了,是相机内参终于对了。
Kalibr是目前最常用的多相机+IMU标定工具,支持相机内参标定、多相机外参标定、相机-IMU外参标定。标定流程一般分三步:先打印一张AprilGrid标定板,固定不动地录制一段包含慢速旋转和缓慢平移的bag;然后运行Kalibr命令行生成相机内参和畸变系数;再做相机与IMU的联合标定,得到外参。整个过程虽然繁琐,但属于“磨刀不误砍柴工”。验证标定质量的简单办法,是查看Kalibr输出的重投影误差,一般做到0.1到0.2像素以内算合格。如果只用公开数据集做评估,数据集自带相机内参,可以跳过这步;但实机验证前,这步不能省。
3.3 evo评估工具:APE、RPE和轨迹对齐的底层逻辑
evo是SLAM评估里的标准工具,几乎每个做SLAM的人电脑里都装了。它支持TUM、KITTI、EuRoC等多种轨迹格式,可以计算绝对轨迹误差(APE)和相对位姿误差(RPE),还能输出各种可视化曲线。
APE和RPE不是一回事。绝对轨迹误差是估计轨迹和真值轨迹对齐后逐点位姿的误差,反映全局一致性,适合看回环检测和全局优化的效果;相对位姿误差则是计算固定时间间隔内相对姿态变化的误差,反映局部漂移和平滑度,适合评估里程计本身的精度。我建议两个指标都算,解读时分开看:APE大说明全局地图有问题,RPE大说明局部运动估计不够平滑。下面是我常用的evo命令速查表。
| 命令场景 | 示例命令 | 参数说明 |
|---|---|---|
| 轨迹对齐并画APE图 | evo_traj tum KeyFrameTrajectory.txt --ref groundtruth.txt -a -p | -a 表示自动对齐旋转和平移,-p 表示绘图 |
| 单独计算APE指标 | evo_ape tum KeyFrameTrajectory.txt --ref groundtruth.txt -a | 输出RMSE、Mean、Std等 |
| 计算RPE指标 | evo_rpe tum KeyFrameTrajectory.txt --ref groundtruth.txt -a | 可加 -d 指定时间间隔 |
| 合并多条结果对比 | evo_res results/*.zip | 把多次evo_ape/evo_rpe的zip结果放进同一目录横向对比 |
3.4 实测一条龙:ORB-SLAM3单目在TUM上的完整评估
用一个最经典的组合演示完整流程:用ORB-SLAM3跑TUM数据集,再用evo评估。第一步,下载TUM数据集并解压,确认目录里有rgb、depth文件夹和groundtruth.txt。第二步,运行ORB-SLAM3的单目启动脚本,命令一般是:
./Examples/Monocular/mono_tum Vocabulary/ORBvoc.txt Examples/Monocular/TUM1.yaml path/to/TUM_dataset注意TUM1.yaml、TUM2.yaml、TUM3.yaml对应不同相机的内参,如果数据集是freiburg1序列就要用TUM1.yaml,用错了结果会虚低,这不是算法的问题。
跑完后ORB-SLAM3会生成KeyFrameTrajectory.txt。第三步,用evo做轨迹对齐和评估:
evo_traj tum KeyFrameTrajectory.txt --ref groundtruth.txt -a -p evo_ape tum KeyFrameTrajectory.txt --ref groundtruth.txt -a evo_rpe tum KeyFrameTrajectory.txt --ref groundtruth.txt -a这里最关键的坑是:单目SLAM没有尺度信息,估计轨迹和真值轨迹的尺度不一致,必须加-a参数做相似变换对齐。如果漏了这步,误差会大得离谱,你会误以为方案很差。另外,我强烈建议同一序列多跑几轮,取APE RMSE的中位数而不是最好的一次,因为SLAM算法有随机性,一次超常发挥不代表真实水平。跑完把命令输出和运行参数记录下来,方便之后复现。
4. 常见问题与排查技巧实录
4.1 编译安装总报错?大概率是版本依赖的问题
以Ubuntu 20.04安装ORB-SLAM2为例,这是很多新手第一个接触的方案,踩坑率非常高。ORB-SLAM2是老代码,在OpenCV4环境下编译通常会报一堆错误,典型的包括findContours参数不匹配、ORBextractor头文件变更等,都需要手动打补丁。ORB-SLAM3相对好一点,但也要求C++14编译环境、Pangolin版本不能过老、Eigen版本要保持一致。可以说,编译这一步消耗的时间,经常比跑通算法本身还长。
我的建议是:评估一个开源方案前,先花10分钟看它的README和Issue区,重点确认依赖库版本要求,然后在干净的独立环境里编译,最好用Docker或专门的虚拟环境,避免和已有的ROS、OpenCV版本冲突。编译时如果内存不够,把make的并行任务数调低些,比如make -j2,虽然慢但至少不会因内存爆掉而失败。这些编译的坑本质上是易用性维度的真实写照,也提醒你:方案再好,如果编译门槛高到劝退,那它在你的场景里就得慎重考虑了。
4.2 评估结果虚高或虚低?先检查轨迹对齐和格式
跑完evo出结果后,先别急着下结论。评估数据虚高或虚低,最常见的原因有三个。
第一是轨迹对齐方式不对。单目方案必须做sim(3)对齐,也就是加-a参数;双目、RGB-D和激光方案因为尺度已知,通常用se(3)对齐就够了,但也要根据数据集类型判断。第二是时间戳没对上。轨迹文件和真值文件的时间基线可能不一致,或者频率不同,需要同步或插值,evo的--sync参数能帮忙,但如果数据本身时间戳乱跳,先回去检查数据集或方案的时间戳输出。第三是数据集内参用错,前面提过的TUM1/2/3对应不同相机,容易踩坑。评估结果不理想时,我会按“对齐方式→时间同步→参数配置→代码完整性”这样的顺序排查,而不是第一时间怀疑算法本身。
4.3 真机跑不起来:仿真环境与真实环境的差距
公开数据集跑得再好,也不代表实机一定稳。真机上的激光雷达噪声、相机畸变、IMU零偏、传感器时间同步延迟,都会让算法表现打折扣。我的经验是,从评估到实机落地,至少要走“公开数据集→仿真环境→真机蹒跚起步”三步。Gazebo等仿真环境能帮你确认算法链路没问题,比如话题通信、TF变换、参数配置,这些如果不在仿真里排掉,上真机排查会非常痛苦。
真机上还要注意计算资源。很多开源方案在桌面PC上跑得很流畅,但一到Jetson或树莓派上就掉帧。评估时最好在目标算力平台上做一轮完整测试,记录CPU占用和帧率,再结合前面说的资源占用维度加权打分。这一步往往能筛掉一批“看着很行、实机不行”的方案。
4.4 开源SLAM方案选型速查表
最后把这几年的选型经验浓缩成一张速查表,你可以直接按场景对号入座,然后根据自己的资源和团队水平做最终决策。
| 应用场景 | 推荐方案 | 核心理由 | 主要风险 |
|---|---|---|---|
| 室内轮式机器人导航(2D) | cartographer | 建图直观、回环修正明显、ROS集成好 | 对激光雷达质量有一定要求 |
| 室内轮式机器人(有纹理环境) | ORB-SLAM3(RGB-D) | 精度高、回环稳定、地图可复用 | 光照突变时容易丢 |
| 室外无人车 | LIO-SAM / VINS-Fusion(双目+GPS) | 融合IMU和GPS,适应大尺度场景 | 标定要求高,调参复杂 |
| 无人机 | VINS-Fusion / LVI-SAM | IMU紧耦合抗运动模糊,适合空中快速运动 | 需要高质量的相机-IMU标定 |
| 低算力嵌入式平台 | ORB-SLAM2单目 / A-LOAM | 轻量、依赖少、成熟 | 精度折扣明显,需降级预期 |
| 快速原型验证 | ORB-SLAM3 / A-LOAM | 文档全、资料多、容易跑通 | 不能直接代表最终落地效果 |
我自己评估下来最大的感受是,这些方案没有绝对的“最好”,只有“特定条件下的最合适”。比如在室内小车上,cartographer精度可能不是最高的,但它编译顺利、社区活跃、和ROS导航天生一对,反而是落地最快、体验最稳的选择。精度高但调参困难的方案,更适合有专门算法团队的项目去深挖。
最后再分享一个小技巧:评估过程中所有记录,包括数据集版本、参数文件、运行命令、evo输出、当时的系统环境,都要整理成一份可复现的文档。SLAM方案迭代快,两个月后再看同一个方案,可能版本变了、参数变了、甚至整个算法框架都重构了。有一份完整的评估记录,你才能做有意义的纵向对比,也才能在“之前明明跑得很好,现在怎么不行了”的时候快速定位问题。这比“我记得当时好像还不错”可靠太多了。