1. 为什么选择 Mid360 加 FAST_LIO2 这套组合
如果你正在找一套能快速跑起来、精度又足够能打的激光雷达 SLAM 方案,Livox Mid360 配 FAST_LIO2 大概率是你绕不开的一个选项。我自己从最早的 Mid40 一路用到 Mid360,中间换过好几套前端里程计方案,最后还是回到 FAST_LIO2 这套组合上。原因不复杂:Mid360 是非重复扫描的固态雷达,FAST_LIO2 是专门针对这类雷达特性做过优化的紧耦合 LiDAR-惯性里程计,两者在数据特性和算法假设上是天然匹配的。
先说清楚这套东西到底能干什么。Mid360 是一台 360 度视场的固态激光雷达,水平视场 360 度,垂直视场 -7 度到 52 度,测距范围官方标称 40 米(对 80% 反射率目标),点频大概 20 万点每秒。FAST_LIO2 则是一个基于迭代误差状态卡尔曼滤波(IEKF)的激光惯性里程计,它把雷达点云和 IMU 数据做紧耦合,输出高频的位姿估计和构建好的点云地图。这套组合的典型用途是:室内外机器人建图、无人机导航、手持扫描建模、自动驾驶小车的定位前端。
适合谁来参考这篇内容?如果你已经装好了 ROS,手上有 Mid360 和对应的 IMU(Mid360 内置了 IMU,这点很关键),想从零把这套系统跑通并且建出一张像样的地图,那这篇就是写给你的。如果你连 ROS 都还没装,建议先把 ROS 环境搞定再回来,因为下面很多坑都建立在 ROS 已经能正常工作的前提上。
我见过太多人卡在第一步——雷达连不上、点云不出来、FAST_LIO2 启动就崩。这些问题九成不是算法的问题,而是环境、驱动、配置、时间同步这些"脏活"没做对。所以这篇不打算给你讲一堆卡尔曼滤波的公式推导,而是把从零到建图这条链路上真正会绊倒你的地方一个个拆开讲。
2. 环境准备阶段最容易翻车的几个点
2.1 ROS 版本与系统版本的选择逻辑
Mid360 的官方驱动 livox_ros_driver2 对 ROS 版本是有要求的。目前主流的两条路线是 Ubuntu 20.04 + ROS Noetic,或者 Ubuntu 22.04 + ROS2 Humble。FAST_LIO2 本身在 ROS1 和 ROS2 下都有分支,但社区里跑得最稳、资料最多的还是 ROS1 Noetic 这一套。如果你不是非要用 ROS2,我建议第一遍跑通就用 Noetic,能省掉大量编译和依赖的麻烦。
这里有个很多人忽略的点:Ubuntu 20.04 默认的 GCC 版本是 9,而 livox_ros_driver2 在某些版本下用 GCC 9 编译会报一些奇怪的模板错误。如果你遇到编译报错,先别急着怀疑代码,检查一下 GCC 版本,必要时装一个 GCC 8 或者用官方推荐的编译选项。我自己是在一台老机器上踩过这个坑,折腾了一下午才发现是编译器版本的问题。
另外提醒一句,别在虚拟机上跑这套东西。Mid360 的数据量不小,虚拟机的时间精度和 USB 吞吐都不够稳,点云会丢帧,建图直接飘。老老实实装双系统或者用物理机。
2.2 网络配置:Mid360 的 IP 是绕不过去的坎
Mid360 通过网口和主机通信,出厂默认 IP 是 192.168.1.1XX 这个网段(具体最后一位和你的雷达序列号有关)。你的主机网卡必须配成同一网段的静态 IP,比如 192.168.1.50,子网掩码 255.255.255.0。这一步看起来简单,但翻车率极高。
常见的错误有这么几种:一是主机网卡还开着 DHCP,结果拿到的 IP 和雷达不在一个网段,ping 都 ping 不通;二是同时开了 WiFi 和有线网卡,路由表里默认路由走了 WiFi,导致发往雷达的包出不去;三是防火墙没关,ICMP 和 UDP 包被拦了。
我的做法是:先把 WiFi 关掉,只留有线和雷达直连,网卡手动配静态 IP,然后用ping 192.168.1.1XX确认能通。通了之后再往下走。如果 ping 不通,先查ifconfig看网卡状态,再查route -n看路由表,最后查防火墙。这个排查顺序能解决 95% 的连接问题。
提示:Mid360 的 IP 最后一位可以通过 Livox Viewer 或者官方提供的配置工具修改,但第一次连接时你得先知道它当前的 IP。如果实在不知道,可以用官方工具扫描网段。
2.3 livox_ros_driver2 的编译与配置细节
驱动这块,官方仓库是 livox_ros_driver2。克隆下来之后,注意它有两个 launch 文件目录,一个是launch_ROS1,一个是launch_ROS2。用 ROS1 的话要进launch_ROS1目录去启动。很多人直接roslaunch livox_ros_driver2 xxx.launch发现找不到文件,就是因为没注意这个目录结构。
编译之前先确认依赖装齐了,rosdep install跑一遍。编译的时候如果报找不到 Livox SDK 相关的头文件,说明 SDK 没装或者路径没配好。官方驱动里其实带了 SDK,但有时候需要你手动指定路径。
配置文件MID360_config.json里有几个关键字段:lidar_configs里的ip要改成你雷达的实际 IP,host_net_info里的cmd_data_ip、push_msg_ip、point_data_ip、imu_data_ip要改成你主机网卡的 IP。这几个 IP 如果配错,表现就是驱动能启动但收不到数据,或者收到数据但点云是空的。我第一次配的时候就因为host_net_info里还留着默认的 192.168.1.5 而自己的网卡是 192.168.1.50,卡了半个多小时。
启动驱动后,用rostopic hz /livox/lidar看一下点云的发布频率,正常应该在 10Hz 左右。再用rostopic hz /livox/imu看 IMU 频率,Mid360 内置 IMU 大概是 200Hz。这两个频率正常,说明驱动这层就通了。
3. FAST_LIO2 的编译、配置与启动链路
3.1 源码获取与依赖处理
FAST_LIO2 的仓库在 GitHub 上,注意要选对分支。ROS1 用ROS1分支,ROS2 用ROS2分支。克隆到你的 catkin 工作空间的 src 目录下,然后catkin_make。
依赖方面,它需要 Eigen、PCL、Sophus 这几个库。Eigen 和 PCL 一般 ROS 桌面版装的时候就带了,Sophus 可能需要单独装。如果编译时报 Sophus 相关的错误,去装一个libSophus-dev或者从源码编译一个。另外它依赖 livox_ros_driver2 的消息类型,所以驱动必须先编译通过,否则 FAST_LIO2 找不到livox_ros_driver2/CustomMsg这个消息类型。
编译顺序很重要:先编译 livox_ros_driver2,再编译 FAST_LIO2。如果两个一起编译,有时候会因为消息类型还没生成而报错。我习惯是分两次catkin_make,第一次只编译驱动,第二次再全量编译。
3.2 配置文件里的参数到底该怎么调
FAST_LIO2 的配置文件在config目录下,Mid360 对应的通常是mid360.yaml或者类似的命名。这个文件里有几个参数直接决定你能不能建出图来。
lid_topic和imu_topic必须和驱动实际发布的 topic 对上。驱动默认发的点云 topic 是/livox/lidar,IMU 是/livox/imu。如果你改过驱动的配置,这里也要同步改。
extrinsic_T和extrinsic_R是雷达和 IMU 之间的外参。Mid360 是内置 IMU 的,理论上外参是固定的,官方也给了一组默认值。但如果你发现建图有明显的旋转漂移或者地面不平,可以怀疑一下这个外参。不过大多数情况下,用默认值就行,别乱调。
blind这个参数是盲区距离,单位米。Mid360 最近测距大概在 0.1 米左右,但太近的点噪声大,一般设成 0.5 到 1.0 比较合适。设太小会有大量近处噪声点进入建图,设太大又会丢失近处信息。
det_range是有效测距范围,Mid360 设成 40 到 50 都行。这个参数影响的是点云筛选,设得比实际测距大一点没关系。
filter_size_surf和filter_size_map是降采样体素大小。这两个参数直接关系到建图精度和计算量。室内场景我一般用 0.2 到 0.3,室外大场景可以用 0.5。设太小计算量爆炸,设太大地图会糊。
acc_cov、gyr_cov、b_acc_cov、b_gyr_cov这几个是 IMU 的噪声协方差。Mid360 内置 IMU 的噪声特性官方有数据手册,但实际用的时候,如果发现建图在快速运动时飘得厉害,可以适当调大这几个协方差值,让滤波器更信任雷达观测而不是 IMU 预测。
3.3 启动顺序与时间同步问题
启动顺序这件事,说简单也简单,说坑也坑。正确的顺序是:先启动雷达驱动,确认点云和 IMU 都在正常发布,再启动 FAST_LIO2。如果反过来,FAST_LIO2 启动时收不到数据,可能会直接退出或者卡住。
时间同步是另一个大坑。Mid360 的点云和 IMU 时间戳来自雷达内部时钟,而 ROS 系统用的是主机时钟。如果两者不同步,FAST_LIO2 在做紧耦合的时候会出现时间对齐错误,表现就是建图飘、重影、甚至直接发散。
解决办法有几个:一是用 PTP 或者 GPS 做硬件时间同步,这个对普通玩家来说太重了;二是确保驱动配置里开启了时间同步选项,让雷达时间戳尽量贴近主机时间;三是在 FAST_LIO2 里检查time_sync_en这个参数,如果雷达和主机时间差太大,可以打开软件时间同步。
我自己的经验是,大多数室内场景下,只要主机和雷达都正常上电,时间差不会大到影响建图。但如果你发现地图有明显的"双层"或者"拖影",第一时间去查时间戳。用rostopic echo /livox/lidar看一下 header 里的 stamp 和当前 ROS 时间差多少,如果差了几秒甚至几十秒,那就是时间同步没做好。
4. 建图过程中那些让人抓狂的现象与排查
4.1 点云稀疏或者干脆没有点云
驱动启动了,topic 也在发,但 RViz 里看不到点云,或者点云稀稀拉拉。这种情况先别怀疑 FAST_LIO2,问题大概率在驱动层。
第一步,确认MID360_config.json里的 IP 配置全对。特别是host_net_info里的四个 IP,必须是你主机网卡的实际 IP。第二步,确认网卡是不是千兆的。Mid360 的数据量需要千兆网口,百兆网口会丢包严重,表现就是点云断断续续。第三步,检查网线。别笑,我真的遇到过网线接触不良导致点云时有时无的情况,换根线就好了。
如果点云能出来但特别稀疏,检查一下publish_freq这个参数。驱动默认可能是 10Hz,但如果你设成了 5Hz 或者更低,点云密度就会下降。另外data_src要设成 0(表示从雷达实时读取),如果设成了 1(从文件读取)而你又没有文件,那自然没有点云。
4.2 建图飘移、重影、地面不平
这是 FAST_LIO2 最常被吐槽的问题,但绝大多数情况下不是算法本身的问题,而是配置或者数据质量的问题。
先看 IMU 数据质量。用rostopic echo /livox/imu看一下角速度和加速度的数值。静止状态下,角速度应该在零附近小幅波动,加速度的 Z 轴应该接近 9.8。如果角速度有几十度每秒的偏置,或者加速度数值离谱,那 IMU 可能有问题。Mid360 内置 IMU 一般不会坏,但如果你把雷达装在振动很大的平台上,IMU 数据会被振动污染,建图必飘。
再看外参。虽然 Mid360 是内置 IMU,但雷达和 IMU 的坐标系定义如果和 FAST_LIO2 的假设不一致,也会导致建图异常。检查配置文件里的extrinsic_R是不是单位矩阵或者官方推荐值。如果你自己改过,改回去试试。
还有一个容易被忽略的点:point_filter_num这个参数。它控制每隔几个点取一个点参与计算。设成 1 表示全用,设成 3 表示每三个点用一个。如果设得太大,参与计算的点太少,建图会不稳;设得太小,计算量又太大。Mid360 点频高,一般设 2 到 3 比较平衡。
4.3 FAST_LIO2 启动就崩或者跑几秒就退出
这种情况通常有几个原因。一是消息类型不匹配,比如 FAST_LIO2 订阅的是livox_ros_driver2/CustomMsg,但驱动发的是sensor_msgs/PointCloud2,类型对不上直接崩。检查驱动的xfer_format参数,设成 1 是 CustomMsg,设成 0 是 PointCloud2。FAST_LIO2 默认要 CustomMsg,所以驱动这边要设成 1。
二是配置文件路径不对。FAST_LIO2 启动时会去读 yaml 文件,如果路径写错了或者文件不存在,它会用默认值或者直接报错退出。检查 launch 文件里的config_file参数指向的路径是否正确。
三是内存不够。FAST_LIO2 建图时会把点云地图存在内存里,如果场景很大跑很久,内存会持续增长。如果你机器内存只有 8G,跑大场景可能会被 OOM killer 干掉。建议至少 16G 内存,大场景最好 32G。
5. 让建图效果更稳的几个实战技巧
5.1 雷达安装位置与振动隔离
Mid360 虽然叫"固态",但它对振动还是很敏感的。如果你把它刚性固定在一个振动很大的底盘上,IMU 数据会被高频振动污染,FAST_LIO2 的预测步骤就会出错。我的做法是在雷达和安装板之间加一层减震垫,哪怕是一层薄薄的橡胶垫,效果都很明显。
安装位置也有讲究。尽量让雷达的视场不被遮挡,特别是垂直视场。Mid360 的垂直视场是 -7 到 52 度,如果你把它装得太低,地面反射会占很大比例;装得太高,近处盲区又大。一般装在机器人顶部或者前方偏上的位置比较合适。
5.2 建图前的静态初始化
FAST_LIO2 启动后需要一段时间的静态初始化,让 IMU 零偏收敛。这段时间里不要移动雷达,让它静止几秒钟。如果你一启动就拿着雷达跑,初始化没完成,建图从一开始就是歪的。
我一般会看 RViz 里的位姿输出,等它稳定个三五秒再开始移动。另外,初始化阶段最好让雷达对着一个有足够几何特征的环境,比如墙角或者有家具的房间。如果对着白墙,特征太少,初始化也会不稳。
5.3 大场景建图的回环与保存
FAST_LIO2 本身不带回环检测,它只做里程计。所以如果你建一个大场景,走一圈回到原点,地图可能会有累积误差,首尾对不上。这是正常的,不是 bug。
要解决回环问题,可以在 FAST_LIO2 后面接一个回环检测模块,比如 SC-PGO 或者 LIO-SAM 里的回环部分。但那是另一套东西了,这篇不展开。如果你只是建个小场景,FAST_LIO2 的精度足够,不回环也能看。
保存地图的话,FAST_LIO2 提供了rosrun fast_lio map_saver之类的工具,或者你可以用pcl_ros把/cloud_registered这个 topic 存成 pcd 文件。注意保存的时候要等地图完全建完再存,别建到一半就存,那样存下来的地图是不完整的。
5.4 计算资源与实时性的平衡
FAST_LIO2 在 Mid360 上的计算量不算小,特别是在降采样体素设得很小的时候。如果你发现建图时 CPU 占用率一直 100%,位姿输出频率掉得很厉害,那就要考虑降一下计算量。
可以调的参数有:增大filter_size_surf和filter_size_map,增大point_filter_num,减少max_iteration(IEKF 的迭代次数)。这几个参数调一调,计算量能降不少,精度损失在可接受范围内。
另外,编译的时候打开-O3优化,对性能也有帮助。FAST_LIO2 的 CMakeLists 里默认可能是-O2,改成-O3能快一些。
6. 一些零散但重要的经验补充
关于 IMU 频率,Mid360 内置 IMU 是 200Hz,但 FAST_LIO2 里有个imu_rate或者类似的参数,要确保和实际频率一致。如果设错了,滤波器的时间更新步长就不对,建图会飘。
关于点云格式,如果你用 ROS2,消息类型和 ROS1 不一样,FAST_LIO2 的 ROS2 分支里订阅的 topic 类型要对应改。这个在 ROS2 下跑的时候特别容易忘。
关于雷达固件,Mid360 的固件版本会影响数据格式和稳定性。如果你的雷达是很早的固件,建议升级到官方推荐版本。升级工具官方有提供,过程不复杂,但升级时别断电。
关于多雷达,如果你要同时用多个 Mid360,配置会更复杂,每个雷达的 IP 和 topic 都要区分开,FAST_LIO2 那边也要改订阅逻辑。这个场景比较小众,遇到问题去官方 issue 里搜,大概率有人踩过。
最后说一个我自己的习惯:每次改完配置,先不急着跑完整建图,而是用rosbag record录一小段数据,然后离线跑 FAST_LIO2。这样调试起来快,不用每次都重新走一遍。录包的时候记得把点云和 IMU 都录上,rosbag record /livox/lidar /livox/imu就行。离线跑通了再上实机,效率高很多。
这套 Mid360 加 FAST_LIO2 的组合,跑通之后你会发现它真的很能打。但跑通之前的那些坑,每一个都够你折腾半天。上面这些是我自己踩过并且印象比较深的,希望能帮你少走点弯路。如果你遇到了上面没提到的问题,大概率是环境或者硬件层面的,回到最基础的检查:IP 通不通、topic 有没有数据、时间戳对不对、IMU 数值正常不正常。把这四个问题排除了,剩下的就好办了。