ARTICLE DETAIL

资讯详情

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

RTAB-Map与RGB-D相机:机器人自主建图实战经验与避坑指南

RTAB-Map与RGB-D相机:机器人自主建图实战经验与避坑指南 去年年底我在一台差速轮机器人上折腾自主建图最初用的是GMapping结果在一条20米长的走廊里连续翻车三次——地图要么首尾对不上要么转角处糊成一团。后来换到RTAB-Map用RealSense D435做RGB-D输入才真正把整个建图链路跑通。这篇文章就把这段时间反复试出来的经验整理出来从选型理由到五步实操再到各种奇葩坑的排查过程一次性说清楚。先说几个关键词RTAB-Map、RGB-D相机、机器人自主建图。RTAB-Map是一个基于图优化的RGB-D SLAM方案它把每一帧图像变成带位姿的节点再用视觉特征做回环检测最终通过全局优化把累积漂移“拉”回来。RGB-D相机则解决了单目没有尺度、双目对弱纹理敏感的问题直接把深度信息喂给SLAM后端。这套组合非常适合室内机器人的建图需求尤其是有明显回环场景的办公室、仓库、居家环境。读这篇文章的人我默认你已经跑通过ROS的基本流程知道roslaunch是什么但对RTAB-Map只停留在听说过或者刚安装完还没跑通的阶段。下面所有内容都基于ROS Noetic环境其他版本差异不大命令基本通用。1. 建图方案选型为什么是RTAB-Map而不是GMapping或Cartographer选SLAM方案这事很多人第一反应是用GMapping因为教程最多、资料最全。但GMapping本质是为2D激光雷达设计的它压根没有“视觉”这个概念。虽然有一些做法是把RGB-D相机的深度图投影成2D激光数据再喂给GMapping但这条路有几个先天缺陷第一深度图投影成激光会在边缘产生大量假点滤波器怎么调都别扭第二GMapping对里程计噪声极其敏感差速轮打滑一次地图就歪一截第三它没有真正意义上的回环检测地图错了就是错了没有修正机会。Cartographer是另一个常被拿来对比的方案它的回环检测和子图机制确实很强尤其是激光版本在2D建图这块几乎是天花板。但如果你手上的传感器就是一台RGB-D相机Cartographer的视觉方案就要走纯定位模式或者做好几个传感器的融合配置入门门槛比RTAB-Map高不少。RTAB-Map的优势在于它天生就是给RGB-D设计的你给它一个深度图加一个彩色图它直接输出6自由度的相机位姿和增量式地图不需要激光雷达不需要额外标定板也不用理解太多后端原理就能在半小时内把第一张地图建出来。我对比过的实际表现三套方案在同一个室内场景的差异是这样的方案传感器要求回环修正能力调参门槛出图速度GMapping2D激光或深度图转激光无低快但容易歪Cartographer激光/多传感器强高慢但精细RTAB-MapRGB-D相机强词袋回环中快且准如果你手头已经有激光雷达那Cartographer值得投入但如果你的传感器预算和安装空间只够放一个RGB-D相机RTAB-Map是性价比最高的选择。另一个被低估的原因是RTAB-Map自带数据库机制建图过程中的所有关键帧、位姿、地图都记录在一个.db文件里建完之后可以离线打开数据库重新优化地图、调整参数而不需要重新跑一遍机器人。这个特性在实际项目中太重要了后面我会单独讲。2. 动手前必须想清楚的坐标系与TF链路问题很多人建图翻车不是SLAM参数的问题而是TF树压根就没配对。RTAB-Map对TF的要求是map - odom - base_link - camera_link这条链路必须完整而且base_link - camera_link的变换必须和相机在机器人上的实际安装位置完全一致。先说一下为什么RTAB-Map要依赖TF。它的后端会实时发布map - odom的变换这个变换的本质就是“修正量”——当回环检测成功时后端发现自己之前估计的位姿有漂移于是通过调整map - odom把漂移修正掉。odom - base_link通常由轮式里程计发布它代表机器人认为自己在odom坐标系里移动了多少。base_link - camera_link则由URDF模型描述把相机观测到的视觉位姿换算回机器人底盘位姿。任何一环缺失或错误RTAB-Map都会直接拒绝工作或者在RVIZ里看到地图疯狂抖动。我见过一个非常典型的错误有人把相机安装位置写成了0 0 0安装在base_link原点实际相机装在底盘前方15厘米、高度50厘米的位置。结果就是RTAB-Map计算出的机器人轨迹和真实轨迹整体偏差了一个固定值建出来的地图在回环时对不上因为“相机看到A点”和“机器人实际在A点”永远差了一截。排查这类问题最好的方法是在RVIZ里显示TF树用tf_echo命令检查每一级变换的平移和旋转量是否和实际情况一致。rosrun tf tf_echo map odom rosrun tf tf_echo odom base_link rosrun tf tf_echo base_link camera_link如果你的机器人没有现成的里程计比如你只是想拿手持相机或者把相机固定在遥控小车上做纯视觉建图RTAB-Map也可以用RGB-D视觉里程计来替代轮式里程计。这种情况下不需要odom - base_link由外部发布RTAB-Map自己会用一个内部频率的视觉里程计来提供。但要注意一个问题如果没有外部里程计整条链路就完全依赖视觉特征的稳定性在纹理稀疏的环境里会非常吃力白色走廊走一半就可能跟丢。我的建议是在正式建图前先用RVIZ看一下TF树是否完整用一张棋盘格验证一下深度图和彩色图的对齐质量确认没有问题了再启动RTAB-Map。这十分钟的准备工作能省掉后面几个小时排错的时间。3. 五步建图实操记录从驱动到出图下面这段是核心流程。我按“准备相机数据—配置运行参数—启动SLAM—规划路线—保存地图”的顺序完整走一遍每一步都标注了关键参数和容易出错的地方。3.1 第一步验证相机数据与深度质量相机驱动通常没什么悬念RealSense、Orbbec、Azure Kinect都有现成的ROS驱动包。启动后先看话题列表确认彩色图和深度图的话题名然后打开RVIZ或者rqt_image_view直接看深度图。roslaunch realsense2_camera rs_camera.launch roslaunch rtabmap_ros rtabmapviz.launch我主要用的是RealSense D435启动后默认话题是/camera/color/image_raw和/camera/depth/image_rect_raw颜色图和深度图已经硬件对齐不需要额外做配准。如果你是其他型号的RGB-D相机一定要先确认深度图和彩色图是同一个视角的未经对齐的深度图和彩色图会让视觉特征匹配变得非常不稳定。深度质量检查的重点是看深度图上有没有大面积黑色空洞。RGB-D相机的深度测量依赖红外结构光或ToF技术碰到强反光表面、黑色吸光物体、透明玻璃、以及距离超过量程范围的物体时都会产生深度缺失。一个简单的测试方法把相机对着房间的不同方向转一圈如果深度图上超过30%的区域是黑色的说明这个环境对RGB-D不友好需要调整光线、距离或者换一个相机型号。3.2 第二步配置TF和相机内参RGB-D相机一般自带IMU或出厂标定数据RealSense的自标定模块已经比较成熟直接用就可以。如果你用的是开源深度相机或者自己拼的传感器组合相机内参标定这一步省不了。用camera_calibration功能包对彩色相机做一次棋盘格标定得到fx, fy, cx, cy和畸变系数。RTAB-Map对畸变的敏感度高于你对视觉里程计的要求因为它的视觉特征匹配、三角化、回环检测全部建立在正确的内参之上。内参不对后面全盘皆输这个问题怼到谁身上都一样。TF配置刚才已经讲过了这里再强调一次确认URDF模型里相机的位置姿态和实际安装一致包括俯仰角。我曾经遇到过把相机俯仰角写反的情况建图时地图整体向后倾斜看起来像是机器人一直在爬坡。3.3 第三步启动RTAB-Map并调整运行参数这是我平时最常用的启动命令roslaunch rtabmap_ros rtabmap.launch \ rtabmap_args:--delete_db_on_start \ depth_topic:/camera/depth/image_rect_raw \ rgb_topic:/camera/color/image_raw \ camera_info_topic:/camera/color/camera_info \ approx_sync:true \ wait_imu_to_init:false几个参数逐个解释--delete_db_on_start每次启动时删除上一次的数据库防止把上次建的图混进来。approx_sync设为true表示允许彩色图和深度图时间戳不必完全同步近似同步即可。如果时间戳精确同步建议设为false结果更稳。wait_imu_to_init如果你没有给RTAB-Map接IMU保持false否则它会一直等IMU初始化。启动后在RVIZ里添加Map显示话题选择/rtabmap/map2D占据栅格或/rtabmap/cloud_map3D点云。也可以用rtabmapviz直接观察节点的生成、回环链接、局部地图它比RVIZ更直观能看到RTAB-Map内部视图。几个影响建图质量的关键参数我在调参时总结了一套经验值参数名默认值推荐值作用RGBD/LinearUpdate0.10.15机器人移动多少米生成一个新节点RGBD/AngularUpdate0.050.1机器人旋转多少弧度生成一个新节点Vis/MinInliers2015~20视觉特征匹配的最少内点数低于这个值视为匹配失败GridMap/Resolution0.050.052D栅格地图的分辨率单位米/像素Mem/STMSize100短期记忆节点数0表示无限最后一个参数值得多说两句。Mem/STMSize是短期记忆窗口大小默认只有10个节点这意味着超过10个节点之后之前的节点会被移到长期记忆里回环检测时从长期记忆里检索效率会下降。在建大面积场景时建议直接设成0表示不限制短期记忆大小让所有节点都在活跃窗口中参与回环检测。代价是内存占用上升但一般室内场景几百个节点内存完全不是问题。如果节点数量上千这个参数就要谨慎开了。3.4 第四步覆盖式建图路径规划技巧这一步是整个建图流程中最容易被低估的。很多新手一键启动RTAB-Map之后拿着遥控器随便溜一圈就喊建图完成结果打开地图一看竖向线条错位、拐角撕裂、两个房间的边界重叠。路径不对参数再漂亮都白搭。RGB-D视觉SLAM的核心约束是相机必须在移动过程中持续看到足够多的特征点而且最好能看到刚才经过的场景。所以我建图时总结了一套路径规则叫做“巡边优先、回头补漏、起点闭环”巡边优先沿着房间或走廊的墙壁走一圈保持相机距离墙壁0.5到1.5米之间这样深度图的质量最高特征也最丰富。太近会导致深度超出相机量程太远则特征点密度不足。回头补漏走完一圈后从中间穿插着再走一遍。关键是制造“回头”动作让相机重新看到之前去过的区域这是回环检测的主要触发来源。起点闭环建图结束时尽量让机器人回到起点附近。RTAB-Map的回环检测最喜欢“回到原点”一旦在起点附近找到历史节点整个地图的累积漂移会被一次性修正效果立竿见影。还有一个细节转弯速度一定要慢。RGB-D相机的全局快门和卷帘快门问题在老型号上比较明显快速转动会让图像产生运动模糊特征提取匹配失败前端里程计就开始飘。我用D435的时候把底盘最大线速度限制在0.5m/s以下角速度限制在0.5rad/s以下测试下来特征跟踪的稳定性提升了很多。3.5 第五步保存地图与离线优化建图完成后保存地图有两个层次一是保存2D栅格地图供move_base等导航模块使用二是保存RTAB-Map数据库留着以后离线调整参数重新优化。2D栅格地图的保存最简单rosrun map_server map_saver map:/rtabmap/grid_map执行完会生成map.pgm和map.yaml两个文件。map.pgm是灰度图map.yaml里记录了分辨率、原点坐标、占据阈值等导航必要的信息。保存数据库则要用RTAB-Map自带的方式rosrun rtabmap_ros rtabmap_save --database_path ~/maps/room.db数据库文件一定要留着它的价值在于你不需要重新跑一遍机器人就能反复调整建图参数。你在rtabmap-databaseViewer room.db里打开数据库可以手动删掉错误的节点、修改回环链接甚至重新跑一次全局优化。rtabmap-databaseViewer ~/maps/room.db在数据库编辑器里左侧是节点列表中间是当前节点对应的图像右侧是地图预览。我一般用它来做几件事删除建图过程中误插入的噪声节点比如有人从相机前走过产生的一堆孤儿节点、调整地图裁剪范围、把2D栅格地图重新导出成不同分辨率。这个工具的存在让RTAB-Map在实际应用中比大多数SLAM方案更“可救”。4. 避坑指南我实测中最容易翻车的六个场景这部分内容是我反复踩坑踩出来的基本上覆盖了RGB-D SLAM在真实环境中的高发问题。每条都按照“现象—原因—解决方案”的思路写。4.1 黑色物体和玻璃深度图的“黑洞”现象机器人经过黑色柜子或玻璃幕墙附近时地图突然缺了一块或者墙体位置出现奇怪的锯齿。原因黑色表面会吸收红外光玻璃则直接让红外光穿透或反射掉这两种材质的深度值都测不准深度图对应区域就是黑洞。解决方案建图时尽量避开这些区域让相机侧面而不是正对着玻璃。如果你必须建包含玻璃门的房间只能在后期手动修正栅格地图或者在RTAB-Map数据库编辑器里把这些节点的深度信息移除重新生成地图。想靠改参数彻底解决是不可能的这是物理层面的限制。4.2 回环检测一直不触发现象地图越来越歪漂移明显但RVIZ里就是看不到回环链接的产生。原因回环检测依赖视觉特征的相似度。如果机器人返回同一区域时视角、光照、拍摄角度和原来差距过大词袋模型匹配不到足够多的相同特征回环就建立不起来。解决方案先检查Vis/MinInliers阈值是否设得太高默认20对新手有点苛刻可以试着降到10~15让回环更容易被触发。其次看Mem/STMSize是否太小导致旧节点被过早清出短期记忆。另一个经常被忽略的原因是光照变化同一个走廊早上去建图时阳光角度和下午完全不同特征变化大导致回环失败。解决方法是尽量在固定光照条件下一次性完成建图不要在一天中光照变化明显的时段跨时段多次建图。如果上述都试过了还是不触发我还有一个压箱底的技巧手动移动机器人到之前访问过的位置附近然后原地缓慢旋转90度再转回来给相机一个重新观察同一场景的机会通常能逼出一个回环。这个操作听起来原始但比改半天参数有效得多。4.3 地图突然跳变位移不连续现象建图过程中RVIZ里的地图突然整体平移或旋转了一个角度。原因这是回环检测成功后的正常现象——后端发现位姿漂移后通过全局图优化把所有节点的位姿重新调整了一遍相当于把歪掉的地图“掰回”正确位置。但如果跳变幅度过大超过一米或者30度说明前期漂移已经积累得相当严重。解决方案跳变本身不用慌关键是观察跳变之后地图是否变得更平直。如果跳变之后反而更乱了那可能是回环建立了错误匹配假阳性回环。可以在rtabmapviz里查看回环链接对应的两帧图像确认它们确实是在描述同一个地方。如果匹配错了删除那条回环链接重新优化。4.4 白色走廊和空旷房间视觉SLAM的噩梦现象机器人进入一条纯白色、无装饰的走廊RTAB-Map前端里程计开始发生漂移地图在走廊尽头严重折弯。原因RTAB-Map的视觉里程计依赖ORB特征点而纯白墙壁几乎提取不到足够的角点、边缘特征前端定位就变成了“睁眼瞎”。解决方案这事的本质是视觉SLAM的纹理依赖问题没有彻底根治的办法但有几个缓解手段。第一挂一块有明显图案的板子在机器人前面给它制造特征第二降低移动速度减小帧间运动量降低特征匹配的难度第三接入轮式里程计信息让它在视觉失效时靠轮子短时间撑住。这也是为什么我在前面强调要保留外部里程计输入的原因——视觉和轮式里程计互相补充才是最稳的组合。4.5 地图边界出现大量噪点现象地图边缘有一圈零散的、没有规律的“毛刺”点。原因RGB-D相机的深度误差随距离增大而增大超过有效量程D435大概5米左右的深度值基本是噪声。这些噪声点投影到栅格地图里就成了边界毛刺。解决方案在启动参数里设置深度裁剪范围把超过4米的深度直接过滤掉。RTAB-Map支持depth_scale和深度限制设置你可以在launch文件里给depth_topic加一个中值滤波或者直接修改相机驱动里的深度范围参数。还有一个技巧开启GridMap/FilterRadius和GridMap/FilterAngle让栅格地图生成时忽略掉那些相邻点太少、方向不一致的孤点。这两个参数默认就是开的如果你关过记得重新开启。param nameGridMap/FilterRadius value0.05/ param nameGridMap/FilterAngle value0.05/4.6 长走廊首尾漂移几乎没有回环的过道场景现象一条30米长、两侧都是白墙和统一房门的走廊走到尽头再走回来地图上的走廊尽头偏移了将近2米。原因走廊场景特征单一回环检测很难找到足够的匹配特征同时里程计误差在长直线上会匀速累积没有回环来修正漂移就会越来越大。解决方案这类场景得换思路。一个办法是让机器人在走廊里走“S”形路线而不是贴着一边墙走直线。S形路线会让相机以不同角度看到走廊两侧的房门和墙角增加特征的多样性同时制造更多潜在的共视区域。另一个办法是中途停下来原地旋转360度把走廊两侧的完整信息都采集一遍这个动作等于强制插入一个“高信息量节点”后续经过这里时更容易形成回环。5. 地图质量评估什么时候算建好了跑完一遍流程地图到手了但怎么判断这张图能不能用我建图完成后会做一个三步检查。第一步是肉眼检查。打开map.pgm看轮廓是否清晰、线条是否平直、房间边界是否闭合。最重要的一点是看有没有重影。重影的意思是同一个墙体在地图上出现两条平行线距离几厘米到几十厘米不等。有重影说明这部分轨迹的位姿偏差没有被修正掉。第二步是看回环节点数。打开rtabmap-databaseViewer查看数据库里的“Loop closure”数量。一个100平米的办公室正常至少要有5到10个回环。如果全程一个回环都没有就算地图表面看着还行这个建图结果也高度可疑尽量重新走一遍路线把回环逼出来。第三步是实际测试。把生成的map.yaml喂给move_base的代价地图做一次导航测试让机器人从一个房间走到另一个房间。地图里如果隐藏着没有对齐的墙导航规划出来的路径会贴墙、卡死或者在原本开阔的地方突然来个急转弯。这个测试能暴露很多看地图看不出来的问题。我自己对“建图完成”的定义是机器人走完一遍全覆盖路径后回到起点时起点附近的地图能够和初始位置准确重合不再有可见的错位和重影。这就说明整个系统的传感器、里程计、回环检测、图优化链路都是健康的。6. 最后的实战心得这套流程还能怎么扩展跑通基本流程之后你可以往两个方向扩展。第一个方向是接入激光雷达把2D激光数据和RGB-D数据放在同一个RTAB-Map实例里。做法是让激光雷达发布2D laser scan话题RTAB-Map内部会把它作为额外的约束来源与视觉特征一起参与定位和图优化。这能显著提升白色走廊等弱纹理场景下的稳定性。第二个方向是加上自主探索模块。现在整个流程还是需要有人遥控机器人运动如果你想做成完全自主建图可以在顶层加一层探索规划器。RTAB-Map有一个配套的rtabmap_ros提供了基于信息增益的探索策略它会根据当前地图的未知区域自动决定机器人下一步往哪里走直到整片区域都被覆盖。不过这个功能需要机器人本身具备较好的避障能力和速度控制不要指望在比较脆弱的小车平台上一次跑通。最后分享一个我自己每次建图前都做的小动作在机器人上电之后先让相机对着一个纹理丰富的墙角停留3到5秒再做几个缓慢的平移和旋转让前端里程计“热身”完再出发。这样做的好处是SLAM系统在一开始就有足够的特征点和稳定的初始位姿比一上来就快速移动成功率高很多。这个细节没有任何文档会写但从实际效果来看对前端稳定性的帮助是实打实的。
返回列表