キャリブレーション
ボードを回転すると、磁力計に対する地球磁場の方向は変わりますが、大きさは変わりません! それでも、磁力計は、ボードが回転すると磁場の大きさが変化することを示しています。
それはなぜでしょうか?結局のところ、磁力計が正しい答えを返すためには、キャリブレーションが必要なのです。
キャリブレーションには、多くの数学(行列)が必要であるため、ここでは取り上げません。もし興味があるのであれば、 アプリケーションノートにその計算方法が記述されています。 代わりに、このセクションでやることは、どの程度正しい答えからずれているか、を視覚化することです。
次の実験を試してみましょう。別方向にボードをゆっくり回転している間、磁力計から読んだ値を記録しましょう。
読んだ値をタブ区切り(TSV; Tab Separated Values)に変換するため、iprintln
マクロを使います。
#![deny(unsafe_code)] #![no_main] #![no_std] #[allow(unused_imports)] use aux15::{entry, iprint, iprintln, prelude::*, I16x3}; #[entry] fn main() -> ! { let (_leds, mut lsm303dlhc, mut delay, mut itm) = aux15::init(); loop { let I16x3 { x, y, z } = lsm303dlhc.mag().unwrap(); iprintln!(&mut itm.stim[0], "{}\t{}\t{}", x, y, z); delay.delay_ms(100_u8); } }
コンソールに次のような出力が得られるはずです。
$ # itmdumpコンソール
-76 213 -54
-76 213 -54
-76 213 -54
-76 213 -54
-73 213 -55
次のコマンドを使って、ファイルにパイプできます。
$ # 注意!他に実行中の`itmdump`インスタンスを全て終了します
$ itmdump -F -f itm.txt > emf.txt
数秒間、データをログ出力している間、ボードを様々な方向に回転します。
その後、TSVファイルをスプレッドシートプログラムに取り込み(もしくは、下記のPythonスクリプトを使い)、 最初の2つの列を散布図としてプロットします。
#!/usr/bin/python
import csv
import math
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import sys
# プロット形式を適用します
sns.set()
x = []
y = []
with open(sys.argv[1], 'r') as f:
rows = csv.reader(f, delimiter='\t')
for row in rows:
# データが欠けている行は捨てます
if len(row) != 3 or not row[0] or not row[1]:
continue
x.append(int(row[0]))
y.append(int(row[1]))
r = math.ceil(max(max(np.abs(x)), max(np.abs(y))) / 100) * 100
plt.plot(x, y, '.')
plt.xlim(-r, r)
plt.ylim(-r, r)
plt.gca().set_aspect(1)
plt.tight_layout()
plt.savefig('emf.svg')
plt.close
ボードを水平な平面上で回転した場合、磁場のZ要素は、比較的同じ値を取り続けたはずです。 このプロットは、原点を中心とした円形(楕円形でない)でなければなりません。 上図のプロットのように、ボードをランダムな方向に回転した場合、多数の点からなる原点を中心とした円が得られるはずです。 円形からの偏差は、磁力計をキャリブレーションする必要があることを示しています。
覚えておいてほしいこと:センサから読んだ値を単純に信用しないで下さい。適切な値が出力されていることを確認して下さい。 適切な出力でなければ、キャリブレーションして下さい。