ARKit:使用摄像头和运动数据来绘制用户移动时本地的地图。
CoreLocation:使用WiFi和GPS数据来确定位置,精度比较低。
ARKit + CoreLocation:将高精度的AR与GPS数据相结合。
将这些技术结合起来的潜力是巨大的,在许多不同的领域有着很多的应用。 这个库有两个主要的特点:
- 允许使用真实世界的坐标将元素放置在AR世界中。
- 利用最近的位置数据点,并结合有关AR世界运动的知识,极大地提高了定位精度。
位置精度的改进目前还处于实验阶段,但在未来可能是最重要的组成部分。
由于目前还有一些工作尚未完成,并且存在其他方面的原因,因此最好由一个开放的社区来为这个项目服务,而不是通过GitHub Issues的方式。 所以我开放了一个Slack组,任何人都可以加入进来,讨论有关这个库的改进和大家的工作。
软硬件要求
ARKit需要iOS 11系统,并支持以下设备:
- iPhone 6S及以上
- iPhone SE
- iPad(2017)
- iPad Pro的所有型号
iOS 11可以从Apple的开发者网站上下载。
使用方法
这个库包含了ARKit和CoreLocation框架, 同时还包含了一个类似于Demo 1的演示程序。
使用CocoaPods进行设置
将本库添加到你的podfile中:
`pod 'ARCL'`
在终端中,进入你的项目目录,然后执行:
`pod update` `pod install`
- 添加
NSCameraUsageDescription
和NSLocationWhenInUseUsageDescription
到 plist文件中以添加一个简短说明(请参考演示项目)
手工设置
- 将
ARKit+CoreLocation/Source
目录中的所有文件添加到项目中。 - 导入ARKit、SceneKit、CoreLocation和MapKit。
- 添加
NSCameraUsageDescription
和NSLocationWhenInUseUsageDescription
到 plist文件中以添加一个简短说明(请参考演示项目)
快速入门指南
要在一座建筑物上放置一个标注点,例如伦敦的金丝雀码头,我们要使用包含ARCL的主要类:SceneLocationView
。
首先,导入ARCL和CoreLocation,然后将SceneLocationView声明为属性:
import ARCL
import CoreLocation
class ViewController: UIViewController {
var sceneLocationView = SceneLocationView()
}
当获取到焦点时,调用sceneLocationView.run()
,当中断时,调用sceneLocationView.pause()
,例如移动到不同的视角或者退出应用程序。
func viewDidLoad() {
override func viewDidLoad()
super.viewDidLoad()
sceneLocationView.run()
view.addSubview(sceneLocationView)
}
在调用run()
之后,就可以添加坐标了。 ARCL附带一个名为LocationNode
的类,它是3D场景中的一个对象,具有真实世界的位置,并且可以在世界范围内显示其他一些属性。 LocationNode
是SceneKit的SCNNode
的子类,也可以进一步子类化。 对于这个例子,我们将使用一个名为LocationAnnotationNode
的子类,我们用它在世界上显示一个总是面向我们的2D图像:
let coordinate = CLLocationCoordinate2D(latitude: 51.504571, longitude: -0.019717)
let location = CLLocation(coordinate: coordinate, altitude: 300)
let image = UIImage(named: "pin")!
let annotationNode = LocationAnnotationNode(location: location, image: image)
默认情况下,你设置的图像会以给定的尺寸显示出来,例如,如果你提供了一个100x100的图像,则会在屏幕上显示为100x100像素大小。 这意味着远处的注释点与近处的注释点看起来大小是相同的。 如果你希望按距离的远近进行缩放,可以将LocationAnnotationNode的scaleRelativeToDistance
设置为true
。
sceneLocationView.addLocationNodeWithConfirmedLocation(locationNode: annotationNode)
就是这样了。 如果你设置sceneLocationView的帧,则现在应该会看到Canary Wharf上方悬停的标注点了。
附加功能
这个库以及演示程序附带了一些额外的配置功能。这些都在文档里做了详细介绍,一定要去看看。
SceneLocationView是ARSCNView的一个子类。 请注意,虽然这样可以让你完全访问ARSCNView以通过其他方式去使用它,但你不应将委托设置为另一个类。 如果你需要使用委托功能,那么应该将SceneLocationView
子类化。
正北校准
有一个我个人无法攻克的难题,目前iPhone正北校准精度最高为15º。这对地图导航来说还好,但是要将东西放在AR世界上时,它就成为了一个问题。
我相信通过使用各种AR技术可以攻克这个问题。
为了改善这个问题,我在库中添加了一些函数,可以用来调整正北方向:
sceneLocationView.moveSceneHeadingClockwise
sceneLocationView.moveSceneHeadingAntiClockwise
sceneLocationView.resetSceneHeading
要使用这些函数,你要将sceneLocationView.useTrueNorth
设置为false
,然后在开始之前将设备指向北方的大致一个方向,这样它才能更接近正北。将useTrueNorth
设置为true(默认),它会根据自己的感觉不断调整正北方。
在演示程序中,有一个名为adjustNorthByTappingSidesOfScreen
的属性,它用于访问这些函数,默认是禁用的。一旦启用这个属性,则允许通过点击屏幕的左侧或右侧来调整场景方向。
我的建议是你所处位置的正北方的附近放置一个地标,使用坐标在那个地方放置一个对象,然后使用moveSceneHeading
函数来调整场景,直到它们排成一条线。
改进的定位精度
CoreLocation每1-15秒更新一次位置,精度从150米到4米不等。有时候,你会收到更精确的读数,如4米或8米。同时,AR使用运动和相机数据来创建本地世界的地图。
用户可能会收到精度为4米的位置,然后他们向北走10米,并接收到另一个位置,读数精确到65米。 这个精度为65米的读数是CoreLocation可以提供的最好的精度,但是当获取到4米精度的读数时,程序知道用户在AR场景中的位置,以及接着朝北走了10米,我们可以通过转换这个数据来提供一个新的精度为4米的坐标。这样就精确到了大概100米。
问题
我曾经提到,目前这些尚处于实验阶段。当用户经过某个场景的时候,ARKit偶尔会发生错乱,并给出错误地位置数据。 这个问题似乎也影响到了“欧拉角度”或者有关设备的方向信息。所以,在走过一小段距离之后,它可能会认为你目前正向着另外一个方向行走。
虽然苹果今后会改进ARKit,但我认为,为了避免出现这些问题,我们需要自己进行改进,例如识别出何时会出现问题并进行纠正,以及通过将位置数据与我们假定的位置进行比较,以确定是否已经超过了某个值。
定位算法改进
我们需要进一步优化定位算法。
例如,有一种技术是查看最近的位置数据,转换用户行程中的每一个点,然后使用数据点之间的重叠来更精确地确定用户可能的位置。
鸣谢
作者@AndrewProjDent,以及相关社区。
在MIT许可证的条款下开源。
文章原标题《ARKit-CoreLocation》,作者:Andrew Hart,译者:夏天,审校:主题曲。
文章为简译,更为详细的内容,请查看原文