方位センサに悩まされる

プライベートでARっぽいのをやろうとしてて、方位センサまわりでちょっと引っかかったのでメモ。

方位センサの基準画面向きからみた現在の画面向きを知る

まず、Androidタブレット機では横長基準でセンサを仕掛けているものがあります。携帯電話機なら縦長基準。この差を認識するのにつまづきました。


(ここに2011年8月22日以前にあった図は誤りです)

Googleさんにいろいろ聞いたところ http://kamoland.com/wiki/wiki.cgi?TYPE_ORIENTATION%A4%F2%BB%C8%A4%EF%A4%BA%A4%CB%CA%FD%B0%CC%B3%D1%A4%F2%BC%E8%C6%C0 に行き着く。
getWindowManager().getDefaultDisplay().getRotation() で Surface.ROTATION_* (*は0, 90, 180, 270)が返ります。方位センサの基準からの回転角度と考えて差し支えないようです。

remapCoordinateSystem() が…

当該アプリは、プレビュー用のビューを貼り付け、アクティビティは横長固定にして立てた姿勢を基準に方位等を算出しています。
Galaxy Sで問題が発生しているとのレビューを受けて…いやS持ってないんだ…Galaxy Tabで様子を見ると、方位がおかしい。
なお、動作チェックは IS03 でやってます。こちらは問題なし。
remapCoordinateSystem()を呼び出さずに手動で座標変換を行ったところ、なんとか動きました。
しかし remapCoordinateSystem() がなんで動かないのかは気になる。
そこで remapCoordinateSystem() の結果をデバッガで見てみると…IS03もGyalaxy Tabも同じ行列を出してくる。
次に remapCoordinateSystem() を2回実行しているのを1回分を削除して、1回だけ実行するようにしたところ、両者とも問題ない。
ということは…remapCoordinateSystem()かSensorManager.getOrientation()かで両者の実装がお互いに異なる、ということになります。
remapCoordinateSystem()で得られる配列は、結局のところ、getRotationMatrix() から得た回転行列に対して右から掛け算していってた結果が返ってくる、というものです。
なので、右から掛ける行列は先に手動で作っておいて、getOrientation()実行時に当該行列を引数で渡するようにしたら思ったような姿勢を知ることができるようになりました。