☰
多传感器融合实战:MID360+D435i与R3LIVE标定部署全攻略
2026/10/7 22:20:01 网站建设 项目流程

在机器人建图定位这个圈子里,单独拎一套激光雷达或者单独用视觉相机跑项目,我都试过不少。纯激光方案在长廊、玻璃房、白墙这种特征稀缺的场景里容易飘,纯视觉方案则在强烈光照变化和快速旋转时频繁丢帧。后来我把 Livox MID-360 和 Intel RealSense D435i 这两款传感器放在一起做多传感器融合,配合 R3LIVE 这套实时导航里程计框架,算是真正解决了我在园区巡检平台和室内服务机器人上遇到的大部分痛点。这篇文章不会只停留在“装好驱动就能跑”的层面,而是会完整记录我从 D435i 相机标定、lidar imu 标定、雷达与相机外参标定,到 R3LIVE 配置适配和最终部署的整个流程,包括中间踩过的坑和排查思路。如果你是结构工程师或者算法工程师,手里刚好有 MID360 和 D435i,又不知道该从哪一步开始下手,那这篇文章应该能帮你省下大量试错时间。

1. 项目概述:为什么是MID360与D435i这对组合

1.1 单传感器方案在真实场景中的痛点

先说一个很实际的问题:为什么非要同时用 MID360 和 D435i?我在实际项目里遇到过不少单传感器的翻车案例。

MID360 是非重复扫描的固态激光雷达,视场角能做到 360°,在室内外都能正常使用。它最大的问题是点云特性比较特殊——不是传统机械雷达那种均匀分布的扫描线,而是花瓣状的轨迹覆盖,单帧点云比较稀疏。如果只靠 MID360 做纯激光定位,在开阔场地或者长走廊里,由于几何特征不足,退化现象非常明显。特别是在机器人原地旋转时,纯激光里程计会出现明显的累积漂移,地图会出现“撕裂”和重影。

D435i 的好处是能提供 RGB 图像、深度图像和内置 IMU。视觉相机的信息在几何退化场景下能提供很强的互补作用。比如在白墙走廊里,激光雷达看到的全是同一距离的平面,而 D435i 能捕捉到墙面纹理、踢脚线、门框颜色这些视觉特征。但纯视觉的问题也显而易见:光照变化、快速运动模糊、弱纹理位置都会让视觉里程计直接失效。

所以把 MID360 和 D435i 放在一起,本质上是希望用激光点云保证整体结构的稳定性,用视觉信息补足几何退化区域的约束,再用 IMU 撑起高速运动时候的帧间状态估计。这个思路和 R3LIVE 的架构非常契合,也是我选这套组合的直接原因。

1.2 为什么R3LIVE能扛住这套配置

在融合框架的选型上,我先后对比过 LIO-SAM、FAST-LIO2、R3LIVE 和 LVI-SAM。LIO-SAM 和 FAST-LIO2 本质上还是激光惯性导航系统,没有把相机信息真正融合进去;LVI-SAM 虽然做了视觉激光联合,但工程结构复杂,标定错误对系统影响非常敏感,调参周期很长。R3LIVE 的优势在于两点:一是它继承了 FAST-LIO2 的核心李代数滤波方式,雷达点云和 IMU 的紧耦合比较成熟;二是它在后端维护了一个全局的彩色点云地图,视觉帧可以直接和地图做帧到地图配准,不需要额外维护视觉特征对应的路标点,这样对 D435i 这种消费级相机的标定误差容忍度更高。

还有一个很现实的优势:R3LIVE 和 Livox 的产品生态本来就有天然适配。代码仓库里面已经提供了针对 MID360 的配置示例,驱动层面用的是 Livox 官方 ROS 驱动,省去了不少对接工作。对于团队项目来说,能少维护一层工具链,就意味着能少踩很多坑。

1.3 这套流程适合什么人参考

这篇文章适合几类读者:

  • 刚入手 MID360 和 D435i,想做多传感器融合建图,但不知道标定如何开始的初学者;
  • 已经能跑通官方 Demo,但换到自己的传感器组合后地图发散、重影、漂移严重的工程师;
  • 需要把 R3LIVE 输出的彩色点云地图用于导航或路径规划的开发者。

