磁気センサーと言えばコンパスアプリということで、コンパスアプリの中身がどうなっているかを考えてみた。
まずは話を簡単にするためにスマホを水平に置いた場合つまり2次元に限定した場合を考えてみる。
コンパスアプリなので、磁気センサーで地磁気を観測して見るのがやはりまずやってみることだろう。ということで机にスマホを置いた状態でスマホを回転させて磁場の変化を確認した。(なるべく一定の速度で回した。今思えばジャイロセンサーと組み合わせれば回転角θとの関係で話ができて、なるべく一定なんていう気を使わなくてよかったな。)
3秒後くらいから回転させたのであるが、Z軸方向は回転させていないので当然ほとんど変化しない。一方でX軸方向とY軸方向の磁場は変化する。地磁気は北方向に向かった一定の大きさの磁場なので、スマホのY軸と地磁気Bhとの間の角度をθとすれば、スマホで観測したX軸方向とY軸方向の磁場は
Bx = - Bh sinθ
By = Bh cosθ
になるはずだ。(Y軸を基準にしているので、Bxにはマイナス符号がつく)
そしてこれが正しいとすると
Bh = √(Bx2 + By2)
の関係が成り立ち、一定の値になるはずなので確かめてみよう。上記グラフの結果からBhを計算したのが下グラフ。
地磁気は一定の大きさなのに、計算結果は変化した。
これは一体何故か?実は地磁気以外に磁場を発生させている何かがあったとか?いやそんなものはなかったし、あったとしてもそれと地磁気を合成したものを検出するだけで絶対値はスマホの向きによって変化しないはずだ。
もうひとつ考えられるのは、磁気センサーのゼロ点がずれているということだ。仮にスマホを磁場がゼロの環境においたとしても、センサーがゼロでない値を出力してしまってるということだ。そうだとしたらBx、Byは
B'x = - Bh sinθ + B0x
B'y = Bh cosθ + B0y
のように修正しないといけなさそうだ。このB0x、B0yがセンサーのずれを表している。ただセンサーの出力がずれているだけで磁場とは関係ないものなので、今回は不要、というかあると困る。なぜなら今回はBx、Byからθを求めたいのでB0x、B0yがあると計算できないからだ。ということでB0x、B0yを取り除こう。このB'x、B'yはB0x、B0yを中心にしてsin、cosで変動するだけなので、B'x、B'yの(最大値+最小値)/2で求まるだろう。最大値、最小値は最初のグラフからわかるので、そこからかB0xとB0yを求め、ゼロ点のズレを補正してBhを計算したのが、下のグラフ。
オレンジ色が補正後で、回転中もほぼ変動していない。やはり、ゼロ点がずれていたのだ。そしてコンパスアプリで初期に補正するためにスマホを回転させろと指示されるのは、こうやってゼロ点を補正しているのだろう。
(最近のアプリは指示されないような気もするが、あれはバックグラウンドでやっているのか?)
これで地磁気との角度を求める準備が出来た。
Bx = B'x - B0x = - Bh sinθ
By = B'y - B0y = Bh cosθ
なので
θ = arctan( - Bx / By)
で計算できる。その結果が下グラフ。(角度は右軸)
最初は10°くらい傾いていて、開始3秒後くらいからだんだんθが大きくなり始め、5秒後くらいに90°→ー90°になり、12秒後にまた90°→ー90°になり、そして15秒後くらいに10°に戻った。
う~ん、ー90~90°までの間でしかないのはおかしい。これはarctanの範囲がー90~90°までしかないためだ。以下のようにBx、Byの符号で条件式を書けば、-180 ~ 180の一周分で表現できる。
Bx ≧ 0、By ≧ 0 → arctan( - Bx / By)
Bx < 0、By ≧ 0 → arctan( - Bx / By)
Bx < 0、By < 0 → arctan( - Bx / By) + 180
Bx ≧ 0、By < 0 → arctan( - Bx / By) - 180
これで角度を計算すると以下のようになる。
10° → 180° → -180° → 10°と変化して一周回ったことがわかる。
ところでスタートとゴールが10°であるがこれはちゃんと真北にスマホを置けなかったからだろうか?いや、四方の壁がほぼ東西南北にきれいに向いた建物の壁に沿うようにスマホを置いたので、そこそこの精度で真北に向けれていたはずだ。ではなぜズレたかと言うと、地磁気が真北を向いていないからだろう。地磁気と真北のなす角度を偏角というが、日本付近では約8°ずれているらしい。なので、この10°というのは偏角とスマホの向きを真北に合わせたつもりで合わせきれなかった角度だろうと考えると、妥当なものだろう。
これで磁気センサーの値から北方向を計算できる。あとはスマホの画面に計算した結果を表示してやればコンパスの完成だ!
ただし常にスマホを水平に置いてやる必要があるけど。
やっぱり3次元で使えた方がいい。ということでもう少し考えよう。(続く予定)