3.2 跟踪与 SLAM


3.2 跟踪与 SLAM

本节摘要:XR 第一道门槛是"知道我在哪、头转到哪"。这由 6DoF 跟踪系统解决。本节拆开视觉惯性里程计(VIO)的工作原理、Inside-out 与 Outside-in 两条工程路线、SLAM 的图优化(Pose Graph Optimization);再用一个最小代码演示如何在 Unity 里订阅头手 6DoF 数据。

学习目标

阅读完本节,你应当能够:

  1. 解释 VIO 的工作原理,并说出 IMU 失效的 3 种场景。
  2. 比较 Inside-out 与 Outside-in 的工程差异。
  3. 描述 SLAM 的 Pose Graph Optimization 是什么。
  4. 在 Unity 里订阅头手 6DoF 数据。

一、问题与直觉

XR 头显的"动"有三个层次:

  • 3DoF:只跟踪旋转(俯仰/偏航/翻滚),不跟踪位置。这是 Google Glass 第一代的水平。
  • 6DoF:同时跟踪旋转+位置(X/Y/Z + 俯仰/偏航/翻滚)。这是当前消费 XR 的事实标准。
  • 3DoF 眼动 + 6DoF 头手:眼动 3DoF + 头 6DoF + 手 6DoF。Vision Pro 的最高配置。

要拿到 6DoF,必须解决"绝对位置"问题——这要靠 SLAM。

二、视觉惯性里程计(VIO)

VIO(Visual-Inertial Odometry)把两个传感器合起来用:

  • 视觉(Visual):摄像头拍 30fps 图像,每帧提取特征点(ORB 特征,约 1000 个/帧),做特征匹配,得到图像间相对运动。
  • 惯性(Inertial):IMU(加速度计+陀螺仪+磁力计)跑 200-1000Hz,给出高频加速度+角速度。
  • 融合:用扩展卡尔曼滤波(EKF)或图优化(Bundle Adjustment)把两个数据源融合。

VIO 解决的是"我这一秒到下一秒的相对运动"。它的输出是 6DoF 位姿,延迟 5-15ms,精度 1cm 以内。但它有两个失效场景:

  1. 低纹理场景:白墙、白纸、强反光(玻璃/镜子)——没有可提取的特征点。
  2. 快速运动:转得太快,图像模糊,特征点匹配失败。

ARCore 解决方法是"运动追踪(Motion Tracking)"和"深度(Depth)"两个 API 配合——深度图能补强低纹理场景。ARKit 用 Visual-Inertial Odometry + ARKit 自研的特征描述子。

三、Inside-out vs Outside-in

第 2 章硬件那一节我们提过,这里展开工程细节:

  • Outside-in:外置基站(Vive Lighthouse 用红外激光扫描,SteamVR 2.0 用摄像头)。基站发出扫描线,头显/手柄上的传感器收到后反推位置。优点是亚毫米精度,缺点是要装基站、固定空间。
  • Inside-out:头显自带摄像头拍环境,特征点匹配得到位姿。优点是无需外设、可跨房间,缺点是受光照/反光影响。

Quest 3 是 Inside-out 标杆:4 颗鱼眼摄像头(前面 2 颗 + 两侧 2 颗)+ 红外泛光照明,6DoF 误差 <1cm,房间尺度漂移 <5mm/分钟。Vision Pro 用 2 颗鱼眼 + 2 颗 LiDAR,LiDAR 提供深度辅助,能在低纹理场景下更稳。

四、SLAM:建图+定位的双向过程

VIO 是"里程计"——只关心相对运动。SLAM(Simultaneous Localization and Mapping)在 VIO 基础上同时建图:每 10-30 秒做一次"回环检测"(Loop Closure)——当前位置和曾经到过的位置相似时,做一次图优化(Pose Graph Optimization)把累积漂移修正掉。

回环检测的关键技术:

  • 词袋模型(Bag of Words):用 SURF/ORB 特征聚类成 10000 个"视觉单词",当前位置的"视觉单词分布"和数据库比对。
  • 几何验证:候选位置再用 RANSAC 做基础矩阵估计,过滤掉误匹配。

Pose Graph Optimization 把"头转过的路径"建成一个图——每个节点是某一时刻的位姿,每条边是相邻两时刻的相对运动。回环检测发现"这两时刻在同一位置"时,新增一条边。优化求解时用 g2o / GTSAM 这类图优化库,把所有节点的位置+朝向同时优化,把累积漂移修正掉。

⚠️ 常见坑:很多团队以为用 VIO 就够了。但 VIO 的累积漂移在 10 分钟后会达到 1m 级——必须叠加 SLAM 回环检测。在 AR 锚点这种"贴在墙上过 10 分钟还要找得到"的场景,回环是必须的。

五、动手演示:订阅 6DoF 数据

Unity + OpenXR 里订阅头部和手柄 6DoF:

using UnityEngine.XR; public class XrInputReader : MonoBehaviour { void Update() { // 1. 头部 6DoF var head = InputDevices.GetDeviceAtXRNode(XRNode.Head); if (head.TryGetFeatureValue(CommonUsages.devicePosition, out Vector3 headPos) && head.TryGetFeatureValue(CommonUsages.deviceRotation, out Quaternion headRot)) { Debug.Log($"头位置: {headPos:F3} 旋转: {headRot.eulerAngles:F1}"); } // 2. 右手 6DoF var rightHand = InputDevices.GetDeviceAtXRNode(XRNode.RightHand); if (rightHand.TryGetFeatureValue(CommonUsages.devicePosition, out Vector3 rPos) && rightHand.TryGetFeatureValue(CommonUsages.deviceRotation, out Quaternion rRot)) { Debug.Log($"右手: {rPos:F3}"); } // 3. 手柄按键 if (rightHand.TryGetFeatureValue(CommonUsages.triggerButton, out bool trigger)) if (trigger) Debug.Log("扳机按下"); } }

把这段代码放到空场景里,戴上头显挥挥手——你就能在 Console 看到 6DoF 数据流。

本节要点回顾

  • 6DoF 跟踪的"母技术"是 VIO(视觉+IMU 融合)。
  • VIO 在低纹理+快速运动两个场景失效——ARCore/ARKit 靠深度信息补强。
  • Inside-out 是消费 XR 主流,Outside-in 退守工业。
  • SLAM 在 VIO 基础上加"回环检测+图优化",把累积漂移修正掉。
  • Unity + OpenXR 订阅 6DoF 数据 5 行代码搞定。

图 3-2:VIO 视觉惯性融合数据流

把 VIO(视觉+IMU 融合)的数据流画出来——能直观看到高频 IMU 与低频视觉怎么融合。

图 3-2:VIO 视觉惯性融合数据流

下一节我们看第三个支柱:空间重建——SLAM 给完"我在哪"之后,怎么回答"周围是什么"。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U