方位角を基に画像を表示させたい②

スポンサーリンク
スポンサーリンク
スポンサーリンク

こんがらがる

上手くいかんなー。

Matrix.setRotate→新たにBitmap作る、だと画像が勝手に縮小される

例えば斜めとかになった時、前のコードだと対角線の長さが縦横の長さに縮められるんだから、当たり前っちゃ当たり前なのか。計算であれこれやればそれ込みで表示させれそうだけどよく分かんない。で、ImageViewにsetRotationなるものがあることを知った。

imageView.setPivotX(imageView.getWidth()/2);
imageView.setPivotY(imageView.getHeight()/2);
imageView.setRotation(azimuth);

setPivotX,setPivotYで中心点を指定して、setRotationで角度を指定してあげると、縮小せずに回転するようになった。わーい。

参考

Attention Required! | Cloudflare

結局、磁気センサーの較正・キャリブレーションって必要なのか

ここらへんあやふやだし全然分からん。センサーの値にはハードウェアでの値、ハードウェアの組み込みソフト内での較正値、スマホ端末での取得値、スマホ端末での較正値と、少なくともこれぐらいの種類の値がある。で、AndroidDeveloper見ると、TYPE_MAGNETIC_FIELDとTYPE_MAGNETIC_FIELD_UNCALIBRATEDと地磁気センサーの値は2つある。

Sensor.TYPE_MAGNETIC_FIELD:

All values are in micro-Tesla (uT) and measure the ambient magnetic field in the X, Y and Z axis.

Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED:

Similar to Sensor.TYPE_MAGNETIC_FIELD, but the hard iron calibration is reported separately instead of being included in the measurement. Factory calibration and temperature compensation will still be applied to the “uncalibrated” measurement. Assumptions that the magnetic field is due to the Earth’s poles is avoided.

The values array is shown below:

  • values[0] = x_uncalib
  • values[1] = y_uncalib
  • values[2] = z_uncalib
  • values[3] = x_bias
  • values[4] = y_bias
  • values[5] = z_bias

x_uncalib, y_uncalib, z_uncalib are the measured magnetic field in X, Y, Z axes. Soft iron and temperature calibrations are applied. But the hard iron calibration is not applied. The values are in micro-Tesla (uT).

x_bias, y_bias, z_bias give the iron bias estimated in X, Y, Z axes. Each field is a component of the estimated hard iron calibration. The values are in micro-Tesla (uT).

Hard iron – These distortions arise due to the magnetized iron, steel or permanent magnets on the device. Soft iron – These distortions arise due to the interaction with the earth’s magnetic field.

ハードアイアンとソフトアイアンって何→こちらに説明あった。

value[3][4][5]がバイアスと書いてあるが、これを普通にオフセット値として使っても、TYPE_MAGNETIC_FIELDの値と一致しない。なぜだ。

他のキャリブレーション機能付きコンパスアプリ

を使った時、value[3][4][5]の値が変わった。しかも変わった値が自分のアプリにも適用された。多分。ここの値の変更の仕方がわからない。ここを見てみると(さっきのコンパスアプリとは違うsatstatってやつのIssueのGPSstatusの話題だけど)

To my knowledge, GPS Status does some extra magic inside the app, which is not part of the Android API and thus not available to other applications.

魔法だってさ!!2014年の話題だけど、状況は変わってないんだろうか。

HuaweiP20Proの磁気センサーは旭化成製

みたい。型番は知らん。

ここを見るとセンサーには自動調整機能がついているようだ。ただセンサーに較正機能がついているからといって、それを全部信用することはできないみたい。結局使用者による較正は必要になるみたい。これとかこれとかとか。じゃあどうやって較正するねんって話になるよね。

電子コンパスの較正方法→俺には無理

をググってみると数式がいっぱい出てくる。

二次元の場合

X軸・Y軸の中点を計算し、その値をオフセットとして使うみたい。センサーで値を取得するとプラス方向とマイナス方向の絶対値は一致するはず、でも現実そうじゃないので、そうなるように補正するってことだよね。

