ARTICLE DETAIL

资讯详情

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

FAST-LIO2建图飘?先查时间同步、外参标定与IMU噪声这三道关卡

FAST-LIO2建图飘?先查时间同步、外参标定与IMU噪声这三道关卡 拿到Mid-360之后我做的第一件事就是套上FAST-LIO2的默认配置直接跑自己的数据。结果很真实墙大体是墙但转完第二圈同一条走廊明显出现接缝错位天花板厚得能切出三层来。圈子里把这种情况统称为建图飘大多数回答都指向调参数可真把参数表打开能动的就那几项来回试了十几次地图该飘还是飘。后来我把传感器数据、标定、时间同步、配置项逐个过了一遍才搞清楚一件事在参数之前还有三道关卡等着你。这篇就按先找病根、再讲参数体系、最后给完整流程和参考配置的顺序整理出来。如果你正准备用自制数据跑FAST-LIO或者已经在为地图精度头疼这篇内容应该能帮你少走不少弯路。1. 建图飘的四种典型症状与最终祸首大家说飘但飘和飘完全不是一回事。同样是地图不对错位、翘曲、发飘、毛糙这四种症状指向的原因截然不同。我建议拿到一张有问题的地图先别急着改参数按下面的表格对号入座症状具体表现最可疑的根源错位同一条墙转一圈后变成两堵接缝明显对不上时间不同步、外参LiDAR与IMU相对位姿不准翘曲地面、墙面整体倾斜像整个地图被掰弯外参旋转部分填错、坐标系定义反了发飘轨迹缓慢漂移走的时间越长偏得越远退化环境长走廊/空旷地 IMU噪声协方差失衡毛糙点云层厚大、墙体边缘粗糙像长了毛动态物体残留、点云抽稀不合理、后处理缺失1.1 错位大概率是时间同步和外参的锅如果地图的错位是局部重复但整体变形也就是同一面墙在第二次经过时出现了第二条位置首先要怀疑的不是参数而是LiDAR和IMU的时间是不是真的对齐。FAST-LIO的核心是紧耦合滤波LiDAR帧里的每个点都要用IMU积分的外姿态去补偿畸变。如果雷达点和IMU数据之间的时间戳偏差有几十毫秒车辆或者手持设备稍微一移动点的补偿就是错的地图自然会出现重影和错位。另一个大头是外参。FAST-LIO需要LiDAR相对IMU的平移和旋转。旋转矩阵哪怕只偏1°10米外的点就会产生约17厘米的横向偏差这个误差随距离线性放大。所以那种近处看着挺好、远处错得一塌糊涂的地图八成是外参有问题。解决办法只有一个认真做外参标定不要靠默认值硬撑。1.2 翘曲的根源几乎都在外参旋转遇到过一种非常迷惑的情况地图的墙和地面本身很清晰但整个地图是歪的就像用手捏住了地图一角把平面拎了起来。这种形态基本不是滤波参数能救回来的大概率是外参中的旋转部分填错了或者IMU与雷达的坐标系轴向定义不一致。FAST-LIO系列对坐标系的方向非常敏感。有些版本的代码定义的是LiDAR到IMU的变换有些资料里写的是IMU到LiDAR一不留神就反了。填进去不会立刻崩溃但优化会收敛到一个奇怪的局部极小值结果就是整体结构看似合理、实际歪斜。遇到这种问题我建议先回官方issue里确认你的fork版本里extrinsic_T/extrinsic_R到底用的是哪个方向的定义。1.3 发飘与长走廊退化场景下IMU协方差的影响在没有明显几何特征的区域超长的走廊、空旷的停车场激光雷达的多帧约束会退化系统基本靠IMU积分来维持姿态和位移。这时候如果IMU噪声协方差设置不合理漂移会被放大。acc_cov和gyr_cov设置太大代表我不太信任IMU在退化场景里缺少激光约束就很容易飘设置太小代表我非常信任IMUIMU零偏和积分误差又会被当成真值一路带偏。最佳值理应来自IMU手册或Allan方差标定而不是照抄别人的参数。后面我会专门讲这块怎么调。1.4 毛糙多是动态物体和点云处理的事地图表面一层白雾、墙体边缘极厚这通常不是位姿问题而是动态物体行人、经过的车扫过时留下的痕迹。FAST-LIO本身没有动态物体剔除模块建完图如果发现大量杂点可以先做后处理统计滤波去掉离群点再体素下采样把点云密度抹匀。别指望一个参数解决所有问题。2. FAST-LIO参数表里真正值得动手的值先看一份典型的FAST-LIO2配置文件骨架大部分版本大同小异字段可能略有增删common: lid_topic: /livox/lidar imu_topic: /livox/imu time_sync_en: false preprocess: lidar_type: 1 scan_line: 6 blind: 0.5 feature_extract_en: true point_filter_num: 4 mapping: acc_cov: 0.1 gyr_cov: 0.1 b_acc_cov: 0.0001 b_gyr_cov: 0.0001 fov_degree: 360 det_range: 100.0 extrinsic_est_en: true extrinsic_T: [-0.011, -0.023, 0.044] extrinsic_R: [1, 0, 0, 0, 1, 0, 0, 0, 1] max_iteration: 512 pcd_save: pcd_save_en: true folder_path: ~/maps file_name: scan这些参数分四类各有各的性格。2.1 传感器类型和话题配置搞错一次后面全白调common: lid_topic: /livox/lidar imu_topic: /livox/imu这两行是你bag里实际的话题名不匹配的话程序起不来或者订阅半天一个点都没有。用rostopic list先确认自己的bag里话题到底叫什么不要凭记忆填。preprocess: lidar_type: 1 scan_line: 6lidar_type在不同fork里含义略有区别常见约定是1表示Livox系列2表示Velodyne系列3表示Ouster系列。如果填错预处理阶段要么直接抛异常要么生成一张完全没法看的图。scan_line代表雷达有多少条扫描线。机械雷达按实际线数填VLP-16填16RS-32填32Livox系列通常填6。很多人会好奇Mid-360不是非重复扫描吗怎么还填6因为FAST-LIO2内部处理Livox点云时把它组织成了伪线束格式这个值必须和代码期望的一致乱填会出现特征提取异常。如果用的是不同fork最好去源码preprocess.h里看一眼它对scan_line的使用方式。2.2 预处理参数blind盲区与point_filter_num抽稀blind: 0.5 feature_extract_en: true point_filter_num: 4blind是盲区半径用来剔除雷达安装位置附近的点。这些点通常是雷达自身外壳、安装支架反射出来的固定不动但离传感器太近会对配准产生干扰。机械雷达常见的blind值是0.3到0.5米Livox Avia有的配置直接给4米因为它的近处点云质量差。Mid-360盲区小0.5可以起步如果发现建图时近处有固定的杂点团再适当加大。point_filter_num是抽稀参数表示每N个点保留1个。数值越大参与配准的点越少CPU压力越小但太小会丢失细节导致地图粗糙。实测下来点云密集的Mid-360在室内场景用4起步没问题如果CPU负载高或者跑实时时掉帧再适当调大到6或8。feature_extract_en这个开关值得多说一句。开启后算法会先做角点和面点提取再用提取后的特征去配准关闭后直接拿原始点云经过抽稀参与配准。对这个参数我建议不同雷达分别实测机械雷达通常开启效果好因为能滤掉大量重复点Livox系列有的场景下反而关闭效果好。我自己遇到过Mid-360开feature extract后地图特征稀疏、关掉后配准更稳的情况别听别人说哪个一定对花十分钟跑两遍对比一下。2.3 滤波核心参数四个噪声协方差的真正含义mapping: acc_cov: 0.1 gyr_cov: 0.1 b_acc_cov: 0.0001 b_gyr_cov: 0.0001这四行是整个配置里玄学浓度最高的地方其实理解起来并不难。acc_cov是加速度计的噪声方差密度gyr_cov是陀螺仪的噪声方差密度单位对应IMU手册里的噪声密度值。b_acc_cov和b_gyr_cov分别是加速度计和陀螺仪零偏随时间随机游走的噪声密度。前两个数值越大表示传感器测量噪声越大滤波就越不敢直接相信原始测量后两个数值越大表示零偏漂移越快滤波会更快地在线修正零偏估计。如果完全没标定过IMU不要瞎改这四项先保持默认把地图跑出来看趋势。真正需要调的时候按这个方向判断建图时静止状态下轨迹还在缓慢漂移说明零偏估计没跟上可以适当加大b_acc_cov和b_gyr_cov让滤波器更快修正零偏。匀速直线运动时轨迹扭曲、旋转后位置对不上可能IMU噪声协方差整体偏小试试把acc_cov和gyr_cov乘10。如果地图抖动剧烈、高频晃动可能是噪声协方差太大滤波器在IMU和激光之间摇摆不定试试缩小。理想情况下这两个值应该来自IMU的Allan方差标定。没有条件标定时至少把IMU原始数据打出来看一眼加速度模长长时间偏离9.8或者静态时角速度输出有异常跳变说明IMU本身就有问题调协方差救不了。2.4 建图范围与视场角fov_degree: 360 det_range: 100.0fov_degree用于描述传感器的可用视场角机械雷达和Mid-360这类水平360°的传感器直接填360即可。det_range代表有效建图范围也就是超过这个距离的点直接丢。Mid-360的量程是40米如果默认填100米那些超过有效量程的点大多是噪声参与配准反而添乱。室外场景我习惯把det_range压到40到50米室内压到30米地图稳定性和计算速度都有改善。2.5 外参参数extrinsic_est_en的开与关extrinsic_est_en: true extrinsic_T: [-0.011, -0.023, 0.044] extrinsic_R: [1, 0, 0, 0, 1, 0, 0, 0, 1]extrinsic_est_en决定是否在运行过程中持续在线优化LiDAR到IMU的外参。默认true的情况下如果初值已经比较接近真值算法能补偿一些微小误差这是好事。但如果初值差得离谱比如旋转矩阵接近错误方向在线估计会让系统在错误的道路上越走越远地图整体扭曲甚至发散。经过严格标定、确认外参可靠后建议把extrinsic_est_en设为false减少额外的自由度滤波状态更容易收敛。如果你是拿默认外参硬跑的先别关否则初始误差会一路保留下来。3. 自制数据调参的完整流程从rosbag到地图验证参数再怎么理解最后都要落到实际操作。我归纳了一套适合自己的流程顺序很重要顺序错了会浪费大量时间。3.1 数据采集阶段就要有纪律很多调参问题其实是采集阶段埋下的雷。跑FAST-LIO之前采集bag时请遵守这几条设备装好后先保持静止5秒以上让IMU零偏估计有个收敛过程。动起来之前故意做几个8字晃动或原地旋转让LiDAR和IMU的位姿被充分激励起来滤波器才能把外参和零偏的可观性拉起来。避免长时间在绝对无特征的纯色墙、白墙走廊里运行那种环境下谁都建不出好图。用下面这种方式录制原始话题不要录拼接后的点云要保留原始雷达消息和IMU消息rosbag record /livox/lidar /livox/imu -O indoor.bag至于话题名以你自己驱动发布的实际名为准上面只是示例。3.2 先跑通官方bag再跑自己的bag我见过太多人拿着自己的bag直接开跑地图乱了就怀疑算法、怀疑电脑。正确做法是先下载FAST-LIO官方提供的bag很多fork的README里都有测试数据用仓库自带的配置跑一遍。官方bag能出好图说明编译、依赖、配置框架都没问题这时候再换成自己的bag如果地图崩了问题一定出在数据或者参数不匹配上。这一步能把环境问题和数据问题快速切开。3.3 调参顺序按这个优先级来别跳步我给新手制定了一个调参优先级表踩过坑之后你会明白为什么顺序如此重要优先级检查项判断标准1话题名、lidar_type、scan_line程序能否正常运行、是否报错2外参T和R地图是否歪斜、错位3时间同步高速运动时是否出现重影4blind、det_range近处杂点和远处噪点是否影响配准5IMU噪声协方差轨迹是否漂移、抖动6point_filter_num、feature_extract_en地图精度与CPU负载平衡每一步做完都重新跑一遍确认这一步ok了再动下一个。永远不要一次改两个参数否则地图出问题你根本不知道是哪一项引起的。3.4 地图质量的验证方法地图质量的验证分定性和定量两档。定性验证是最快的方式建图结束后保存pcd用CloudCompare打开看墙体厚度是否在合理范围通常在几厘米到十几厘米之间取决于传感器和运动速度、直角是否垂直、第一次和第二次经过同一条走廊时墙线是否重合。定量验证需要真值。如果你在室内用动作捕捉或者高精度设备录制过真值轨迹可以用evo工具对比FAST-LIO输出的轨迹和真值evo_ape kitti groundtruth.txt trajectory.txt -a没有真值也不强求很多场景连RTK都用不了定性验证足够判断参数有没有调对。保存地图时注意pcd_save部分的配置pcd_save: pcd_save_en: true folder_path: ~/maps file_name: indoor程序正常退出后会生成带姿态信息的PCD文件建议保存后顺手做一次统计滤波和体素下采样视觉上会干净很多。4. 不同雷达与场景的参数组合参考参数不是玄学但也不是放之四海而皆准。下面三组参数是我基于常见实践调整出来、并在自采数据上验证过的起始配置你可以当起点来用而不是当终点来抄。4.1 Mid-360室内小场景室内场景空间有限、特征密集、近距离点云多重点是控制盲区和距离范围避免近处杂点干扰配准common: lid_topic: /livox/lidar imu_topic: /livox/imu time_sync_en: false preprocess: lidar_type: 1 scan_line: 6 blind: 0.5 feature_extract_en: true point_filter_num: 4 mapping: acc_cov: 0.1 gyr_cov: 0.1 b_acc_cov: 0.0001 b_gyr_cov: 0.0001 fov_degree: 360 det_range: 30.0 extrinsic_est_en: true max_iteration: 512室内环境det_range压到30米后远处穿墙透进来的散点会被滤掉地图更干净。如果墙体厚度明显偏大把point_filter_num调到6或8试试点少一些配准可能反而更稳。4.2 Mid-360室外大场景室外场景最主要的挑战是空旷区域多、远距离点云稀疏容易出现退化漂移。我的做法是加大抽稀、略微调大IMU噪声协方差让滤波器在缺乏激光约束时不至于过度自信preprocess: lidar_type: 1 scan_line: 6 blind: 1.0 feature_extract_en: false point_filter_num: 6 mapping: acc_cov: 0.2 gyr_cov: 0.2 b_acc_cov: 0.0001 b_gyr_cov: 0.0001 fov_degree: 360 det_range: 40.0 extrinsic_est_en: false # 前提是外参已标定 max_iteration: 512feature_extract_en在室外我倾向于关掉因为Mid-360在远距离上的点本来就稀疏再提一遍特征能用来做约束的点就更少了。前提换来的是Body上CPU占用略高但建图稳定性通常更好。如果你实测发现开了特征提取效果更好那说明你的场景很适合就保留true不要迷信我这套。4.3 VLP-16 自定义IMU机械式16线雷达点云结构和Livox完全不同参数也要跟着变common: lid_topic: /velodyne_points imu_topic: /imu/data time_sync_en: false preprocess: lidar_type: 2 scan_line: 16 blind: 0.5 feature_extract_en: true point_filter_num: 4 mapping: acc_cov: 0.1 gyr_cov: 0.1 b_acc_cov: 0.0001 b_gyr_cov: 0.0001 fov_degree: 360 det_range: 80.0 extrinsic_est_en: true max_iteration: 51216线雷达的scan_line直接对应16条扫描线这个最直观。det_range不用压得太狠VLP-16标称量程100米远距离点虽然稀疏但偶尔还能提供一些约束压到80米比较平衡。如果你的IMU是那种很便宜的模块先检查零偏是否稳定否则上面这四个协方差怎么调都很勉强。4.4 一组参数怎么验证是否合适拿到一组参数后我的建议是同一份bag数据跑三遍第一遍用默认参数记录问题现象。第二遍只改传感器相关配置雷达类型、线数、话题不改噪声和外参看现象是否变好。第三遍再微调外参和噪声看地图厚度、接缝是否改善。尽量用同一份bag反复验证不要每次调整都去重新采集数据。同一份数据才能保证变量唯一这才是真正有效的调参实验。5. 调试中我踩过的五个坑和绕坑方法最后一part全是实战里真金白银踩出来的坑。有些坑看起来低级但关键时刻真的会绊倒人。5.1 scan_line写错重扫了三遍数据第一次用Mid-360跑FAST-LIO时我把scan_line想当然填了16因为脑子里总觉得线数多更高级。结果是程序不报错但点云预处理出来的伪线束错乱建图地图像被人揉皱的纸。我一度以为是雷达坏了换了电脑重装环境最后翻源码才发现是scan_line参数的问题。所以遇到地图完全不可理喻的情况先回去检查这些基础参数别急着怀疑硬件。5.2 外参旋转矩阵填错顺序有次我标定完外参把标定工具输出的四元数转成旋转矩阵后直接按行优先填进了extrinsic_R。结果地图的地面做得特别好但所有竖直墙面都朝一个方向倾斜。后来才发现那个fork里的extrinsic_R是按列优先解析的。旋转矩阵填错顺序不会报错它只会给你一个看起来差一点但怎么都调不对的地图。遇到这种情况建议把矩阵转置后再填一次对比往往瞬间就对了。5.3 打开time_sync_en反而更糟FAST-LIO2里有个time_sync_en参数作用是在雷达和IMU时间戳不同步时尝试做插值对齐。我一开始觉得这不就是为我这种不严谨采集的人准备的吗果断打开。结果地图反而飘得更厉害。原因是这个功能依赖稳定的消息到达时间我用的bag是压缩格式录的回放时消息抖动很大插值出来的时间戳反而不靠谱。正确的做法是录制时保证传感器驱动发布的是硬件时间戳回放用rosbag play --clock保持话题原始时间语义。如果采集现场没条件做硬同步至少让两个驱动都以各自硬件时间戳发布再通过配置文件里的时间偏移量补偿。与其指望插值不如把原始时间做好。5.4 在RViz里被看起来对欺骗建图过程中RViz里看到的地图是增量式的局部地图和最终保存的PCD并不完全一样。有次我在RViz里看到闭环接缝完美重合信心满满保存点云结果CloudCompare一打开走廊末端的墙错位了半米。原因很简单RViz的显示有LOD细节层次点少的时候看不出问题导出静止点云后所有误差都暴露了。验证地图请以保存的PCD为准不要以RViz画面为准。保存的时候加大点云密度导出后用CloudCompare仔细看厚度和接缝。5.5 急着调协方差忽略了IMU数据本身异常有段时间地图总是发飘我花了整整两天在调acc_cov和gyr_cov从0.001试到100地图始终没好。最后无聊把IMU的原始数据打印出来发现IMU加速度计的输出在静止时不停跳动跳动幅度远超正常水平。拆开一看IMU被双面胶粘在一个振动明显的铝型材上电机一启动整个板子都在抖。再好的滤波参数也救不了一个物理上就没装好的IMU。调协方差之前先把IMU的原始波形拉出来看一眼确保零偏小、噪声平稳、无明显振动耦合。数据源有问题参数调得再勤都是白费。最后再分享一点个人体会FAST-LIO这套系统很有意思它的参数数量不多看起来比cartographer那一大堆权重简单得多但它的简单建立在传感器高质量输入之上。调参调到后面你会发现真正决定地图精度的往往不是那几个数值而是采集时雷达和IMU装得好不好、时间戳齐不齐、外参标定准不准。参数表格只是最后的微调旋钮而已。我现在的习惯是拿到任何一个新设备先花半天时间采集数据、观察IMU波形、做外参标定再花半小时调参数这样顺序走下来的成功率远高于直接改参数。希望这篇文能帮你在调参路上少走点弯路。
返回列表