在机器人SLAM领域,从算法仿真到实机部署的“最后一公里”往往充满挑战。最近,我们团队基于Livox Mid360固态激光雷达,成功将经典的LIO-SAM算法部署到实车,并在华南理工大学五山校区3号楼前完成了实机建图与定位测试。与此同时,为了验证算法逻辑和进行安全、高效的开发迭代,一套完整的Gazebo仿真环境也必不可少。本文将系统性地拆解LIO-SAM + Mid360的全流程部署方案,涵盖实机环境搭建、驱动配置、算法适配、实机运行,以及Gazebo仿真环境构建与测试。无论你是正在研究激光SLAM的学生,还是希望将先进算法落地的工程师,这份从仿真到实机的完整笔记都将为你提供清晰的路径和可复现的代码。
1. 背景与核心概念:为什么选择LIO-SAM与Mid360?
在开始实操之前,有必要厘清几个核心概念,理解我们技术选型背后的原因。
LIO-SAM (Lidar Inertial Odometry via Smoothing and Mapping)是Tixiao Shan于2020年开源的一个紧耦合激光惯性里程计框架。它并非一个纯粹的“建图”算法,而是一个高频率、高精度的里程计。其核心优势在于:
- 紧耦合优化: 将激光雷达点云特征(面特征、角特征)与IMU预积分结果在一个因子图框架下进行联合优化,充分利用IMU的高频特性弥补激光雷达低帧率的不足,从而得到平滑、高频率的位姿估计。
- 回环检测与全局优化: 集成基于Scan-Context的回环检测模块,能够有效消除累积误差,实现大规模场景下的全局一致性地图。
- 工程友好: 代码结构清晰,基于ROS框架,易于二次开发和与其他模块(如导航)集成。
Livox Mid360是一款非重复扫描模式的固态激光雷达。与传统机械旋转雷达相比,它的优势在于:
- 高可靠性与长寿命: 无旋转部件,更耐冲击和振动。
- 独特的扫描图案: 非重复扫描模式使得随着时间推移,点云覆盖率会越来越高,对于特征提取尤其是平面特征非常有利。
- 内置IMU: Mid360本身集成了6轴IMU,这为LIO-SAM这类紧耦合激光惯性里程计提供了“开箱即用”的硬件基础,无需额外标定雷达与IMU的外参(需注意内置IMU的质量和同步问题)。
Gazebo仿真在机器人开发中扮演着“安全沙盒”的角色。在实机调试前,在仿真环境中:
- 验证算法逻辑: 确保算法流程正确,话题通信正常。
- 测试极端场景: 可以轻松模拟传感器失效、剧烈运动等难以在实机复现的场景。
- 加速开发迭代: 无需硬件准备和户外测试,效率极大提升。
- 成本与安全: 避免实机测试可能带来的设备损坏和安全风险。
因此,LIO-SAM + Mid360的组合,在理论上是性能与工程实践的优秀结合。而从Gazebo仿真到实机部署的路径,则是一套稳健的机器人系统开发方法论。
2. 环境准备与版本说明
我们的工作将在Ubuntu系统和ROS框架下进行。以下是经过验证的环境配置,强烈建议你保持一致以避免不必要的兼容性问题。
2.1 硬件与操作系统
- 实机平台: 搭载NVIDIA显卡的移动机器人/车辆。我们的测试平台为Intel NUC + NVIDIA Jetson Xavier NX。
- 仿真平台: 任何支持Ubuntu的PC或虚拟机均可。
- 操作系统:Ubuntu 20.04。这是ROS Noetic的官方支持系统,拥有最完善的生态。虽然Ubuntu 22.04/24.04也可行,但部分依赖(如PCL、GTSAM)的编译可能会遇到更多问题。
- ROS版本:ROS Noetic。这是最后一代支持Ubuntu 20.04的ROS1版本,LIO-SAM原生基于ROS1开发。
2.2 核心依赖安装
在Ubuntu 20.04上,首先安装ROS Noetic桌面完整版,然后安装必要的系统依赖和第三方库。
# 1. 配置ROS Noetic源并安装 sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list' sudo apt-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 sudo apt update sudo apt install ros-noetic-desktop-full # 2. 初始化rosdep sudo rosdep init rosdep update # 3. 安装系统依赖和工具 sudo apt install -y git cmake libeigen3-dev libboost-all-dev libsuitesparse-dev sudo apt install -y ros-noetic-navigation ros-noetic-robot-localization ros-noetic-robot-state-publisher sudo apt install -y libpcl-dev ros-noetic-pcl-ros ros-noetic-pcl-conversions ros-noetic-tf2-sensor-msgs # 4. 安装GTSAM (因子图优化库, LIO-SAM的核心) cd ~ git clone https://github.com/borglab/gtsam.git cd gtsam git checkout 4.1.1 # 使用与LIO-SAM兼容的版本 mkdir build && cd build cmake -DGTSAM_BUILD_WITH_MARCH_NATIVE=OFF .. # 关闭本地指令集优化以提高兼容性 sudo make install -j$(nproc)2.3 Livox SDK与ROS驱动安装
这是让Mid360在ROS中“说话”的关键。
# 1. 安装Livox SDK cd ~ git clone https://github.com/Livox-SDK/Livox-SDK.git cd Livox-SDK mkdir build && cd build cmake .. make sudo make install # 2. 安装Livox ROS Driver cd ~ git clone https://github.com/Livox-SDK/livox_ros_driver.git ws_livox/src cd ws_livox catkin_make -j$(nproc) source devel/setup.bash编译成功后,livox_ros_driver包会提供启动Mid360的launch文件。
3. LIO-SAM算法部署与Mid360适配
LIO-SAM原版代码主要适配Velodyne和Ouster雷达,需要对点云预处理部分进行修改以适配Mid360的坐标体系和点云格式。
3.1 下载与编译LIO-SAM
cd ~ mkdir -p lio_ws/src cd lio_ws/src git clone https://github.com/TixiaoShan/LIO-SAM.git cd .. catkin_make -j$(nproc)3.2 关键适配修改:点云预处理
Mid360发布的点云话题为/livox/lidar,消息类型为livox_ros_driver/CustomMsg,且雷达坐标系通常为livox_frame。我们需要将其转换为LIO-SAM所需的sensor_msgs/PointCloud2类型,并映射到正确的坐标系(如laser_link)。
方法一:使用livox_to_pointcloud2节点(推荐)我们可以编写一个简单的转换节点。在lio_ws/src下创建一个新包:
cd ~/lio_ws/src catkin_create_pkg mid360_adapter roscpp sensor_msgs pcl_ros livox_ros_driver在mid360_adapter/src下创建livox_converter.cpp:
#include <ros/ros.h> #include <livox_ros_driver/CustomMsg.h> #include <sensor_msgs/PointCloud2.h> #include <pcl/point_cloud.h> #include <pcl/point_types.h> #include <pcl_conversions/pcl_conversions.h> typedef pcl::PointXYZINormal PointType; pcl::PointCloud<PointType> cloud; ros::Publisher pubCloud; void livoxCallback(const livox_ros_driver::CustomMsg::ConstPtr& msg) { cloud.clear(); cloud.header.stamp = pcl_conversions::toPCL(msg->header).stamp; for (const auto& point : msg->points) { if (std::isfinite(point.x) && std::isfinite(point.y) && std::isfinite(point.z)) { PointType p; p.x = point.x; p.y = point.y; p.z = point.z; p.intensity = point.reflectivity; // 注意:Mid360的CustomMsg中没有直接的`time`字段,如果需要时间偏移,需额外处理 cloud.push_back(p); } } sensor_msgs::PointCloud2 output; pcl::toROSMsg(cloud, output); output.header.frame_id = "laser_link"; // 发布到LIO-SAM期望的坐标系 output.header.stamp = msg->header.stamp; pubCloud.publish(output); } int main(int argc, char** argv) { ros::init(argc, argv, "livox_converter"); ros::NodeHandle nh; ros::Subscriber sub = nh.subscribe<livox_ros_driver::CustomMsg>("/livox/lidar", 100, livoxCallback); pubCloud = nh.advertise<sensor_msgs::PointCloud2>("/points_raw", 100); // 发布到LIO-SAM订阅的话题 ros::spin(); return 0; }在CMakeLists.txt中添加:
add_executable(livox_converter src/livox_converter.cpp) target_link_libraries(livox_converter ${catkin_LIBRARIES} ${PCL_LIBRARIES}) add_dependencies(livox_converter ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})重新编译工作空间:cd ~/lio_ws && catkin_make。
方法二:修改LIO-SAM的imageProjection.cpp(进阶)直接修改LIO-SAM源码中的imageProjection.cpp的cloudHandler函数,使其能直接订阅并解析livox_ros_driver/CustomMsg。这种方法更彻底,但侵入性强。核心是添加一个针对CustomMsg的回调函数,将点数据提取并填充到LIO-SAM内部的cloudQueue中。由于代码较长,这里给出关键思路:复制原有的laserCloudHandler函数,修改参数类型,并在utility.h中声明新的回调函数。
3.3 配置LIO-SAM参数
修改~/lio_ws/src/LIO-SAM/config/params.yaml以适应Mid360和你的机器人。
# 常见需要修改的参数 pointCloudTopic: “/points_raw” # 改为我们转换后的话题 imuTopic: “/imu/data” # Mid360 IMU话题,通常是 /livox/imu lidarFrame: “laser_link” # 激光雷达坐标系 baselinkFrame: “base_link” odometryFrame: “odom” mapFrame: “map” # 传感器设置 sensor: livox # 雷达类型设为livox N_SCAN: 1 # Livox Mid360可视为单线(虽然是非重复面扫描) Horizon_SCAN: 4000 # 根据点云密度调整 timeField: offset_time # 对于CustomMsg,可能需要设置为 ‘offset_time’ 或 ‘none’ # 外参(关键!) # 如果Mid360的IMU与雷达中心不重合,或机器人有外置IMU,需要填写准确的变换矩阵。 # 这里假设雷达和IMU坐标系重合(对于Mid360内置IMU,这是一个近似)。 extrinsicTrans: [0.0, 0.0, 0.0] extrinsicRot: [1, 0, 0, 0, 1, 0, 0, 0, 1] # 单位矩阵 extrinsicRPY: [0.0, 0.0, 0.0] # 地图和优化参数(可根据场景调整) mapResolution: 0.4特别注意:extrinsicRot是旋转矩阵的行优先展开。如果雷达和IMU之间存在安装角度,必须通过标定获取准确的外参,否则会严重影响精度。
4. 实机部署与华南理工大学现场测试
4.1 实机系统启动流程
在实机机器人上,我们需要按顺序启动各个节点,形成一个完整的SLAM系统。
启动Mid360驱动: 连接Mid360雷达到机器人主机,并启动驱动节点。
source ~/ws_livox/devel/setup.bash roslaunch livox_ros_driver livox_lidar.launch启动后,使用
rostopic list应能看到/livox/lidar和/livox/imu话题。启动点云转换节点: 将CustomMsg转换为PointCloud2。
source ~/lio_ws/devel/setup.bash rosrun mid360_adapter livox_converter此时,
/points_raw话题应有数据。启动LIO-SAM: 这是核心算法节点。
source ~/lio_ws/devel/setup.bash roslaunch lio_sam run.launch启动后,LIO-SAM会开始接收点云和IMU数据,并输出高频的
odometry话题和map话题。启动可视化(RVIZ): 用于实时查看建图效果和机器人轨迹。
roslaunch lio_sam rviz.launch在RVIZ中,添加
PointCloud2显示,话题选择/map或/cloud_registered;添加Path显示,话题选择/odometry_path。
4.2 华南理工大学五山校区3号楼前测试要点
我们在华工3号楼前的广场及周边道路进行了测试。该场景包含:
- 开阔广场: 特征相对较少,考验IMU和里程计的稳定性。
- 林荫道与建筑: 提供丰富的结构化特征(墙面、柱子、树木)。
- 行人与非机动车: 动态物体对点云匹配是干扰。
测试过程与观察:
- 初始化: 在开阔地缓慢旋转机器人一周,帮助算法初始化并构建初始地图。
- 匀速行驶: 控制机器人沿道路匀速行驶,在RVIZ中观察地图的拼接质量和轨迹的平滑度。
- 回环测试: 控制机器人绕行一个闭合环路(如绕楼一周),观察回环检测是否触发,以及触发后地图是否被正确修正(明显的“拉直”效果)。
- 动态物体处理: 观察行人穿过时,地图中是否会留下“鬼影”。LIO-SAM基于特征匹配,对动态物体有一定鲁棒性,但快速移动的物体仍可能产生短暂干扰。
实机运行效果: 在场景特征丰富的情况下,LIO-SAM+Mid360能够稳定输出高频率、低漂移的里程计,构建的栅格地图或点云地图清晰,建筑轮廓分明。回环检测有效,能够在大范围运行后校正累积误差。
5. Gazebo仿真环境搭建与测试
仿真环境允许我们在没有硬件的情况下验证整个算法流水线。我们将创建一个带激光雷达和IMU传感器的机器人模型,并在Gazebo中运行。
5.1 创建仿真机器人URDF模型
在lio_ws/src下创建一个新的功能包用于仿真:
cd ~/lio_ws/src catkin_create_pkg lio_sam_gazebo rospy urdf xacro gazebo_ros mkdir -p lio_sam_gazebo/urdf lio_sam_gazebo/launch lio_sam_gazebo/worlds在urdf文件夹下创建mobile_robot.xacro文件,定义一个简单的差分驱动机器人,并搭载一个仿Mid360的激光雷达和IMU传感器。
<?xml version="1.0"?> <robot name="mobile_robot" xmlns:xacro="http://www.ros.org/wiki/xacro"> <!-- 基础底盘 --> <link name="base_footprint"/> <link name="base_link"> <visual> <geometry> <box size="0.6 0.4 0.2"/> </geometry> </visual> <collision> <geometry> <box size="0.6 0.4 0.2"/> </geometry> </collision> <inertial> <mass value="10"/> <inertia ixx="0.4" ixy="0" ixz="0" iyy="0.2" iyz="0" izz="0.4"/> </inertial> </link> <joint name="base_footprint_joint" type="fixed"> <parent link="base_footprint"/> <child link="base_link"/> </joint> <!-- 激光雷达(模拟Mid360) --> <link name="laser_link"> <visual> <geometry> <cylinder length="0.05" radius="0.05"/> </geometry> </visual> <inertial> <mass value="0.1"/> <inertia ixx="0.0001" ixy="0" ixz="0" iyy="0.0001" iyz="0" izz="0.0001"/> </inertial> </link> <joint name="laser_joint" type="fixed"> <parent link="base_link"/> <child link="laser_link"/> <origin xyz="0.2 0 0.15" rpy="0 0 0"/> </joint> <!-- Gazebo插件:模拟激光雷达 --> <gazebo reference="laser_link"> <sensor type="ray" name="lidar_sensor"> <pose>0 0 0 0 0 0</pose> <visualize>false</visualize> <update_rate>10</update_rate> <!-- 仿真频率 --> <ray> <scan> <horizontal> <samples>4000</samples> <!-- 模拟Mid360点云密度 --> <resolution>1</resolution> <min_angle>-3.14159</min_angle> <max_angle>3.14159</max_angle> </horizontal> <vertical> <samples>1</samples> <!-- 模拟固态雷达的非重复扫描,这里简化为单线 --> <resolution>1</resolution> <min_angle>0</min_angle> <max_angle>0</max_angle> </vertical> </scan> <range> <min>0.1</min> <max>50.0</max> <resolution>0.01</resolution> </range> <noise> <type>gaussian</type> <mean>0.0</mean> <stddev>0.01</stddev> </noise> </ray> <plugin name="gazebo_ros_lidar_controller" filename="libgazebo_ros_ray_sensor.so"> <ros> <namespace>/</namespace> <remapping>~/out:=scan</remapping> <!-- 发布到/scan话题 --> </ros> <output_type>sensor_msgs/LaserScan</output_type> <frame_name>laser_link</frame_name> </plugin> </sensor> </gazebo> <!-- Gazebo插件:模拟IMU --> <gazebo reference="base_link"> <sensor type="imu" name="imu_sensor"> <always_on>true</always_on> <update_rate>200</update_rate> <visualize>true</visualize> <topic>/imu/data</topic> <plugin filename="libgazebo_ros_imu_sensor.so" name="imu_plugin"> <topicName>/imu/data</topicName> <bodyName>base_link</bodyName> <updateRateHZ>200.0</updateRateHZ> <gaussianNoise>0.000001</gaussianNoise> <xyzOffset>0 0 0</xyzOffset> <rpyOffset>0 0 0</rpyOffset> <frameName>base_link</frameName> <initialOrientationAsReference>false</initialOrientationAsReference> </plugin> </sensor> </gazebo> <!-- 差分驱动控制器 --> <gazebo> <plugin name="differential_drive_controller" filename="libgazebo_ros_diff_drive.so"> <commandTopic>cmd_vel</commandTopic> <odometryTopic>odom</odometryTopic> <odometryFrame>odom</odometryFrame> <robotBaseFrame>base_footprint</robotBaseFrame> <publishOdomTF>true</publishOdomTF> <publishWheelTF>false</publishWheelTF> <publishTf>true</publishTf> <wheelSeparation>0.4</wheelSeparation> <wheelDiameter>0.1</wheelDiameter> <torque>10</torque> <updateRate>30.0</updateRate> </plugin> </gazebo> </robot>5.2 创建Gazebo世界与启动文件
在worlds文件夹下创建一个简单的世界文件test.world,可以添加一些墙壁和障碍物。在launch文件夹下创建simulation.launch:
<launch> <!-- 启动Gazebo世界 --> <include file="$(find gazebo_ros)/launch/empty_world.launch"> <arg name="world_name" value="$(find lio_sam_gazebo)/worlds/test.world"/> <arg name="paused" value="false"/> <arg name="use_sim_time" value="true"/> <arg name="gui" value="true"/> <arg name="headless" value="false"/> <arg name="debug" value="false"/> </include> <!-- 将机器人模型加载到参数服务器 --> <param name="robot_description" command="$(find xacro)/xacro '$(find lio_sam_gazebo)/urdf/mobile_robot.xacro'" /> <!-- 在Gazebo中生成机器人 --> <node name="spawn_urdf" pkg="gazebo_ros" type="spawn_model" args="-param robot_description -urdf -model mobile_robot -x 0 -y 0 -z 0.1" /> <!-- 发布机器人关节状态 --> <node name="robot_state_publisher" pkg="robot_state_publisher" type="robot_state_publisher" output="screen"> <param name="publish_frequency" type="double" value="50.0" /> </node> <!-- 启动LIO-SAM(需要先对仿真点云进行转换) --> <!-- 仿真激光雷达发布的是LaserScan,需要转换为PointCloud2 --> <node pkg="laser_scan_matcher" type="point_cloud_converter" name="point_cloud_converter"> <remap from="scan" to="/scan"/> <remap from="cloud" to="/points_raw"/> </node> <!-- 启动LIO-SAM --> <include file="$(find lio_sam)/launch/run.launch"> <!-- 需要根据仿真传感器话题调整params.yaml中的话题名 --> <!-- 例如,将pointCloudTopic改为/points_raw, imuTopic改为/imu/data --> </include> <!-- 启动RVIZ --> <node pkg="rviz" type="rviz" name="rviz" args="-d $(find lio_sam)/config/mapping.rviz" /> </launch>注意: 仿真中的激光雷达是sensor_msgs/LaserScan类型,而LIO-SAM需要sensor_msgs/PointCloud2。我们需要一个转换节点,如laser_scan_matcher包中的point_cloud_converter,或者使用laser_geometry库编写一个简单的转换节点。
5.3 仿真环境测试
- 启动仿真:
cd ~/lio_ws source devel/setup.bash roslaunch lio_sam_gazebo simulation.launch - 控制机器人运动: 打开一个新终端,使用键盘控制机器人移动,观察建图过程。
rosrun teleop_twist_keyboard teleop_twist_keyboard.py - 观察与调试: 在RVIZ中,你应该能看到仿真激光雷达的点云被转换为
PointCloud2后输入LIO-SAM,并实时输出地图和轨迹。由于仿真环境传感器数据纯净且无噪声,建图效果通常会非常理想。这验证了算法流水线的正确性。
6. 常见问题与排查思路
在实机部署和仿真过程中,你可能会遇到以下典型问题:
| 问题现象 | 可能原因 | 排查思路与解决方案 |
|---|---|---|
| 启动LIO-SAM后无点云显示 | 1. 话题名称不匹配。 2. 点云转换节点未运行或出错。 3. 雷达驱动未启动。 | 1. 使用rostopic list和rostopic echo /points_raw检查话题和数据。2. 检查转换节点的日志 rosnode info /livox_converter。3. 确认 /livox/lidar话题存在且有点云数据。 |
| 地图严重漂移或发散 | 1. 雷达-IMU外参不准确。 2. IMU数据质量差或话题频率低。 3. params.yaml中运动模型参数不合适。 | 1.重新标定外参,这是影响精度的最关键因素。 2. 使用 rostopic hz /imu/data检查IMU频率,应高于100Hz。3. 调整 params.yaml中的imuAccNoise,imuGyrNoise等噪声参数。 |
| 回环检测不触发 | 1. Scan-Context描述子参数不合适。 2. 场景特征太少,回环检测失败。 3. 位姿估计误差太大,候选帧搜索失败。 | 1. 调整params.yaml中loopClosure相关参数,如distanceThres,scanDistance。2. 尝试在更具辨识度的场景下测试。 3. 确保前端里程计精度,可先在小范围内测试回环。 |
| Gazebo仿真中LIO-SAM不更新地图 | 1. 仿真点云未正确转换为PointCloud2。 2. 仿真时间 /clock话题未启用或不同步。 | 1. 检查point_cloud_converter节点是否正常运行,输出话题是否为/points_raw。2. 在 simulation.launch中确保use_sim_time为true,并在LIO-SAM的launch文件中也设置<param name="use_sim_time" value="true"/>。 |
| 编译GTSAM或LIO-SAM时出错 | 1. 依赖库版本冲突。 2. 编译器版本问题。 3. 内存不足。 | 1. 严格按照本文的版本(Ubuntu 20.04, GTSAM 4.1.1)。 2. 尝试使用 catkin_make -j1单线程编译定位错误。3. 检查系统内存,编译GTSAM可能需要较大内存。 |
| Mid360点云在RVIZ中显示异常(如全红) | 点云强度值范围异常。 | Livox雷达的反射率 (reflectivity) 范围可能与RVIZ默认的强度色彩映射不匹配。在RVIZ的PointCloud2显示属性中,将Color Transformer改为AxisColor或FlatColor,或者调整Autocompute Intensity Bounds。 |
7. 最佳实践与工程建议
将研究型算法稳定地部署于实机机器人,需要遵循一定的工程规范。
外参标定是生命线: 对于LIO-SAM这类紧耦合算法,雷达与IMU之间的变换矩阵 (
extrinsicTrans和extrinsicRot) 必须精确。建议使用开源工具如lidar_imu_calib或Kalibr进行严格标定。标定场地应避免振动和磁干扰。时间同步与传感器诊断: 确保雷达点云和IMU数据的时间戳是同步的。Mid360驱动通常能提供硬件时间同步。使用
rosbag record录制数据包,然后用rqt_bag检查不同话题的时间戳对齐情况。定期检查IMU数据的零偏和噪声。参数调优循序渐进: 不要一次性修改大量参数。建议的调优顺序:
- 基础运行: 确保外参正确,算法能跑起来。
- 前端里程计: 调整
featureExtraction和mapOptmization中的cornerThreshold,surfThreshold等特征提取参数,使特征点数量适中、分布合理。 - 后端优化与回环: 调整
loopClosure参数,在保证实时性的前提下提高回环检测的召回率和准确率。 - 性能与鲁棒性: 调整
voxelFilter体素滤波参数以平衡地图精度和计算负载。
仿真与实机结合迭代: 将仿真环境作为算法逻辑的“单元测试”环境。任何大的代码修改或参数调整,先在仿真中验证基本功能,再上实机测试性能。可以录制实机的ROS Bag数据,在仿真环境中进行“数据回放”测试,这能极大提高调试效率。
系统集成与日志: 将LIO-SAM作为机器人导航系统的一个节点。其输出的
odometry话题可以提供给robot_localization包进行多传感器融合。务必为关键节点(如LIO-SAM、驱动、转换节点)配置roslaunch中的output=”screen”或rosout日志,并建立日志归档机制,便于问题回溯。安全与容错: 实机运行时,务必有紧急停止机制。LIO-SAM可能因剧烈运动、特征丢失等原因发生短暂失效,导致位姿跳变。应在下游节点(如控制器)中增加对里程计质量的判断和容错逻辑,例如检查协方差或使用健康状态话题。
从Gazebo中的虚拟传感器到华南理工大学校园里的真实Mid360雷达,这条部署路径打通了机器人算法从仿真验证到实地应用的闭环。通过解决驱动适配、坐标转换、外参标定、参数调优等一系列实际问题,我们不仅让LIO-SAM算法跑了起来,更深刻理解了激光惯性里程计系统各模块间的耦合关系。希望这份详尽的记录能帮助你少走弯路,更快地将优秀的SLAM算法部署到你自己的机器人平台上。下一步,你可以尝试集成视觉传感器进行VIL-SAM,或者将LIO-SAM的输出与导航栈(如MoveBase)结合,实现真正的自主导航。