多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

D455深度相机实战:rtabmap、ORB-SLAM3与VINS-Fusion建图调优对比

D455深度相机实战:rtabmap、ORB-SLAM3与VINS-Fusion建图调优对比 这几年做移动机器人导航和室内建图我手上经手的深度相机从Kinect v1到Astra再到现在的Intel D455基本是踩着一路的坑走过来的。D455这款相机其实很有意思它和D435i最大的区别不只是把测距范围拉到了6米、深度精度提到2%以内更关键的是把IMU从外挂变成了内置这意味着你拿它做视觉惯性SLAM的难度比上一代低了不少。不过硬件到位只是第一步真正让人头疼的是算法侧的选择和调参。这篇文章我就用自己的实际经历把Intel D455从rtabmap、ORB-SLAM3到VINS-Fusion这三套方案的建图对比、数据采集细节、参数调优经验和踩坑记录完整写出来给正在做机器人建图、视觉导航或者状态估计的朋友一个可以直接参考的路线。如果你想上手D455跑SLAM但不知道该选哪套算法或者已经装上驱动但录出来的数据总是跑不出稳定效果这篇文章应该能帮你省下几个星期的试错时间。我做这套测试的硬件平台是Intel NUC系统是Ubuntu 20.04 ROS Noetic中间的坑基本都记下来了。1. 项目概述与方案选型思路1.1 为什么最终选择了Intel D455先说相机本身。D455是目前Intel RealSense系列里深度精度最高的一款基础深度误差在0.2米到6米范围内能做到小于2%RGB和深度分辨率都支持到1280x72030fps。相比D435iD455最明显的变化是IMU型号改成了BMI055而且安置方式经过重新设计加速度计和陀螺仪的轴间对齐关系在出厂前就做了标定这对后续跑VINS-Fusion这类对IMU敏感的系统非常友好。但真正让我下决心换成D455的原因主要有三个。第一它的深度模块和RGB模块之间基线从之前的固定结构变成了双目立体视觉结构深度图边缘的毛刺少了在近距离建图时不会出现明显“拉丝”第二它内置的IMU可以和深度数据流通过realsense-ros自动对齐省去了自己手动做时间同步的麻烦第三USB-C 3.0单线供电和传输接线比上一代简单太多装在移动平台上不会多出一堆转接板。当然D455也不是没有缺点它在完全黑暗的环境下还是依赖结构光补光户外阳光下深度数据基本废掉这是所有主动式深度相机都绕不过去的限制。1.2 三套SLAM方案的定位差异这三套方案虽然都能用D455喂数据但设计目标和输出结果差别非常大。rtabmap严格来说不是一个纯粹的SLAM算法而是一个完整的SLAM框架它把视觉里程计、回环检测、图优化和建图整合在一起可以直接输出稠密的3D点云地图和可用于导航的OctoMap。ORB-SLAM3则是基于特征点的视觉SLAM教科书级实现它能利用单目、双目、RGB-D以及这些传感器与IMU的组合输出高精度的相机位姿轨迹和稀疏地图。ORB-SLAM3的定位精度在结构化的环境里确实能打但稀疏地图点做不了导航和避障。VINS-Fusion走的是优化型视觉惯性融合路线核心价值在于姿态估计和定位建图能力比ORB-SLAM3还弱一些基本只有稀疏特征点。我在项目里的实际分工是rtabmap负责最终的建图输出ORB-SLAM3用来做长时间运行时的精确重定位VINS-Fusion用来做IMU退化或者快速运动场景下的姿态补偿。三套方案在同一台D455上跑正好把不同层面的需求都覆盖到。2. 环境搭建与数据采集细节2.1 ROS环境与realsense驱动配置无论用哪套算法第一步都是让D455在ROS下稳定出图和出IMU数据。我用的是ROS Noetic驱动用的是realsense-ros官方源编译安装。安装过程不复杂但有个关键点必须提前确认D455的固件版本和librealsense版本要匹配否则会出现深度流不稳定或者IMU数据卡死的情况。我的建议是直接把librealsense升级到最新稳定版然后重新编译realsense-ros。驱动装好后用官方launch文件启动时不要直接默认启动而是加上几个关键参数roslaunch realsense2_camera rs_camera.launch \ unite_imu_method:linear_interpolation \ enable_imu:true \ enable_sync:true \ align_depth:true \ depth_width:640 \ depth_height:480 \ color_width:640 \ color_height:480 \ depth_fps:30 \ color_fps:30 \ imu_fps:200这两行参数值得多说几句。enable_sync是开启硬件同步信号让彩色图、深度图和IMU数据的时间戳尽量对齐这一步不做的话后面视觉惯性算法会频繁因为时间戳跳变而崩溃。unite_imu_method是让加速度计和陀螺仪数据通过线性插值合成一个统一的高频IMU话题默认值是disabled如果不改很多算法只会收到其中一轴的imu数据跑起来会有明显的漂移。align_depth会把深度图对齐到彩色相机坐标系也就是输出/camera/aligned_depth_to_color/image_raw这个话题是rtabmap处理RGB-D数据时最需要的话题。启动之后用rostopic list查看话题重点确认三个话题是否都存在/camera/color/image_raw、/camera/aligned_depth_to_color/image_raw、/camera/imu。如果这三个话题都有数据D455这一环就算通了。2.2 相机标定与IMU参数提取很多朋友拿到D455就想直接开跑ORB-SLAM3或者VINS-Fusion结果发现轨迹发散得一塌糊涂原因绝大多数时候不是算法不行而是参数没喂对。D455虽然出厂自带内参但那个内参是相机出厂时的标定结果实际安装到你的机器人上之后镜头松动、温度变化都会让内参产生细微漂移。对于要求不太高的定性测试直接用出厂内参也行但要是想做定量对比还是得自己重新标定。我用的是Kalibr标定包分别做相机内参标定和相机-IMU外参标定。相机标定需要打印一张棋盘格然后拿着D455在格板前变换姿态同时采集彩色图和IMU数据。Kalibr对数据质量要求比较高太慢的移动会退化太快又会产生运动模糊实际操作中我一般是让摄像头以椭圆轨迹缓慢晃动确保6个自由度都有运动。标定最后会生成一个yaml文件里面包含相机内参矩阵、畸变系数和IMU的噪声密度与随机游走参数。这三个数据后面配置ORB-SLAM3和VINS-Fusion时几乎都要用所以标定文件的保存路径一定要规划好我习惯统一放到工作空间下的calib/d455/目录避免到时候到处翻。如果你嫌Kalibr麻烦也可以先用imu_utils和camera_calibration这套组合。但我的体验是imu_utils对D455内置IMU的加速度计噪声估计有时候偏大因为它只是统计静态数据没有激励充分最终还是Kalibr的结果更可信一些。2.3 rosbag录制的几个关键选择录好rosbag是做离线调优的基础也是最容易被忽略的一步。我录bag之前的固定流程是先启动realsense驱动然后用小幅度、中速的手持运动预热3到5分钟让IMU的零偏先稳定下来然后再开始录制。这样做的原因是D455刚通电时IMU的零偏会有一段明显的漂移如果直接录制后期算法里IMU噪声参数可能完全匹配不上。录制时用rosbag record但不要一股脑把所有话题都录进去那样bag文件体积会大得离谱。我只录三个话题rosbag record -O d455_test.bag \ /camera/color/image_raw \ /camera/aligned_depth_to_color/image_raw \ /camera/imu这里要提醒的是/camera/color/image_raw和/camera/aligned_depth_to_color/image_raw是两条独立的话题前者的尺寸和后者一样但颜色图没有对齐到深度坐标系。如果你只想跑RGB-D模式那么aligned_depth_to_color就够了但如果后面准备用ORB-SLAM3的双目模式还得另外录/camera/infra1/image_rect_gray和/camera/infra2/image_rect_gray这两个红外图话题。D455的红外摄像头不采集RGB信息但作为双目灰度图来跑特征点SLAM效果其实很稳定因为避开了自动白平衡干扰。录制的时候还要关注CPU负载。D455在720p、30fps下同时输出三路话题而且开了alignCPU占用不低如果电脑性能紧张建议用640x480而不是720p否则录制过程中掉帧会让后续算法时间戳完全乱掉。3. rtabmap建图实战与参数调优3.1 rtabmap的RGB-D建图流程rtabmap跑D455的RGB-D建图是这三套方案里最省事的一条路因为rtabmap_ros包提供了现成的launch文件只要话题对接正确几乎开箱就能跑出点云。我的启动命令是这样roslaunch rtabmap_ros rtabmap.launch \ rtabmap_args:--delete_db_on_start \ rgb_topic:/camera/color/image_raw \ depth_topic:/camera/aligned_depth_to_color/image_raw \ camera_info_topic:/camera/color/camera_info \ approx_sync:false第一次跑的时候看到3D视图里快速生成点云地图很多人会觉得很惊艳但后续的烦恼也随之而来地图会越来越糊甚至出现明显的错位。这就需要调参数了。rtabmap的核心优势是它的回环检测和图优化能力如果你的运动路径一直在转圈它能靠视觉特征把同一地点识别出来并修正漂移最终地图会非常干净。但如果路径是单纯的来回直线回环机会很少地图就会越走越飘这个不是调参能完全解决的需要在采集路径上设计闭环。3.2 参数调节的核心思路rtabmap参数非常多但不是所有都需要动。我实际调节过程中效果最明显的有这么几个第一个是特征点最小内点数Vis/MinInliers默认值大约在20左右。对于D455采集的室内场景我一般调到30。这个参数代表着回环检测时至少要有多少个特征点匹配才算有效。太低了容易产生误回环地图会出现多重影太高了又容易漏检回环闭合不够及时。第二个是地图点可见阈值RGBD/ProximityBySpace。这个参数会判断当前帧附近是否已经存在足够近的地图点如果存在就认为不需要重复添加关键帧这样做能显著减少地图冗余但也可能导致地图细节丢失。我通常把这个参数和RGBD/ProximityBySpaceMaxPaths配合起来用后者控制搜索半径在走廊和狭窄空间里要调小。第三个是Rtabmap/DetectionRate。这个值代表SLAM的检测频率如果你的计算性能足够保持10Hz问题不大如果录bag时发现处理速度跟不上可以降到5代价是地图更新的延时会变高。还有一个不得不提的是RGBD/CreateOccupancyGrid。如果你最终目标是要给机器人导航用这个参数要设为truertabmap会自动生成一个基于激光假数据的2D栅格地图可以直接被move_base使用。我实际测试中D455在3米以内的深度数据生成栅格地图的效果很好但超过4米后深度点变稀疏栅格地图边缘会缺一块。3.3 实际建图效果与限制我用D455在办公室走廊里跑了一圈rtabmap最终生成的3D点云地图整体轮廓很完整墙面、门框、桌椅这些特征在视觉上都能分辨点云颜色来自彩色图看起来立体的真实感很强。回环闭合之后地图累计漂移大概在1%以内对导航来说是够用的。但rtabmap的缺点也很明显。第一它对CPU和内存的消耗非常大长时间运行时维护的图节点数量会迅速膨胀内存占用经常跑到几个GB在处理10分钟以上的bag时尤其明显。第二它对纹理缺失环境非常敏感纯白墙面、无纹路地板会直接导致跟踪丢失。第三在室外光照下D455的深度数据本身就不可用更谈不上地图质量了。所以rtabmap在我这个项目里被定位成“建图利器”但只适合在室内、纹理适中、光线稳定的环境里发挥它最大的价值。4. ORB-SLAM3实战与参数调优4.1 ORB-SLAM3的三种输入模式ORB-SLAM3是我在这套系统里用来做重定位和轨迹精度验证的“度量衡”。它支持三种输入模式单目、双目、RGB-D并且每种都可以和IMU组合。用D455可以跑RGB-D模式也可以跑双目IMU模式我重点测试的是双目IMU和RGB-DIMU。ORB-SLAM3从接口上设计得比较直接提供的是命令行程序不是ROS节点需要自己写一个简单的ROS wrapper来订阅D455的话题然后把图像和IMU数据转成ORB-SLAM3的输入格式。官方的Examples_old/ROS目录下面提供了模板但那个模板主要是针对TUM数据集写的需要改动的地方不少。我自己写的wrapper逻辑是订阅/camera/color/image_raw和/camera/infra1/image_rect_gray、/camera/infra2/image_rect_gray然后分别压入左右目队列同时订阅/camera/imu把加速度和角速度按时间顺序存入IMU队列。当拿到一帧左目图像时就把所有时间戳早于该帧的IMU数据一次性塞给ORB-SLAM3再执行跟踪。这种做法的关键是IMU数据不能滞后太多否则视觉惯性初始化会失败。我的经验是D455的IMU话题频率设为200Hz连续缓冲区保留最近0.5秒的数据基本能保证消息顺序是够用的。4.2 yaml参数配置细节ORB-SLAM3要能把D455跑起来最核心的是写好相机参数yaml文件。文件里的相机内参必须和你标定出来的结果一致分辨率要和D455实际输出分辨率对应。我用的分辨率是640x480对应的内参矩阵和畸变系数是Camera.fx: 386.5 Camera.fy: 386.5 Camera.cx: 319.5 Camera.cy: 239.5 Camera.k1: -0.003 Camera.k2: 0.0002 Camera.p1: 0.0001 Camera.p2: 0.0001 Camera.k3: 0.0 Camera.width: 640 Camera.height: 480 Camera.fps: 30.0这里的Camera.fx/fy是根据我手上这台D455的实际标定结果填的每台相机会有细微差异不能直接抄。如果你的相机输出720p记得对应地把fx、fy、cx、cy放大两倍或者直接把图像resize到640再跑这样可以显著降低特征提取的耗时。IMU参数部分是和ORB-SLAM3的IMU初始化直接相关的IMU.NoiseGyro: 0.0005 IMU.NoiseAcc: 0.006 IMU.GyroWalk: 0.00002 IMU.AccWalk: 0.0003 IMU.frequency: 200.0这些参数对应D455内置BMI055的噪声密度和随机游走估计。如果你用Kalibr重新标定过就用标定结果代替没有的话就用官方手册上的近似值。反正IMU参数比相机内参的容错性稍好一点差个两三倍影响不大但数量级不能错。4.3 实跑效果与问题我用D455的640x480图像在走廊环境里跑ORB-SLAM3的双目IMU模式定位轨迹非常平稳运行5分钟后没有出现明显的漂移回环也能正常检测。但有一个问题让我一开始很头疼程序在启动初期会出现频繁的初始化失败提示“Vision inertial initialization failure”。排查下来原因是我录制bag时手持运动太慢IMU激励不足。ORB-SLAM3的视觉惯性初始化需要同时估计重力方向和尺度如果机器人一直静止或者缓慢平移IMU积分的变化量太小初始化就无法收敛。解决办法是启动后先做几个明显的倾斜和旋转动作让IMU感受到充分的角速度变化大约2到3秒后再进入正常运动这样初始化基本100%成功。还有一个缺点是ORB-SLAM3没有提供稠密建图接口。它输出的地图在可视化工具里是一堆稀疏的特征点作为定位而言已经够用但要直接用于避障和路径规划则完全没有可能。所以我的项目里ORB-SLAM3只做定位和轨迹比对建图还是交给rtabmap。5. VINS-Fusion实战与参数调优5.1 VINS-Fusion的输入匹配VINS-Fusion是港科大开源的视觉惯性定位系统主要解决“没有先验地图时机器人怎么准确估计自身姿态”的问题。它的核心是滑动窗口优化通过融合双目图像特征点重投影误差和IMU预积分误差来估计位姿。用D455和VINS-Fusion组合最大的挑战不是算法本身而是数据接口VINS-Fusion的ROS节点订阅的是单目或双目的特征点图像和IMU话题对图像的话题名和消息类型有固定预期需要做话题重映射。我使用双目的方式订阅左右目灰度图话题分别是/camera/infra1/image_rect_gray和/camera/infra2/image_rect_grayIMU话题为/camera/imu然后用VINS-Fusion自带的launch文件跑。需要说明的是D455的红外图是单通道灰度图分辨率640x480很适合VINS-Fusion因为它不需要彩色信息而且灰度图可以避免自动白平衡的干扰。VINS-Fusion对图像帧率比较敏感我测试下来30fps是最合适的太高会增加CPU负担但精度提升不明显太低则位姿输出太稀疏控制回路会不稳定。5.2 参数配置和外参标定VINS-Fusion的配置文件相比ORB-SLAM3更正式也更复杂主要有三个部分相机参数、IMU参数、相机到IMU的外参变换矩阵。相机参数部分要写清楚模型类型。D455的针孔模型是PINHOLE畸变模型是radtan对应配置文件里的写法是model_type: PINHOLE camera_name: d455_rgb image_width: 640 image_height: 480 distortion_parameters: k1: -0.003 k2: 0.0002 p1: 0.0001 p2: 0.0001 projection_parameters: fx: 386.5 fy: 386.5 cx: 319.5 cy: 239.5IMU参数部分要填写噪声密度和随机游走以及IMU输出频率acc_n: 0.012 gyr_n: 0.0005 acc_w: 0.0004 gyr_w: 0.00002 imu_rate: 200.0外参部分body_T_cam0和body_T_cam1是相机在IMU坐标系下的位姿这个外参可以用Kalibr标定出来也可以先填一个粗略的估计值再用VINS-Fusion校准。实测中如果外参误差小初始化阶段VINS会自动修正一些但误差超过5度就很容易发散所以外参标定不能省。5.3 实跑效果与应用定位VINS-Fusion的效果在我测试的三套方案里位姿轨迹最平滑短时间内没有明显漂移而且在快速转动手持相机时IMU的补偿作用让轨迹不至于像纯视觉那样瞬间丢失。但它的一个致命弱点是回环检测能力弱长时间大范围运行后累积漂移明显没有地图修正机制。在项目中我主要用它来给机器人底盘提供一个“无地图状态下也能稳定走直线”的位姿反馈。换句话说VINS负责短时高精度的惯性导航rtabmap负责长时地图一致性。两者配合使用之后机器人在遇到突然光照变化导致相机图像失效时VINS的IMU还能继续顶着几秒不会瞬间丢定位。6. 三套方案横向对比与选型建议6.1 建图效果与精度对比这应该是大家最关心的一节。我直接给出一张基于实测和多次复测的对比表供参考维度rtabmapORB-SLAM3VINS-Fusion地图类型稠密点云地图 栅格地图稀疏特征点地图稀疏特征点地图回环检测强图优化效果明显强回环修正有效中回环能力有限轨迹精度室内10min累计漂移约0.5%~1%双目IMU漂移约0.3%双目IMU无回环漂移约0.6%IMU融合可用但非必须强烈推荐核心依赖建图完整性高低低硬件负载高中中需要说明的是轨迹精度不是绝对值不同环境、不同路径下会有波动。但整体趋势很明确ORB-SLAM3在里程计短期精度上最强rtabmap在全局一致性和地图完整性上最强VINS-Fusion在鲁棒性和平滑性上有优势但不是顶级。6.2 资源占用与实时性对比资源占用方面rtabmap是绝对的“大户”。在我那台Intel NUC上跑720p的RGB-D输入rtabmap进程的CPU占用经常冲到60%以上内存也会随地图规模持续增长。如果把建图分辨率降到640x480CPU可以降到40%左右但点云细节明显变少。ORB-SLAM3在640x480下CPU占用大约30%到40%特征提取是主要瓶颈。如果换成720p几乎翻倍所以在嵌入式平台上我建议坚决用640x480。VINS-Fusion相对最轻量在640x480下CPU占用约25%左右因为它不需要做全局优化滑动窗口大小限制得很死。如果只做定位这是抢占实时性最好的方案。6.3 选型建议什么场景用哪个我个人的经验可以总结成三条简单的选择规则。第一如果你最终目标是要输出一张能直接拿来做导航的地图哪怕需要付出更高的硬件成本也别犹豫直接上rtabmap它把点云地图和栅格地图都给你生成好了省去自己写转换的步骤。第二如果你只关心机器人自身定位想要一个高精度的轨迹而且你已经有其他传感器比如激光雷达在负责建图那么ORB-SLAM3是最稳定的选择特征点定位在室内结构化环境里非常可靠。第三如果你的应用场景经常出现剧烈运动、光照突变或者你要做的是没有先验地图的探索任务VINS-Fusion的价值就凸显出来了它能在视觉退化时靠IMU稳住姿态给你宝贵的几秒补偿时间。7. 高频问题排查与调优经验7.1 D455的IMU问题D455内置BMI055虽然出厂前已经做了温漂校准但长时间使用或者环境温度变化大的情况下IMU零偏依然可能发生变化。表现就是VINS-Fusion初始化时重力估计在启动后前几秒一直在跳。解决办法是每次启动前让相机静置2到3秒做一次静态零偏校准。realsense-ros提供了imu_calibration相关的接口但我实际操作中发现简单的静态采集2秒之后取平均也能把零偏修正到可接受范围。如果你的应用要求很精确建议写一个小的校准节点在系统启动时自动完成这个过程。7.2 时间戳与话题对齐问题这是三套方案都会踩的坑。D455的彩色图、深度图和IMU数据虽然来自同一个硬件但如果在realsense-ros里没有开启enable_sync时间戳会有几十毫秒级别的误差。对视觉惯性算法来说几十毫秒的IMU延迟会造成明显的轨迹拖影。解决方法是开启硬件同步同时检查彩色图和IMU时间戳的延迟是否在100微秒级。用rostopic delay看一眼就能判断一般延迟在10毫秒以内问题不大超过50毫秒就需要重新配置同步参数。另外录制bag时建议把所有话题的frame_id统一到camera_odom_frame或者直接用realsense-ros默认的frame_id体系避免在不同算法之间切换时出现TF缺失。7.3 环境干扰反光、玻璃、弱纹理这一条可能是D455用户遇到最多的问题。深度的反面教材主要是光滑地面、白墙、玻璃窗。D455在反射面和非朗伯体上的深度测量会出现大量空洞和错误点直接导致rtabmap建图出现“空洞洞”的地图。我的处理方式比较简单粗暴建图时优先选择纹理丰富的路径比如走廊里贴着宣传栏、门牌、消防栓的一侧走如果必须经过玻璃或全白走廊就提前调高rtabmap的Vis/MinInliers和RGBD/ProximityBySpace减少这些低质量深度点对地图的污染。在ORB-SLAM3和VINS-Fusion上弱纹理和反光环境主要影响的是特征点数量。VINS-Fusion对特征点数量很敏感低于20个特征点时容易退化ORB-SLAM3稍微好一些因为它的特征提取有金字塔多尺度加成但极端环境下同样会跟踪失败。这种情况我一般会降低图像分辨率并提升帧率到60fps通过更大的运动视差来弥补特征不足的缺陷。7.4 从rosbag离线调优时的小技巧最后分享一个我养成的习惯测试任何算法前先录一份包含“初始化剧烈运动 正常巡航 回环”三种工况的bag然后把这份bag作为基准数据集。之后所有参数调整都在同一份bag上离线运行这样对比结果才有意义。离线跑bag时可以加--pause参数逐步观察每一步的状态也可以把中间状态打印出来和线上运行时的表现对拍。很多难以复现的偶发问题都能在一份完整bag里快速定位到具体时间点。我用这套方法排查过一个非常诡异的VINS漂移问题每次跑到同一段走廊附近轨迹就突然跳一下。后来翻bag才发现那段走廊正好有一块金属反光板D455深度图在那一帧产生了大范围错误点VINS把错误特征当成了有效点。如果我每次都在线测试这种问题几乎不可能稳定复现。8. 最后的实操心得这套D455 三种算法跑下来我最深的一个体会是没有一款SLAM算法能通吃所有场景关键是搞清楚自己的核心需求。rtabmap适合做最终地图产品ORB-SLAM3适合做高精度定位基准VINS-Fusion适合做恶劣环境下的姿态兜底。它们在D455上是互补关系而不是替代关系。如果你刚入手D455我给的建议是先别急着上高级算法老老实实把驱动和标定做好录一份高质量bag再跑一遍简单的RGB-D rtabmap。哪怕只是几分钟的走廊往返这一步能帮你排除大多数硬件和数据链路问题。之后再逐步上手ORB-SLAM3和VINS-Fusion你会发现很多看起来玄学的漂移和初始化失败其实都是前期数据准备工作没做到位。无论你最终选哪套方案D455都是一台值得好好折腾的深度相机这套搭配组合目前已经跑进了我的多个实际项目里稳定性足够扩展空间也很大。
返回列表