如果你的项目只是在纯室内小场景做短时间建图,可能用官方默认参数就够了,但只要你需要做实时定位、长时间运行、或者把地图用于后续导航,标定这一步就绝对绕不开。

2. 硬件平台与软件环境准备

2.1 传感器关键参数与坐标系约定

在开始标定之前,必须先搞清楚传感器各自的坐标系和输出数据特性,否则后面拿到外参矩阵都不知道该怎么用。

MID360 的关键参数:

  • 探测距离:最远 40 米(90% 反射率),10 米(10% 反射率);
  • 视场角:水平 360°,垂直 -7° 到 +52°;
  • 扫描频率:10Hz,非重复扫描模式;
  • 内置 IMU:200Hz,加速度计和陀螺仪;
  • 点云输出 topic 通常是/livox/lidar,IMU 输出 topic 通常是/livox/imu。

D435i 的关键参数:

  • RGB 相机:最高 1920x1080@30fps,实际常用 640x480 或 1280x720;
  • 深度相机:主动红外立体测距,0.2-10 米量程;
  • 内置 IMU:BMI055,加速度计和陀螺仪,约 400Hz;
  • 内参出厂已标定,可以通过 ROS 的 CameraInfo 话题直接读取。

坐标系约定方面,我建议整个系统以 MID360 的内置 IMU 坐标系作为主体坐标系(也就是 R3LIVE 里的body系或imu系),因为激光雷达的点云和 IMU 数据都来自 MID360 这个设备,时间和空间上的一致性最好。D435i 的相机外参则描述为“相机坐标系到 MID360 内置 IMU 坐标系”的变换关系。如果你用 D435i 自己的 IMU 作为主体坐标系也可以,但这样雷达和相机都要标到 D435i 的 IMU 上,中间多了一次变换,误差环节会更多,我不建议第一次做就选这种方案。

2.2 软件栈:驱动、ROS版本和编译环境

我的开发环境是 Ubuntu 20.04 + ROS Noetic,这也是目前 R3LIVE 社区验证最充分的组合。Ubuntu 18.04 + ROS Melodic 也能用,但部分较新的依赖库版本在 Melodic 上会有兼容问题,反而增加排查成本。

需要准备的软件栈:

  • livox_ros_driver2:Livox 官方 ROS2 驱动,但在 ROS1 下也能编译使用,MID360 必须用这个驱动;
  • realsense-ros:Intel RealSense 官方 ROS 驱动,用于发布 D435i 的图像、深度和 IMU 数据;
  • livox_ros_driver:早期版本,部分教程还在用,但 MID360 建议直接用 driver2;
  • R3LIVE 源码仓库;
  • Kalibr 工具链(用于相机内参和相机-IMU 标定);
  • livox_camera_calib(雷达与相机外参标定工具,也可用 R3LIVE 自带的标定方法)。

编译时需要注意一个顺序问题:最好先编译livox_ros_driver2和realsense-ros,确认两个传感器的话题都能正常输出,再编译 R3LIVE。R3LIVE 在catkin_make时会依赖这两个驱动头文件,如果驱动没有先编译好,会出现找不到头文件的报错。

2.3 驱动联调与数据流验证

驱动装好之后,先别急着跑 R3LIVE,先把数据流验证清楚。我的验证步骤很简单:

  1. 启动 MID360 驱动,确认/livox/lidar有频率约 10Hz 的点云,/livox/imu有约 200Hz 的 IMU 数据;
  2. 启动 D435i 驱动,确认/camera/color/image_raw和/camera/depth/image_rect_raw有稳定输出;
  3. 在 Rviz 里同时显示点云和图像,人工确认两者的视野范围是否有交集;
  4. 快速移动传感器平台,观察 IMU 数据是否合理(加速度、角速度变化方向是否正确)。

这一步很重要,因为很多外参标定失败的根本原因是数据本身就不对。比如我遇到过 MID360 点云固定在一个方向缺失,原因是传感器安装时被支架遮挡了部分视场角;还遇到过 D435i 彩色图和深度图的畸变参数在不同话题下不一致,导致对齐后出现明显的错位。数据验证阶段如果偷懒,后面标定出来的外参矩阵再好也是白搭。