float[] midXYZ = new float[3];

for (int i = 0; i < 3; i++) {
    if (fMagnetic[i] > 0 && fMagnetic[i] > maxXYZ[i]) {
        maxXYZ[i] = fMagnetic[i];
    } else if (fMagnetic[i] < 0 && fMagnetic[i] < minXYZ[i]) {
        minXYZ[i] = fMagnetic[i];
    }

    midXYZ[i] = (maxXYZ[i] + minXYZ[i]) / 2;
}
fMagnetic[0] = fMagnetic[0] - midXYZ[0];
fMagnetic[1] = fMagnetic[1] - midXYZ[1];
fMagnetic[2] = fMagnetic[2] - midXYZ[2];

書いてみたけどこれは良くない。最大値・最小値に例外的に飛んだ値が取得された場合を加味してない、てことはそういう場合ちゃんと較正されない。ので駄目だ。これもローパスフィルタかけりゃいいのかな…。

三次元の場合

こっちはコードも書けなかったぜ。複数の三次元上の点から楕円体を求めて、最小二乗法とかいう方法で原点を求めるらしいぞ。言ってて意味が分からんな。こことかここ

でもさ、これで補正値を得られたとして、自分のアプリで使うことはできるかもしれないけれども、↑で書いたvalue[3][4][5]の値を変更する方法がわからないのだからやっぱり片手落ちな気がする。負け惜しみだけどな。このvalue[3][4][5]の値を変更する方法が知りたい。どこかにないかなー、探したけど見つかんない。

getRotationMatrixFromVectorを使って方位角を取得する

switch (event.sensor.getType()) {
    case Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR:
        fGeoRotVec = event.values.clone();
}

if (fGeoRotVec != null) {
    SensorManager.getRotationMatrixFromVector(inR, fGeoRotVec);
    SensorManager.getOrientation(inR, attitude);
    azimuth = (float) Math.toDegrees(attitude[0]);
}

回転ベクトルセンサーを使っても方位を計算できるらしいぞ。回転ベクトルセンサーは、磁力センサ・加速度センサ・ジャイロセンサを使ってソフトウェア上でほにゃららしてるみたい。詳しいことは知らんが、なんかめっちゃ早い。

もうこれでいいんじゃないかとも思ったが、これもやっぱり較正しないと正しい値は取れないんじゃないだろうか。資料が少なくて調べてない。動画にはなってないけど、最初角度がすっ飛んだりはした。

いっかな。

いいよね。結局value[3][4][5]の謎は解けないし。

参考

SensorEvent  |  API reference  |  Android Developers
ロボティクスにおける地磁気センサの基礎知識 - MyEnigma
サンハヤト 加速度、地磁気センサーモジュール ロジックレベル変換IC付きモジュール MM-TXS05 目次 目次 はじめに 地磁気センサとは 地磁気センサのデータの単位 地磁気センサの種類 2軸地磁気センサにおける方位計算の方法 3軸地磁気...
https://github.com/mvglasow/satstat/issues/24
AndroidSDKの加速度・角速度・地磁気センサ周りはどのように実装されているのでしょうか
現在Androidにおいて,IMUセンサ周りがどのように実装されているのかを調べています.開発するアプリケーション側でIMUセンサから得られるデータは,オフセット除去やフィルタリング等,どの程
Attention Required! | Cloudflare
Attention Required! | Cloudflare
Attention Required! | Cloudflare
http://m.eclipsim.com/gpsstatus/
https://www.aichi-mi.com/home/%E9%9B%BB%E5%AD%90%E3%82%B3%E3%83%B3%E3%83%91%E3%82%B9/%E3%82%B3%E3%83%B3%E3%83%91%E3%82%B9%E3%81%AE%E8%BC%83%E6%AD%A3%E3%82%BD%E3%83%95%E3%83%88%E3%81%AE%E5%8E%9F%E7%90%86/
Attention Required! | Cloudflare
Attention Required! | Cloudflare

コメント

タイトルとURLをコピーしました