DK2 OVRManager.tracker.GetPose()の不具合(0.4.3-0.4.4)報告

izm11izm11 投稿:6
NerveGear
1月 2015 編集されました カテゴリ: 日本語(一般)
izmと申します。不具合らしきものを見つけたので報告と、教えてくださいという件です。

#やってみたい事
OculusRift DK2のカメラから見たDK2のユーザ頭部の「絶対値での」位置と姿勢を取得したい(カメラ座標系での頭部位置)
Unity4.5.5p5+Windows+OVRSDK(0.4.3-)

#どうすると出来そうか
OVRManager.tracker.GetPose();と言うAPIがあり、これは「常に絶対値」での位置と姿勢を返す事が期待できます。(頭部位置のリセットをしても変わらないはず)

類似のAPIに
OVRManager.display.GetHeadPose(); と言うAPIがあります。
これはいわゆる「それっぽい」頭の位置と姿勢を返します。また、頭部位置のリセットでこの値はリセットできます。
それっぽい=OVRSDKがリセットした時(例えばシーンリロード、もしくはRキー)の頭の位置を原点とした、x,y,zの頭の位置と姿勢を返す

#何が問題か
OVRManager.tracker.GetPose();で取得できるOVRPoseが最初の1フレーム目で取得したと思われる頭の位置と姿勢から変化しません。
その間にもOVRManager.display.GetHeadPose();は正常に動作します。

#どうなってほしいか
OVRManager.tracker.GetPose();で常時正しい値を返してほしいです。
もしくは、 #やってみたい事 で書いた絶対値での頭部位置姿勢を取得するworkaroundがあれば、教えて頂ければ嬉しいです。 

コメント

  • needleneedle 投稿:49
    Brain Burst
    1月 2015 編集されました
    お問い合わせありがとうございます。
    OVRManager.tracker.GetPose()ですが、これは実はHMDの位置姿勢を取得するものではなく、tracker (ポジショントラッキングセンサー)の位置姿勢を得るAPIになります。
    GetPose()で返ってくる値は「前回の頭部姿勢リセット時にHMDがいた位置姿勢を原点として、そこから見たtrackerの位置姿勢」になります。なので、OVRManager.display.RecenterPose()を呼んで姿勢リセットを行うとGetPose()の値は変わりますが、毎フレーム変動したりしていないのは異常ではありません。

    一方OVRManager.display.GetHeadPose()はご指摘の通り、リセット時のHMDの位置姿勢を原点として、現在のHMDの位置姿勢を返すものです。いずれのAPIもリセット時の位置姿勢を原点とした座標系で動作するものですが、これらを組み合わせることでtrackerから見たHMDの位置姿勢を算出することが出来ると思います。
  • GOROmanGOROman 投稿:3
    NerveGear
    こんばんは!

    補足です。
    シーン移行時やRキー(OVRMainMenuの機能)押下時は、RecenterPose()が呼ばれ、
    display側(ヘッドセット)の姿勢はいわゆる単位行列にリセットされます。
    それと同時に tracker側は、displayから見た相対位置と向きに
    再設定されます。(これを利用するとtrackerの姿勢からポジトラカメラをシーン内に描画する等ができます)

    おそらく izmさんが取得したい絶対的な姿勢は、trackerからの逆変換で求められると思います。
    		// トラッカー(Positional Tracker)の姿勢を得る
    		OVRPose tracker = OVRManager.tracker.GetPose();
    
    		// ヘッドセットの姿勢を得る
    		OVRPose head    = OVRManager.display.GetHeadPose();
    
    		// トラッカーの逆行列を求める
    		Matrix4x4 matrix = Matrix4x4.TRS( tracker.position, tracker.orientation, Vector3.one ).inverse;
    	
    		// 頭の位置を変換
    		transform.position = matrix.MultiplyPoint3x4( head.position );
    
    		// 頭の向きを変換
    		transform.rotation = head.orientation * Quaternion.Inverse( tracker.orientation );
    
  • izm11izm11 投稿:6
    NerveGear
    Needleさん、Goromanさん、ありがとうございます!

    1.OVRManager.tracker.GetPose()の挙動は不具合では無かったと言う事、僕の勘違いでした。申し訳ないです。

    2.Needleさんの解説、大変分かりやすかったです。納得の挙動でした。
    OVRManager.displat.RecenterPose()を呼んで、Needleさんの説明通りの挙動であることを確認しました。

    3.Goromanさんのサンプルコード、とても明解でした。ありがとうございます。特にRecenterPose()を呼ぶと位置だけでなく、姿勢も正面方向にリセットされるのが盲点でした。
    サンプルコードを試しました。常に意図した通り、DK2のHMDの(カメラから見た)絶対位置及び姿勢が取得できていました。

    これで、思っていたことが実現出来そうです。ありがとうございました。 :idea: :idea:
コメントするにはサインインまたは登録して下さい。