HOME | Raspberry Pi | ビジネス書籍紹介 | 2026-03-24 (Tue) Today's Access : 584 Total : 1314941. Since 10 Sep. 2019

雑談:慣性センサ

2026.03.24

スマートロボットカーの走行距離を計測するために、加速度センサーを使ってみました。 使用した製品は、Adafruit製BNO055 と MIKROE製ICM42688Pです。

Adafruit BNO055 + BMP280 BFF Add-On for QT Py
BNO055とICM-42688-Pは、どちらも高性能な慣性計測装置(IMU)ですが、設計思想と主な用途が異なります。 最大の違いは、BNO055は「センサーフュージョン(処理)内蔵のオールインワン9軸センサー」であるのに対し、 ICM-42688-Pは「高精度で高速な6軸rawデータ(生データ)センサー」という点です。
The BNO055 can output the following sensor data:
・Absolute Orientation (Euler Vector, 100Hz) Three axis orientation data based on a 360° sphere
・Absolute Orientation (Quaternion, 100Hz) Four point quaternion output for more accurate data manipulation
・Angular Velocity Vector (100Hz) Three axis of 'rotation speed' in rad/s
・Acceleration Vector (100Hz) Three axis of acceleration (gravity + linear motion) in m/s^2
・Magnetic Field Strength Vector (20Hz) Three axis of magnetic field sensing in micro Tesla (uT)
・Linear Acceleration Vector (100Hz) Three axis of linear acceleration data (acceleration minus gravity) in m/s^2
・Gravity Vector (100Hz) Three axis of gravitational acceleration (minus any movement) in m/s^2
・Temperature (1Hz) Ambient temperature in degrees celsius

加速度とジャイロ情報を連続して100回取得してみました
bno.begin();
long start = millis();
for (int i = 0; i < 100; i++) {
	bno.getEvent(&ev, Adafruit_BNO055::VECTOR_ACCELEROMETER);
	bno.getEvent(&ev, Adafruit_BNO055::VECTOR_GYROSCOPE);
}
Serial1.printf("erapsed time = %ld ms\n", millis() - start);
結果は・・・
erapsed time = 13558 ms
ななななんと、13.5秒も掛かっています。
BNO055の初期モードはフュージョンモードで、内部センサフュージョンを使って姿勢角を計算するモードです。
そこで、フュージョン機能を解除して生データを取得するモードに変更して実行してみましたが、処理時間は変わりませんでした。
bno.begin(OPERATION_MODE_ACCGYRO);

そこで次にMIKROE(ミクロエ)製のICM-42688Pを使ってみます。

MIKROE-4237
6DOF IMU 14 Click | ICM-42688-P Accelerometer + Gyro Module

6DOF IMU 14 Click
このBoard™には、X軸、Y軸、Z軸の回転を検出する振動型MEMSレートジャイロスコープと、3軸MEMS加速度センサーが搭載されています。 ジャイロセンサーのフルスケール範囲は、±15.625度/秒から最大±2000度/秒(DPS)までデジタルプログラム可能です。 ICM-42688-Pアーキテクチャにより、加速度センサーは製造ばらつきや熱ドリフトの影響を低減します。 デバイスを平面に置くと、X軸とY軸は0g、Z軸は+1gを測定します。デジタル出力のフルスケール範囲は、±2gから最大±16gまで調整可能です。
ICM-42688-Pは、割り込み信号を生成できるプログラム可能な割り込みシステムを備えています。 2つの割り込み出力があり、そのうち1つはmikroBUS™のPWMピンにルーティングされたフレーム同期入力を表します。 クロックソースの切り替え時、新しいデータ(FIFOおよびデータレジスタから)の読み取りが可能になった時、加速度センサーイベント時、FIFOウォーターマーク時、およびオーバーフロー時に割り込みをトリガーできます。

同様に、加速度とジャイロ情報を100回取得してみました
IMU.begin(&Wire1, 0x68);
IMU.setAccelFS(ICM42688::gpm2);
IMU.setGyroFS(ICM42688::dps500);
IMU.setAccelODR(ICM42688::odr200);
IMU.setGyroODR(ICM42688::odr200);
long start = millis();
for (int i = 0; i < 100; i++) {
	IMU.getAGT();
}
Serial1.printf("erapsed time = %ld\n", millis() - start);
さて、結果は
erapsed time = 49 ms
早い!49ミリ秒です。この結果により、走行距離測定にはICM-42688Pを使うことにします。

