ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

从激光SLAM到3DGS:机器人建图导航的工程实践与踩坑总结

从激光SLAM到3DGS:机器人建图导航的工程实践与踩坑总结 SLAM这个词我第一次接触是在研究生阶段帮师兄调一台差速底盘小车。当时它在一个十来平米的房间里转圈建出来的地图像被揉皱的纸墙角全是重影。师兄丢下一句你把回环检测那块再看看就走了我对着屏幕上的点云发了半天呆。后来折腾了几年从2D激光SLAM做到视觉SLAM再到最近把3D Gaussian Splatting往建图流程里塞踩过的坑比走过的路还多。这篇笔记不打算写成教科书而是把我自己从入门到能独立跑通一套完整建图导航链路的过程中真正卡住过、想明白过、以及后来带新人时反复被问到的东西系统地梳理一遍。不管你是刚买了激光雷达准备做小车导航的学生还是想把视觉SLAM接进自己产品里的工程师或者只是被视觉SLAM十四讲刷屏后想搞清楚这玩意到底能干嘛的人应该都能从里面找到点有用的东西。1. 先把SLAM这件事的边界划清楚1.1 SLAM到底在解决什么问题SLAM全称是Simultaneous Localization and Mapping中文叫同时定位与建图。这个名字其实已经把核心矛盾说透了一个在未知环境里移动的机器人它既不知道自己在哪里也不知道周围长什么样而这两件事互为前提——要知道自己在哪得先有地图要建地图得先知道自己在哪。这是一个典型的鸡生蛋蛋生鸡问题。解决思路说白了就是边走边猜边猜边修。机器人每移动一步根据运动模型推测自己大概到了哪这叫预测同时用传感器观测周围环境拿观测结果去修正刚才的推测这叫更新。这个过程反复迭代位置越来越准地图也越来越清晰。听起来简单但真正难的地方在于误差会累积。你每一步的推测都有微小偏差走一百步之后偏差可能就大到地图完全对不上了。所以SLAM系统里必须有一个回环检测机制当机器人回到曾经走过的地方时能认出来哎这地方我来过然后一次性把累积的误差抹平。我常跟新人打一个比方蒙着眼睛在陌生房间里摸索着画平面图。你每走一步都在心里估算方向和距离同时用手摸墙壁来校正。走久了估算肯定飘但如果你绕了一圈又摸到最开始那面墙你就知道我回来了于是可以把整张图重新对齐一遍。SLAM干的就是这件事只不过用的是激光雷达、相机、IMU这些传感器算的是概率分布而不是心里的感觉。1.2 激光SLAM和视觉SLAM的分岔路口刚入门最容易纠结的就是选哪条路。我的建议是先想清楚你的应用场景而不是先纠结哪个更先进。激光SLAM用激光雷达LiDAR作为主要传感器直接测距离精度高、受光照影响小、建出来的2D栅格地图或3D点云地图直观好用。经典的2D方案有Gmapping、Cartographer、Hector SLAM3D方案有LOAM系列、LIO-SAM、FAST-LIO等。它的短板是激光雷达贵虽然这两年降得厉害而且在长廊、隧道这种几何特征重复的环境里容易退化。视觉SLAM用相机成本低、信息丰富能识别纹理、颜色、物体但受光照和纹理影响大纯视觉在弱纹理墙面或快速运动时容易跟丢。经典方案有ORB-SLAM系列、VINS-Mono、LSD-SLAM等。视觉SLAM又分单目、双目、RGB-D几条路线单目有尺度不确定性双目和RGB-D能直接拿到深度但标定和同步更麻烦。对比维度激光SLAM视觉SLAM传感器成本较高近年下降明显低普通相机即可精度高直接测距中依赖三角化光照鲁棒性强弱纹理依赖低高地图形式栅格/点云直接可用稀疏/半稠密/稠密点云典型场景室内导航、自动驾驶AR/VR、无人机、低成本机器人实际项目里我越来越倾向于多传感器融合。纯激光在玻璃、镜面面前会失效纯视觉在暗光下抓瞎把IMU加进来做紧耦合鲁棒性会好很多。LIO-SAM和FAST-LIO就是激光IMU紧耦合的代表VINS系列是视觉IMU。如果你的平台预算允许激光IMU轮式里程计的组合是目前室内建图导航最稳的方案。1.3 建图和定位其实是两件事很多人把SLAM和建图导航混为一谈其实要拆开看。SLAM解决的是在未知环境里边走边建图而实际产品里更常见的是先建好图然后在地图里定位导航。后者叫定位Localization是在已知地图上估计位姿难度比SLAM低不少因为不用再维护地图了。所以一个完整的机器人导航链路通常是两阶段第一阶段跑SLAM建图把环境地图存下来第二阶段加载地图跑蒙特卡洛定位AMCL或类似算法做实时定位再叠加路径规划和避障。ROS里的经典组合就是Gmapping/Cartographer建图 AMCL定位 move_base导航。搞清楚这个分工你就不会在为什么建完图还要单独定位这种问题上绕圈了。2. 从零跑通一套激光SLAM建图的实际路径2.1 硬件和环境的准备清单我假设你手上有一台带激光雷达的差速小车或者至少有一个能发布激光扫描和里程计话题的仿真环境。真机的话你需要确认几件事激光雷达的安装高度和角度一般水平安装离地20到40厘米比较合适太低会扫到地面噪点太高会漏掉矮障碍物、雷达和底盘中心的相对位姿这个要写进TF树、轮式里程计的标定轮子直径和轮距不准的话里程计会飘得厉害。软件环境我推荐Ubuntu 20.04 ROS Noetic这个组合资料最全坑最少。如果你用ROS2Humble是当前比较稳的选择但很多老教程还是ROS1的新手容易被版本问题劝退。装好ROS之后至少需要这几个包雷达驱动比如rplidar_ros或你雷达厂商提供的、tf、robot_state_publisher、以及建图算法包gmapping或cartographer_ros。提示雷达驱动装好后先用rostopic hz /scan确认扫描频率稳定再用RViz看一眼点云是不是正常的一圈。我见过太多人建图失败最后发现是雷达数据本身就有问题。2.2 TF树SLAM里最容易被忽视的地基TF树是ROS里描述坐标系关系的机制SLAM里几乎所有位姿问题最后都能追溯到TF配置错误。你需要理清这几个坐标系map地图坐标系、odom里程计坐标系、base_link机器人本体、laser雷达。它们的关系是map → odom → base_link → laser每一层都是一个变换。map到odom这个变换是由SLAM算法发布的它代表了算法修正后的真实位置和里程计累积位置之间的偏差。odom到base_link由里程计发布base_link到laser由静态TF发布因为雷达是固定在车上的。很多人建图时地图乱飘、重影八成是TF树断了或者某两个坐标系接错了。我踩过的一个经典坑雷达驱动默认发布的frame_id是laser_frame而我在URDF里写的是laser结果TF树里这两个坐标系对不上RViz里雷达点云和机器人模型完全错位。排查方法很简单rosrun tf view_frames生成一张TF关系图或者rosrun tf tf_echo map laser看变换能不能正常输出。如果报错说找不到某个frame那就是名字对不上或者没发布。2.3 Gmapping和Cartographer的取舍Gmapping是基于粒子滤波的2D SLAM优点是配置简单、对里程计依赖适中、小场景下效果不错。缺点是粒子数随地图增大而爆炸大场景下计算量吃不消而且它没有回环检测严格说是有个简单的回环但很弱走远了容易漂。Cartographer是Google出的基于图优化有完善的回环检测支持2D和3D大场景下表现明显更好。代价是配置复杂需要调一堆lua参数而且对里程计和雷达的时间同步要求更高。我的实际经验是如果你只是在小房间几十平米里做demoGmapping够用十分钟就能跑起来。如果场景超过一两百平米或者有长走廊、多房间直接上Cartographer别在Gmapping上浪费时间调参。下面是一个Gmapping的最小launch配置思路launch node pkggmapping typeslam_gmapping nameslam_gmapping outputscreen param namebase_frame valuebase_link/ param nameodom_frame valueodom/ param namemap_frame valuemap/ param namedelta value0.05/ param nameparticles value30/ param namelinearUpdate value0.2/ param nameangularUpdate value0.2/ /node /launchdelta是地图分辨率0.05米就是5厘米一格越小地图越精细但越占内存。particles是粒子数小场景30够用大场景要加到80甚至更多。linearUpdate和angularUpdate控制机器人移动多少距离或转多少角度才做一次更新太小会算力爆炸太大会丢细节。2.4 建图过程中的操作节奏建图不是开着车乱跑就行操作节奏很影响最终地图质量。我的习惯是先让车原地慢慢转一圈让算法初始化并建立第一帧地图然后沿着房间边缘走一圈把外墙轮廓勾出来最后再走弓字形把中间区域填满。转弯要慢别急打方向因为快速旋转时雷达扫描会畸变里程计也容易打滑。走的过程中盯着RViz如果发现地图开始重影或者墙壁变厚说明位姿估计飘了这时候应该原路返回走一段给回环检测一个机会去修正。如果怎么走都修不回来那就停下来重新开始别硬撑越走越乱。注意建图时尽量避开动态物体比如走动的人、开着的门。Gmapping会把动态物体当成静态障碍物画进地图留下永远擦不掉的鬼影。如果环境里有人让他们尽量站着别动。3. 视觉SLAM入门绕不开的几个硬骨头3.1 从视觉SLAM十四讲说起几乎每个学视觉SLAM的人都会被推荐《视觉SLAM十四讲》。这本书确实经典但它有个特点数学推导非常密前几章就把李群李代数、非线性优化、卡尔曼滤波全砸过来新手很容易在第三讲就放弃。我的建议是不要试图一次读懂所有推导第一遍先跑通书里的代码把ORB特征提取、PnP位姿估计、光束法平差Bundle Adjustment这几个核心模块的输入输出搞清楚知道每一步在干嘛第二遍再回头啃数学。书里的代码基于较早的库版本直接编译大概率报错。比较省事的做法是用较新的依赖版本或者直接找社区维护的适配版。Sophus、Ceres、g2o这几个库是重点位姿表示和优化都靠它们。我第一次编译g2o折腾了整整一个下午最后发现是Eigen版本不兼容这种环境问题在视觉SLAM里太常见了。3.2 特征点法、直接法和半直接法视觉SLAM按前端处理方式分三大类。特征点法如ORB-SLAM先提取角点、计算描述子然后做特征匹配来估计运动。优点是鲁棒、对光照变化有一定容忍度缺点是特征提取耗时在弱纹理场景下提取不到足够的点。直接法如LSD-SLAM、DSO不提取特征直接最小化像素灰度误差来估计运动。优点是能利用所有像素信息在弱纹理下也能工作还能建半稠密地图。缺点是对光照变化极其敏感而且灰度不变假设在现实中经常不成立。半直接法如SVO折中用特征点做稀疏对齐用直接法做位姿优化速度快适合无人机这种对实时性要求高的场景。方法代表方案优势短板特征点法ORB-SLAM3鲁棒、成熟、回环完善特征提取耗时、弱纹理失效直接法DSO、LSD-SLAM弱纹理可用、可建稠密图光照敏感、易发散半直接法SVO速度快精度略低、回环弱选哪条路取决于你的场景。室内结构化环境、纹理丰富特征点法最稳。无人机高速飞行、纹理一般SVO这类半直接法更合适。AR应用需要稠密地图直接法或RGB-D方案更对路。3.3 视觉SLAM的初始化难题单目视觉SLAM有个绕不开的问题尺度不确定性。单张图像无法恢复绝对尺度你只能知道相机移动了某个相对距离但不知道是1米还是10米。解决办法通常是初始化时做一段平移运动通过三角化估计出尺度或者融合IMU来提供尺度信息。初始化的质量直接决定后续跟踪能不能稳住。我的经验是初始化时相机要缓慢平移不要纯旋转纯旋转无法三角化场景里要有足够的特征点分布在远近不同的深度上。如果初始化时尺度估歪了后面整个轨迹都会缩放错误而且很难纠正回来。双目和RGB-D就没这个问题直接能拿到深度。但双目要做立体校正和视差计算RGB-D的有效距离有限结构光一般0.5到5米ToF稍远超出范围深度就不可靠了。选传感器时要把工作距离算清楚。4. 回环检测、后端优化与地图的最后一公里4.1 回环检测为什么是精度的命门前面说过误差会累积回环检测就是那个一次性抹平累积误差的机制。它的原理是当机器人回到曾经到过的地方通过识别场景相似性判断我回来了然后把这个约束加进后端优化把整条轨迹和地图重新调整。激光SLAM里回环检测常用扫描匹配scan matching把当前帧和历史上的帧做匹配相似度超过阈值就认为是回环。视觉SLAM里常用词袋模型Bag of Words把图像描述子量化成单词通过比较单词向量判断场景相似度。DBoW2、DBoW3是常用库。回环检测最难的是假阳性——把两个其实不同的地方误判成同一个地方这会直接把地图搞崩。所以阈值不能设太松而且通常要加几何验证光看外观相似不够还要检查匹配上的特征点能不能构成合理的几何变换。ORB-SLAM里就有这一步叫sim3求解和几何一致性检查。4.2 后端优化的两种主流思路后端负责把前端估计的位姿和回环约束统一优化。主流有两类滤波方法扩展卡尔曼滤波EKF、粒子滤波和图优化方法基于因子图。滤波方法是增量式的每来一帧就更新一次状态计算量稳定但只能处理当前状态历史信息被边缘化了。图优化方法把所有位姿和约束建成一个图一次性求解全局最优精度更高但计算量大通常要配合滑动窗口或分层优化。现在主流SLAM系统基本都是图优化路线g2o、Ceres、GTSAM是三大优化库。g2o在视觉SLAM里用得最多Ceres在激光和通用优化里常见GTSAM在因子图建模上更优雅。选哪个看你团队熟悉度功能上都能满足。4.3 地图的保存、加载与后续使用建完图别急着关地图得存下来。2D栅格地图用map_server的map_saver存成pgm加yaml两个文件pgm是图像yaml是元数据分辨率、原点、阈值。3D点云地图可以存成pcd格式用PCL库读写。加载地图做导航时map_server读入yaml发布/map话题AMCL订阅地图和激光数据做定位move_base做路径规划。这里有个常见坑建图时的原点和导航时的初始位姿要对上否则AMCL一开始就定位错机器人会以为自己在别的地方。通常做法是让机器人在建图起点附近启动或者在RViz里手动给一个初始位姿估计。提示地图文件里的分辨率参数要和建图时一致我见过有人建图用0.05、加载时yaml里写成0.1结果地图尺度直接翻倍导航全乱套。5. 当3D Gaussian Splatting遇上SLAM5.1 3DGS为什么突然和SLAM扯上关系3D Gaussian Splatting3DGS是这两年很火的三维表示方法用一堆带位置、协方差、颜色、透明度的三维高斯球来表征场景渲染质量高、速度快。它和SLAM结合的逻辑很自然SLAM本来就在估计相机位姿并重建场景而3DGS提供了一种比点云更漂亮、比神经辐射场NeRF更快的场景表示。传统SLAM建出来的点云地图稀疏、有噪声、看着像一团雾。用3DGS重建出来的场景渲染出来接近照片级对AR、VR、数字孪生这类应用吸引力很大。所以最近一批工作如SplaTAM、Gaussian-SLAM、Photo-SLAM都在尝试把3DGS嵌进SLAM流程边跟踪边优化高斯球。5.2 把3DGS接进SLAM流程的实际难点理想很丰满实际做起来有几个硬骨头。第一是计算量3DGS的优化本身就不轻再叠加SLAM的实时跟踪对GPU要求很高。目前多数方案在桌面级显卡上能跑但离嵌入式部署还有距离。第二是位姿和高斯球的联合优化容易陷入局部最优。SLAM的位姿估计有误差3DGS的重建又依赖准确位姿两者互相拖累。常见做法是用SLAM先给一个粗略位姿再用3DGS做光度优化精修但精修过头又会破坏SLAM的几何一致性。第三是回环和全局一致性。3DGS是局部表示回环发生后怎么把已经优化好的高斯球整体调整目前还没有特别成熟的方案。多数工作还是靠SLAM后端先优化轨迹再重新训练高斯球做不到真正的在线全局优化。我自己的尝试是在一个室内场景里用RGB-D数据跑Gaussian-SLAM重建质量确实惊艳但帧率只有个位数而且场景一大显存就爆。所以现阶段我的判断是3DGSSLAM适合离线或准在线的场景重建比如扫描一个房间生成可交互的3D场景暂时还不适合做实时导航。5.3 现阶段值得关注的几个方向如果你对这个交叉领域感兴趣我建议关注三条线一是高斯球的增量式优化怎么在不重新训练的前提下加入新观测二是位姿和高斯球的紧耦合让两者在同一个优化框架里互相促进三是内存和计算优化比如高斯球的剪枝、量化、层次化表示。这几条线解决好了3DGSSLAM才有可能真正落地到移动平台。6. 那些文档里不会写的踩坑经验6.1 时间同步一个能让你查一整天的坑多传感器SLAM里激光、相机、IMU的数据必须时间对齐。ROS里用message_filters做时间同步但前提是各传感器的时间戳来自同一个时钟源。如果雷达用自己的内部时钟、相机用系统时钟两者差个几十毫秒融合结果就会错位。我遇到过一次激光和IMU融合建图走直线没问题一转弯地图就扭曲。查了两天最后发现是IMU驱动发布的时间戳用的是传感器内部时间和系统时间差了将近100毫秒。改成统一用ROS时间后问题消失。排查这类问题的工具是rosbag录制数据后离线分析把各话题的时间戳打出来对比一眼就能看出偏差。6.2 标定外参错一点建图歪一片雷达和相机之间的外参标定旋转和平移如果不准融合出来的地图会有系统性偏差。标定方法有基于标定板的如棋盘格、AprilTag也有无靶标的如基于互信息的自动标定。我推荐先用标定板做一次粗略标定再用无靶标方法精修。标定完一定要验证把激光点云投影到图像上看边缘是否对齐。如果点云和图像里的物体轮廓明显错位说明外参有问题。这个验证步骤很多人省掉结果带着错误外参跑了几周才发现。6.3 动态环境和地图维护真实环境不是静止的家具会移动、门会开关、人会走动。SLAM建出来的地图如果包含这些动态元素导航时就会撞上地图里有但实际没有的障碍物或者撞上地图里没有但实际有的东西。解决办法有两条一是建图时尽量清场建一张干净的静态地图二是引入地图更新机制比如用长期观测统计每个栅格被占据的概率动态物体的栅格概率会随时间衰减。Cartographer和某些激光SLAM方案支持这种概率更新。视觉方案里可以用语义分割把动态物体人、车剔除后再做SLAM。6.4 算力分配和实时性的平衡SLAM系统里前端、后端、回环检测都在抢CPU和GPU。前端要实时后端可以慢一点回环检测可以更慢。合理的做法是把它们放到不同线程用队列解耦。ROS里可以用nodelet或component把多个节点塞进同一个进程减少通信开销也可以用多机分布式部署把重计算放到带GPU的机器上。我见过新手把所有东西塞进一个节点里顺序执行结果前端被后端阻塞帧率掉到个位数跟踪直接丢失。记住一个原则前端必须保证实时宁可丢帧也不能阻塞后端和回环可以异步、可以降频。6.5 评估别只看看起来对不对SLAM系统好不好不能只靠肉眼看地图。有标准数据集和评估指标绝对轨迹误差ATE、相对位姿误差RPE。常用数据集有KITTI自动驾驶、TUM RGB-D室内视觉、EuRoC无人机视觉惯性。把你的算法在这些数据集上跑一遍和真值对比才知道到底差多少。自己采数据评估的话可以用运动捕捉系统或全站仪提供真值成本高但最准。退而求其次可以让机器人走一个已知的闭合路径看起点和终点的估计位姿偏差这个叫闭环误差能粗略反映累积误差水平。7. 给不同阶段学习者的路线建议如果你是完全的新手我建议的顺序是先用ROS跑通Gmapping建一张2D地图理解TF、话题、坐标系这些基础概念然后读《视觉SLAM十四讲》并跑通代码理解特征、位姿、优化再挑一个开源方案ORB-SLAM3或LIO-SAM精读代码搞清楚数据怎么流、优化怎么建最后找一个自己的场景从采数据到建图到导航完整走一遍。如果你已经有基础想深入某个方向我的建议是做激光的往多传感器紧耦合和长期地图维护走做视觉的往语义SLAM和3DGS结合走做工程的往嵌入式部署和实时性优化走。SLAM这个领域理论深、工程重光看论文不动手是学不会的一定要有真机、有数据、有反复调试的过程。我个人最大的体会是SLAM的难点往往不在算法本身而在工程细节——时间同步、标定、TF、参数、算力分配这些脏活决定了系统能不能真正跑起来。算法决定上限工程决定下限。把下限做扎实了再去追上限路会顺很多。
返回列表