ARTICLE DETAIL

资讯详情

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

Livox Avia与IMU外参标定:用lidar_imu_init解决FAST-LIO地图分层问题

Livox Avia与IMU外参标定:用lidar_imu_init解决FAST-LIO地图分层问题 做激光雷达SLAM的人迟早要在“外参标定”这件事上栽一回。尤其当你手里拿着一台Livox Avia这种固态激光雷达它对IMU外参的敏感程度一点不比机械雷达低。外参给错了最典型的表现是FAST-LIO刚启动没几秒就飘明明跑的是同一段路点云地图却一层一层地错开像打印了重影。这个问题的根源十有八九不是SLAM算法不行而是IMU坐标系和LiDAR坐标系之间的变换矩阵没对上。这几年我用lidar_imu_init给多套Livox设备做过标定包括Avia、Mid-360以及各种外接IMU组合踩过的坑足够写一篇长文章了。这篇内容就围绕lidar_imu_init跑通Livox Avia与IMU外参标定的完整过程展开包括这套工具到底在算什么、数据怎么采集、配置文件哪些参数最容易改错、标定结果拿回来后怎么验证。无论你是刚入门激光雷达SLAM还是已经跑通FAST-LIO但地图一直分层这篇都适合从头看一遍。1. 为什么别急着标外参外参误差在SLAM里会放大成什么1.1 外参是怎么定义的外参就是LiDAR坐标系和IMU坐标系之间的刚性变换矩阵通常记作 T_il含义是把IMU坐标系下的量转换到LiDAR坐标系下。反过来也存在 T_li两者互为逆矩阵使用之前必须搞清楚目标系统要的是哪个方向。在FAST-LIO这类紧耦合系统里激光点云要被变换到IMU坐标系下参与状态估计。外参如果带误差每个点都带着一个系统性的偏置进入滤波算法再怎么调参数都救不回来。用大白话说激光雷达和IMU虽然是背靠背装在一起的但坐标系原点、轴方向都不一样而且雷达坐标系原点是光学中心IMU坐标系原点是MEMS惯性器件中心不是外壳上某个好量的螺丝孔。指望“大致水平、旋转90度装”就手填一个外参实际跑起来一定会翻车。1.2 为什么“量一量、猜一猜”不靠谱很多人第一反应是拿尺子量安装偏移再根据结构件角度估算旋转。这个做法在视觉SLAM里也许勉强能用但在激光雷达紧耦合SLAM里基本不成立结构件有加工公差螺丝拧紧后实际角度和图纸理论值经常差0.2到1度。零点几度的旋转误差在20米外就会放大成十几厘米的点云错位。Avia这类固态雷达是非重复扫描点云分布和机械雷达不一样外参误差带来的畸变也更隐蔽光靠肉眼看点云很难判断。还有朋友把手眼标定工具的结果直接搬过来用但手眼标定对数据质量要求很高运动稍微退化一点结果就偏离真实值。等你把标定结果写进FAST-LIO的配置文件跑起来才发现问题再回头排查浪费的时间比标定本身多得多。1.3 为什么我选lidar_imu_init而不是其他工具lidar_imu_init来自开源社区的MaRS实验室团队和FAST-LIO同一套技术体系对Livox系列雷达的支持尤其顺手。它的定位是解决LiDAR与IMU之间外参未知或初值不准的问题不需要标定板不需要复杂靶标在自然环境里晃动设备就能估计出外参旋转、平移甚至时间偏移。相比之下有些方案必须用标定板有些方案对场景要求很苛刻lidar_imu_init在工程落地时的容错率更高。如果你后续要在ROS2下的Cartographer或FAST-LIO里使用标定结果可以在标定阶段单独用ROS1环境标定完成后把外参导出给ROS2系统使用。这个流程我实际验证过完全可行。2. 标定门槛驱动版本、IP路由和时间戳单位2.1 驱动选型与编译Livox Avia官方驱动有livox_ros_driver和livox_ros_driver2两个版本。lidar_imu_init目前是ROS1工程推荐在Ubuntu 20.04加ROS Noetic环境下操作。livox_ros_driver2同时支持ROS1和ROS2对Avia的点云时间戳处理更规范建议直接用第二代驱动。编译过程不复杂但依赖要装齐cd ~/catkin_ws/src git clone https://github.com/Livox-SDK/livox_ros_driver2.git cd ~/catkin_ws catkin_make source devel/setup.bash再把lidar_imu_init放进同一个工作空间编译cd ~/catkin_ws/src git clone https://github.com/hku-mars/lidar_imu_init.git cd ~/catkin_ws catkin_make启动驱动后应该能同时看到 /livox/lidar 和 /livox/imu 两个话题。很多人在这里卡住IMU话题一直没数据。排查顺序是先看Livox Viewer里能否发现设备、点云是否在转再看驱动配置里是否把IMU发布功能打开。驱动没问题再看后面几项。2.2 雷达IP与PC网卡通信Livox Avia出厂默认IP一般是192.168.1.1这类固定地址PC端网卡需要手动设置同网段的静态IP才能通信常见的配置参考如下。项目推荐值雷达默认IP192.168.1.1以官方文档为准PC网卡IP192.168.1.5子网掩码255.255.255.0默认网关留空或192.168.1.1均可如果雷达IP不是你想要的网段可以用Livox Viewer或命令行工具livox_lidar_config修改。改完之后必须重启雷达设备否则不会生效。很多次“检测不到雷达”就是改了IP没重启。还有一个非常容易忽视的路由问题电脑同时连着Wi-Fi和有线网卡手动设置有线网卡静态IP后发往192.168.1.1的数据仍可能走Wi-Fi的默认路由导致驱动一直找不到设备。此时手动指定路由即可sudo route add -net 192.168.1.0/24 dev eth0eth0换成你的有线网卡名称。这个问题排查起来很隐蔽建议在标定环境里直接把Wi-Fi关掉省心。2.3 时间戳单位与时钟源时间同步是外参标定里最容易忽略却影响最大的环节。lidar_imu_init依赖IMU数据和点云数据的时间对齐如果两者不在同一个时钟源下旋转约束会被严重污染。Avia的点云时间戳有特殊性。它既有header.stamp也有点内部的offset_time字段。lidar_imu_init配置里的timestamp_unit参数就是告诉预处理模块如何解释这个时间。默认配置通常是纳秒如果你的驱动输出的是微秒这里必须改否则时间差会被放大1000倍标定结果直接变成废数据。另外Avia内置IMU频率通常为200Hz采集时请确认IMU话题确实有稳定输出。如果使用外接IMU更要确认IMU驱动没有丢帧。丢帧会导致陀螺积分和雷达旋转增量对不上标定结果飘得毫无规律。3. lidar_imu_init到底在解什么方程旋转约束与平移估计3.1 旋转增量约束AXXBlidar_imu_init的核心原理是手眼标定。在任意一个小时间段内雷达通过点云配准能得到LiDAR坐标系下的旋转增量 ΔR_LIMU通过陀螺积分能得到IMU坐标系下的旋转增量 ΔR_I。这两个增量之间通过未知外参 R_IL 联系在一起写出矩阵方程就是 AXXB 的形式。用人话说你让设备绕三个轴转一圈雷达“眼里”的旋转变化和IMU“身体感受到”的旋转变化它们的差异就是外参旋转。多采集几组不同姿态的数据用最小二乘就能把 R_IL 解出来。这里有一个关键点只有当设备在多个轴向都有旋转激励时方程组的各个维度才会被激活。如果只是绕z轴转圈滚转和俯仰方向完全没有约束程序也能输出一个数字但那个数字可能只是数学上的伪解不是真实外参。这也是为什么采集动作设计如此重要。3.2 平移外参与重力对齐旋转外参确定后平移外参 t_IL 靠加速度通道估计。把加速度计测量的比力、重力向量以及雷达轨迹的线加速度放在一起可以构成线性方程组用最小二乘求解。这个过程有一个隐含前提加速度计零偏不能太大而且数据段里要包含足够多的动态加速度变化。如果设备大部分时间在匀速平移动态加速度太小重力偏置会把平移约束淹没结果自然会偏离真实值。所以采集时不能只做匀速运动要有明显的加速和减速段。3.3 为什么必须“慢速大幅度”旋转lidar_imu_init内部依赖雷达里程计点云配准来计算相邻帧的旋转增量它不依赖标定板但对场景纹理和运动速度很敏感。Avia是非重复扫描短时间窗口里的点云分布本来就不均匀如果运动太快点云畸变会变得非常严重雷达配准误差增大最终污染外参估计。所以采集肢体语言总结下来就六个字慢速大幅度多轴。幅度越大激励越充分速度越慢点云畸变越小。二者看起来矛盾但实际操作中并不难做到手持设备缓慢但大幅度地转动整个手臂和手腕让设备依次经历大角度滚转、俯仰、偏航。4. 合格的bag怎么录动作设计、配置核查与收敛判断4.1 场景与动作设计虽然lidar_imu_init不需要标定板但场景质量直接决定标定成败。我踩过的场景雷区包括长白墙走廊、大面积玻璃幕墙、地下车库空旷区、纯草地。这些场景里雷达帧间匹配退化旋转增量计算出来自带漂移外参自然不对。推荐场景是室内办公区、货架区、有桌椅和墙角的房间、楼道交叉口或者室外的树木和建筑立面。特征是几何结构丰富但没有大量重复纹理。我的采集流程一般是把设备刚性固定如果是Avia内置IMU盖好外壳再绑上支架别用手直接捏着雷达外壳晃动。通电后预热1分钟让IMU内部温度稳定减小温漂影响。先绕roll轴大幅度摆动再绕pitch轴摆动再绕yaw轴转动。做几次“8字形”摆动中间穿插短距离加速平移。每个动作后略微停顿0.3到0.5秒给算法一个稳定帧。总时长控制在90秒到3分钟太长的bag反而增加预处理时间。如果设备是装在小车或机器人底盘上不能手持那就控制底盘原地旋转加小幅前进后退尽量让六个自由度都有激励。纯小车平移的bag基本废了标出来的外参完全不能用。4.2 配置文件中必须核对的六项以config/avia.yaml为例我每次标定都逐项核对下面这些参数。参数作用我的配置习惯lidar_type1表示Livox1timestamp_unit时间戳单位3纳秒/2微秒先确认驱动文档再填point_filter_num抽稀点云降低配准计算量4到6calib_point_num单帧参与标定的点数4000到8000max_imu_num窗口内IMU帧数上限默认值即可X/Y/Z外参旋转初值单位度完全未知就填0已知安装角就填粗略值如果IMU和LiDAR之间有明确的安装角度比如IMU绕x轴转了90度把初始旋转填上会明显加快收敛速度。完全不知道安装角度也可以从0开始试但要注意观察是否发散。还有一个容易漏掉的配置项是话题名。lidar_imu_init订阅的IMU话题和LiDAR话题必须是实际发布的topic名尤其是外接IMU时很多人的IMU话题叫/imu/data和配置默认值不一致节点启动后一直等数据这是最常见的“启动失败”。4.3 运行流程与收敛判断推荐离线标定用录好的bag反复调参不浪费现场时间。具体流程# 终端1 roscore # 终端2启动Livox驱动 roslaunch livox_ros_driver2 msg_Avia.launch # 终端3回放bag rosbag play -r 1.0 your_bag.bag # 终端4启动标定节点 roslaunch lidar_imu_init lidar_imu_init.launch如果直接在线标定就先启动驱动再启动lidar_imu_init然后手持设备按预设轨迹晃动。判断是否收敛不要只看程序有没有退出。我一般看两点终端反复打印的外参数值是否趋于稳定不再阶梯式跳变。程序是否打印了收敛提示。如果跑了十几秒数值还在大幅漂移说明数据质量或配置有问题别硬等。最好的做法是停下来换一段数据把可能改错的参数重新过一遍。5. 我踩过的坑四条典型故障的完整排查链路5.1 平移外参出现几米的偏置第一次用lidar_imu_init标定Avia时我拿到的旋转外参看着还算正常但平移外参是[2.3, -1.8, 0.9]这种离谱值。设备物理上就那么点大平移怎么可能有几米。排查链路是这样的先怀疑运动激励。回看bag里的IMU加速度波形发现大部分时间是匀速平移动态加速度太小平移约束被重力偏置淹没。再查时间戳。确认IMU的header.stamp和雷达点云的header.stamp是否同源时间单位是否写对。重新采集改成以原地大幅旋转为主、穿插短暂加速平移的动作。三次尝试后平移外参落在几厘米内这才算正常。后来我把这套排查顺序固定下来出现任何标定异常先看运动激励再看时间戳最后才怀疑工具本身。5.2 标定过程中疯狂提示特征不足现象是控制台不断打印no enough features或者类似的报错雷达配准完全跑不起来。根因往往是场景纹理给不了雷达足够特征比如地下车库整齐的混凝土柱子配大面积白墙。Livox Avia是非重复扫描短时间窗口里点云本来就稀疏特征不足时帧间匹配基本失效。解法很简单换场景。优先找货架区、办公桌椅、室外树木这类几何丰富的区域。如果只能在现场标就把旋转速度再放慢保证相邻帧点云重叠率足够高。5.3 回放bag时节点收不到IMU现象是rostopic list里能看到/livox/imu但lidar_imu_init节点一点反应都没有。排查链路检查bag里到底录了哪些话题rostopic list -b your_bag.bag。检查配置文件里的imu_topic和lidar_topic是否与实际话题名一致。确认回放顺序先启动驱动节点还是先回放bag这个话题订阅有时会因为时间戳跳变而错过。那次问题的根因是我录bag时只录了雷达点云没录IMU。因为当时另一个程序也在用IMU话题录制命令里漏掉了。回到现场重录问题立刻解决。录bag的教训总结一句话只录你需要话题的完整数据别偷懒。5.4 标定结果放进FAST-LIO立刻发散这是最让人头疼的坑标定程序显示收敛结果也合理但把外参写进FAST-LIO的配置文件后系统几秒钟就飘了。排查到最后是方向定义不一致。lidar_imu_init默认求出的是IMU到LiDAR方向的变换而目标系统里期望的外参可能是LiDAR到IMU方向两者互为逆矩阵。放进系统之前必须先确认目标框架的定义必要时把外参矩阵求逆再填进去。那次把矩阵求逆后的结果填入FAST-LIO立刻正常。从那以后我每次标定完都会在launch文件旁边写一行业注释记录外参的方向定义。这个习惯帮我在换设备后少踩很多坑。6. 标定结果拿回来后怎么验证方向、重复性和交叉测试6.1 可视化验证标定结果最终要交给SLAM系统使用。最直观的验证方式就是把外参填进FAST-LIO或Point-LIO启动后手持设备原地缓慢旋转30秒再走一圈回到原点。在RVIZ里看两样东西点云地图有没有分层墙面是否厚实清晰。轨迹起点和终点是否闭合。如果外参方向反了或者数值不对最直接的表现就是刚启动几秒内地图出现双层墙。这个验证适合现场快速判断但不适合作为唯一验证手段因为有些错误外参在小范围运动时表现不明显。6.2 轨迹交叉验证更可靠的验证是把外参代入公式把雷达轨迹反算成IMU轨迹再和IMU预积分轨迹对齐比较偏差。实际操作中大多数人没有精力去写这个计算脚本可以用一个更简单的替代方案拿同一段bag分别用两组外参跑两次里程计对比输出轨迹的一致性。如果外参正确轨迹应该平滑点云地图边缘锐利如果外参有几十度的旋转误差轨迹在转弯时会明显抖动。这个方法虽然不够精确但用来排除方向错误和显著数值错误非常有效。6.3 重复性验证还有一种容易被忽视的验证是重复性。同一平台不做任何结构改动连续标定3次对比每次输出的外参旋转外参各轴差异应在0.5度以内。平移外参各轴差异应在2到3厘米以内。如果重复性差说明数据质量不够重新采集比相信某一次数值更重要。反过来如果3次结果都稳定但放进系统还是发散那就是方向定义或坐标系约定出了问题。最后分享一个小习惯标定完成后把最终外参写进设备自带的标定文档同时记录采集场景、bag名称、标定时间、方向定义。下次换电脑重装系统或者换一台同型号设备这份记录能帮你省下大量重复排查时间。
返回列表