MIKROE
MIKROE(MikroElektronika)は、セルビアに本社を置く、組込みシステム向けの開発ボード、コンパイラ、デバッガなどを提供する大手開発ツールメーカーです。 MIKROEという響きとロゴ・デザインがファッションブランド風でオシャレです。


MIKROE-4237は、DigiKey価格4899円ですが、メルカリでなんと800円で手に入れてしまいました。

6DOF IMU 14 Clickは、I2CとSPIの両方のインターフェースを使用できます。 最大周波数は、I2Cで1MHz、SPIで25MHzです。COMM SELと表示されたSMDジャンパーを適切な位置に配置することで選択できます。 I2Cインターフェースが選択されている場合、ICM-42688-PではI2Cスレーブアドレスの最下位ビット(LSB)を選択できます。 これは、ADDR SELと表示されたSMDジャンパーを使用して行うことができます。 このClick Board™は3.3Vロジックレベルでのみ動作するように設計されています。

I2CとSPIの両方のシリアル通信をサポートしているようですが、上記画像ではSPI側のジャンパーが0Ω抵抗でショットされています。 実際に手に入れた製品はI2C側がショートされていたので、今回はI2Cで制御します。


TDK InvenSense ICM-42688-P
TDK InvenSense社のICM-42688-P(およびICM-42688-V)は、非常に高速なデータ出力レート(ODR)に対応した高性能6軸(3軸加速度+3軸ジャイロ)モーションセンサです。 主な出力レート仕様は以下の通りです。
1. 最大出力データレート (ODR)
ジャイロスコープ (Gyrosocpe): 最大 32 kHz (Low Noise Mode時、信号処理後のデータレートは設定による)
加速度センサー (Accelerometer): 最大 32 kHz (Low Noise Mode時)
FIFO出力: 最大 1000Hz (1kHz)
2. 出力レートの設定とモード
ICM-42688は、電力とノイズ性能のバランスをとるために2つの動作モードを持ち、それによってODRの挙動が異なります。
Low Noise (LN) Mode: 常に高レートでサンプリングし、指定されたODRにデシメーション(間引き)します。高性能用途向け
Low Power (LP) Mode: 加速度センサのみ対応。ODRによってADCのサンプリングレートが変化するため、低消費電力です

今回は下記の設定で計測しています。
IMU.setAccelFS(ICM42688::gpm2);
IMU.setGyroFS(ICM42688::dps500);
IMU.setAccelODR(ICM42688::odr200);
IMU.setGyroODR(ICM42688::odr200);


micro:bit用スマートロボットカーをESP32搭載車に改造しています。
センサーを車体に対して横に設置しているので、前(-)後(+)がY軸、左(+)右(-)がX軸になります。
使用に際しては十分な電力供給が行われないとセンサーの初期化に失敗します。


finani/ICM42688
ICM42688用コードはgithubを利用しました


Raspberry Pi 3 model A+ でビルドしています。 コードをビルドするとヘッダーファイルでエラーが発生します。 書式を直してビルドを通してもデータを取得できなかったので、クラスファイルを編集して使いました。


ロボットカーが静止している状態での3軸加速度、ジャイロ、温度を表示しています。 Y軸方向の加速度平均を取って測定値の補正に用います。

次にロボットカーを走行させて計測してみました。
測定値はESP32のメモリー上に蓄積し、測定終了後に配列データとして出力しています。 これにPHPの処理を追加して、グラフ表示用のPythonコードを吐き出して表示しています。
<?php

