ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

多传感器融合实战:MID360与D435i驱动R3LIVE的标定部署全攻略

多传感器融合实战:MID360与D435i驱动R3LIVE的标定部署全攻略 最近在给项目里的巡检机器人升级感知系统手里正好有一台 Livox 的 MID360 和一台 Intel RealSense D435i目标很明确把激光雷达、相机、IMU 三条数据链路组合起来跑 R3LIVE实现实时定位和彩色点云建图。折腾完这套MID360 D435i R3LIVE从标定到部署的全流程之后最大的感受是单看每个环节的教程都不算少但能把这几个传感器真正串在一起、把标定关系捋顺、把 R3LIVE 跑稳定中间其实藏着不少文档里不会明写的坑。这篇文章不是概念介绍而是我实际把整套系统推上线之后整理的完整链路包括为什么选这两个传感器、驱动和话题怎么打通、相机内参和雷达相机外参怎么标、外参怎么填进 R3LIVE 的 launch 文件、部署时有哪些参数值得调以及我在现场踩过的几个典型问题。不管是实验室里做多传感器融合课题的学生还是准备把 R3LIVE 用在实际机器人平台上的工程师照着这条链路走一遍应该能省下不少乱试的时间。1. 项目概述与传感器选型思路1.1 这套组合能解决什么问题先说结论MID360 负责提供激光雷达点云D435i 提供彩色图像和内置 IMUR3LIVE 把这三路数据紧耦合在一起实时输出带 RGB 颜色的高密度彩色点云地图同时给出机器人自身的位姿估计。和单纯跑 FAST-LIO、LIO-SAM 这类纯激光惯导方案相比R3LIVE 最大的差异点是加入了视觉信息能利用图像中的纹理信息去修正激光里程计累积的漂移在建图效果上尤其是场景特征相对稀疏的走廊、厂房里地图的细节和稳定性会好很多。另一个实际价值是它能把定位和建图放到一个系统里做不需要先跑一个建图、再单独跑一个定位模块。对于巡检机器人、仓储 AGV、校园配送车这种项目这是很常见的需求白天跑一圈地图带颜色后续做导航的时候可以直接用彩色点云做语义观察这会省掉很多后端处理的功夫。1.2 为什么选 MID360 和 D435iMID360 是 Livox 的 360 度非重复扫描固态激光雷达体积小、重量轻适合装在巡检机器人和无人机上水平视角 360 度、垂直视角大概 59 度最近探测距离能做到 0.1 米左右这意味着机器人附近的点云不会因为近距盲区而缺失。它不像传统机械式雷达那样转着圈扫描而是用非重复扫描的方式在视场里不断填充点云密度对 SLAM 来说点云覆盖率和均匀性更好。D435i 选择它主要看中三点RGB 图像分辨率可以调到 640x480 甚至更高帧率能跑到 30fps满足 R3LIVE 对图像频率的要求它自带 IMU虽然精度比不上独立的高性能 IMU但省去了额外接线和标定 IMU 到相机外参的麻烦驱动成熟realsense-ros 在 ROS 生态里很稳定话题输出非常规整。这套组合还有个好处D435i 是双目结构光深度相机但 R3LIVE 并不依赖它的深度图主要用彩色图像做视觉约束深度图可以留给其他模块使用。这样一来同一个相机承担了两个任务硬件成本没有增加系统集成度反而更高。不过要注意如果项目对 IMU 的零偏稳定性要求很高比如长时间在剧烈振动环境下工作D435i 内置的消费级 IMU 可能会成为精度瓶颈到时候建议外加一个独立 IMU并把 IMU 和激光雷达的外参单独标定。2. 前期准备驱动安装与数据链路打通2.1 MID360 驱动与话题验证MID360 必须使用 livox_ros_driver2而不是老的 livox_ros_driver这一点很多人一上来就踩坑。老驱动主要适配的是 Horizon、HAP 这类一代雷达MID360 的消息定义和接口都不完全兼容直接用老驱动编译没问题但就是不出点云或者点云形状明显不对。安装方式是把它放进工作空间的 src 目录比如cd ~/catkin_ws/src git clone https://github.com/Livox-SDK/livox_ros_driver2.git cd ~/catkin_ws catkin_make source devel/setup.bash连接雷达后通过 udp 方式启动roslaunch livox_ros_driver2 msg_MID360.launch启动后可以用 rostopic list 确认话题重点看/livox/lidar是否在输出。默认情况下这个 launch 输出的是 livox_ros_driver2/CustomMsg 类型的点云话题R3LIVE 默认订阅的就是这个类型所以这里保持默认即可。如果你在其他项目里需要标准 sensor_msgs/PointCloud2 类型可以在 launch 里把pointcloud_type参数改成 1但跑 R3LIVE 时建议不要改否则后续话题类型不匹配还得在 R3LIVE 里改订阅接口。确认点云数据正常可以用 rviz 订阅/livox/lidar能看到实时扫描的点云。这里有一个细节MID360 的雷达数据里包含反射强度和点的时间戳偏移CustomMsg 类型会比 PointCloud2 多携带每点的时间偏移字段R3LIVE 做去畸变时会用到这个信息所以尽量保持 CustomMsg 不变。2.2 D435i 驱动与图像/IMU 话题验证D435i 的驱动是 realsense-ros官方维护得比较勤直接源码编译或者 apt 安装都行。我用的是源码编译方式cd ~/catkin_ws/src git clone https://github.com/IntelRealSense/realsense-ros.git cd ~/catkin_ws catkin_make source devel/setup.bash启动的时候建议直接用带 IMU 的 launchroslaunch realsense2_camera rs_camera.launch unite_imu_method:linear_interpolation这里unite_imu_method:linear_interpolation是把加速度计和陀螺仪的数据在时间上对齐合并成一个 IMU 消息输出。R3LIVE 需要 IMU 频率和加速度、角速度数据一般会订阅/camera/imu话题。如果这里不加这个参数IMU 会分成/camera/accel/imu_info和/camera/gyro/imu_info之类多个话题配置起来更麻烦。启动之后留意几个话题/camera/color/image_raw彩色图像R3LIVE 的主输入之一/camera/imu加速度计和陀螺仪合并后的 IMU 数据/camera/color/camera_info相机内参信息因为 D435i 出厂默认内参会写入相机本身realsense-ros 会直接把这些内参放到 camera_info 话题里。这对 R3LIVE 是好事它启动时会从/camera/color/camera_info读取内参不需要手动填。但如果后续用 Kalibr 重标过相机内参记得要么在 realsense-ros 里覆盖内参文件要么直接在 R3LIVE 的配置里手动填入标定后的内参否则两个内参不一致会直接影响视觉约束的效果。在跑 R3LIVE 之前我建议先录一段数据看看话题时间戳和帧率。一个很常见的坑是realsense-ros 默认输出的图像是 1280x720 或者更高分辨率帧率有时候会掉到 15fps 甚至更低而 R3LIVE 对图像帧率比较敏感频率太低会导致视觉帧间隔过大。所以在配置里提前把彩色流分辨率设为 640x480、帧率设为 30fps能避免后期很多麻烦。3. 标定流程从相机内参到全局外参3.1 内参标定D435i 彩色相机虽然 D435i 出厂带了内参但我还是建议实际标一次。原因很简单出厂内参在个体之间存在差异尤其是相机被摔过、温度变化大、或者换了镜头模组之后出厂值可能偏得比较明显。对于 R3LIVE 这种紧耦合系统内参错了视觉投影误差会慢慢累积成地图重影且极难排查。标定内参我用的是 Kalibr因为后面标相机到 IMU 外参也需要 Kalibr一套工具链用到底不用在中途切换。准备工作是打印一张 kalibr 支持的目标板我常用 apirlgrid 6x6 型号打印后贴在平整硬板上注意不要让纸张有褶皱否则角点提取精度会受影响。标定过程大致是rosbag record -O camera_calib.bag /camera/color/image_raw录制时拿着标定板在相机前慢慢移动覆盖画面中心和边缘尽量让标定板在画面中处于不同角度和距离大概录 60 到 90 秒。然后运行kalibr_calibrate_cameras --bag camera_calib.bag --topics /camera/color/image_raw --models pinhole-equi --target aprilgrid_6x6.yamlpinhole-equi 模型是 Kalibr 里对旋转对称畸变的常见选择。运行完会得到一个camchain-xxx.yaml文件里面就是 fx、fy、cx、cy 和畸变系数。拿到之后可以先把这些值记下来后面 R3LIVE 的外参计算和 launch 配置都会用到。这里要多说一句相机标定不要只标一次就完事。我在项目里有一个习惯每次更换相机固定座、拆装镜头之后都会重标一遍内参。内参和外参是强耦合的内参偏一点你后面就算把外参调到最优视觉重投影误差还是达不到理想值。3.2 IMU 标定与相机-IMU 外参D435i 内置 IMU 不是专门为高精度 SLAM 设计的所以出厂数据里的噪声密度和随机游走参数不一定能直接满足 R3LIVE 的需求。虽然 R3LIVE 本身能在线估计 IMU 零偏但提前获取一份 IMU 的 noise density 和随机游走值写进配置里能明显减少系统启动初期的收敛时间。IMU 的标定工具我推荐 imu_utils这个包需要配合一个静止放置的 IMU 数据包使用。操作方法是把 D435i 平放在桌面上静置两小时以上其实 imu_utils 官方推荐至少静止录两个小时这个时间有点长但实际录一两个小时并不算夸张。录制命令rosbag record -O imu_static.bag /camera/imu然后用 imu_utils 处理得到imu_imu.yaml文件里面包含加速度计和陀螺仪的噪声密度及随机游走。对于 D435i 这种消费级 IMU数据一般差强人意但至少比没有强。接下来是相机到 IMU 的外参标定。这一步在 Kalibr 里是一套完整流程先准备好 IMU 数据话题和图像话题然后执行kalibr_calibrate_imu_camera --bag camera_imu_calib.bag --cam camchain.yaml --imu imu_imu.yaml --target aprilgrid_6x6.yaml跑完之后会输出相机坐标系到 IMU 坐标系的旋转和平移以及时间延迟。这里的输出就是后面计算雷达到 IMU 外参的中间量。需要留意的是Kalibr 计算出的外参定义是 IMU 到相机还是相机到 IMU不同版本的文档注释有差异拿到结果后建议先在 rviz 里做一次投影验证确认旋转方向是对的再往下走。3.3 激光雷达-相机外参标定MID360 到 D435i 彩色相机的外参可以通过 Livox 官方开源的livox_camera_lidar_calibration工具来标也可以用其他通用标定方案。这个工具的原理是利用一块已知尺寸的标定板同时提取点云中的平面约束和图像中的棋盘格角点通过非线性优化求出雷达坐标系到相机坐标系的变换。标定操作大概分几步准备一块足够大的标定板推荐棋盘格边长至少 5cm 以上的型号因为 MID360 是非重复扫描点云比较稀疏标定板太小了点云落到板面上的点太少平面拟合精度会差。启动 MID360 和 D435i让雷达和相机同时看到标定板板子距离传感器 1 到 3 米之间姿态倾斜一些不要正对。采集一段数据用工具自带的点选界面在图像上选棋盘格角点在点云上选标定板边缘点自动拟合平面。优化输出外参通常会给出旋转矩阵和平移向量保存下来。这个环节容易出问题的地方是点云里的标定板很难选准。MID360 在近距离上的点云密度并不高尤其如果标定板是黑色边框、表面不太反光点云返回的反射强度很弱平面拟合出来会偏。我的建议是在采集数据之前先用抹布把标定板表面擦干净保证漫反射板子尽量选哑光材质不要用玻璃或者高反光表面。另外标定过程中让标定板在整个视场里保持静止至少 2 到 3 秒不要一直晃否则点云叠加后平面会模糊。拿到激光雷达到相机的外参之后再结合 Kalibr 输出的相机到 IMU 外参就能算出激光雷达到 IMU 的外参。计算公式很简单T_lidar_to_imu T_camera_to_imu * T_lidar_to_cameraT 代表 4x4 齐次变换矩阵顺序不能反实际编程时建议用 Eigen 或者 tf2 把每一步都打出来核对。3.4 外参串联与 launch 配置R3LIVE 的 launch 文件里需要填写两个参数extrinsic_R和extrinsic_T一般表示从雷达坐标系到 IMU 坐标系的外参。extrinsic_R是一个 9 元素的旋转矩阵字符串按行优先写入extrinsic_T是 3 元素的平移向量字符串。比如标定得到旋转矩阵的 9 个数值是r00, r01, r02, r10, r11, r12, r20, r21, r22平移是tx, ty, tz那么在 launch 里填arg nameextrinsic_R defaultr00,r01,r02,r10,r11,r12,r20,r21,r22 / arg nameextrinsic_T defaulttx,ty,tz /填写前一定要确认坐标系方向。R3LIVE 源码注释里对extrinsic 表示哪个坐标系到哪个坐标系在不同版本里写得不完全一样我的做法是先用标定结果直接填然后在 rviz 里叠加显示相机图像投影和雷达点云如果彩色点云边缘和图像边缘明显错开就交换旋转方向再试。这个方法虽然朴素但比盯着矩阵判断哪个是 R 哪个是 R 的转置可靠得多。外参填完也别急着跑真机可以先找一个有丰富几何特征的场景反复走几遍观察彩色地图里墙面、门框的线条是否干净。如果地图边缘重影明显大概率是外参平移量有偏差如果整体旋转导致地图歪斜大概率是旋转矩阵方向反了。标定不是一次性的我实际调这一套外参就花了大概一个下午反复标定、反复进 rviz 看才把重投影误差控制在可接受范围。4. R3LIVE 编译部署与 launch 参数详解4.1 环境与依赖R3LIVE 主要在 ROS 1 环境下运行我用的系统是 Ubuntu 20.04 ROS Noetic。依赖不算复杂但建议按顺序装齐避免编译到一半缺库sudo apt install libgoogle-glog-dev libgflags-dev libeigen3-dev libpcl-dev libopencv-dev ros-noetic-pcl-ros ros-noetic-cv-bridge ros-noetic-image-transport然后是 R3LIVE 本体mkdir -p ~/r3live_ws/src cd ~/r3live_ws/src git clone https://github.com/hku-mars/r3live.git cd ~/r3live_ws catkin_make source devel/setup.bash如果前面已经在 catkin_ws 里编译过 livox_ros_driver2 和 realsense-ros也可以直接把 r3live 放进同一个工作空间编译时一起 catkin_make这样后续启动时环境变量不用切来切去。需要注意R3LIVE 编译时对 Eigen 和 OpenCV 的版本有要求不要图省事装太新的 OpenCV4.2 以下通常没问题太新的版本偶尔会编译报错。4.2 launch 配置与外参填入R3LIVE 的 launch 文件一般在r3live/r3live/launch/r3live.launch。打开之后需要重点改三处雷达话题名、图像话题名、外参。雷达话题默认是/livox/lidar这个对应 MID360 驱动默认输出不用改。图像话题默认可能是/camera/color/image_raw和 realsense-ros 默认输出一致也不用改。IMU 话题默认应该是/imu/data或者/camera/imu一类的名字如果你的 D435i 是直接启动驱动IMU 话题大概率是/camera/imu那就在 launch 里把 IMU 话题参数改成/camera/imu。外参填法在 3.4 节说过这里不再重复。剩下一个比较隐蔽的参数是图像分辨率。R3LIVE 默认可能期望 640x480 的输入如果你在 D435i 驱动里把分辨率设置成了 1280x720可能也能跑但每帧的图像处理时间会明显增加导致实时性下降。建议在 realsense 的 launch 里提前固定彩色流参数arg namecolor_width default640/ arg namecolor_height default480/ arg namecolor_fps default30/这样 R3LIVE 收到的图像尺寸就是它最熟悉的形态处理速度和视觉特征提取效果都比较均衡。4.3 启动与初始化注意事项所有配置完成后启动顺序建议如下# 终端1启动 MID360 驱动 roslaunch livox_ros_driver2 msg_MID360.launch # 终端2启动 D435i 驱动 roslaunch realsense2_camera rs_camera.launch unite_imu_method:linear_interpolation # 终端3启动 R3LIVE roslaunch r3live r3live.launchR3LIVE 启动时会有一段初始化过程这个过程非常关键。很多人启动后看到点云没有立刻变彩色就以为系统没跑起来其实是因为初始化阶段激光雷达和相机的数据还没有对齐。我的经验是启动前先把机器人放置在静止状态等 R3LIVE 的日志里出现初始化完成的提示之后再缓慢移动机器人。如果一启动就大力晃动初始化期的视觉和激光匹配很容易发散表现为位姿突然跳变、地图飘飞。初次运行建议开着 rviz加载 R3LIVE 提供的r3live.rviz配置文件重点观察三个东西/laser_cloud_vis实时点云、/rgb_cloud_vis彩色点云、以及/path_vis轨迹。彩色点云正常出现后说明视觉约束已经参与优化整套系统基本跑通了。5. 运行调优与常见问题排查5.1 实时运行效果与参数调优R3LIVE 跑起来是一回事跑得稳是另一回事。我在实际项目中主要调过几个参数位置在r3live/r3live/config/r3live_config.yaml里。第一个是图像分辨率相关的视觉处理参数。如果 CPU 负载过高可以适当降低图像金字塔层数或者减少每帧提取的特征点数量。这个要看你电脑的算力来权衡我的建议是先保持默认跑一版用top观察 CPU 占用如果某个核长期占满再考虑降参数。第二个是点云体素滤波参数。R3LIVE 会把地图维护成体素结构体素大小直接决定地图细节度和内存占用。默认值在室内场景表现不错但如果在户外或者面积很大的厂房体素可以适当调大一点减少地图点数量防止内存爆炸。体素太小会导致地图点太多体素太大则地图细节丢失这个参数需要根据场景反复试。第三个是 IMU 相关参数。如果你从 imu_utils 拿到了 D435i 的噪声密度和随机游走记得填进配置里。不少人忽略这一步系统也能跑但初始化阶段会多花几秒甚至十几秒去估计 IMU 零偏而且在运动激励不足的场景里容易初始化失败。调参没有万能公式我个人的建议是每次只改一个参数记录修改前后的地图重影和轨迹漂移情况。多传感器融合系统的参数是强耦合的一次改好几个参数出了问题很难定位是哪一项导致的。5.2 常见问题速查表我把这次部署中遇到的典型问题整理成了一张表方便快速对照。现象可能原因排查与解决办法启动后一直没有彩色点云图像话题没有数据或 R3LIVE 订阅的话题名和驱动输出不一致用rostopic hz /camera/color/image_raw检查图像频率用rostopic info确认话题类型点云整体抖动或地图重影外参不准确尤其是旋转矩阵方向错误回到 rviz 做投影对齐检查调整 extrinsic_R 旋转方向初始化阶段系统发散启动时机器人移动太快或外参误差过大静止放置 3 到 5 秒后再移动重新检查外参精度CPU 占用过高实时性差图像分辨率过高特征提取数量过大把彩色图像降到 640x480减少视觉特征数量地图颜色和实际场景对不上相机曝光时间设置不当或自动曝光开启固定曝光时间避免图像亮度剧烈变化影响视觉匹配长时间运行后轨迹漂移明显IMU 数据质量差或时间戳同步不严格检查 IMU 话题频率必要时换独立 IMU或者用硬件同步线缆关于时间戳同步这个值得单独说。D435i 和 MID360 是两套独立设备时间戳来自各自驱动在没有硬件同步信号的情况下两者之间存在几毫秒到几十毫秒的偏差。R3LIVE 对这种偏差有一定容忍度但如果偏差过大系统会表现为初始化困难或者运行中位姿跳变。如果项目对精度要求高建议给两套设备接同一个外部时钟源或者在录制 rosbag 时使用rosparam set /use_sim_time true配合时钟源做离线对齐。对于原型验证阶段软件时间同步基本够用但要心里有数没有硬件同步系统长期运行的稳定性上限会降低。还有一个小坑D435i 内置 IMU 的坐标系方向和相机彩色图坐标系方向并不完全一致realsense-ros 会做一部分转换但如果你在 Kalibr 标定时把 IMU 话题直接给进去一定要确认 IMU 数据的加速度方向。有些数据集里加速度方向反了会导致 R3LIVE 的重力估计完全相反表现为点云地图翻转非常难排查。5.3 关于 FAST-LIO 建图的横向对比很多人在部署完 MID360 之后会顺手用 FAST-LIO 做一版建图我也这么干过。FAST-LIO 是纯激光惯导融合方案既不需要相机标定也不需要视觉处理启动非常简单适应性强在没有纹理的场景里也能稳定运行。但它输出的是不带颜色的雷达点云图而且因为没有视觉修正在长走廊、大平面这类退化场景里激光里程计仍然会有累积漂移只是漂移速度比纯雷达方案慢一些。R3LIVE 的优势在环境有足够纹理信息时体现得最明显。比如室内办公区、仓库货架区墙面上的标识、货架上的标签都能提供很丰富的视觉约束地图明显更紧实颜色信息也能直接用于后续分割。反过来如果环境是纯白色墙面或者空旷的地下停车场视觉约束很少R3LIVE 的表现就会退化到接近纯激光惯导的水平但还多了相机标定的复杂度。所以我的建议是如果项目只要求几何定位不要求颜色地图MID360 FAST-LIO 是更省事的组合如果要做彩色地图、要带视觉回环或者需要给后续感知模块提供纹理信息那才值得上 R3LIVE。前期多花在标定上的功夫在后期建图质量和系统稳定性上都会赚回来。6. 一些实操体会与扩展方向整套系统从零开始配置到稳定运行我大概花了两个工作日。如果只算纯跑通流程可能半天就够但真正把地图质量调到满意的状态时间基本都耗在标定和参数微调上。尤其是激光雷达到相机外参我反复标了三次才让自己满意。第一次标完直接跑彩色地图边缘发虚第二次发现是标定板在点云里提取的平面不够准第三次换了更大的标定板、放慢采集动作效果才明显好起来。我的经验是多传感器融合项目的坑九成在数据质量不在算法本身。传感器时间戳对不对、话题频率稳不稳、标定板干不干净、启动时机器人动不动这些细节决定了 R3LIVE 能不能发挥出论文里的效果。与其迷信参数调优不如先花时间把数据链路检查干净很多看似玄学的漂移问题最后发现都是时间戳偏差导致。后续如果要在真机上长跑我建议在这个方案之外加两个模块一是保存 rosbag定期回放做离线标定复核二是引入回环检测R3LIVE 本身不内置全局回环长时间大范围运行时累积漂移会成为主要矛盾外部再接一个回环模块或者定期用其他建图方法做闭环修正整套系统才更接近可交付状态。
返回列表