基于KITTI数据集:从LIO-SAM算法适配到EVO精度评估全流程解析

张开发
2026/4/21 8:53:20 15 分钟阅读

分享文章

基于KITTI数据集:从LIO-SAM算法适配到EVO精度评估全流程解析
1. KITTI数据集准备与格式转换第一次接触KITTI数据集时我被它庞大的数据量和复杂的目录结构搞得一头雾水。经过多次实践我总结出一套最高效的处理流程。KITTI作为自动驾驶领域最权威的公开数据集包含城市、乡村和高速公路等多种场景的传感器数据。对于SLAM研究而言我们主要关注其Odometry数据集中00-10序列这些序列提供了完整的激光雷达、IMU和真值轨迹数据。下载数据集时有个小技巧国内用户建议使用百度云离线下载提取码tc10速度比官网快很多。需要特别注意LIO-SAM算法需要同时下载*_sync.zip和*_extract.zip两部分数据。前者包含10Hz的IMU数据和去畸变的激光点云bin格式后者则提供100Hz的原始IMU数据。我曾在只下载_sync数据的情况下调试了一整天始终无法获得理想效果后来才发现是IMU频率不足导致的。数据转换环节最容易踩坑。推荐使用改进版的kitti2bag.py脚本这个版本解决了原始工具的两个关键问题一是自动补全ring和time信息二是支持高频率IMU数据同步。转换命令如下python3 kitti2bag.py -t 2011_09_30 -r 0016 raw_synced转换完成后建议用rosbag info检查数据完整性。正常情况应该看到如下话题/points_raw激光点云Velodyne HDL-64E/imu_raw100Hz IMU数据/gps/fixGPS定位数据/tf坐标变换树2. LIO-SAM算法深度适配原始LIO-SAM直接跑KITTI数据会立即崩溃这主要是因为两个核心差异一是KITTI点云缺少ring和time字段二是坐标系定义不同。经过多次尝试我找到了最稳定的修改方案。2.1 点云信息补全在imageProjection.cpp中添加的这段代码堪称救命稻草它通过计算垂直角度动态生成ring值float verticalAngle atan2(thisPoint.z, sqrt(thisPoint.x*thisPoint.x thisPoint.y*thisPoint.y)) * 180 / M_PI; rowIdn (verticalAngle ang_bottom) / ang_res_y;对于时间戳补全则需要利用激光雷达的扫描特性。这段代码通过计算水平角度占比来估计相对时间float ori -atan2(thisPoint.y, thisPoint.x); float relTime (ori - cloudInfo.startOrientation) / cloudInfo.orientationDiff; laserCloudIn-points[i].time 0.1 * relTime; // 10Hz扫描周期2.2 坐标系转换KITTI的真值轨迹位于左相机坐标系而LIO-SAM输出在IMU坐标系。需要通过标定矩阵进行转换这个转换矩阵藏在calib_cam_to_velo.txt中。我在代码中添加了自动读取标定参数的功能Eigen::Matrix4d cali_param; ifstream cali_file(calib_cam_to_velo.txt); for(int i0; i4; i){ for(int j0; j4; j){ cali_file cali_param(i,j); } }3. 轨迹输出与格式优化为了适配EVO评估工具需要对LIO-SAM的输出进行三项关键改造时间戳规范化将ROS时间转换为Unix时间戳轨迹格式转换从ROS的Odometry消息转为TUM格式频率统一将100Hz的IMU预测结果降采样到10Hz我开发了一个简单的ROS节点来做实时转换#!/usr/bin/env python import rospy from nav_msgs.msg import Odometry def odom_callback(msg): tum_line %.6f %.8f %.8f %.8f %.8f %.8f %.8f %.8f\n % ( msg.header.stamp.to_sec(), msg.pose.pose.position.x, msg.pose.pose.position.y, msg.pose.pose.position.z, msg.pose.pose.orientation.x, msg.pose.pose.orientation.y, msg.pose.pose.orientation.z, msg.pose.pose.orientation.w) with open(trajectory.tum, a) as f: f.write(tum_line)4. EVO精度评估实战EVO工具虽然强大但参数设置不当会导致评估结果失真。经过数十次测试我总结出最佳参数组合4.1 APE绝对轨迹误差evo_ape tum kitti_00_gt.txt lio_sam_result.txt \ -r trans_part \ --align_origin \ --plot_mode xz \ --save_plot ape_result.png关键参数解析-r trans_part只评估平移部分旋转误差单独评估--align_origin强制轨迹起点对齐--plot_mode xz选择鸟瞰图视角4.2 RPE相对位姿误差evo_rpe tum kitti_00_gt.txt lio_sam_result.txt \ --delta 10 \ --delta_unit m \ --plot_mode xz \ --save_plot rpe_result.png--delta 10表示每10米计算一个相对误差这个值建议设为场景大小的1/20左右。4.3 多算法对比技巧当需要比较多个算法时使用evo_res命令可以生成专业对比报表evo_res lio-sam.zip lego-loam.zip inslam.zip \ --use_filenames \ --save_table compare.csv生成的CSV表格可直接导入Excel进行可视化分析。我曾用这个方法发现LIO-SAM在弯道处的误差比直道高23%这个发现直接推动了后续的算法优化。5. 性能优化与调试技巧5.1 实时性优化在i7-11800H处理器上原始LIO-SAM处理KITTI数据只能跑到8Hz左右。通过以下改动可以提升到15Hz降采样激光点云到0.2度分辨率禁用回环检测模块对KITTI这种连续场景不是必须使用IMU预积分替代原始数据5.2 典型问题排查问题1轨迹出现突然跳变检查IMU和激光雷达的时间同步确认标定矩阵没有写错行列顺序问题2EVO评估时报timestamp disorder使用sort_tum.py脚本对轨迹文件重新排序检查是否有重复时间戳问题3建图出现重影调整mapOptimization.cpp中的关键帧间距参数增加回环检测的搜索半径经过完整流程的实践验证在KITTI 00序列上优化后的LIO-SAM可以达到如下精度指标APE均值0.78% (平移)1.2度/100m (旋转)RPE均值0.32% (10米间隔)实时性15Hz (i7-11800H RTX3060)

更多文章