$ICM_ms = array(
0,10,20,30,40,50,60,70,80,90,
100,110,120,130,140,150,160,170,180,190,
200,210,220,230,240,250,260,270,280,290,
300,310,320,330,340,350,360,370,380,390,
400,410,420,430,440,450,460,470,480,490,
500,510,520,530,540,550,560,570,580,590,
600,610,620,630,640,650,660,670,680,690,
700,710,720,730,740,750,760,770,780,790,
800,810,820,830,840,850,860,870,880,890,
900,910,920,930,940,950,960,970,980,990,
1000,1010,1020,1030,1040,1050,1060,1070,1080,1090,
1100,1110,1120,1130,1140,1150,1160,1170,1180,1190,
1200,1210,1220,1230,1240,1250,1260,1270,1280,1290,
1300,1310,1320,1330,1340,1350,1360,1370,1380,1390,
1400,1410,1420,1430,1440,1450,1460,1470,1480,1490,
1500,1510,1520,1530,1540,1550,1560,1570,1580,1590,
1600,1610,1620,1630,1640,1650,1660,1670,1680,1690,
1700,1710,1720,1730,1740,1750,1760,1770,1780,1790,
1800,1810,1820,1830,1840,1850,1860,1870,1880,1890,
1900,1910,1920,1930,1940,1950,1960,1970,1980,1990
);

$ICM_Ay = array(
0.003890,0.005355,0.002425,0.083724,0.009993,-0.083146,0.070174,-0.052995,0.223861,0.025374,
0.030867,0.006820,-0.012712,-0.100968,0.074447,-0.034928,0.025008,-0.001847,-0.004289,-0.056047,
0.036849,-0.019914,0.002547,-0.022721,0.042586,0.034774,-0.121232,0.091048,0.011702,-0.018205,
0.054915,0.047103,-0.055070,-0.043840,0.055892,0.021712,-0.051652,0.111190,0.004012,-0.111467,
-0.122087,0.189559,-0.156999,0.055648,0.003890,0.018538,0.016341,-0.037126,0.020125,0.027327,
-0.085099,-0.027604,0.087264,-0.067399,-0.017961,-0.011857,0.049666,0.014388,-0.054093,0.048201,
0.120589,-0.068132,-0.109635,0.084945,0.075789,-0.084489,-0.104386,0.100325,0.017074,-0.016740,
-0.007463,0.033919,0.045272,-0.118058,-0.015031,0.100692,0.004744,0.051253,0.074080,-0.047624,
0.044051,0.069075,0.002181,-0.079606,-0.062760,0.098616,-0.003678,-0.101091,0.067244,-0.080217,
-0.083757,0.052962,0.082747,-0.145890,0.017074,0.116439,0.064193,-0.100480,0.015365,0.075057,
-0.009538,-0.072160,0.031356,0.092147,-0.029191,-0.036515,-0.004899,0.008040,0.010360,0.006942,
-0.011003,-0.028092,0.062240,-0.002946,-0.082292,-0.055925,0.103377,-0.036027,-0.001359,0.027938,
-0.068742,-0.064592,0.101546,0.063826,0.109359,-0.099626,0.015365,0.035262,0.046126,-0.115129,
-0.079972,0.094954,0.066878,-0.115739,0.085433,-0.063737,-0.034074,0.062728,0.106551,-0.178361,
-0.019059,0.139510,0.022078,-0.099870,0.033431,0.045272,0.023055,-0.084489,-0.010026,0.022933,
0.007186,0.010604,-0.005754,-0.068864,0.059554,0.108870,0.006087,-0.065080,-0.050553,0.193709,
0.002181,-0.104509,0.013289,0.096663,0.060531,-0.027970,-0.074601,0.147933,-0.027238,-0.057145,
0.057113,0.014388,0.032210,-0.028337,0.015242,0.002181,0.016097,-0.023088,-0.012223,0.028792,
-0.022966,0.018538,-0.041032,0.043929,-0.010636,0.044906,-0.101579,-0.011369,0.092757,0.018416,
-0.108415,0.026839,0.107650,0.064437,-0.135026,0.030623,0.118880,-0.048722,-0.023332,0.073226
);

$MT_MS = 200;

$__TEXT_1 = <<<EOF
import matplotlib.pyplot as plt
import math

if __name__ == '__main__':
  sampling  = 200
  amplitude = [0]*sampling
  cycle     = [0]*sampling
EOF; 

$__TEXT_2 = <<<EOF
  plt.plot(cycle, amplitude)
  plt.show()
  plt.close()
