基于地理位置的AR(Geography Location Based AR,以下简称地理AR)因其巨大的潜在价值而受到广泛关注,通过将AR虚拟物体放置在真实世界经纬坐标上,可以实现如真实物体一样的自然效果,并支持持久共享。例如,可以在高速路两侧设置AR电子标志、虚拟路障、道路信息,一方面可以大大降低使用实物的成本;另一方面可以极大地提高信息反应速度,提高道路使用效率。
地理AR是非常具有前景的应用形态,但目前也面临很多问题,最主要的问题是定位系统的精度,在室外开阔的空间中,GPS/北斗等导航系统定位精度还不能满足AR需求,而且也受到很多因素的影响,如高楼遮挡、多径效应、方位不确定性等,无法仅凭GPS/北斗等导航系统确定虚拟物体(或者移动设备)的姿态。
ARKit已经在这方面进行了探索尝试,通过综合GPS、设备电子罗盘、环境特征等各方面信息确定设备姿态。ARKit实现地理AR非常依赖GPS与环境特征信息,如果这两者中的一个存在问题,则整体表现出来的效果就会大打折扣。GPS信号来自卫星,环境特征信息来自地图,这里的地图不是普通意义上的地图,更确切的表述为点云地图,是事先采集的环境点云信息。当这两者均满足要求时,ARKit就可以融合解算出设备的姿态,也就可以正确地加载虚拟物体,实现虚拟物体姿态与真实世界经纬度的对齐。
在ARKit中,为了更好地使用地理AR,需要使用ARGeoTrackingConfiguration配置类和ARGeoAnchor锚点类,前者专用于处理与地理位置相关的AR事宜,后者用于将虚拟物体锚定在一个指定经纬度、海拔高度的位置上。
使用ARGeoTrackingConfiguration配置类启动的AR会话会综合GPS、设备电子罗盘、环境特征点信息数据进行设备姿态解算,如果所有条件都符合,则会输出设备的姿态。使用该配置类运行的AR会话也可以进行诸如平面检测、2D图像检测、3D物体检测之类的功能。另外,与所有其他类型应用一样,需要使用一个锚点将虚拟物体锚定到特定的位置,在地理AR中,这个锚点就是ARGeoAnchor。
ARKit为地理AR应用提供了与其他应用基本一致的操作界面,由于是锚定地理空间中的虚拟物体,所以ARGeoAnchor不仅需要有Transform信息,还需要有地理经纬坐标信息,并且ARGeoAnchor自身的 X 轴需要与地理东向对齐, Z 轴需要与地理南向对齐, Y 轴垂直向上,如图3-13所示。与其他所有锚点一样,ARGeoAnchor放置以后也不可以修改。
图3-13 ARGeoAnchor自身坐标轴与地理坐标轴对齐
进行地理位置定位不可控因素非常多,如GPS信号被遮挡、点云地图当前位置不可用等,都有可能导致设备位姿解算失败,ARKit引入了ARGeoTrackingState枚举,用于描述当前设备定位状态,AR应用运行时将处于表3-6中的某种状态。
表3-6 ARGeoTrackingState枚举值
在AR应用运行过程中,设备定位状态也会由于各种因素发生变化,如图3-14所示,只有当定位状态为ARGeoTrackingStateLocalized时才能有效地跟踪ARGeoAnchor。
图3-14 定位状态会在运行时不断地变化
当定位状态不可用时,ARKit使用ARGeoTrackingStateReason枚举描述出现问题的原因,开发人员可以实时地获取这些值,引导用户进行下一步操作,该枚举所包含的值如表3-7所示。
表3-7 ARGeoTrackingStateReason枚举值
为营造更好的用户体验,即使在定位成功(定位状态为ARGeoTrackingStateLocalized)时,ARKit也会根据当前定位的准确度将状态划分为若干精度级,由ARGeoTrackingStatus.Accuracy枚举描述,具体如表3-8所示。
表3-8 ARGeoTrackingStatus.Accuracy枚举值
ARKit对定位精度进行划分的目的是希望开发者能依据不同的精度制定不同的应对方案,定位精度越低,虚拟物体与定位点之间的误差就越大,表现出来就是虚拟物体偏移,如原来放置在公园大门前的虚拟物体会偏移到广场中间。针对不同的定位精度可以采用不同的策略,在定位精度较低时使虚拟物体不要过分依赖特定点,如飘浮在空中的热气球就比放置在门口的小木偶更适合,更不容易让使用者察觉到定位点的偏移。
提示
本节讨论的基于位置的AR相关技术均为原生ARKit类,目前在AR Foundation中,并没有完全实现相应的方法和枚举,因此需要开发者自行进行处理。
由于AR Foundation当前并不直接支持地理AR,因此需要通过Object-C原生代码进行桥接,在ARKit初始化前通过ConfigurationChooser类进行配置,引导ARKit使用ARGeoTrackingConfiguration配置进行初始化。同时,为了在原生代码与托管代码间传递ARSession对象,也需要对XRSessionSubsystem类nativePtr指针进行转换。
另外,使用地理AR需要iOS 14以上操作系统及A12以上处理器,而且只有苹果公司提供点云地图的区域(目前区域有限,仅北美地区若干城市和伦敦提供)才可以使用,由于需要使用GPS,因此需要开启GPS权限和支持网络连接。
下面以一个简单示例进行使用说明,该示例中,在获取当前设备位置姿态定位信息后,通过单击屏幕,在该地理位置添加一个ARGeoAnchor锚点
。
首先通过Object-C原生代码实现互操作类及方法,新建一个代码脚本文件,命名为GeoAnchorsNativeInterop.mm,编写代码如下:
图3-15 选择原生代码运行平台与所需特性
将该文件放置到Unity工程Assets/Plugins/iOS文件夹下(这里只是为了便于管理,放其他路径下也没关系),选中该文件,在属性窗口(Inspector窗口)中,勾选使用平台iOS和该平台框架ARKit后的复选框,如图3-15所示,以使GeoAnchorsNativeInterop代码能正确地在iOS平台下编译运行。
实现地理AR操作还是比较简单的,首先使用ARGeoTrackingConfiguration配置初始化ARKit,如果当前配置不是ARGeoTrackingConfiguration配置,则需要进行替换和重新初始化。在此基础上,打开设备GPS定位功能,如果定位成功,则可以在该地理坐标位置添加ARGeoAnchor锚点,进而可以添加虚拟物体。也可以通过查询该地理位置所有的ARGeoAnchor锚点,获取锚点后就可恢复所有的虚拟物体对象,从而实现持久化的基于真实地理位置的AR体验。创建一个C#脚本,命名为GeoAR,编写代码如下:
上述代码逻辑比较简单,使用时只需将该脚本挂载于场景中ARSession对象上。
使用ARKit地理AR需要满足GPS和点云地图同时可用才能正常运行,而基于真实地理位置的点云地图需要苹果公司预先对场景进行扫描并更新到地图中,由于地理信息的敏感性,国内使用还需时日。另外,开启GPS使用需要用户授权,所以AR应用应当在使用前进行GPS定位授权申请。