Tutti Lab

元シリコンバレー在住のおっさん技術者、モバイルVRアプリ開発に挑戦中

KUDAN SDKを使って、Gear VRでどこでもドア(2)

前回は、Gear VRで「どこでもドアに近づく」体験を実現すべく、まずはマーカレスARが可能なKUDANをインストールしました。
今回は、KUDAN SDKを利用して、ポジショントラッキング機能を実装し、どこでもドアに近づいてみます。

www.youtube.com

Kudan Camera prefabをシーンに設置

KudanAR/Prefabsにある「Kudan Camera - Markerless Only」をドラッグ&ドロップし、シーン内に設置した上で、インスペクタより以下の通り設定します。

  • Camera→Depth = -2 (本カメラを表示対象にしないようにするため)
  • API Key = 前回KudanのWEBページより取得した開発用API Key

f:id:tuti107:20170325025958p:plain

ポジショントラッキング用のスクリプト作成

次にKudanPositionTrackerを作成します。
gist.github.com

そして、VR用カメラ(Main Camera)の位置に、空のGameObject(player)を生成し、VR用のカメラを、player配下にぶら下げます。
f:id:tuti107:20170325031447p:plain

また、playerに、上記で作成したKudanPositionTrackerを設置します。
f:id:tuti107:20170325031557p:plain
設置後、インスペクタより、以下の通り設定してください。

  • Kudan Tracker = シーンに設置した「Kudan Camera - Markerless Only」

動作解説

「Kudan Camera - Markerless Only」に設定されているコンポーネント「Kudan Tracker」が、KUDANのAR機能の制御を行います。
Kudan Trackerを利用してポジショントラッキングを行う手順は、以下のとおりです。

  1. FloorPlaceGetPose()を呼び出して、floorPosition, floorOrientationを取得(ドキュメントに詳細な記述はないのですが、恐らくAR空間におけるカメラの位置と向きをそれぞれ取得しているのだと思われます)
  2. floorPosition, floorOrientationを引数として、ArbiTrackStart()メソッドを呼び出す。これによりマーカレスARのトラッキングが開始される
  3. Update()内で、毎フレームArbiTrackGetPose()を呼び出し、トラック対象のポジションと向きを取得する
  4. トラック対象のポジションと向きを、カメラの位置に変換する
  5. playerのlocalPositionを、上記算出したカメラ位置とすることで、Gear VRの位置(向き)に応じた、VRカメラの位置を設定する

注意点など

  • ArbiTrackGetPose()で取得する、位置・向き情報は、前回サンプルアプリ実行時に表示された黒色カプセル型のオブジェクトの表示位置・向きとなります。RevRotateVector()は、この表示位置・向きから、カメラの位置を算出しています。
  • ArbiTrackは、ArbiTrackStart()呼び出し時にトラック対象を決定しそれをトラッキングし続けますが、トラッキング対象を見失う(頭の並行移動ではトラッキング対象を見失うことはあまりありませんが、頭を回転させるとあっさり見失います)と、ArbiTrackが終了してしまいます。このため、ポジショントラッキングをし続けるためには「ArbiTrackが終了時は再開する」処理の実装が必要となります
  • KudanTrackerのトラッキング開始直後に、ArbiTrackStart()を呼び出すと、例外が発生し、ArbiTrackを開始できません("KudanTrackerのトラッキング"と"マーカレスAR用のArbiTrack"は別物)。トラッキングはKudan TrackerのStart On Enableをチェックしていると、本コンポーネントの初期化のタイミングで開始されます(もしくはStartTracking()メソッドをスクリプトから呼び出すことで、トラッキングを開始できる)。そこで、直後ではなく少し時間をおいてから(上記コードでは5秒)、ArbiTrackStart()を呼び出すことで、本問題を回避しています。
  • これは、マーカレスARだから仕方がないことかと思いますが、ArbiTrackでは正確な距離の測定ができません(トラック対象の寸法情報がないのだから、当然ですね)。このため、ArbiTrackGetPose()で取得できる位置情報は所定の単位(メートルとか)ではなく、ArbiTrackのトラッキング対象の位置等により毎回異なります。上記コードでは、取得した位置情報にscaleFactor(0.0004)をかけて、Unityの座標に変換していますが、この0.0004は試行錯誤で見つけた「私の部屋ではそれっぽく見える値」であり、0.0004をかけることで、Unityの座標に正しく変換できる、というものではありません。このため、scaleFactor = 0.0004では、ArbiTrackトラッキング対象とGear VRの距離によっては、頭の動きに対して、動きすぎたり、逆に全然うごかなかったり、ということが起きます。このあたりを正確にしたいなら、試行錯誤scaleFactorの値を調整するか、マーカARにするしかなさそうですね。

おわりに

今回は、Gear VRで「どこでもドアに近づく」体験を実現すべく、KUDANを利用してポジショントラッキング機能を実装してみました。
Vuforiaで実装した際と比較し、マーカが不要であり、かつマーカがなくても結構高精度なトラッキングが実現されているため、Vuforiaよりも使い勝手のよいポジショントラッキングの実装が可能かと思います。
一方、KUDAN ARはポジショントラッキング用に作られたものでないため、トラッキング対象が視界から消えるとポジショントラッキングができなくなる等、ちゃんとしたポジショントラッキングの実現のためには、色々工夫が必要となりそうです。ただ、基本座って・前を向いて使用するアプリ、であれば、今回実装程度のものでも充分かと思います。