ARKit增強現實版實景導航開源
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,譯者:夏天,審校:主題曲。
文章為簡譯,更為詳細的內容,請查看原文
最後更新:2017-08-13 22:50:36