EOF; 

	echo $__TEXT_1."\n";

	for ($i = 0; $i < $MT_MS; $i++) {
		echo '  cycle['.$i.'] = '.$ICM_ms[$i]."\n";
		$ICM_Ay[$i] = $ICM_Ay[$i] * 9.80665;
		echo '  amplitude['.$i.'] = '.$ICM_Ay[$i]."\n";
	}
	echo $__TEXT_2."\n";
?>
> php icm42688.php > icm42688.py
> python3 icm42688.py


フローリングの床を走らせた場合、機体の振動が激しく補正できるような状況ではありません。 プチプチを敷いてその上を走らせてみましたが、改善されません。

仕方なく、ロボットカーを手にもって動かしました。

測定値にばらつきはあるもののこれであれば使えます


走行距離は隣接する加速度値を台形の上底、下底、測定間隔を高さと見なし台形の面積を求め、これを測定時間で足し込むことで近似します。
※細かく測定すれば、上底 * 測定間隔でもたいして違いはありません。
<?php

$ICM_ms = array(
0,10,20,30,40,50,60,70,80,90,
100,110,120,130,140,150,160,170,180,190,
200,210,220,230,240,250,260,270,280,290,
300,310,320,330,340,350,360,370,380,390,
400,410,420,430,440,450,460,470,480,490,
500,510,520,530,540,550,560,570,580,590,
600,610,620,630,640,650,660,670,680,690,
700,710,720,730,740,750,760,770,780,790,
800,810,820,830,840,850,860,870,880,890,
900,911,920,930,940,950,960,970,980,990,
1000,1010,1020,1030,1040,1050,1060,1070,1080,1090,
1100,1110,1120,1130,1140,1150,1160,1170,1180,1190,
1200,1210,1220,1230,1240,1250,1260,1270,1280,1290,
1300,1310,1321,1331,1341,1351,1361,1371,1381,1391,
1401,1411,1421,1431,1441,1451,1461,1471,1481,1491,
1501,1511,1521,1531,1541,1551,1561,1571,1581,1591,
1601,1611,1621,1631,1641,1651,1661,1671,1681,1691,
1701,1711,1721,1731,1741,1751,1761,1771,1781,1791,
1801,1811,1821,1831,1841,1851,1861,1871,1881,1891,
1901,1911,1921,1931,1941,1951,1961,1971,1981,1991
);

$ICM_Ay = array(
-0.014421,-0.012467,-0.004411,0.002547,0.020491,0.039046,0.051375,0.049178,0.029525,0.012191,
-0.010392,-0.022111,-0.026750,-0.018937,-0.008683,-0.002214,-0.006120,-0.004411,-0.006120,-0.016740,
-0.024064,-0.026017,-0.028825,-0.020402,-0.012956,-0.001237,0.003402,0.003768,0.003035,0.000838,
0.003035,-0.003068,-0.008439,-0.005265,0.002913,0.010116,0.013656,0.017440,0.017318,0.018660,
0.019637,0.015609,0.010848,0.002425,0.001449,0.007064,0.017074,0.022200,0.030867,0.028304,
0.030013,0.031844,0.027938,0.037459,0.041854,0.051864,0.054549,0.052718,0.047835,0.049178,
0.042708,0.036727,0.027816,0.025863,0.025741,0.028182,0.025618,0.036361,0.039657,0.037215,
0.031356,0.027572,0.026961,0.034041,0.034530,0.037581,0.047835,0.049422,0.039412,0.031356,
0.028060,0.025130,0.023909,0.024276,0.024886,0.028182,0.034774,0.038070,0.033919,0.028792,
0.020858,0.012923,0.013411,0.009017,0.010238,0.009017,0.004744,0.000594,-0.006608,0.004744,
0.016097,0.029158,0.030013,0.038802,0.030257,0.012801,0.022200,0.041976,0.049056,0.048446,
0.050155,0.048934,0.050277,0.048446,0.040267,0.041610,0.046859,0.041732,0.048446,0.044173,
0.038680,0.045882,0.047103,0.047957,0.058577,0.051009,0.056502,0.054793,0.047347,0.048079,
0.040145,0.040877,0.044661,0.056502,0.059310,0.061507,0.049178,0.045272,0.044906,0.047103,
0.039534,0.030013,0.038192,0.050521,0.052352,0.049910,0.037459,0.031966,0.018660,0.013045,
0.015487,0.009261,0.018660,0.011092,0.018660,0.023543,0.013411,0.024154,0.004989,0.004744,
0.015975,0.025374,0.042708,0.049788,0.051497,0.052718,0.058455,0.043441,0.027938,0.010116,
0.008895,0.018783,0.025252,0.003768,0.005477,0.025008,0.051497,0.075911,0.097518,0.112410,
0.112777,0.103621,0.068831,0.059310,0.062484,0.061019,0.062362,0.068587,0.071883,0.096297,
0.109847,0.114974,0.112166,0.088851,0.067611,0.059676,0.052108,0.051619,0.048568,0.070418
);

