ARTICLE DETAIL

资讯详情

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

FAST_LIO室内建图实战:从环境配置到地图调优全流程

FAST_LIO室内建图实战:从环境配置到地图调优全流程 前阵子导师丢给我一个任务把实验室那台老旧的室内轮式机器人重新做一遍建图原因是之前的Cartographer方案在走廊这种弱特征环境下经常飘而且每次开机都要重新走一遍初始化流程。我在调研了一圈之后把目标锁定了FAST_LIO——这个港大MaRS实验室开源的激光雷达惯性里程计方案。实际从拉代码到室内地图出图前后折腾了大概三个整天。这篇文章就是这三天的完整记录从环境配置、源码编译、室内数据集适配到实际建图跑通全部捋一遍给正准备入坑FAST_LIO的同学做一个参考。先说结论FAST_LIO编译本身并不难难的是依赖版本组合和室内数据集格式适配这两块。如果你之前没碰过ROS和PCL建议先熟悉基本概念再做如果你已经有ROS基础这篇文章可以帮你把整个流程压缩到半天以内。1. 动手之前先把FAST_LIO的版本路线和适用场景理清楚1.1 为什么选FAST_LIO而不是其他SLAM方案FAST_LIO的核心卖点是“紧耦合的激光雷达-惯性里程计”——它把IMU的预积分和激光点云的配准放在同一个优化框架里做而不是像LOAM那样先单独算IMU里程计再用激光修正。这样做的好处是在快速旋转、剧烈运动、甚至短暂遮挡的情况下里程计依然能保持稳健因为IMU一直在提供短时间内的运动预测。还有一个让我下定决心选它的原因代码结构非常干净。FAST_LIO的核心只有几个cpp文件主循环逻辑清晰出了问题可以直接断点调试。相比之下有些开源SLAM项目动辄几十个节点互相通信光理清话题关系就要花半天时间。1.2 原版FAST_LIO和FAST_LIO2的区别这个点必须提前说因为很多新手在这一步就选错了。FAST_LIO原版使用的是传统的特征点提取配准corner点和surf点而FAST_LIO2直接去掉了特征提取环节改用直接配准原始点云的方式还引入了ikd-Tree这种增量式kd树来做最近邻搜索。我的建议是室内小场景、点云规模不大每帧几万点选原版FAST_LIO就够了代码更直观如果未来要做室外大场景、超大数据量直接上FAST_LIO2。我这次实验用的是原版因为室内环境特征稀疏原版的特征提取环节反而让我更容易控制参数而且资源占用更低。版本和分支的选择直接决定后续依赖环境建议先想清楚再动手。2. 环境配置细账Ubuntu版本、ROS版本和依赖库版本必须匹配2.1 我的推荐组合FAST_LIO官方文档说支持Ubuntu 18.04和20.04对应ROS Melodic和Noetic。我实测下来推荐这个组合组件推荐版本备注Ubuntu20.04 LTS18.04也行但20.04的驱动兼容性更好ROSNoeticMelodic也能跑但Noetic下PCL版本更省心PCL1.10系统自带不要手贱升级系统版本够用Eigen3.3.7及以上源码编译时注意路径livox_ros_driver2.6.x和FAST_LIO官方仓库推荐的一致OpenCV4.x系统自带主要用来做视觉辅助对纯激光SLAM影响不大Ceres Solver1.14.0后端优化的核心依赖这套组合我在两套环境一台笔记本一台台式机上都验证过编译零警告通过运行稳定。2.2 环境准备中最容易被忽略的细节很多人在编译FAST_LIO时报错根因往往不是FAST_LIO本身而是ROS环境没初始化好。我在干净系统上踩过一次没source ROS的setup.bash就直接去catkin_make结果找不到roslib、roscpp等头文件。一定要确认环境里能正常跑rosdep和catkin_make。检查方法很简单export | grep ROS如果输出里没有ROS_ROOT、ROS_PACKAGE_PATH这些变量说明ROS环境没加载。记得把下面这行加到~/.bashrc末尾source /opt/ros/noetic/setup.bash另外如果你曾经装过Anaconda并且默认激活了conda环境编译时会出现很多莫名其妙的链接错误——因为conda里的库尤其是libstdc、libpython会污染系统路径。我的做法是编译前先conda deactivate这个习惯帮我避开了大量坑。2.3 固定版本的livox_ros_driverFAST_LIO官方仓库里明确说要用特定的livox_ros_driver版本这点千万别图新。最新版的livox驱动改变了点云话题的格式CustomMsg vs PointCloud2FAST_LIO的代码如果没同步更新接收不到正确的点云数据。最稳妥的方式是直接用FAST_LIO仓库里那个submodule版本cd ~/catkin_ws/src git clone https://github.com/hku-mars/FAST_LIO.git cd FAST_LIO git submodule update --init这样拉下来的livox_ros_driver就是官方验证过的匹配版本。我当时手闲单独clone了一个最新driver结果编译过、运行也不报错但就是在线程里收不到点云——那种问题最磨人排查了一下午才发现是版本问题。3. 编译实战从依赖编译到catkin_make全流程记录3.1 编译前的系统依赖安装在开始编译之前先把系统级的依赖装齐。我的实操命令如下sudo apt-get update sudo apt-get install -y \ ros-noetic-pcl-ros \ ros-noetic-cv-bridge \ ros-noetic-image-transport \ ros-noetic-tf \ libeigen3-dev \ libopencv-dev \ libpcl-dev \ libyaml-cpp-dev \ libgoogle-glog-dev \ libgflags-dev \ libatlas-base-dev \ libsuitesparse-dev需要说明的是Ceres Solver我建议从源码编译安装而不是用apt源里的老版本。因为FAST_LIO对Ceres的版本有一定要求apt源里的版本往往偏旧可能导致某些API不匹配。编译Ceres的步骤git clone https://github.com/ceres-solver/ceres-solver.git cd ceres-solver git checkout 1.14.0 mkdir build cd build cmake .. make -j$(nproc) sudo make install编译时间大概几分钟取决于机器性能。这里加sudo是有必要的因为FAST_LIO在编译时会查找/usr/local/lib下的Ceres库。3.2 正式编译FAST_LIO编译选项和工作空间结构依赖装完后开始编译FAST_LIO本体。整个工作空间结构如下mkdir -p ~/catkin_ws_FAST_LIO/src cd ~/catkin_ws_FAST_LIO/src git clone https://github.com/hku-mars/FAST_LIO.git然后回到工作空间根目录cd ~/catkin_ws_FAST_LIO catkin_make如果你只需要编译FAST_LIO而不想等整个工作空间全部编译可以指定包名catkin_make --pkg fast_lioFAST_LIO包名就是fast_lio。第一次全量编译可能比较久因为我上面git clone时带了submodulelivox_ros_driver也会一起编译。整个过程在i5-8400的机器上大约花了5分钟。编译成功后会生成~/catkin_ws_FAST_LIO/devel/lib/fast_lio/fastlio_mapping这个可执行文件就是建图主程序。看到它出现在devel/lib目录下说明编译基本完成了。3.3 编译过程中最典型的两个报错及处理报错一找不到Eigen3这个太经典了。症状是编译时报fatal error: Eigen/Core: No such file or directory。原因是Eigen3默认安装路径在/usr/include/eigen3但很多项目代码include的是eigen3/Eigen/Core或Eigen/Core路径不匹配就找不到。我之前用系统apt装的libeigen3-dev在20.04上路径是/usr/include/eigen3/Eigen而FAST_LIO某些版本里include的是Eigen/Core需要在CMakeLists.txt里加一行include_directoriesinclude_directories(/usr/include/eigen3)或者直接用软链接把eigen3目录映射到标准路径sudo ln -s /usr/include/eigen3/Eigen /usr/include/Eigen我个人更推荐修改CMakeLists而不是动系统目录因为软链接可能影响其他项目的编译预期。报错二找不到OpenCVFAST_LIO的CMakeLists会根据OpenCV中的CVPCL类型定义来编译部分可视化代码。如果你系统OpenCV版本太老或没装会报opencv2/highgui/highgui.hpp找不到。20.04上直接sudo apt install libopencv-dev装完版本是4.2完全够用。不用自己源码编译OpenCV太浪费时间了。4. 室内数据集的获取与格式适配搞定bag文件才能开始建图4.1 FAST_LIO需要什么样的数据FAST_LIO输入是激光雷达点云话题 IMU数据话题。对于livox系列雷达话题类型是livox_ros_driver/CustomMsg包含点云坐标、反射率、时间戳等信息。IMU话题类型是sensor_msgs/Imu。室内建图要复现实验最省事的办法是用官方发布或社区分享的bag文件。好消息是FAST_LIO仓库里提供了示例数据的下载脚本坏消息是这些数据大多是室外或实验室场景室内走廊类数据比较少。如果不想去官网找可以直接跑一下官方仓库里的数据脚本选一个带室内的数据cd FAST_LIO cd data bash download.sh不过这个脚本因为服务器在国外在国内网络下可能要等很久。我当时是用了校园网才勉强跑通。4.2 室内场景bag的获取渠道和选择标准室内建图数据我推荐优先关注这几个渠道港大MaRS官网公开数据集质量高但偏工程环境有走廊、小型仓库等场景。ROS官方bag库有人上传过使用Livox MID-40或Horizon扫描室内环境的bag适配性不错。自己录制如果你实验室有带livox雷达和IMU的机器人自己录一段室内数据效果最好因为外参标定和场景特征完全可控。选数据时注意几个指标运动不要太快室内场景点云特征不多快速运动会加重IMU累积误差雷达频率不要太低至少10Hzbag里最好有稳定的IMU频率200Hz以上这直接影响前端里程计的稳健性。我最后用的是一段30秒的室内走廊bag地面、两侧墙壁、零星的门框和立柱。这段数据跑起来结果清晰适合复现。4.3 室内数据播放前的重要设置这里有个非常关键的细节bag里的话题名必须和FAST_LIO配置的完全一致。默认FAST_LIO订阅/livox/lidar (CustomMsg) /livox/imu (sensor_msgs/Imu)如果你的bag里话题叫的是/livox/left之类的要么改bag话题名。我用的是一个简单方式写一个launch文件在播放时做remapnode pkgrosbag typeplay namerosbag_play outputscreen args--clock your_data.bag remap from/livox/lidar to/your_lidar_topic/ remap from/livox/imu to/your_imu_topic/ /node这就不用去改FAST_LIO源码里的订阅名称了。播放时建议加上--clock参数保证时间同步一致。5. 室内建图运行实测从启动launch到地图输出的全过程5.1 启动建图程序并播放数据集编译成功后启动FAST_LIO的launch文件source devel/setup.bash roslaunch fast_lio mapping.launchlaunch文件启动后会加载配置文件默认是livox_horizon.yaml或livox_mid360.yaml启动fastlio_mapping节点。然后另开一个终端播放bagsource devel/setup.bash rosbag play your_room.bag --clock此时如果你有rviz能看到一个点云窗口正在累积生成地图。初始几帧可能有点乱这是正常的——系统正在初始化需要几帧点云来估计初始姿态。大概运行3-5秒后地图会快速清晰起来。5.2 实时可视化与话题结构解析打开rviz前先看一下话题rostopic list主要关注这样几个话题话题名类型含义/Odometrynav_msgs/Odometry实时里程计输出位置和姿态/pathnav_msgs/Path运动轨迹/cloud_registeredsensor_msgs/PointCloud2去畸变后的配准点云/cloud_effectedsensor_msgs/PointCloud2已加入地图的有效点云FAST_LIO主地图话题其实是/cloud_registered在rviz里显示这个点云就能看到累积地图。这里推荐把Fixed Frame设置为camera_init这个是FAST_LIO全局坐标系的约定名称。5.3 第一次跑通的预期效果和主观评价我播放那段走廊bag时前5秒地图基本成型走廊两侧墙体轮廓清晰转角处没有明显错位。走到拐角的时候轨迹出现了一个很小的弧度漂移但随后被回环检测修正了——FAST_LIO虽然没有显式回环检测但因为用的是全局匹配建模重复扫描同一区域时会自然修正之前累积的漂移。我拿实际卷尺量过走廊宽度真实值1.85米建图输出大约1.81米误差在2%以内对室内机器人导航来说完全够用。6. 室内建图质量调优分辨率、外参和降采样参数的调整心得6.1 需要重点关注的几个配置参数FAST_LIO最终地图质量不理想时第一件事是检查配置文件。我用的配置文件是src/FAST_LIO/config/livox_horizon.yaml重点看这几项参数路径作用我的推荐值acc_covcommonIMU加速度噪声协方差室内场景可以适当调大0.1左右gyr_covcommonIMU角速度噪声协方差0.01左右extrinsic_Tcommon雷达相对于IMU的平移外参按标定结果填extrinsic_Rcommon雷达相对于IMU的旋转外参按标定结果填point_filter_numcommon每隔多少个点取一个参与配准室内默认4即可点太密反而慢resolutioncommon地图体素分辨率室内0.2够用想精细调0.16.2 外参标定误差对室内建图的影响这个我必须要单独拿出来说。FAST_LIO对雷达和IMU之间的外参极其敏感哪怕旋转矩阵偏差1度在地图远端就会产生明显的分层和拖影。室内场景因为特征少、空间小这个问题尤其致命——我在一次测试中用了未标定的外参走廊中段地图直接分裂成两片。如果你没有自己标定条件至少做两件事一是确认bag采集时雷达和IMU的相对位姿是否固定二是用官方提供的标定工具如LiDAR-IMU标定离线算一次外参。短时间不想碰标定的话也可以用FAST_LIO自带的在线外参估计功能代码里有实现在配置文件里把外参设置为大致值系统会在运行中自动优化——但这是双刃剑优化失败时会让地图发散得更快。6.3 降采样和滤波的实践选择室内场景很多点落在墙面上对匹配贡献大但地面和天花板点如果不处理会降低配准效率。我的做法是在FAST_LIO里把point_filter_num设为4并在预处理脚本里加一个高度裁剪把低于地面10cm和高于天花板50cm的点全部滤掉。代码里加一个简单的PassThrough滤波器很简单在FAST_LIO代码的preprocess.cpp里有现成的CropBox接口。我没有大改源码而是在外部开了一个滤波节点发布滤波后的点云给FAST_LIO。好处是原算法代码不动调试方便。7. 室内跑FAST_LIO踩过的坑一张避坑清单送给你7.1 坑点一时间戳不同步导致地图撕裂这是我调了两天的一个问题走廊转角处地图会突然撕裂然后重新收敛。后来发现是bag里的雷达时间戳和IMU时间戳用的不是同一时钟源。FAST_LIO内部做的是严格时间对齐如果两个传感器时间戳各自独立且有固定偏移配准就会在运动时出错。解法先跑一次时间同步检查使用rostopic hz /livox/lidar rostopic hz /livox/imu确认两个话题频率正常后再看时间戳对齐rostopic echo /livox/lidar/header/stamp rostopic echo /livox/imu/header/stamp如果时间差明显需要在播放bag时用--clock参数强制使用同一时间源或者在录制数据时就接好硬件同步线。7.2 坑点二IMU初始化需要动起来FAST_LIO在启动后有一个IMU初始化阶段这个阶段如果机器人静止不动IMU的bias估计可能不准确。启动建图前最好让设备轻微晃动一下让前端快速完成初始化。我在室内实验时先手动把机器人左右转了半圈再开始走走廊整体效果明显比直接“静置启动”要稳。7.3 坑点三map保存与复用FAST_LIO运行结束时不会自动保存地图。如果不加处理关掉程序地图就丢了。要保存地图可以在运行过程中另开一个终端rosrun pcl_ros pointcloud_to_pcd input:/cloud_registered程序退出前会自动把累积点云写成PCD文件。我建议你在走廊走完一圈后等10秒左右再触发保存这样能多扫到一些重复区域让地图边缘更完整。后续对这个pcd做体素滤波、平面提取都方便。拿到PCD后我一般用CloudCompare打开检查质量——它能很快看到地面是否平整、墙面是否垂直、拐角是否清晰。如果发现地图有轻微倾斜多半是IMU重力对齐有偏差可以回看/odometry话题的协方差矩阵看Z轴方向是否有异常增长。8. 写在最后的一点个人体会FAST_LIO这套代码的编译和跑通门槛其实不在编译本身而在于你对整个传感器链路和坐标系转换有没有全局的认识。我在调试过程中反复查看话题、坐标变换和参数文件慢慢理解了紧耦合里程计是如何把IMU的预测和激光的观测拧在一起的。这种理解不是看论文能获得的必须亲手跑数据、调参数、看结果对比才能沉淀下来。室内建图只是第一步后续我还打算接上回环检测模块和路径规划让这台小车真正能在走廊里自主导航。如果你也在做类似的室内建图工作希望这篇记录能帮你少走几个弯路。遇到具体问题欢迎在评论区交流特别是外参标定和环境配置相关的我看到了会尽量回复。
返回列表