文章

ORB-SLAM3 VIO 初始化失败:你可能不缺传感器,而是缺运动激励

从机器人 rosbag 诊断出发,解释纯旋转为什么无法稳定完成惯性初始化,以及应该如何录制可观测的数据。

ORB-SLAM3 VIO 初始化失败:你可能不缺传感器,而是缺运动激励

VIO 初始化失败时,人们通常先检查话题有没有录全:RGB、Depth、陀螺仪、加速度计、内外参和时间戳。如果这些都在,问题就显得很神秘。一次 Codex 历史会话里,我对机器人录制的 ROS2 bag、转换结果和 ORB-SLAM3 源码逐项核对,结论却是:通道没有缺,缺的是足够强、持续且多方向的平移加速度变化。

视觉能跟踪,不代表惯性可初始化

普通 RGB-D SLAM 可以依赖图像特征和深度恢复相机运动。RGB-D-Inertial 模式还要估计重力方向、速度与 IMU bias,它需要运动为这些变量提供可观测性。

一段“画面动得很明显”的数据,可能只是机器人原地转头。视觉会看到大量像素变化,陀螺仪也有清晰角速度,但加速度计主要仍是恒定重力和噪声。纯旋转不足以把重力、线性加速度和 bias 稳定分离。

这解释了一个常见现象:同一段 bag 用普通 RGB-D 可以完整跟踪,换成 IMU_RGBD 却一直停留在 NOT_INITIALIZED。这不首先说明相机画质差,而是两种模式需要的状态可观测性不同。

初始化包含不止一道门槛

在当时检查的 ORB-SLAM3 工作树和默认配置中,惯性初始化至少涉及这些条件:

  • 当前画面有足够 ORB 特征,代码路径检查超过 500 个特征点;
  • 相邻帧拥有完整 IMU 预积分;
  • IMU.fastInit=0 时,相邻窗口平均加速度变化达到约 0.5 m/s²
  • 建图后积累至少约 10 个关键帧和 1 秒数据;
  • 关键帧之间存在足够平移;
  • 后续持续运动,让约 5 秒与 15 秒处的两轮惯性 BA 有机会完成。

具体阈值会随版本和分支变化,排障时应以正在运行的源码为准,而不是把这组数字当成永恒配置。重要的是理解它们在筛选什么:不是“有没有 IMU 消息”,而是这些消息是否包含足以约束状态的变化。

用统计量区分静止、纯旋转和有效激励

那次会话把相邻图像窗口内的平均加速度做差。几段失败数据的最大变化约为 0.10–0.25 m/s²,低于源码中的 0.5 m/s² 检查;最初两秒甚至只有约 0.08–0.10 m/s²。整体各轴标准差接近静止噪声水平。

这类统计比“看视频感觉动得挺多”可靠。可以同时检查:

  • 平均加速度差的峰值和分布;
  • 角速度积分,判断是否以旋转为主;
  • RGB-D 位姿中的平移幅度;
  • 图像与 IMU 的频率、时间跨度和最大 gap;
  • 每个图像区间是否都有可积分的 IMU 样本;
  • 关键帧数量与初始化状态随时间的变化。

如果 acceleration 近似常数、角速度明显、视觉平移很小,那么问题通常不是“IMU 太差”,而是运动模式对初始化不友好。

新数据应该怎样录

初始化阶段不要长时间静止,也不要只原地转动。更有效的动作是:

  1. 向前移动并明确加速、刹停;
  2. 左右平移并改变方向;
  3. 条件允许时加入少量上下运动;
  4. 走小型 8 字,同时保证存在速度变化;
  5. 持续 15–20 秒,让后续惯性优化有足够数据。

关键不是“走得远”,而是产生加速、减速与多轴方向变化。匀速直线同样可能缺乏足够激励。动作也不应剧烈到造成运动模糊或深度失效。

同步质量同样重要。图像、深度和 IMU 应使用一致时间基准;gyro/accel 中的长 gap 会破坏预积分。场景还要有稳定纹理和有效深度,避免把运动可观测性修好后又遇到纯视觉退化。

fastInit 不是补数据的开关

打开 IMU.fastInit 可以跳过前面某个加速度变化检查,但不能凭空创造平移信息。那批数据即使绕过早期门槛,后续运动可观测性检查仍会触发地图重置,甚至在病态优化中出现 NaN。

参数开关适合已知运动条件下的工程取舍,不适合用来掩盖数据本身不满足估计问题。若普通 RGB-D 能跑、时间与标定也合理,而惯性模式始终失败,应优先重新录制含多方向平移和加减速的数据。

VIO 排障最重要的观念是:传感器“存在”、数值“连续”和状态“可观测”是三件不同的事。初始化器真正需要的是第三件。

参考项目:UZ-SLAMLab/ORB_SLAM3

本文由作者按照 CC BY 4.0 进行授权