2022.11.3 2021.10.30 Coskx Lab
micro:bitの姿勢はピッチ角とロール角で表されます。
MakeCodeプログラミングでは,LEDスクリーンを上に向けて水平置きしたときのピッチ角とロール角が簡単に求められるようになっているので,これを使います。
ピッチ角とロール角は舞台裏で3軸加速度センサが用いられています。
3軸加速度センサ値からピッチ角とロール角を得ることもできますが,ここでは加速度センサ値を直接読み出す作業は行いません。
MakeCodeプログラミングでは,LEDスクリーンを上に向けて水平置きしたときのピッチ角[deg]とロール角[deg]が簡単に求められるようになっているので,これを使います。
なお,測定値を連続取得する場合(測定値の平均を求める場合など)は,補足の注意事項を参考にしてください。
micro:bitでこのプログラムが起動し,Makecode画面左のShow data deviceボタンを押すと,次のように得られた表示が連続して表示されます。
roll: -2 pitch: 7
roll: -1 pitch: 7
roll: -2 pitch: 7
roll: -2 pitch: 7
roll: -2 pitch: 7
roll: -2 pitch: 7
roll: -2 pitch: 7
roll: -1 pitch: 7
roll: -1 pitch: 7
roll: -2 pitch: 7
roll: -2 pitch: 7
roll: -1 pitch: 7
roll: -2 pitch: 7
roll: -2 pitch: 7
roll: -2 pitch: 7
ピッチ角・ロール角の時間平均を作る関数を考えます。
関数が戻す値は1つだけなので,平均測定されたピッチ角・ロール角は変数(グローバル変数)で呼び出し側に返すことにします。
そうすると次のようなプログラムになり,実行結果も次のようになります。
ピッチ角・ロール角の連続取得の場合には,このプログラムにあるように20msecの間隔が必要です。(補足 短インターバル繰り返し測定)
roll: 1 pitch:6
roll: 1 pitch:6
roll: 1 pitch:6
roll: 1 pitch:6
roll: 1 pitch:6
roll: 1 pitch:6
roll: 1 pitch:6
roll: 1 pitch:6
roll: 1 pitch:7
roll: 1 pitch:6
roll: 1 pitch:6
roll: 1 pitch:6
roll: 1 pitch:6
roll: 1 pitch:6
また,ピッチ角\(\beta\)・ロール角\(\alpha\)が小さな場合,最傾斜方向は,次の図を参考に,ピッチ角とロール角から求めることができるでしょう。
しかし,ピッチ角もロール角も1桁しか精度がない場合,最傾斜方向計算では精度が得られません。
「3」「4」で,測定の様子を示しましたが,これはmicro:bitを動かないようにして測定したものです。
モータで動く模型カーなどに搭載されたmicro:bitで,移動しながら姿勢測定すると,振動の影響が加速度センサに大きく作用するため,正しい姿勢が得られません。
正しく姿勢を測定するには,模型カーを止めて測定する,測定平均回数を増やすなどの工夫が必要になります。
どのくらい測定値が暴れるのか観察して対策を練ってから姿勢測定を行う必要があります。
LEDスクリーンを上に向けた水平置きのmicro:bitのピッチ角とロール角の求め方を示しました。
注意 ピッチ角・ロール角の連続取得するときは,最低でも20msは間隔をとる必要があります。micro:bit側の測定値更新が20msほどかかるので,それ以下の間隔での測定値取得では,同じ値を取り込んでしまうことになります。特に測定値の平均化のときは,平均化が無意味になってしまうので注意が必要です。(「補足 短インターバル繰り返し測定」参照)
ピッチ角,ロール角は加速度センサで測定された値から作られています。加速度センサは,内部でAD変換・I2C通信しており,その結果をプログラムで加速度センサ値として受け取っています。
AD変換・I2C通信は一定の時間を必要とするため,短インターバル繰り返しで加速度センサ値を受け取ろうとすると,思い通りのピッチ角・ロール角の測定値が得られないことがあります。(実は舞台裏でセンサ値の更新周期が設定されています。)
micro;bitを絶えず動かしながら(取得されるべきセンサ値は不規則に変化するはず),
(1)インターバル無し
(2)インターバル10ms
(3)インターバル20ms
で16回連続測定し,得られた加速度センサ値を観察してみました。
(1)インターバル無し(測定間隔ほぼ0)
16回の測定するときは,時間のかかる測定値表示をせず,配列に測定値を保存して,最速で測定します。測定終了後に,配列に保存されていた測定値をコンソールに表示する手法をとりました。
その結果は次の通りになりました。
16回の取得データはすべて同じ値でした。
AD変換・I2C通信によるデータの更新が間に合わず,同じデータを受け取り続けていたと考えられます。
これでは使えません。
started
6, 36
6, 36
6, 36
6, 36
6, 36
6, 36
6, 36
6, 36
6, 36
6, 36
6, 36
6, 36
6, 36
6, 36
6, 36
6, 36
(2)インターバル10ms(測定間隔10ms)
16回の測定するときは,時間のかかる測定値表示をせず,配列に測定値を保存して,10msのpause(一時停止)を行っています。測定終了後に,配列に保存されていた測定値をコンソールに表示する手法をとりました。
その結果は次の通りになりました。
ところどころで,同じデータが2回続けて得られています。
AD変換・I2C通信によるデータの更新が完全には間に合わず,同じデータを受け取ってしまうことがあると考えられます。
これでは使えません。
started
-16, -9
-16, -9 ←
-19, 4
-19, 4 ←
-32, 15
-32, 15 ←
-23, 47
-13, 67
-13, 67 ←
-14, 81
-14, 81 ←
-17, 80
-22, 70
-22, 70 ←
-14, 81
-14, 81 ←
(3)インターバル20ms(測定間隔20ms)
16回の測定するときは,時間のかかる測定値表示をせず,配列に測定値を保存して,20msのpause(一時停止)を行っています。測定終了後に,配列に保存されていた測定値をコンソールに表示する手法をとりました。
その結果は次の通りになりました。
同じデータが繰り返し取得されることなく,測定できています。
started
-6, 37
0, 40
0, 31
3, 34
6, 36
7, 35
5, 35
4, 36
2, 35
0, 34
-3, 38
-7, 39
-8, 39
-13, 47
-28, 43
-36, 48
このテストから,加速度センサでの測定には,20msほどのインターバルが必要なことがわかりました。
なお,「ずっと」ブロックでは舞台裏において20msのpause(一時停止)が行われているため,「ずっと」ブロック中ではプログラム中にpause(一時停止)を書かなくても最新の測定値を得ることができます。
参考 「ずっと」ブロックの動作
≫