3. 标定全流程:从相机内参到雷达与相机外参

标定是整个系统里最繁琐、也最容易劝退新手的环节。我这里把标定分为四层:D435i 相机内参、相机与 IMU 外参、MID360 激光雷达与 IMU 外参、雷达与相机外参。前两步主要解决相机自身的问题,第三步解决激光雷达和 IMU 的位姿关系,第四步解决两个传感器之间的空间变换。

3.1 D435i相机内参标定实操

D435i 出厂时已经带了内参标定结果,通过camera_info话题可以拿到。但在实际项目中,我仍然建议做一次自己的标定,原因有两个:一是不同批次的镜头存在个体差异,出厂值不一定精准;二是我们经常需要把彩色图像重投影到激光点云坐标系,内参误差会被放大到外参标定结果上,导致整个系统精度下降。

用 ROS 自带的camera_calibration功能包标定彩色相机内参的步骤:

rosrun camera_calibration cameracalibrator.py \ --size 8x6 \ --square 0.108 \ image:=/camera/color/image_raw \ camera:=/camera/color

实际操作注意几个点:

  • 标定板必须在画面中缓慢移动,覆盖画面的四个角和中心区域;
  • 标定板平面要相对相机有俯仰角变化,不能只保持正对;
  • 取到 20-30 个有效位姿后,界面的 CALIBRATE 按钮才会激活;
  • 标定结果会以.yaml文件输出,里面的camera_matrix和distortion_coefficients就是后续要用的内参。

如果你需要更高精度的内参,可以用 Kalibr 的kalibr_calibrate_cameras工具,配合棋盘格或 Aprilgrid 标定板。Kalibr 的优势是支持多相机联合标定,能同时标出两个相机的相对外参,后续如果要做红外图和彩色图的联合使用会很方便。

3.2 相机与IMU的标定

D435i 自带 IMU,这个 IMU 与相机在硬件上是固定的,理论上外参接近一个固定的平移和单位旋转。但实际安装时,镜头的微型偏移和 IMU 在 PCB 上的定位误差,会导致我们需要重新标定相机坐标系到 IMU 坐标系的变换。

这一步我用的工具是 Kalibr。流程概括如下:

  1. 固定传感器平台,避免剧烈振动;
  2. 启动 D435i 驱动,同时采集图像和 IMU 数据,时长约 2-3 分钟;
  3. 使用kalibr_calibrate_imu_camera命令联合标定。

采集数据时有一个非常关键的技巧:要保证 IMU 的可观测性。IMU 标定最忌讳的就是把设备静止放在桌面上录数据,这样加速度计和陀螺仪的 bias 根本无法区分。正确做法是让设备做六个方向的缓慢旋转(绕 x、y、z 轴各正反旋转),再加上一些小幅度的平移激励。记住,激励越丰富,标定结果越稳定。

D435i 的 IMU 话题会发布原始测量值和 covariances,如果你发现 IMU 数据有明显的跳变,可以检查是否需要在驱动参数里打开 IMU 的自动校零功能。我遇到过 D435i 的 IMU 因为环境振动导致零偏漂移很大的情况,重新校准后明显改善。

3.3 MID360激光雷达与内置IMU的标定

这一步很多人会忽略,因为 MID360 的 IMU 是内置的,电源和通信都在同一个设备里,大家潜意识会觉得内部标定已经做好了。但实际上,R3LIVE 需要的是“从激光雷达坐标系到 IMU 坐标系”的位姿变换,这个变换虽然很小,却不能简单设为零矩阵。

MID360 的内置 IMU 和激光雷达之间存在一个固定的安装偏移,Livox 官方在驱动或私有配置中给出了这个值的参考范围,但最好还是通过实际标定校准一次。我用的方式是lidar_imu_calib这个开源工具,基本逻辑是:把激光雷达点云通过 IMU 积分得到的轨迹做配准,反过来优化雷达与 IMU 之间的旋转和平移。