$MT_MS = 200;

$__TEXT_1 = <<<EOF
import matplotlib.pyplot as plt
import math

if __name__ == '__main__':
  sampling  = 240
  amplitude = [0]*sampling
  cycle     = [0]*sampling
EOF; 

$__TEXT_2 = <<<EOF
  plt.plot(cycle, amplitude)
  plt.show()
  plt.close()
EOF; 

	$avg = 0;
	for ($i = 0; $i < 20; $i++) $avg += $ICM_Ay[$i];
	$avg /= 20;

	echo $__TEXT_1."\n";

	for ($i = 0; $i < $MT_MS; $i++) {
		$ICM_Ay[$i] = ($ICM_Ay[$i] - $avg) * 9.80665;
	}
	$distance = 0;
	echo '  cycle[0] = 0'."\n";
	echo '  amplitude[0] = 0'."\n";
	for ($i = 1; $i < $MT_MS; $i++) {
		$square = ($ICM_Ay[$i-1] + $ICM_Ay[$i]) * (($ICM_ms[$i] - $ICM_ms[$i-1])/1000) / 2;
		$distance += $square;
		echo '  cycle['.$i.'] = '.$ICM_ms[$i]."\n";
		echo '  amplitude['.$i.'] = '.$distance."\n";
	}

	echo $__TEXT_2."\n";
?>

時間経過に伴う走行距離をグラフ化しています。縦軸はメートル、横軸はミリ秒です。
今回は機体を手にもって移動させたので、計算と移動距離の誤差を判断することはできませんが、 ネットで調べてみると計測値から算出される移動距離と実際の距離では2割近くの誤差が生じているものもありました。
難しい数式云々以前に振動対策が重要です。

●備考:BNO055 VS ICM-42688P詳細比較


1. BNO055: 9軸オールインワン「スマートセンサー」
特徴:加速度、ジャイロ、磁気センサ(コンパス)に加えて、データフュージョンを行うMCU(マイコン)がチップに内蔵されています。
メリット: すぐに使える: 外部マイコンにクォータニオン(Quaternion)やオイラー角(Euler Angle)などの姿勢データを直接出力するため、高度な数学的計算(カルマンフィルタなど)が不要。
磁気センサ内蔵: 9軸データにより、絶対的な方位(Yaw)を算出可能。
デメリット: 磁気ノイズに弱い: モーターなど磁気を出すロボットの近くでは、校正(キャリブレーション)が非常に困難。
処理が少し遅い: 内部フュージョンの更新レートは最大100Hz程度。
Drift (漂流): 長時間動かすと、少しずつ方位がずれる。
2. ICM-42688-P: 高性能・超高速「6軸RAWセンサー」
特徴: 6軸(加速度+ジャイロ)の生データを極めて高い精度・低ノイズで出力する、現在の最新鋭6軸IMUの一つです。
メリット: 高精度・低ノイズ: 非常に正確で、ジャイロのノイズが極めて少ない。
高速・低遅延: 高速な応答が要求されるFPVドローンや、激しく動くロボットに最適。
6軸としての性能: 9軸が必要ない場合、最も信頼性の高い6軸センサーの一つ。
デメリット: 複雑: 生データしか出ないため、姿勢を求めるには、ArduinoやRaspberry Pi側で「Madgwickフィルタ」や「カルマンフィルタ」などの処理を実装する必要がある。
9軸でない: 磁気センサがないため、長時間のYaw(方位)安定性には工夫が必要。

