管理会话生命周期和追踪质量

无论是在当前的会话状态还是从中断中恢复都能够保证用户得到通知


概述

世界追踪的AR会话使用了一个称为视觉惯性测距(visual-inertial odometry) 的技术。这个过程通过将摄像头的图像进行计算机视觉分析与运动传感器数据相结合,来追踪设备在真实世界中的位置和方向,也被称为姿态(pose),并在ARCamera transform属性中表述出来。为了得到最好的结果,世界追踪需要持续不断的传感器数据和具有视觉复杂度或者可识别特征的摄像头图像。

当你开始一个会话的时候,ARKit需要花一点时间来收集足够的数据来对设备姿态进行建模。在一个会话中,影响世界追踪质量的条件会发生变化。可以使用ARSessionObserver代理方法和ARCamera属性来跟踪这些变化。

基础生命周期和AR会话

下图展示了当你开始运行AR会话时追踪状态的变化

不可用 受限(初始化中) 正常

当你刚刚运行一个会话的时候,对于提供的帧的追踪状态是ARCamera.TrackingState.notAvailable , 表示ARKit还没有收集到可以预估设备姿态的足够信息。

处理一些帧之后,追踪状态将变为ARCamera.TrackingState.limited(_:) , 表示设备姿态可用,但是准确性不确定。受限的状态一般都包含一个原因就是较低的追踪质量;在这个例子中,会话的状态还是 ARCamera.TrackingState.Reason.initializing

在一小段时间之后,追踪状态变为了ARCamera.TrackingState.normal ,表示设备的姿态是准确的,同时所有的ARKit功能都可用。

针对追踪状态的变化提供反馈

下图展示了由用户交互或者环境变化引起的追踪状态变化

正常 受限(特征不足) 正常

当追踪状态是ARCamera.TrackingState.limited(_:) ,基于ARKit对用户本地环境映射的特性都不可用:

  • 平面检测不会添加或者更新平面锚点
  • 重装检测不会提供返回结果

由于用户本地环境变化或者用户移动设备的原因,一个会话可以在任何时间进入ARCamera.TrackingState.limited(_:) 状态。例如,如果用户将设备指向一面空白的墙面或者房间的灯光被关掉,追踪质量就有可能降低到ARCamera.TrackingState.Reason.insufficientFeatures

通过ARCamera.TrackingState.Reason 关联的值来为用户提供反馈并引导用户解决问题,便可以将追踪状态变回到ARCamera.TrackingState.normal

从会话中断中恢复

如果没有ARSession,ARKit便无法追踪设备姿态。默认来说,如果你的会话被中断(例如,切换到其他app),会话中跟真实世界相关的任何虚拟内容都有可能不在原地。

你可以使用重定位(relocalization) 来从中断中恢复。如果你的sessionShouldAttemptRelocalization(_:) 方法返回 true,ARKit会通过当前的相机和传感器数据尝试重建中断之前的用户环境认知。在这个过程中,追踪状态为ARCamera.TrackingState.limited(_:) (原因是ARCamera.TrackingState.Reason.relocalizing )。如果成功,追踪状态将会在短时间内回到ARCamera.TrackingState.normal

正常 中断 不可用 受限(初始化中) 受限(重定位) 正常

如果想要重定位成功,设备的位置和方向必须回到靠近会话被中断的地方。如果这个情况永远不会发生(例如,如果设备被移动到了一个完全不同的环境),会话将会一直停留在ARCamera.TrackingState.Reason.relocalizing 状态。

重要

当你的app在ARCamera.TrackingState.Reason.relocalizing 状态时,请提供给用户一个可以重置会话的途径(同时提供run(_:options:) and resetTracking),以防重定向永远不成功

创建一个持久化的AR体验

iOS12.0以及之后,ARWorldMap 类储存了ARKit用来恢复会话的信息。通过将一个世界地图存储到文件,无论是短暂的中断还是较早的会话,即使你的app被重启,你都可以使用同样的重定位进程恢复会话。世界地图包含了众多锚点,因此你也可以替换虚拟内容以匹配之前的会话。

重要

使用ARWorldMap 恢复一个会话的可靠性强烈依赖于真实世界的环境。例如,在室内人工灯光下记录的地图,或者之前准备的捕获了片刻的地图是非常容易重定位成功的。如果灯光条件或者本地环境的特征一直发生变化,那么成功的概率会降低很多。

正常 保存地图 app关闭/重启 加载地图 受限(初始化中) 受限(重定位) 正常

想要允许用户在离开你的app之后返回同样的AR会话,你可能需要明确的基于一个用户操作,或者自动的在applicationDidEnterBackground(_:) 触发后保存世界地图。只有在你的AR会话拥有值得保存的状态时再保存世界地图-例如,用户放置了你想要记录位置的虚拟物体,同时会话的状态处于ARFrame.WorldMappingStatus.mapped (或者在这次会话中至少一次处于过该状态)。

为了重定位一个保存过的世界地图,需要在运行会话的时候使用initialWorldMap 属性。当从一个中断中恢复时,会话开始于ARCamera.TrackingState.limited(_:) (ARCamera.TrackingState.Reason.relocalizing) 追踪状态。如果ARKit可以使得世界地图和当前环境一直,那么追踪状态将在一小段时间后变为ARCamera.TrackingState.normal ,即表示会话与记录的世界地图匹配。

Tip

为了重定位的成功,设备需要访问本地环境中它在创建地图前穿过的区域-- 你可能需要如下任务来帮助用户完成重定位,即通过存储带有世界地图的截图并在用户尝试重定位的时候将该截图展示为放置引导。

一个从世界地图中恢复的会话包含了世界地图中保存的所有锚点。如果你使用name属性来识别你放置锚点的虚拟物体,你可以将恢复会话中的锚点用于虚拟内容的重建。为了保证这些内容放置的准确,只有在追踪状态变为ARCamera.TrackingState.normal 之后再进行展示

如果ARKit无法将记录的世界地图和当前的环境一致化(例如,如果设备处于跟之前世界地图被记录的地方完全不同的地点),会话将会一直处于ARCamera.TrackingState.Reason.relocalizing 。为用户提供重启会话的渠道以避免用户无法恢复会话。如果放弃世界地图的重定位,需要在会话上再次调用run(_:options:) ,并且resetTracking 作为option参数,配置中initialWorldMap 属性的值为nil。