标定时需要注意的是:

  • 标定环境要有足够的几何特征,不能是空白房间;
  • 让设备沿各个方向运动,保证 IMU 激励充分;
  • 点云和 IMU 时间戳必须对齐,否则优化结果会严重偏斜。

标定完成后,你会得到一个 4x4 的外部参数矩阵,这个矩阵描述的是T_lidar_imu,也就是把 IMU 坐标系下的量转换到雷达坐标系下的变换。

如果你在项目早期比较赶时间,可以先用 MID360 官方的近似值。比如它的 IMU 中心大概在雷达光学中心下方几厘米处,旋转近似为单位矩阵。这个近似值足够让 R3LIVE 跑通,但地图精度和长时间稳定性会打折,后面有时间还是要补一次标定。

3.4 雷达与相机外参标定实操

这是整个标定流程里最核心的一步。雷达与相机外参标定,本质上是求解一个 4x4 的变换矩阵,把相机坐标系下的点映射到雷达坐标系下,或者反过来。这类问题和机械臂的手眼标定非常相似,都是求解空间刚体变换。手眼标定里经典的 AX=XB 方程,在这里同样适用,只是观测对象从机械臂末端变成了环境中可识别的标定板。

我采用的方法是livox_camera_calib,这个工具专为 Livox 雷达设计,核心流程是:

  1. 将 D435i 彩色图和 MID360 点云同时录制到 bag 文件中;
  2. 运行工具,提取标定板在图像中的位置和点云中的平面特征;
  3. 优化外参使重投影误差最小。

实际操作中,我会把标定板放在距离传感器 1-3 米的位置,保证标定板同时出现在 D435i 视野和 MID360 点云覆盖范围内。这里有个限制要注意:MID360 的垂直视场角是 -7° 到 +52°,而 D435i 的水平视场角约 85°,两者重叠区域比较小。所以摆放传感器支架时,我建议让 D435i 略微向下倾斜 10°-15°,使两个传感器的主要视野尽可能重叠。

标定过程中需要采集多个位姿的数据:

采集序列平台状态标定板位置
1静止标定板正对相机,距离 1m
2静止标定板左侧 30°
3静止标定板右侧 30°
4静止标定板下俯 20°
5小幅旋转标定板保持在视野内,移动平台
6小幅平移标定板保持在视野内,平移平台

每个位姿采集 2 秒左右的静态数据。工具会自动检测标定板角点和平面对应关系,最后输出变换矩阵。

如果livox_camera_calib在你的场景中始终无法收敛,可以试试 R3LIVE 社区有人分享的基于点云平面拟合的方案:在点云中手动框选标定板区域,拟合平面,再与图像中检测到的标定板角点建立对应,用 PnP 算法求解外参。虽然是半自动方式,但结果也很可靠。

3.5 外参在R3LIVE配置中的落地写法

标定完成后,得到的所有变换都要写进 R3LIVE 的配置文件中。R3LIVE 的r3live_config.yaml里最关键的是这几项:

common: lid_topic: "/livox/lidar" img_topic: "/camera/color/image_raw" imu_topic: "/livox/imu" r3live_vio: # lidar to imu r_imu_lidar: [0.0, 0.0, 0.0] # 单位:rad,此处是示例,需换成标定结果 t_imu_lidar: [0.0, 0.0, 0.0] # 单位:m,此处是示例,需换成标定结果 r_imu_cam: [0.0, 0.0, 0.0] # 相机到IMU的旋转,单位:rad t_imu_cam: [0.0, 0.0, 0.0] # 相机到IMU的平移,单位:m

这里的一个常见理解误区是:r_imu_cam和t_imu_cam到底表示“IMU 到相机”还是“相机到 IMU”。我建议看注释确认,不同版本可能有细微差异。我自己的习惯是把每一个外参矩阵先在 MATLAB 或 Python 里验证一遍:把相机采集到的标定板角点投影到雷达坐标系下,点云位置和角点位置如果能对上,再写进配置文件。

4. R3LIVE核心原理与配置适配

4.1 R3LIVE的工作逻辑

