ARKitによる自分の位置判定

これはARKit Advent Calendarの17日目の記事です。(遅れてすみません)

ARKitでは、空間にある平面などを判定できます。 同時に、自分が動いた時に自分の位置もわかるので、その位置をとってみましょう。

ARKit

まずは、XcodeでARKitのサンプルアプリを作りましょう。 画面描画フレームワークをSceneKit、SpriteKit、Metalから選べますが、ここではSceneKitを選んでください。

このサンプルコードを動かすと、ARKitで把握した空間情報をもとに、空中に飛行機の3Dモデルを表示してくれます。

ここで、空間に座標軸を表示してみましょう。 ARSCNView(SceneKitのAR用View)では、デバッグ用に座標軸を表示するモードがあります。 サンプルコードのviewDidLoadの最後にdebugOptionsとして、ARSCNDebugOptions.showWorldOriginを設定してみましょう。

override func viewDidLoad() {
   super.viewDidLoad()
        
   // (sceneViewの初期化など)

   // 特徴点を表示、座標軸の原点を表示
   sceneView.debugOptions = [ARSCNDebugOptions.showWorldOrigin]
}

これで実行すると、ARの画面に座標軸が表示され、原点がわかるようになります。 (座標軸の原点は、AR Sessionがはじまったときの端末の位置です。)

自分の位置を取得する

AR空間での自分の位置というのは、AR空間のカメラの位置です。

ARのセッションのARSessionDelegateを設定し、(ViewControllerに設定すると良いでしょう)カメラ情報を取得できます。

ARSessionDelegateのdidUpdateは、カメラの画像情報が更新され、AR状態が変化するたびに呼ばれます。 (画面の中の何かが少しでも動いたらこれがよばれることになります。) ここでsessionのcurrentFrameを取得、それに付随したcameraがデバイスの位置を表すカメラとなります。

func session(_ session: ARSession, didUpdate frame: ARFrame){

   let currentCamera = session.currentFrame?.camera
   let transform = currentCamera?.transform
   print("transform")
}

このtransformは、4x4のFloatの行列情報で、その4行目の情報がデバイスの位置情報となります。

この4x4の行列はクォータニオンとよばれるものです。

クォータニオン

クォータニオンは、数学者のハミルトンが定義した複素数を拡張した数体系で、日本語では四元数とよばれています。

歴史的には、もともと純粋数学の概念として誕生したものでしたが、3次元空間での回転をあらわすのに最適だったため、現在では3次元空間での回転・位置情報を表すために使われていることが多いです。

このあたりは、時間があるときにもう少し勉強してみたいと思います。