尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

LIO_SAM在ROS2仿真环境下的机器人导航系统搭建与改进

LIO_SAM在ROS2仿真环境下的机器人导航系统搭建与改进 简介激光雷达与惯性测量单元IMU的融合是机器人自主定位导航的关键技术。LIO_SAM作为一种紧耦合的激光惯性里程计框架通过因子图优化实现高精度建图与位姿估计在ROS2 Humble和Ubuntu 22.04环境中适配仿真场景可有效解决纯激光SLAM在稀疏点云下的漂移问题。结合Gazebo仿真环境开发者能够低成本验证多传感器融合定位与导航算法。该改进版系统将建图结果转换为八叉树地图并集成Nav2导航栈实现从地图构建到路径规划的完整闭环。本文以实际项目为基础详解环境搭建、代码迁移、参数调优及常见问题排查为在仿真环境中实践SLAM与导航提供可复现的工程参考。 说实话拿到这个“基于LIO_SAM算法的仿真环境机器人导航系统”的压缩包时我第一反应是老玩家回归——LIO_SAM这套东西在ROS1时代几乎是做激光惯性SLAM的标配但到了ROS2 Humble Ubuntu 22.04的环境下能把它跑通并适配到Gazebo仿真里确实需要踩不少坑。这个项目说白了就是干三件事把LIO_SAM从ROS1迁移到ROS2在仿真环境里喂给它雷达和IMU数据完成建图再把生成的地图交给导航栈去规划路径。如果你正在折腾ROS2环境、想学多传感器融合定位或者手头没有真机但想跑通一套完整的SLAM导航流程这个项目非常适合拿来当蓝本。下面我就以这个项目为核心把从环境搭建到算法改造再到实操验证的完整链路拆开揉碎讲清楚。1. 项目整体设计与思路拆解1.1 为什么是LIO_SAM而不是Cartographer或FAST-LIO在聊这个项目的具体实现之前得先搞清楚一个核心问题仿真环境里做定位建图算法选型为什么是LIO_SAM我的判断是三个原因。第一LIO_SAM是典型的紧耦合激光惯性里程计方案它把激光雷达点云和IMU数据放进一个因子图框架里做联合优化相比纯激光的Gmapping、Cartographer它对雷达帧率低、运动畸变大的场景容忍度更高。仿真环境里Gazebo的雷达模型往往只有16线甚至更少点云稀疏这时候IMU能补上帧间运动的估计正好弥补雷达的先天不足。第二LIO_SAM自带回环检测和全局优化。仿真的场景虽然小但机器人来回巡航时会产生累计漂移没有回环检测的话地图会出现裂缝。LIO_SAM通过ISAM2增量优化实时处理回环因子地图的一致性明显比纯里程计方案好。第三LIO_SAM的代码结构相对清爽。整个系统拆成了featureExtraction、mapOptimization、imuPreintegration等几个节点每个节点负责一块独立任务配合ROS2的节点通信机制非常好做模块化改造。相比之下Cartographer那一大坨代码新手光读源码就要耗掉半条命。1.2 仿真环境与真机环境的差异决定了“改进版”的方向标题里特意标注了“适配仿真环境的改进版”这就说明原版LIO_SAM不能直接拿来用。仿真和真机有三大显著差异任何做过仿真转真机的人都能秒懂第一个差异是传感器数据特性。真实雷达有强度信息、有运动畸变而Gazebo里的雷达模型默认是理想化的点云分布均匀、没有噪声如果你把仿真雷达数据直接喂给LIO_SAM反而会因为“太干净”导致特征提取模块的阈值判断失效——真实数据里有噪声点需要过滤仿真数据里没有噪声但也会让一些边缘特征变得不典型。第二个差异是时间同步。真机上每个传感器都有自己的时间戳要用TimeSynchronizer做近似同步仿真里所有传感器都是同一个仿真时钟驱动时间戳天然对齐。但正因为太整齐了LIO_SAM的IMU预积分模块反而要小心如果参数里配错了时间基准在仿真里跑起来会感觉“哪里不对劲”但又说不出为什么通常是IMU预积分的时间补偿逻辑在仿真时钟下无法匹配。第三个差异就是最现实的代码依赖。原版LIO_SAM基于ROS1的roscpp、tf、pcl_ros要迁移到ROS2 Humble就必须改掉所有ROS1 API同时把GTSAM、PCL这些底层库换成ROS2对应版本。这个“改进版”项目最值的部分就是把上面的差异都处理掉了。从参数配置到launch文件再到消息类型改造用户拿到zip包后不需要从零造轮子改改路径就能跑。1.3 多传感器融合在这个项目里的实际含义热词里出现了“多传感器融合定位与导航”听起来很高大上实际在这个项目里就是三路数据的融合激光雷达点云做特征提取与帧间匹配IMU做帧间运动预测和畸变校正以及可选GPS仿真里一般用Gazebo的ground truth位置来模拟。这三路数据在LIO_SAM里通过因子图进行统一优化输出的是odom里程计、map全局一致的地图和位姿估计。我自己做仿真测试时的体会是仿真环境里最容易忽略的是IMU的bias。Gazebo的IMU插件默认没有bias和随机游走噪声但真实IMU一定有。所以这个项目如果要贴近真机效果得在Gazebo的IMU传感器配置里人为加一点噪声参数否则融出来的位姿过于理想反过来验证不了算法的鲁棒性。2. 环境搭建的完整记录Ubuntu 22.04 ROS2 Humble2.1 装机方案怎么选双系统、虚拟机还是WSL2热词里反复出现WSL2、ubuntu22.04安装教程、双系统这些内容说明很多人卡在第一步。我的建议分情况看如果你后续打算长时间做ROS2开发强烈建议双系统。Gazebo的物理引擎和RViz2的OpenGL渲染在双系统下能吃到完整的GPU性能跑仿真明显更流畅。WSL2默认虽然支持GPU加速但涉及USB设备直通、网络通信ROS2的DDS发现机制要广播组播时会出现莫名其妙的问题。虚拟机最不推荐虽然最安全但Gazebo的光线渲染和点云显示都会卡成PPT。如果你确实是Windows用户又不想动分区WSL2也可以但一定要用WSL2而不是WSL1同时把项目放在Linux文件系统/home/...而不是/mnt/c/...否则IO性能会拖垮编译。2.2 ROS2 Humble安装的核心步骤与环境变量这部分几乎所有教程都会讲但我要强调几个容易翻车的细节。官方推荐的安装方式是deb源安装核心命令大致是sudo apt update sudo apt install ros-humble-desktop这里有一个关键点ros-humble-desktop才带RViz2和Gazebo相关的可视化工具装ros-humble-ros-base的话后面跑rviz2会提示找不到命令我又踩过一次。装完记得配置环境变量echo source /opt/ros/humble/setup.bash ~/.bashrc source ~/.bashrc如果你之前装过ROS1 Noetic注意两个版本的setup.bash不要同时source。我自己就用两个终端分别开ROS1和ROS2的环境互不干扰。另外Ubuntu 22.04自带的Python版本是3.10ROS2 Humble是官方支持这个版本的不需要额外装Python但colcon必须自己装sudo apt install python3-colcon-common-extensions2.3 依赖包清单与安装顺序LIO_SAM在ROS2下编译除了核心的ROS2本体还依赖下面这些库缺失任何一个都会让编译中途报错依赖库用途安装命令GTSAM因子图优化LIO_SAM的核心后端sudo apt install libgtsam-devPCL点云处理sudo apt install libpcl-devEigen3线性代数sudo apt install libeigen3-devBoostC基础库sudo apt install libboost-all-devOpenCV特征可视化/图像处理sudo apt install libopencv-devnav2导航栈后续集成用sudo apt install ros-humble-nav2-bringuprobot_localization扩展卡尔曼滤波备选方案sudo apt install ros-humble-robot-localization安装顺序上先装GTSAM和PCL再装ROS2的导航相关包最后编译项目。GTSAM如果系统源里没有需要自行编译这个比较耗时建议早点开始。3. 核心代码改造与仿真适配细节3.1 ROS1到ROS2迁移LIO_SAM代码改动清单这是整个项目里技术含量最高的部分。原版LIO_SAM在ROS1下写得很漂亮但迁移到ROS2 Humble要动的地方非常多。我当时记录了一份改动清单现在拿出来作为参考首先是头文件和命名空间的替换。ROS1里用的是#include ros/ros.hROS2要改成#include rclcpp/rclcpp.hpp同时所有ros::NodeHandle变成rclcpp::Node的智能指针。这个改动是全局性的几乎每个文件都要碰。其次是消息类型的适配。一个典型例子是点云消息ROS1用sensor_msgs::PointCloud2ROS2里消息类型名不变但包名和导入方式变了PCL的转换函数要从pcl_conversions包调用。LIO_SAM里大量使用pcl::PointCloudPointType和sensor_msgs::PointCloud2的互转这里是最容易编译报错的地方。第三是TF库的改动。ROS1的tf::TransformBroadcaster在ROS2里变成了tf2_ros::TransformBroadcaster同时消息类型从tf::tfMessage变成了tf2_msgs::TFMessage。LIO_SAM的mapOptimization节点里有大量TF广播操作这里要逐一替换。第四是参数服务器。ROS1用ros::param::get()ROS2改成declare_parameter和get_parameter转换的时候注意带默认值避免参数文件里漏配导致节点崩溃。第五是launch文件。ROS1的.launch是XML格式ROS2是Python脚本LIO_SAM原本带的launch文件全部要重写。这一套改下来工作量大概在一周左右好在进阶项目已经帮我们做完了这也是它最大的价值。3.2 仿真环境的关键参数配置仿真里跑LIO_SAM比改代码更容易让人崩溃的是参数配置。这里我直接给出一套实测可行的参数看板雷达参数雷达线数用16线仿真即可太高反而影响实时性水平分辨率0.2度比较合适太小会导致点云过大LIO_SAM的处理压力飙升最大测距10米到20米仿真场景通常不会太大噪声给雷达加少量高斯噪声模拟真实情况建议sigma0.01IMU参数更新频率200Hz是LIO_SAM的推荐值低于100Hz时预积分效果明显变差加速度计噪声密度建议2e-3这个值接近真实IMU陀螺仪噪声密度建议1.7e-4避免仿真数据过于理想bias随机游走照实设置即可系统参数/use_sim_time必须设为true否则全部时间戳错乱地图坐标系map这个是LIO_SAM的输出框架雷达坐标系laser_link或velodyne要与URDF中的link名一致IMU坐标系imu_link这里有个坑LIO_SAM源代码里硬编码了imu的frame id必须改代码里的常量才能匹配3.3 改进版的几个亮点八叉树地图、Nav2导航与自动巡航这个项目既然是“导航系统”那建图只是前半场后半场就是导航。从热词中“八叉树地图导航”可以看出作者把LIO_SAM输出的点云地图转成了八叉树地图OctoMap再喂给Navigation2做路径规划。这个技术路线的思路非常聪明LIO_SAM输出的是稠密点云地图直接用做代价地图的话处理效率太低而且它不支持动态障碍物的概率更新。转成八叉树地图后每体素有占据概率和颜色信息天然适合做导航的障碍物层。具体实现上在拿到LIO_SAM生成的点云地图后启动octomap_server节点把点云转成八叉树地图。注意此时要用LIO_SAM的map坐标系作为全局坐标系同时把地图发布到/map话题。Nav2的全局代价地图直接订阅这个/map局部代价地图则用激光雷达的实时数据来更新。这套链路打通后你甚至可以在RViz2里点击目标点让机器人自己规划路径走过去。我实测下来由于LIO_SAM建的地图精度比较高导航时定位到目标点的偏差能控制在10厘米以内这个成绩在仿真里已经很能说明算法本身的融合质量了。3.4 RViz2可视化配置与常用插件跑通了算法不等于能看懂结果RViz2的可视化配置同样重要。LIO_SAM在RViz2里的典型显示项包括PointCloud2雷达点云 /velodyne_pointsMap全局地图 /mapPath轨迹 /odom_pathTF坐标变换树FPV第一人称视角用来检查建图过程这里我踩过的一个坑是RViz2的Global Options里Fixed Frame必须设为map否则地图会跟着机器人一起动看起来像闪屏。另一个坑是robot_description的URDF如果没加载RViz2里就看不到机器人模型只有一坨点云和轨迹线。插件方面如果想把点云的俯视图压缩成2D栅格图可以用pointcloud_to_laserscan把3D点云转成2D LaserScan这样Nav2的局部代价地图就能直接用。这个转换参数里要注意target_frame、transform_tolerance这些选项调的不对会导致2D扫描数据全被丢进无效区间。4. 实操过程与核心环节实现4.1 从零跑通整个系统的详细步骤假设你已经按上面的说明装好了Ubuntu 22.04、ROS2 Humble和所有依赖下面就是从我笔记本上直接抄下来的完整操作序列。这套流程我跑过不只一次顺序千万不要乱。第一步把zip包解压到工作空间mkdir -p ~/lio_sim_ws/src cd ~/lio_sim_ws/src unzip ~/下载/LIO_SAM_ROS2_Sim.zip cd ~/lio_sim_ws rosdep install --from-paths src --ignore-src -r -y colcon build --symlink-install对先跑rosdep install把缺失的依赖一次性补上。如果rosdep命令不存在先sudo apt install python3-rosdep然后sudo rosdep init rosdep update。第二步编译完成后source环境source ~/lio_sim_ws/install/setup.bash第三步启动仿真世界和机器人模型。这个项目应该自带Gazebo的world和URDF一般会写成一个launch文件ros2 launch lio_sim_ros2 gazebo_world.launch.py启动后你会看到Gazebo界面跳出来里面有一台带激光雷达和IMU的四轮差速机器人。这里注意Gazebo的启动有时候会非常慢因为要加载模型和物理引擎别急着关等它出现机器人模型。第四步启动LIO_SAM算法ros2 launch lio_sim_ros2 lio_sam.launch.py这个launch文件会启动LIO_SAM三个核心节点featureExtraction、imuPreintegration、mapOptimization并且会自动加载params.yaml。看到终端里刷出“Initialization finished”之类日志说明初始化完成。第五步启动RViz2ros2 run rviz2 rviz2然后手动添加显示项。这一步虽然烦但很关键建议先添加Map、PointCloud2、Path、TF四样对准frame后就能看到建图过程。第六步启动导航ros2 launch lio_sim_ros2 nav2.launch.pynav2启动后RViz2里会出现Nav2的规划面板这时就可以用2D Goal Pose发布目标点让机器人自己走过去了。4.2 关键节点运行日志解读跑仿真的时候终端日志是我们的眼睛。LIO_SAM几个核心节点的常见日志含义如下featureExtraction节点如果输出“time stamp of LiDAR point is earlier than the sweep”这是时间戳异常说明/use_sim_time没设对或者是点云消息的frame id跟参数文件里对不上。imuPreintegration节点经常输出“IMU message publish rate is too low”的警告这是IMU频率不够仿真里默认可能只有50Hz需要回Gazebo的IMU插件配置里把更新频率调到200Hz。mapOptimization节点如果长时间没有输出新关键帧说明特征太少或者运动太小机器人原地不动时确实不会加因子。掌握这些日志特征后就算你改动了某些参数也能快速定位到是哪个环节出了问题。4.3 仿真数据的采集与离线回放验证仿真环境最大的好处是可重复性。我拿到这个项目后最喜欢干的一件事就是用ros2 bag record把整个仿真过程录下来然后离线回放做算法验证ros2 bag record -a -o sim_2025_01录完之后重新启动LIO_SAM但这次不启动Gazebo改启动bag播放ros2 bag play sim_2025_01这样LIO_SAM的输入变成了已录制的话题数据参数怎么改都不会影响仿真本身。这个方法特别适合做参数调优因为一旦录好数据包你可以无限次试验直到把漂移调到一个可接受的范围。我做过的一个对比实验是同一个包、不同IMU噪声参数LIO_SAM的轨迹误差差了将近一倍。离线回放把这些差异量化的能力是纯在线调试很难做到的。5. 常见问题与排查技巧实录5.1 编译阶段的坑GTSAM版本、Eigen对齐和fmt冲突编译LIO_SAM是在这个项目里最容易劝退新手的一关。我整理出三个最高频的编译报错及其解决方法第一个GTSAM相关的链接错误。如果你在编译mapOptimization节点时看到一大堆“undefined reference to gtsam::...”说明系统里GTSAM要么没装要么版本太旧。LIO_SAM要求GTSAM 4.0.2以上Ubuntu 22.04的apt源里自带版本通常够用但如果你之前手动编译过旧版本赶紧把旧的卸载干净。第二个LIO_SAM用了Eigen的固定大小矩阵而Eigen 3.4默认开启了AVX/SSE加速在C17编译环境中容易出现“static assertion failed: YOU_MIXED_DIFFERENT_NUMERIC_TYPES”这类报错其实不是类型问题而是内存对齐的问题。解决方法是给C编译器加上-marchnative参数或者用-DEIGEN_DONT_ALIGN_STATICALLY重新编译。第三个ROS2 Humble自带的fmt版本和某些旧代码里引入的fmt版本冲突。这个比较隐蔽会报“undefined reference to fmt::v8::...”。LIO_SAM的ROS2移植版一般已经把fmt问题处理了如果你自己改代码时引入了fmt::print之类的调用就要注意系统里是否同时存在多个fmt版本。5.2 运行时点云错位、地图散乱问题仿真环境里跑LIO_SAM最常见的问题是rviz2里看到的点云地图有重影或者是一堆乱麻没有任何结构。这个通常是如下几个原因首选检查TF。用ros2 run tf2_tools view_frames生成tf树确认map → odom → base_link → velodyne/imu_link的链路是否完整。如果缺了odom到base_link的连接LIO_SAM的mapOptimization会认为雷达是凭空出现在世界中的建图必然失败。然后检查IMU数据是否真的被消费了。用ros2 topic echo /imu/data看消息频率和数值如果IMU数据恒定为零那LIO_SAM的预积分就变成了积分零运动估计全依赖雷达回环效果大打折扣。还有一个容易被忽略的是点云帧的畸变问题。仿真里若将雷达的帧率调得太低比如2Hz而机器人运动速度快LIO_SAM在做帧间匹配时误差会放大点云地图就散了。解决方案是把仿真雷达频率至少调到10Hz并且给机器人限速大概在0.5m/s左右这样建图效果最好。5.3 导航阶段目标点发布后机器人不动或乱走完成了建图导航阶段的问题也很有代表性。常见场景是在RViz2里点击2D Goal Pose机器人毫无反应。这种情况要检查Nav2的全局代价地图有没有收到/map数据。如果地图为空说明octomap_server没有正常发布或者TF中map到odom没有连上。我遇到过一次是octomap_server发布的点云话题名跟Nav2配置里的期望话题名不一致导致代价地图始终是空的。另一种情况是机器人走了一段后偏离路线甚至撞墙。这通常是代价地图的膨胀半径设置不合理仿真场景中墙壁比较薄膨胀半径太小机器人会贴墙走太大又找不到可通行路径。我的经验值是机器人直径的一半再加10厘米。5.4 仿真特有的一些奇怪现象与避坑建议经常有人问为什么LIO_SAM在仿真里表现完美一上真机就拉胯这个问题在仿真里跑这个项目时也要有心理准备。仿真的传感器数据太干净、噪声模型太简单、没有动态障碍物和光照变化这些因素会让算法参数过于乐观。我的建议是如果你打算在这个项目基础上做真机迁移从仿真阶段就开始给传感器增加噪声和模拟故障比如给雷达点云增加随机dropout、给IMU增加突发的bias跳动。这样在仿真里验证出的参数上真机后才不会一败涂地。另外仿真环境的物理模型对振动不敏感但真实电机一振动IMU数据就全是毛刺。在仿真阶段哪怕IMU的表现好到让人觉得“可以不用滤波了”导航链路里也别去掉任何鲁棒性组件比如扩展卡尔曼滤波、IMU低通滤波这些在真机上迟早用得到。6. 扩展思考除了LIO_SAM这套系统还能怎么发展聊完了具体的坑最后给这个项目做个价值延伸。这个zip包本质上是一个“ROS2 多传感器融合SLAM 导航”的教学级完整链路它的价值不在于LIO_SAM这一个算法而是把SLAM、导航、仿真的通用方法论串了起来。你可以尝试的扩展方向至少有三个把LIO_SAM替换成FAST-LIO2对比效果。FAST-LIO2在雷达退化环境、震动明显场景下往往更能打如果把它移植到这套仿真框架里可以做一个定位精度的横向对比。这种对比实验在论文和求职作品集里都是加分的。把单机器人扩展成多机器人协同。ROS2原生支持多机通信只要每个机器人分配不同的命名空间就能在一张仿真地图里让多个机器人同时建图、共享地图。这个玩法特别适合做编队控制、多机协同探索的入门。接入视觉传感器做视觉-激光-惯性三融合。热词里反复出现vins-fusion、rtabmap说明视觉SLAM的热度还很高。在仿真里给机器人加一个双目相机把LIO_SAM的里程计输出作为视觉SLAM的初始值再做一次松耦合或紧耦合融合就能玩出更花哨的融合框架。我个人的体会是这个项目的最大价值并不是代码本身而是它把“仿真环境里如何验证一个复杂机器人算法”这件事讲透了。很多人在真机上跑SLAM失败其实不是算法不行而是环境准备不足——没有可控的对比实验、没有标准化的测试流程。这套仿真系统的存在让你能在半小时内搭起一个可重复、可观测、可量化的测试环境这才是它最值钱的地方。最后再分享一个小技巧如果你在跑这个项目时发现某些参数不管怎么调都无效试着把params.yaml里的debug开关打开或者去看launch文件里有没有被强行覆盖参数的逻辑。我在很多资料包里都见过这种“隐藏参数吞噬器”——launch里的一段参数重映射会把文件中精心设置的参数全部覆盖掉。仿真调试就是这样80%的时间花在追查“我以为生效了但实际没生效”的配置上希望这篇文章能帮你把这80%的坑提前填平。本文还有配套的精品资源点击获取
返回列表