R3LIVE 名字里的 R3 指 Robust、Real-time、RGB-based,它同时吸收了 FAST-LIO2 的激光惯性导航系统框架和一个轻量化的视觉惯性导航系统前端。具体来说,雷达点云和 IMU 数据先通过直接法配准到全局地图,得到整个系统的主体位姿估计;同时,彩色相机图像作为辅助信息,通过帧到地图的配准去修正视觉误差。

它和传统松耦合方案最大的区别是:视觉信息不是单独跑一个视觉里程计再融合结果,而是直接参与地图配准。这样做的优势是,即使相机发生了短暂的遮挡或运动模糊,系统主体仍然可以靠激光雷达和 IMU 撑住,不会轻易漂移。

4.2 针对MID360与D435i的配置修改

我在实测时,主要调整了这几个参数:

第一,确认lid_topic、imu_topic、img_topic三个主题名称与驱动实际发布一致。MID360 的 driver2 版本中,点云主题可能带命名空间前缀,需要根据实际rostopic list结果修改。

第二,图像分辨率。R3LIVE 的视觉配准模块对高分辨率图像很敏感,D435i 如果输出 1280x720 的彩色图,会导致 CPU 占用过高,帧率下降到难以接受。我建议先把彩色图降为 640x480,并确认相机内参也相应缩放。

第三,初始化时map_frame、odom_frame、body_frame的名称要与驱动保持一致。MID360 驱动默认的 frame_id 是livox_frame,D435i 的彩色话题默认是camera_color_optical_frame,R3LIVE 会以自己的方式维护坐标变换,但保持统一可以减少后续调试成本。

4.3 编译与启动流程

R3LIVE 的编译流程是这样:

mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone https://github.com/hkust-aerial-robotics/r3live.git git clone https://github.com/Livox-SDK/livox_ros_driver2.git cd ~/catkin_ws catkin_make source devel/setup.bash

我遇到过编译时缺少opencv头文件的情况,解决方法是先安装依赖:

sudo apt install libopencv-dev sudo apt install ros-noetic-cv-bridge ros-noetic-image-transport

编译完成后,启动顺序是:

  1. 启动 MID360 驱动;
  2. 启动 D435i 驱动;
  3. 启动 R3LIVE 节点。

在 Rviz 中订阅/r3live/map话题查看彩色地图,订阅/r3live/odom查看里程计轨迹。如果地图能正常显示且轨迹平滑,说明整个系统已经跑通。

5. 在线部署与建图运行

5.1 启动一组与实际运行

我实际运行时的命令组合如下:

roslaunch livox_ros_driver2 msg_MID360.launch roslaunch realsense2_camera rs_camera.launch \ color_width:=640 \ color_height:=480 \ color_fps:=30 \ enable_depth:=false roslaunch r3live r3live.launch

我这里把 D435i 的深度流关掉了,只保留彩色图。原因有两点:第一,R3LIVE 的视觉配准用的是彩色图像,深度流对这套框架没有直接收益;第二,同时打开深度流会占用 USB 带宽,影响彩色图的帧率稳定。如果你的项目需要同时使用深度信息做别的任务,比如避障,可以考虑另外开一个节点跑深度,但注意 USB 带宽分配。

R3LIVE 启动后会有一段初始化过程,通常 1-2 秒内开始输出里程计。这时先不要移动设备,保持静态几秒钟,让系统完成初始帧和 IMU bias 的估计,然后再缓慢移动。如果一启动就剧烈晃动,初始化失败的概率会很高。

5.2 运行效果评估与调优

地图质量怎么评估?我一般看三个指标:

第一,彩色点云地图的清晰度和厚度。正常的地图墙面点云应该是薄薄一层,颜色与真实场景一致。如果墙面粉尘明显,说明位姿漂移或外参有偏差。

第二,轨迹闭环误差。让设备走一圈回到起点,观察 Rviz 中轨迹终点和起点的偏差。如果偏差小于 0.2 米,算基本合格;如果偏到离谱,就要回头查外参和时间同步。

第三,运行时的 CPU/GPU 占用。R3LIVE 默认会用 GPU 加速视觉配准,如果你的设备上没有独立 GPU,也会退化为 CPU 模式,但是帧率会下降很多。实测在笔记本的 NVIDIA GPU 上,MID360+D435i 的完整流程能跑到 10Hz 左右,基本接近实时。

