
拿到 MID360 的第一天我本来以为插上网线、装个驱动、launch 一下 FAST-LIO 就能直接建图结果从晚上八点弄到凌晨两点才看到第一幅点云图。后面真正上手之后又陆续遇到漂移、保存地图打不开、走廊里跑两圈就分层这些事一步一步全记录了下来。这篇文章就是一份 MID360 配 FAST-LIO 的功能笔记覆盖硬件怎么接、驱动怎么编、mid360.yaml 每一行参数到底在干嘛、从启动到出图的全流程以及我实测中踩过的坑和完整的排障链路。目标读者是手头有或准备买 MID360、想在 ROS 环境里用 FAST-LIO 快速建图的工程师也适合刚入坑固态激光雷达 SLAM 的同学——这篇笔记的定位不是论文复现而是照着能跑通、跑通后能调优。1. 先摸清 MID360 的脾气它和机械雷达根本不是同一类东西1.1 一张表把关键指标看明白MID360 官方标称的主要参数我整理成了一张表后面讲参数和排障都要反复用到这些数字项目参数对建图的意义水平视场角360°单台即可覆盖全周不用像多线雷达那样纠结安装朝向垂直视场角59°-7° ~ 52°仰角 52° 意味着室内贴墙、室外看树冠都够用测距能力40m10%反射率200m80%反射率多数室内外场景够用但黑色物体、深色地毯会明显缩短有效距离点频200,000 pts/s等效 10Hz 扫描每帧约两万点对 FAST-LIO 来说非常充裕扫描方式非重复扫描这是和机械雷达最大的分野后面单独说内置 IMUBMI088200Hz省掉外置 IMU 的接线和标定也降低了对安装刚性的要求接口以太网数据链路简单但也引入 IP、防火墙这些新坑防护等级IP67雨天户外实测没问题但镜头脏了必须及时擦补充说明一下测距能力那个 40m10% 的约束。10% 反射率对应的就是黑色哑光表面、深色衣服这类目标看起来没多远点云信噪比已经很低了。实际建图时如果你发现远处墙体断断续续先别怀疑算法大概率是材料反射率不够。我在园区里测过深灰色墙面有效匹配距离经常只剩下二三十米这不是 MID360 的个体问题是这类近红外激光雷达的共性。1.2 非重复扫描这件事理解错了会处处踩坑机械雷达是固定角分辨率一圈一圈扫每一帧点云结构很规整但也意味着每帧覆盖的区域基本固定想加密某个局部只能靠多帧叠加。MID360 的非重复扫描图案每次都不一样短时间内点云看着很乱、很稀疏但只要让雷达在一个位置停留几秒钟覆盖密度会迅速上升。这个特性对 SLAM 是双刃剑。好处是匹配时每一帧都是一个新的采样图案不太会出现机械雷达那种相邻帧点云高度重合、有效信息少的情况坏处是如果你的算法假设点云按线束组织很多传统 LO 都这么假设直接套上去就会崩。FAST-LIO 把点云当成离散特征点处理不依赖线束结构刚好和 MID360 的脾性对上。这也是为什么MID360 配 FAST-LIO几乎成了这类固态雷达的默认组合。另外还有一个容易忽略的点非重复扫描在动态场景里会留下残影。比如人从雷达前面走过激光点是不同时刻采到的运动物体会在帧内被拉出一条淡痕反映到地图上就是一层噪点。后面参数部分我会给一个缓解思路。还有一个连带影响是你拿同一台 MID360 去跑那种假设每帧点云均匀覆盖的传统配准算法效果往往很差这不是算法烂是数据形态不匹配。1.3 FAST-LIO 的融合逻辑一句话讲清楚FAST-LIO 的核心是IMU 负责猜激光负责改。IMU 以 200Hz 做状态预测把姿态、速度、位置往前推激光点云到了之后用当前预测把每个点做运动补偿再和地图匹配出残差通过迭代扩展卡尔曼滤波IEKF修正状态。因为每个点都有自己的时间戳运动补偿是逐点做的这正好消化了非重复扫描每帧点云时间跨度大的问题。FAST-LIO2 相比第一版最大的变化是用 ikd-Tree 做增量地图不再需要固定分辨率体素栅格图。收益是内存随场景增长更平滑、大场景跑起来更顺对 MID360 这种每帧两万点的输入CPU 占用也能压得住。如果你看到的仓库名是 FAST_LIO默认就是第二版算法。简单类比第一版是拿一张固定密度的渔网去捞鱼第二版是手里拿着一棵不断生长的树鱼往哪游树就往哪长场景再大也不至于网格爆炸。2. 环境搭建和驱动编译三处最容易被绊倒的地方2.1 硬件连接网线只走数据供电别指望 PoE先把物理链路讲清楚。MID360 的配套线缆里电源线和网线是分开的12V 电源接到供电端子网线RJ45接到电脑或交换机。很多第一次用的人会下意识认为网线都插上了用电应该也行吧然后发现设备狂闪但程序找不到——因为网口只走数据必须单独供电。网络配置是第一个大坑。Livox 系列雷达默认在 192.168.1.x 网段电脑网卡要配成同网段的静态 IP比如 192.168.1.50掩码 255.255.255.0。我自己的习惯是先把 Livox Viewer 2 打开在软件里能看到雷达型号和 IP确认通信正常之后再去跑 ROS 驱动。这一步能帮你把硬件问题和软件问题快速切干净——如果 Viewer 里都看不到设备就别急着怪驱动代码。还需要提醒一句如果电脑开着 ufw 防火墙Livox 的设备发现广播很可能会被拦表现是驱动 launch 之后日志里一直报找不到设备。排查时可以先sudo ufw disable试试确认是防火墙再针对性放行不必长期关着。另外尽量不要在虚拟机里直接桥接雷达USB 转以太网适配器在虚拟机里的广播行为很不稳定我在这上面浪费过一整个下午后来换到物理机一次就通了。2.2 livox_ros_driver2 的分支陷阱ROS1 环境别用默认分支拿到驱动仓库之后第一件事不是 catkin_make而是先看分支。livox_ros_driver2 默认分支面向 ROS2ROS1 环境要切到 ros1 分支。我见过太多人默认分支一把梭最后 CMake 报一堆找不到 rclcpp 之类头文件的错误实际上就是分支不对。推荐的做法ROS1 Noetic 为例cd ~/catkin_ws/src git clone https://github.com/Livox-SDK/livox_ros_driver2.git cd livox_ros_driver2 git branch -a # 看一眼有哪些分支 git checkout ros1 cd ~/catkin_ws catkin_make source devel/setup.bash编译完成之后先启动驱动验证roslaunch livox_ros_driver2 msg_MID360.launch如果一切正常你应该能在rostopic list里看到/livox/lidar和/livox/imu。再用两个命令确认数据频率rostopic hz /livox/lidar rostopic hz /livox/imulidar 稳定在 10Hz 左右、imu 在 200Hz 左右说明驱动这关过了。如果 hz 显示为 0回到 2.1 的 IP 配置继续查。特别提醒msg_MID360.launch 里有个 xfer_format 参数保持默认的 0输出 livox 自定义消息不要为了图方便改成 PointCloud2——FAST-LIO 的 lidar_type1 依赖的是自定义消息类型一换话题虽然还在但 FAST-LIO 根本解析不出来。2.3 FAST-LIO2 的编译子模块是必须的FAST-LIO2 依赖 ikd-Tree 这个子模块直接 clone 主仓库不会带下来必须手动更新cd ~/catkin_ws/src git clone https://github.com/hku-mars/FAST_LIO.git cd FAST_LIO git submodule update --init --recursive cd ~/catkin_ws catkin_make如果你的环境已经装了完整的 ROS-desktopPCL 和 Eigen 这些依赖基本是齐的。编译时如果报 Eigen 版本相关错误多半是系统里同时存在多个 Eigen 版本导致 CMake 找错头文件路径把/usr/include/eigen3确认一下就行。编译通过后启动文件在 FAST_LIO 的 launch 目录下mid360 对应的就是 mapping_mid360.launch。到这一步驱动和算法都齐了先别急着跑下一章的配置文件值得花十分钟逐行看一遍后面所有调优都从这里面来。3. mid360.yaml 逐项拆解每一行都值得看懂再改FAST-LIO 的 mid360 配置在 FAST_LIO/config/mid360.yaml 里。我按功能块拆开说。3.1 common 块话题名与时间同步开关common: lid_topic: /livox/lidar imu_topic: /livox/imu time_sync_en: false time_offset: 0.0话题名必须和驱动发出来的完全一致最常见的驱动有数据但算法没反应就是这里没对齐。time_sync_en 这个开关注释里也写了只在真的有时钟同步时才打开。MID360 内置 IMU 和激光走同一条数据链路驱动给两者打的时间戳来自同一时钟域所以保持 false 就好。如果你换成了外置 IMU 或者搞了多机分布式采集时间基准不统一才需要考虑 PTP 或 GPS 同步否则强行打开反而是灾难。3.2 preprocess 块三个参数控制着点云质量preprocess: lidar_type: 1 scan_line: 6 blind: 2 point_filter_num: 10lidar_type1 表示 livox 系列和驱动消息类型配套别乱改。scan_line 对 MID360 这种非重复扫描没有实际线束意义保持默认即可。blind 是近处滤除距离单位米。雷达安装位置附近通常会被自身支架、线缆、桌面干扰设成 2 能省掉大量脏点。如果你的应用场景需要近距离避障可以降到 0.5但要做好近处噪点变多的心理准备。point_filter_num 的含义是每隔 N 个点取一个数值越大参与计算的点越少、越省 CPU。MID360 每帧两万点设成 10 就是每帧两千点参与匹配对多数场景已经够稳想更快就加大想更细腻就减小。我自己的经验是 10~20 这个区间最平衡低于 3 只是徒增 CPU 占用精度提升肉眼看不出来。这里插一句我在实际使用中的体会point_filter_num 别一开始就取 1 或者 2觉得点越多越准。FAST-LIO 的匹配是点到地图的距离残差点太多反而会把近处重复点、噪点也全部纳入优化迭代次数变多、计算时间变长精度却没有本质提升。先用默认值跑通再根据 CPU 余量一点点往下调这才是正常节奏。3.3 mapping 块外参和噪声协方差别乱动但要懂mapping: acc_cov: 0.1 gyr_cov: 0.1 b_acc_cov: 0.0001 b_gyr_cov: 0.0001 fov_degree: 360 det_range: 50.0 extrinsic_est_en: false extrinsic_R: [1, 0, 0, 0, 1, 0, 0, 0, 1] extrinsic_T: [0, 0, 0]先说外参。FAST-LIO 里的 extrinsic_R/extrinsic_T 指的是 IMU 到激光坐标系的外参。因为 MID360 内置 IMU出厂时激光和 IMU 已经刚性固定这两项填单位阵和零向量是合理的。这里容易混的一个概念是如果你把 MID360 装到机器人上雷达相对机器人底座的那个位姿是 TF 树里的事不要填到 FAST-LIO 里来两者作用域完全不同。acc_cov/gyr_cov 是 IMU 观测噪声b_acc_cov/b_gyr_cov 是 IMU 零偏随机游走。默认值对 MID360 内置 BMI088 是合理的一般不用动。只有当你在强振动平台上建图、或者明显感觉姿态抖动时可以尝试把 gyr_cov 调到 0.2~0.3让滤波器更信任激光修正。extrinsic_est_en 在线估计外参这个开关我建议保持 false在线标定在某些场景能救急但也可能把已经收敛的状态带歪新手上路先关着。det_range 是有效建图距离。MID360 硬件测距能力 40m10%但实际建图时把 det_range 拉到 100 反而会让空旷场地里的远端噪点参与匹配。室内建议 30~40室外开阔地可以设 60~80后面我会给一套可直接抄的参数表。3.4 室内外两套可直接抄的参数参数室内地下车库、办公室室外开阔园区、工地blind24point_filter_num1020det_range3060fov_degree360360time_sync_enfalsefalse这套参数是我实测过比较稳的起点。先用它跑一遍拿到基准结果再根据你自己的传感器安装高度、环境材料微调而不是一上来就追求最优参数。所谓最优参数一定是跟场景强相关的照抄任何人的参数都不如自己跑一遍对比来得靠谱。4. 建图实操从启动到拿到一份干净的地图4.1 标准启动顺序驱动、算法、可视化我习惯开三个终端顺序不能错。终端 1启动驱动source devel/setup.bash roslaunch livox_ros_driver2 msg_MID360.launch终端 2启动 FAST-LIOsource devel/setup.bash roslaunch fast_lio mapping_mid360.launch终端 3启动可视化source devel/setup.bash rosrun rviz rvizRViz 里把 Fixed Frame 设成 camera_init然后添加话题。FAST-LIO 实时发布的关键话题有/cloud_registered配准后的全局点云、/Odometry里程计、/path轨迹。把这三个都加上建图过程就能看得明明白白。如果只想快速验收加一个 /cloud_registered 就够轨迹话题是用来判断漂移和跳变的。有个容易被忽略的细节FAST-LIO 的初始化需要 IMU 数据所以一定是先起驱动、确认 imu 有数据再起算法。反过来起的话算法启动时会有一段听不到 IMU的空窗期偶尔会导致初始姿态不对开局就飘。别小看这个顺序问题我在不同的机器上遇到过至少三次明明是同样的代码为什么这次开局就崩最后都是因为手快先把算法拉起来了。4.2 初始化阶段的操作手感算法启动后先让传感器静止 3~5 秒。这一步不是玄学是让滤波器把初始姿态和陀螺零偏收敛掉。静止状态下 rviz 里的 /cloud_registered 应该稳定不动/path 只在原地抖动数值在厘米级。然后开始缓慢移动。刚开始的 10~20 秒是滤波器最容易崩的时候尽量别做快速旋转或剧烈晃动。等点云与地图的贴合肉眼可见地稳定了再恢复正常走动速度。如果是在机器人上同样道理先原地静止几秒再缓慢起步。我个人的习惯是采集过程中偶尔停顿一下比如每个房间门口停 1~2 秒。这样地图在关键转角处会更干净也给后续可能的闭环处理留下更多可靠的约束。这个技巧在之后做重定位时尤其有用转角处的密集点云就是天然的路标。4.3 地图保存按 s 键之前先把人稳住跑完一圈回到起点附近先让传感器静止几秒然后再保存——最后这段静止点云会让地图收尾更干净。保存方式是在运行 FAST-LIO 的终端里按下键盘的 s 键并回车。程序会把全局地图写到 PCD 目录下文件一般以 scans_时间戳.pcd 命名。如果按 s 没反应检查一下配置里 pcd_save_en 是不是 true。拿到 pcd 文件之后我推荐用 CloudCompare 或者 pcl_viewer 检查。CloudCompare 可以直接按 intensity 上色能一眼看出哪些地方点云稀疏、哪些地方有残影。如果你后续要把地图转成其他格式比如 las、plyCloudCompare 导出也很方便。一个小提醒长时间建图产生的 pcd 文件可能非常大几百 MB 甚至上 GB。保存前想清楚你只需要全局地图还是也要中间帧如果只是做导航用保存后可以在 CloudCompare 里抽稀一遍再导出后面处理 octomap 会快很多。我见过同事直接拿 1.2GB 的 pcd 去跑 octomap_server内存直接爆掉其实抽稀到 20% 对导航完全够用。5. 翻车日志四个高频问题的完整排查链路5.1 现象一雷达数据有FAST-LIO 却一动不动这个现象最常见排查链路一般是先看rostopic list确认 /livox/lidar 和 /livox/imu 都在。再看rostopic hz /livox/lidar如果频率为 0要么 IP 配置不对要么 xfer_format 被改过。如果频率正常用rostopic echo /livox/lidar -n 1看消息类型确认是 livox_ros_driver2/CustomMsg。最后检查 FAST-LIO 配置里 lid_topic/imu_topic 是不是和驱动话题完全一致包括斜杠和大小写。这套链路走完90% 的没反应都能定位。剩下 10% 基本是启动顺序反了按 4.1 的顺序重启一遍就好。要特别提一点不要只看话题存在就判断没问题hz 才是关键。话题存在但数据频率为 0说明驱动和雷达之间的链路还是断的这在 ROS 里特别有迷惑性。5.2 现象二前几秒正常手一动就飞这是初始化没收敛的典型症状。最常见的原因是启动后没静止够、或者初始移动太猛。另一种可能你用了外置 IMU但没有做时间同步IMU 和激光的时间戳差了哪怕 20ms快速运动时残差就会被放大表现在轨迹上是一加速就甩头。如果静止初始化都做了还飞把数据录下来回放逐帧看轨迹能看出是在哪个动作点开始发散的。回放方式很简单先rosbag record /livox/lidar /livox/imu -O test.bag采集一段之后用rosbag play test.bag重放同时跑 FAST-LIO。注意重放时最好设-r 0.5放慢速度便于观察。这个办法也适合反复调参——同一个 bag 可以无限重放参数改一版测一版不用每次重新采集。5.3 现象三地图跑着跑着出现分层或整体漂移分层通常发生在长直走廊、开阔平地这类退化场景。特征点都在一个平面附近激光匹配在沿走廊方向约束很弱IMU 的零偏又没法完全约束就会慢慢飘。我在地下车库的笔直主通道上测过一条 200m 的直线走过去横向偏差不到 0.3m但纵向已经偏出将近 1m这就是典型的退化场景。缓解手段有几种采集时让传感器有意识地做上下俯仰给匹配增加不同深度的特征调低 det_range把走廊远端那些低置信度的点排除掉把 point_filter_num 调小一点保留更多点参与匹配实在不行就中途走回已知位置人为制造回环虽然 FAST-LIO 本身不做闭环但轨迹绕一圈后整体误差会明显小很多。另外如果分层是间歇性的、有规律地出现检查雷达镜片或外壳有没有松动——毫米级的结构变形在激光匹配里会被放大成明显分层。这个案例我遇到过两次都是云台支架的螺丝松了重新拧紧之后问题消失。5.4 现象四保存的 PCD 打开是花屏或全黑这种情况大概率不是建图问题而是查看方式问题。FAST-LIO 输出的是无颜色点云只有 xyz 和 intensity 字段。pcl_viewer 默认着色方式是高度如果你的场景高度变化小看起来就是一片灰切到 intensity 着色模式就能看到反射强度纹理。在 CloudCompare 里记得把显示属性设为 intensity它的默认渐变色能很好地反映墙面、地面和植被的差异。还有一点地图坐标系是 camera_init也就是建图起始点的位姿。如果你想在其它软件里结合机器人模型或 CAD 查看需要先做一个刚体变换把起始姿态摆正到目标坐标系别指望 pcd 自带你想要的朝向。这个坐标系朝向不对的问题经常被误判成地图建坏了实际上点云本身没问题只是观察者的参考系没对齐。6. 从能出图到能用图调优顺序和进阶玩法6.1 我建议的调优顺序如果你已经能出一张基本可用的图想继续压精度按这个顺序来不要跳先确认采集质量。回看 path 轨迹找明显的跳变点和抖动段这些是精度差的根源。再调预处理。室内调 blind 和 point_filter_num室外调 det_range。然后看外参。如果传感器相对机器人/手持杆的安装有明确角度确认 TF 和外参都正确。最后才考虑动协方差和在线估计。默认值在绝大多数场景都够用乱调只会让你失去一个稳定的基准。这个顺序的逻辑是先排除数据源和采集动作的问题再优化算法参数最后才碰滤波器内部。反过来调你会陷入调完感觉好了、再跑一次又飘了的循环因为你根本不知道是哪个环节在拖后腿。6.2 和几套常见方案的横向对比方案与 MID360 配合度上手难度是否带闭环适合场景FAST-LIO2高官方有现成 mid360 配置低一晚上能跑通否纯 LiDAR-inertial 建图绝大多数场景Point-LIO高带宽受限场景更稳中否高速运动、高动态场景LIO-SAM中需要额外配置 IMU 消息中高自带因子图可加闭环愿意多折腾、需要闭环的工程LIO-VX 等视觉激光融合中可以跑但依赖相机标定高视版本而定需要视觉信息辅助的科研场景需要说明的是这个对比基于我自己的测试和社区反馈不是严格评测。对于第一次接触 MID360 的人我的建议永远是把 FAST-LIO2 当第一套方案跑通、跑稳、理解参数之后再按项目需求换更复杂的框架否则你连到底是算法问题还是参数问题都分不清。6.3 建图之后还能干什么地图建出来只是第一步。常见的后续链路至少有三种。做导航的话把 pcd 抽稀、滤波后喂给 octomap_server 生成占据栅格再给 move_base 用。记得先把地图转到机器人 base 坐标系下再生成 octomap不然地图和机器人在 RViz 里永远对不上。做定位的话把保存的 pcd 作为先验地图用 ICP/NDT 类方法做实时重定位。MID360 的强度信息在结构相似场景里能显著提高匹配稳定性我试过在一栋楼的两条相似走廊里做重定位纯几何匹配失败加上 intensity 权重之后稳定通过。做数据回放的话所有原始数据都建议留一份 bag后面不管是调参还是换算法一条rosbag play就能复现当时的场景省去重新采集的时间。6.4 最后几条经验写到最后还是想把几个吃亏换来的习惯再唠叨一遍。第一每次建图前花十秒钟确认三个 hzlidar、imu、算法输出数据链路全绿再开始走。第二启动后一定静止几秒这句话我已经说了三次因为踩过的次数也差不多有三次。第三所有实验都录 bag你永远不知道哪一次的数据会在两天后变得重要。第四室外强光或雨雪天记得先擦镜头MID360 虽然 IP67但镜头上的水渍会让点云质量肉眼可见地下降而且这个问题在数据里很难事后修复。