●参考文献
加速度センサによる移動距離算出
加速度センサから得られた値を移動距離に変換
adafruit/Adafruit_BNO055
Arduino で BNO055 を試したら、setMode() が効かない
Raspberry Pi(ラズベリー パイ)は、ARMプロセッサを搭載したシングルボードコンピュータ。イギリスのラズベリーパイ財団によって開発されている。
2022.05.27 まずはロボットカーでお勉強
2022.06.10 第1回テスト環境構築
2022.07.02 第2回テレメトリ通信
2024.06.23 第3回 機体制御 雑談
2024.07.23 第4回 慣性センサ
2025.02.22 第5回 自作シリアル・プロポ
2025.03.10 簡易二足歩行ロボット
2025.04.24 第6回 自作TELNET・プロポ
2025.10.23 M5STACK BugC
2026.03.24 雑談:慣性センサ

たいていのことは100日あれば、うまくいく。長田英知著
「時間がなくて、なかなか自分のやりたいことができない」 「一念発起して何かを始めても、いつも三日坊主で終わってしまう」 「色んなことを先延ばしにしたまま、時間だけが過ぎていく」 そこで本書では、そんな著者が独自に開発した、 まったく新しい目標達成メソッド「100日デザイン」について、 その知識と技術を、余すところなくご紹介します。

まんがで納得ナポレオン・ヒル 思考は現実化する
OLとして雑務をこなす日々に飽き足らず、科学者だった父が残した薬品を商品化すべく、起業を決意した内山麻由(27)。彼女はセミナーで知り合った謎の女性からサポートを得ながら、彼女と二人三脚でナポレオン・ヒルの成功哲学を実践し、さまざまな問題を乗り越えていく。 ヒル博士の<ゴールデンルール>に従い、仕事に、恋に全力疾走する彼女の、成功への物語。

今日は人生最悪で最高の日 1秒で世界を変えるたったひとつの方法 ひすいこたろう著
偉人の伝記を読むと、最悪な日は、不幸な日ではなく、新しい自分が始まる日であることがわかります。最悪な出来事は、自分の人生が、想像を超えて面白くなる兆しなのです。偉人伝を読むことで、このときの不幸があったおかげで、未来にこういう幸せがくるのかと、人生を俯瞰する視線が立ち上がるのです。

ご飯は私を裏切らない heisoku著
辛い現実から目を背けて食べるご飯は、いつも美味しく幸せを届けてくれる。 29歳、中卒、恋人いない歴イコール年齢。バイト以外の職歴もなく、短期バイトを転々とする日々。ぐるぐると思索に耽るけど、ご飯を食べると幸せになれる。奇才の新鋭・heisokuが贈るリアル労働グルメ物語!

【最新版Gemini 3に対応!】できるGemini (できるシリーズ)
Geminiを「最強の知的生産パートナー」として使いこなすための、実践的なノウハウを凝縮した一冊です。 基本的な操作方法から、具体的なビジネスシーンでの活用、日々の業務を自動化するGoogle Workspaceとの連携、さらには自分だけのオリジナルAIを作成する方法まで余すところなく解説します。

Rustプログラミング完全ガイド 他言語との比較で違いが分かる!
Rustの各手法や考え方を幅広く解説! 500以上のサンプルを掲載。実行結果も確認。 全24章の包括的なチュートリアル。

ポチらせる文章術
販売サイト・ネット広告・メルマガ・ブログ・ホームページ・SNS… 全WEB媒体で効果バツグン! カリスマコピーライターが教える「見てもらう」「買ってもらう」「共感してもらう」すべてに効くネット文章術

小型で便利な Type-C アダプター USB C オス - USB3.1 オスアダプター
Type-C端子のマイコンボードをこのアダプタを介して直接Raspberry Piに挿すことができます。ケーブルなしで便利なツールです。

Divoom Ditoo Pro ワイヤレススピーカー
15W高音質重低音/青軸キーボード/Bluetooth5.3/ピクセルアート 専用アプリ/USB接続/microSDカード

電源供給USBケーブル スリム 【5本セット】
USB電源ケーブル 5V DC電源供給ケーブル スリム 【5本セット】 電源供給 バッテリー 修理 自作 DIY 電子工作 (100cm)

Copyright © 2011-2027 Sarako Tsukiyono All rights reserved®.