调优阶段,我最常用的是调整两个参数:一个是激光点云降采样分辨率,另一个是地图更新频率。点云降采样分辨率越大,计算越快,但地图细节越差;地图更新频率太高会导致 CPU 繁忙,降低系统稳定性。建议保留默认参数,先跑通再逐步微调。

5.3 彩色点云地图的输出与导航衔接

R3LIVE 本身的产出是一套实时里程计地图,但对于很多实际项目,我们还需要把地图保存下来供后续导航使用。R3LIVE 提供了保存地图的服务接口:

rosservice call /r3live/save_map

执行后会在指定目录生成一个包含彩色信息的点云 PCD 文件。你可以用 PCL 库或 CloudCompare 打开查看。

如果要用于导航,还需要做一步转换:把彩色点云地图降采样、滤除地面点,然后转换成 2D 栅格地图。这块可以和 Cartographer 的 2D 输出做融合,也可以直接用 PCL 的高度过滤加占据栅格化实现。

6. 常见问题排查与实战避坑

6.1 外参不收敛与点云重影

这是我在社区回答里被问得最多的问题。现象是:地图能出来,但同一面墙有明显的两层点云,或者远处墙壁的投影位置和图像明显错位。

排查步骤如下:

  1. 确认 D435i 内参是否准确,先用一块已知尺寸的标定板验证投影结果;
  2. 确认雷达与相机外参是否写反,常见错误是把T_camera_lidar和T_lidar_camera弄反;
  3. 确认雷达与 IMU 外参是否准确,这一步即使有误,系统也能运行,但地图会缓慢漂移;
  4. 确认两个传感器的时间戳是否同步,时间偏差超过 50ms 就会出现明显重影。

解决外参问题,我通常会在代码里加一个简单的验证函数:随机抽取 20 个环境特征点,分别在点云和图像中手动标注,计算重投影误差。误差小于 5 个像素,说明外参基本可靠。

6.2 时间同步导致的问题

MID360 和 D435i 是两台独立设备,时间戳来源不同,不做同步就会出现“图上看到的位置和点云实际位置不一致”的怪问题。最直观的表象是:机器人静止时地图没问题,一运动地图就开始错位。

我采用的方案是:

  • D435i 启用硬件时间戳,确保图像时间戳与帧曝光时刻一致;
  • MID360 的点云和 IMU 时间戳本身由设备产生,注意检查驱动是否有时间戳跳变;
  • 在录制 bag 或实时运行时,尽量让两台设备的时钟使用同一主时钟源。

如果你的系统是纯离线建图,可以在录制 bag 时用rosbag record的时钟同步选项来减小问题。实时运行时,最省事的办法是设置 R3LIVE 允许一定的消息时间偏差容限,但这是治标不治本。

6.3 性能瓶颈与落地建议

不同硬件上跑 R3LIVE,差异非常大。我的低配测试机是 i7-8700 + GTX 1660,跑 640x480 图像和默认点云降采样时,整体 CPU 占用约 120%(8 核中的 1.2 核),GPU 占用约 20%,系统还算流畅。但换到无独显的 NUC 上,帧率就掉到 5Hz 左右,视觉配准明显滞后。

落地建议:

  • 如果要在嵌入式平台部署,建议降低图像分辨率到 424x240,并调大点云降采样体素大小;
  • 如果只是做建图,可以离线把 bag 录制下来,再用 R3LIVE 跑离线模式,这样能保证每一帧都处理完成;
  • 不建议在工控机上同时跑 R3LIVE 和三维重建渲染,资源竞争严重时会导致里程计丢帧。

我个人在实际操作中的体会是:标定环节占整个部署工作量的 60% 以上,但很多人把精力都花在编译和跑通 Demo 上。其实只要把 D435i 相机标定、lidar imu 标定、雷达与相机外参标定这三关认真过一遍,R3LIVE 在 MID360+D435i 这套硬件上跑得其实非常稳,最终建图效果和系统稳定性都会超出预期。如果你后面要换不同的相机或雷达,这套标定和部署的思路也完全可以直接复用。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询