魅力的な加速度センサー・ジャイロセンサー、ドローンがうまく飛ぶ秘密がここにあった!!
そこで、加速度センサー・ジャイロセンサーを学んでいきたいと思います。
加速度センサーは、ドローンの傾き(ピッチ、ロール)や静止状態での重力方向を検知します。
これにより、飛行中の姿勢を常に監視し、必要に応じてモーター出力を調整します。
- ピッチ: 前後の傾き(例:前進・後退の動き)。
- ロール: 左右の傾き(例:横方向への移動)。
- ヨー: 回転(加速度センサー単体ではなくジャイロセンサーが主に担当)。
加速度センサーのデータを基に、ドローンがバランスを保つように制御します。
例えば、外部からの風や軽い衝撃でドローンが傾いた場合、加速度センサーがその変化を検知し、モーターを調整して水平を保つようにします。
- 例:
- 前方に傾いた場合 → 後部モーターの回転速度を上げてバランスを取る。
- 左に傾いた場合 → 右側モーターを調整して安定させる。
ドローンの操作性向について
加速度センサーは、操縦者の操作に対するドローンの応答を最適化します。具体的には、操縦スティックの入力に応じて加速度データを元にモーター出力を調整し、スムーズな飛行を実現します。
それでは、手ごろなArduino と ADXL345 加速度センサーを使用して加速度を測定し、ドローンに使われている方法を学びます。
まずは、動画をご覧ください。
Arduino と ADXL345 加速度センサーを使用して加速度を測定
接続方法
ADXL345 GND → Arduino GND
ADXL345 SCL → Arduino A5
ADXL345 SDA → Arduino A4 *SDA(データライン): データの送受信に使用される双方向ライン。
ADXL345 CS → 3.3Vまたは5V接続 *SCL(クロックライン): データ送受信を同期させるためのクロック信号。
軸デジタル加速度計ADXL345を制御するためのArduinoライブラリ。ADXL345 は、SPI モードと I2C モードの両方をサポートし、データ レートと「範囲」(+/-2/4/8/16g) を調整できるデジタル加速度計です。Adafruit_ADXL345 ドライバーをインストールします。
左のようにスケッチ例より、Adafruit ADLX345 ⇒sensortestのスケッチでまず動かしてみる。
Adafruit ADLX345 ⇒sensortestのスケッチ
#include <Wire.h> //Wire.h: I2C通信に必要なライブラリ。
#include <Adafruit_Sensor.h> //ADXL345用のAdafruitライブラリ
#include <Adafruit_ADXL345_U.h> //ADXL345用のAdafruitライブラリ
/* Assign a unique ID to this sensor at the same time *///センサーオブジェクトの初期化
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345); //accelという名前でセンサーオブジェクトを作成//=12345はセンサーのユニークID
void displaySensorDetails(void) //センサーの基本情報をシリアルモニターに出力します
{
sensor_t sensor;//sensor_t構造体を使用して、以下の情報を表示します。
accel.getSensor(&sensor);
Serial.println("------------------------------------");
Serial.print ("Sensor: "); Serial.println(sensor.name);//センサー名
Serial.print ("Driver Ver: "); Serial.println(sensor.version);//ドライバのバージョン
Serial.print ("Unique ID: "); Serial.println(sensor.sensor_id);//ユニークID
Serial.print ("Max Value: "); Serial.print(sensor.max_value); Serial.println(" m/s^2");//加速度の最大値(単位は m/s²)
Serial.print ("Min Value: "); Serial.print(sensor.min_value); Serial.println(" m/s^2");//加速度の最小値(単位は m/s²)
Serial.print ("Resolution: "); Serial.print(sensor.resolution); Serial.println(" m/s^2"); //解像度(単位は m/s²)
Serial.println("------------------------------------");
Serial.println("");
delay(500);
}
void displayDataRate(void) //センサーのデータ取得レート(サンプリングレート)を表示
{
Serial.print ("Data Rate: ");
switch(accel.getDataRate())//現在のデータレートを取得//switch文で該当する値を文字列として表示
{
case ADXL345_DATARATE_3200_HZ:
Serial.print ("3200 ");
break;
case ADXL345_DATARATE_1600_HZ:
Serial.print ("1600 ");
break;
case ADXL345_DATARATE_800_HZ:
Serial.print ("800 ");
break;
case ADXL345_DATARATE_400_HZ:
Serial.print ("400 ");
break;
case ADXL345_DATARATE_200_HZ:
Serial.print ("200 ");
break;
case ADXL345_DATARATE_100_HZ:
Serial.print ("100 ");
break;
case ADXL345_DATARATE_50_HZ:
Serial.print ("50 ");
break;
case ADXL345_DATARATE_25_HZ:
Serial.print ("25 ");
break;
case ADXL345_DATARATE_12_5_HZ:
Serial.print ("12.5 ");
break;
case ADXL345_DATARATE_6_25HZ:
Serial.print ("6.25 ");
break;
case ADXL345_DATARATE_3_13_HZ:
Serial.print ("3.13 ");
break;
case ADXL345_DATARATE_1_56_HZ:
Serial.print ("1.56 ");
break;
case ADXL345_DATARATE_0_78_HZ:
Serial.print ("0.78 ");
break;
case ADXL345_DATARATE_0_39_HZ:
Serial.print ("0.39 ");
break;
case ADXL345_DATARATE_0_20_HZ:
Serial.print ("0.20 ");
break;
case ADXL345_DATARATE_0_10_HZ:
Serial.print ("0.10 ");
break;
default:
Serial.print ("???? ");
break;
}
Serial.println(" Hz");
}
void displayRange(void) //加速度の計測範囲を表示します。
{
Serial.print ("Range: +/- ");
switch(accel.getRang()) //現在の範囲を取得し、±16g, ±8g, ±4g, ±2gのいずれかを表示
{
case ADXL345_RANGE_16_G:
Serial.print ("16 ");
break;
case ADXL345_RANGE_8_G:
Serial.print ("8 ");
break;
case ADXL345_RANGE_4_G:
Serial.print ("4 ");
break;
case ADXL345_RANGE_2_G:
Serial.print ("2 ");
break;
default:
Serial.print ("?? ");
break;
}
Serial.println(" g");
}
void setup(void)
{
#ifndef ESP8266
while (!Serial); // for Leonardo/Micro/Zero
#endif
Serial.begin(9600);//シリアル通信の初期化
Serial.println("Accelerometer Test"); Serial.println("");
/* Initialise the sensor */
if(!accel.begin())
{
/* There was a problem detecting the ADXL345 ... check your connections */
Serial.println("Ooops, no ADXL345 detected ... Check your wiring!");
while(1);
}
/* Set the range to whatever is appropriate for your project */
accel.setRange(ADXL345_RANGE_16_G);//測定範囲を±16gに設定//コメントアウトを変更すれば、別の範囲も選択可能
// accel.setRange(ADXL345_RANGE_8_G);
// accel.setRange(ADXL345_RANGE_4_G);
// accel.setRange(ADXL345_RANGE_2_G);
/* Display some basic information on this sensor */
displaySensorDetails();
/* Display additional settings (outside the scope of sensor_t) */
displayDataRate();
displayRange();
Serial.println("");
}
void loop(void)
{
/* Get a new sensor event */
sensors_event_t event;
accel.getEvent(&event);
/* Display the results (acceleration is measured in m/s^2) */
Serial.print("X: "); Serial.print(event.acceleration.x); Serial.print(" "); //X軸: 横方向の加速度。
Serial.print("Y: "); Serial.print(event.acceleration.y); Serial.print(" ");//Y軸: 縦方向の加速度。
Serial.print("Z: "); Serial.print(event.acceleration.z); Serial.print(" ");Serial.println("m/s^2 "); //Z軸: 高さ方向の加速度。
delay(500);
}
シリアルモニターには次のようなデーターが表示されます。
X: 2.28 Y: 2.31 Z: 9.85 m/s^2
X: 0.63 Y: 0.16 Z: 9.96 m/s^2
X: 1.61 Y: 2.35 Z: 10.12 m/s^2
X: -2.20 Y: 4.90 Z: 7.18 m/s^2
X軸:
- 横方向(左右)への加速度。
- 正の値は右方向への加速、負の値は左方向への加速を表します。
Y軸:
- 縦方向(前後)への加速度。
- 正の値は前方向への加速、負の値は後方向への加速を表します。
Z軸:
地球の重力加速度(約9.8 m/s²)がZ軸に常に含まれます
上下方向への加速度。
正の値は上方向への加速、負の値は下方向への加速を表します。
観測例
手で持って動かすと、各軸の値が変化します。
加速度データはm/s²で示され、重力加速度(約9.8 m/s²)が常にZ軸に含まれています。
なぜ傾きが加速度に影響するのか
重力加速度の影響
地球の重力(約9.8 m/s²)は常に下方向(Z軸方向)に向かっています。センサーを傾けると、重力がX軸やY軸にも分配されるため、各軸での加速度値が変化します。
例えば:
センサーが水平な場合:
Z≈9.8m/s²、 X≈0、Y≈0
センサーを45度傾けた場合:
重力がX軸またはY軸に一部分配されるため、Xや Y に値が現れます。
傾き角度と加速度の関係
傾きの角度 θは、重力成分と各軸の加速度から次のように計算できます:
$$θ=arcsin\frac{(加速度 (XまたはY)}{重力加速度 (約9.8))}$$
例えば、X軸が 4.9 m/s² を示す場合、対応する角度は約30度です。
水平に持った状態(静止)
X軸: ≈0 m/s²
Y軸: ≈0 m/s²
Z軸: ≈9.8 m/s²
前方に傾けた場合(X軸方向に傾ける)
X軸: 正の値(例: 4.9m/s²)
Y軸: ≈0 m/s²
Z軸: 値が減少(例: 8.5 m/s²)
横方向に傾けた場合(Y軸方向に傾ける)
X軸: ≈0 m/s²
Y軸: 正または負の値(例: −4.9 m/s²)
Z軸: 値が減少(例: 8.5 m/s²)
このデータを使用して、センサーの傾きや動きを計算することができます。
- 傾き(角度):
atan2()
関数を用いてX軸・Y軸から計算可能。 - 動きの方向: X軸とY軸の値を見て判定。
- 振動や衝撃の検出: 加速度の変化量を計測。
次にADXL345を使ってArduinoでX軸・Y軸の傾きに応じて4個のLEDを点灯させるコードを以下に示します。
- X軸、Y軸の傾きを判定し、LEDを次のように制御します:
- 前に傾けたらLED1を点灯
- 後ろに傾けたらLED2を点灯
- 右に傾けたらLED3を点灯
- 左に傾けたらLED4を点灯
ADXL345はI2C通信を使用します。
VCC
→ Arduino3.3V
GND
→ ArduinoGND
SCL
→ ArduinoA5
(UNOの場合)SDA
→ ArduinoA4
(UNOの場合)
4個のLEDはそれぞれ任意のデジタルピンに接続してください。
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_ADXL345_U.h>
// ADXL345センサーを初期化
Adafruit_ADXL345_Unified accel = Adafruit_ADXL345_Unified(12345);
// LEDのピン番号
const int led1 = 2; // 前
const int led2 = 3; // 後ろ
const int led3 = 4; // 右
const int led4 = 5; // 左
void setup() {
Serial.begin(9600);
// LEDピンを出力に設定
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
// ADXL345の初期化
if (!accel.begin()) {
Serial.println("ADXL345を検出できません。接続を確認してください。");
while (1);
}
accel.setRange(ADXL345_RANGE_16_G); // 測定範囲を±16Gに設定
}
void loop() {
sensors_event_t event;
accel.getEvent(&event); // ADXL345から加速度データを取得
float x = event.acceleration.x;
float y = event.acceleration.y;
Serial.print("X軸: "); Serial.print(x); Serial.print(" m/s^2 ");
Serial.print("Y軸: "); Serial.print(y); Serial.println(" m/s^2 ");
// 傾きの閾値(m/s^2)
float threshold = 5.0; //threshold を5.0 m/s²に設定しています。この値を超えるかどうかで傾きを判定します。
// LEDの点灯制御
digitalWrite(led1, y > threshold); // 前に傾けたらLED1//傾きの方向に応じたLEDを点灯させます
digitalWrite(led2, y < -threshold); // 後ろに傾けたらLED2
digitalWrite(led3, x > threshold); // 右に傾けたらLED3
digitalWrite(led4, x < -threshold); // 左に傾けたらLED4
delay(100); // 100msの遅延//100ミリ秒ごとにデータを更新し、LEDの点灯を切り替えます
}
float threshold = 5.0;
というコードで設定された 閾値(スレッショルド)は、特定の加速度を基準にしてLEDを点灯させるかどうかを判断するための値です。この場合、5.0 m/s² という値はX軸やY軸方向の加速度が5.0 m/s²を超えたときに、傾いていると見なしてLEDを点灯させるように設定されています。
1. 閾値の決定方法
閾値は、使用する環境やセンサーの用途によって決まります。以下の要素を考慮して設定されます:
- 重力加速度との関係
静止している状態のセンサーには地球の重力(約9.8 m/s²)がZ軸方向にかかります。このため、X軸やY軸方向の加速度が0 m/s²に近い場合は水平とみなされ、ある程度の値を超えると傾きと見なすことができます。 - 許容する傾きの角度
センサーの加速度値を使って傾きを計算すると、加速度 aと重力 g=9.8 m/s²との比率から角度 θ を求められます:θ=arcsin(a/g)閾値を a=5.0 m/s² とした場合、対応する角度 θは次のようになります:θ=arcsin(5.0/9.8)≈30∘つまり、この場合はセンサーが約30度以上傾いたときにLEDが点灯するようになっています。
2. 閾値を調整する理由
- 高すぎる場合:小さな傾きでは反応しなくなり、より大きく傾けないとLEDが点灯しません。
- 低すぎる場合:少しの振動や誤差でLEDが点灯してしまい、誤動作が増えます。
この閾値 5.0
は、傾きの検出を約30度以上に設定するための目安として使用されています。プロジェクトの特性や必要な感度に応じて、この値を適宜調整することで最適な動作を得られます。
作成中
#include <Wire.h>
#include <MPU6050.h>
MPU6050 mpu;
void setup() {
Serial.begin(115200);
Wire.begin(); // Arduino AVRではピン番号を指定しない
// MPU6050の初期化
mpu.initialize();
if (mpu.testConnection()) {
Serial.println("MPU6050の接続に成功しました");
} else {
Serial.println("MPU6050の接続に失敗しました");
while (1); // エラー時は停止
}
}
void loop() {
int16_t ax, ay, az;
int16_t gx, gy, gz;
// 加速度とジャイロのデータを取得
mpu.getAcceleration(&ax, &ay, &az);
mpu.getRotation(&gx, &gy, &gz);
// データを表示
Serial.print("加速度 (X, Y, Z): ");
Serial.print(ax); Serial.print(", ");
Serial.print(ay); Serial.print(", ");
Serial.println(az);
Serial.print("ジャイロ (X, Y, Z): ");
Serial.print(gx); Serial.print(", ");
Serial.print(gy); Serial.print(", ");
Serial.println(gz);
delay(1000); // 0.5秒ごとにデータを取得
}
ジャイロ (X, Y, Z): 1235, 290, -170
加速度 (X, Y, Z): 15076, 1992, -6080
ジャイロ (X, Y, Z): -950, 5698, -4739
加速度 (X, Y, Z): 6788, 9320, -1992
ジャイロ (X, Y, Z): 4236, -11815, -7154
加速度 (X, Y, Z): 5924, 15716, 52
次は、Telloの実機に加速度センサーADLX345を外付けし、生データーを見てみたいと思います。
#include <WiFi.h>
#include <Wire.h>
#include <MPU6050.h>
#include <WebServer.h> // HTTPサーバー用ライブラリ
// Wi-FiのSSIDとパスワード
const char* ssid = "30******-2G"; #WIFI ID
const char* password = "2********"; #PASS WORD
// Webサーバーのポートを80番に設定
WebServer server(80);
MPU6050 mpu;
// センサーデータを保持する変数
int16_t ax, ay, az;
int16_t gx, gy, gz;
// センサーのデータを取得してHTML形式で返す
void handleRoot() {
mpu.getAcceleration(&ax, &ay, &az);
mpu.getRotation(&gx, &gy, &gz);
String html = "<html><body><h1>MPU6050 Sensor Data</h1>";
html += "<p><strong>Acceleration (X, Y, Z):</strong> " + String(ax) + ", " + String(ay) + ", " + String(az) + "</p>";
html += "<p><strong>Gyro (X, Y, Z):</strong> " + String(gx) + ", " + String(gy) + ", " + String(gz) + "</p>";
html += "</body></html>";
server.send(200, "text/html", html);
}
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("\nWiFi connected.");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
Wire.begin();
mpu.initialize();
if (mpu.testConnection()) {
Serial.println("MPU6050の接続に成功しました");
} else {
Serial.println("MPU6050の接続に失敗しました");
while (1);
}
// ルートパスに対するハンドラを設定
server.on("/", handleRoot);
// HTTPサーバーを開始
server.begin();
Serial.println("HTTPサーバーが開始されました");
}
void loop() {
// クライアントからのリクエストを処理
server.handleClient();
}
投稿
- 空撮事始め (2021年6月18日)
- 航空法施行規則改正されました。令和3年6月1日 (2021年6月19日)
- Tello(Ryze Technology 社 POWERED BY DJI)の飛ばし方マニュアル (2021年7月5日)
- 趣味におすすめ!ドローン(Tello)のいろいろな楽しさをお伝えします。 (2021年7月5日)
- プログラミング言語って?Pythonの導入前にプログラミング言語の種類をおおまかにまとめてみました。 (2021年7月6日)
- ドローンのプログラミングらしき事をやってみる! はじめてのPython&IDEのインストール方法 (2021年7月7日)
- Tello の画像をOpenCVでPCに写してみる!!OpenCVの導入方法 (2021年7月9日)
- これだけは知っておこう!ドローンを飛ばすのに法律って関係あるの? (2021年7月15日)
- ドローンの空撮は最高!きままに撮ってみました(^^♪ 空撮Gallery集 (2021年7月30日)
- ドローンを飛ばすなら これだけは知っておこう!ドローンの飛行ルール(令和3年6月施行) (2021年7月30日)
- これだけは知っておこう!ドローン空撮には注意が必要です。映像等のインターネット上での注意事項。 (2021年7月30日)
- socket通信プログラムの部分を少しだけ解説してみました (2021年9月2日)
- OpenCVで遊んでみる。 PC内蔵webカメラから動画の撮影。 (2021年9月14日)
- PCでOpenCVで顔認識して遊んでみる。(^^♪ カスケード分類器の使い方 (2021年10月30日)
- ドローン・無人航空機の登録が義務化されます。リモートIDの付け方 (2021年12月14日)
- ドローンのプログラミングでOpenCVをつかい顔認識をしてみる (2022年1月9日)
- ドローン(Tello)を飛ばしてOpenCVで顔認識してみる改良版 (2022年2月21日)
- TelloでOpenCVで顔認識させたらFLIP(フリップ)させる(^^♪ (2022年5月2日)
- Pythonを使いTello(ドローン)でOpenCV(顔認識)から自動追尾をしてみる!☺ (2022年6月13日)
- フィンガーサインでドローン(Tello)を操縦してみた!MediaPipeを使用 (2022年9月29日)
- Pythonプログラミング・OpenCv&MediaPipeを使いドローン(Tello)を自由に操縦してみた! (2022年11月21日)
- Pythonで「Tello(ドローン)で自動追尾プログラミング」改良版を紹介します!これはいける! (2023年3月22日)
- OpenCVで遊んでみる。 PC内蔵カメラから映像の表示 と ドローンからの映像を表示をする (2023年4月13日)
- Telloとパソコンの通信の部分を少しわかりやすくしてみました (2023年4月13日)
- 100g未満のドローン、100g以上のドローンを飛ばすには?法律や準備しないといけないことは何? (2023年4月21日)
- mediapipe(メディアパイプ)& OpenCV・ Pythonでposeランドマーク検出Telloの自動操縦 (2023年5月8日)
- プログラミングで動かせるオススメ!ドローン・ロボット ベスト2選!! (2023年6月1日)
- 海外、子供に人気!プログランミングで動かせるドローンLitebeeWing紹介(パソコン接続方法解説)します。 (2023年7月2日)
- 講座用ダウンロード サイト (2023年7月7日)
- ドローン(Tello)を音声認識コントロールできる?パソコンで2か所Wi-Fi接続してGoogle Speech to Text (2023年7月9日)
- 最近はまっている 楽しーい気分転換アイテム ドローン&プログラミング学習用教材&ラジコン (2023年7月26日)
- Scratch(スクラッチ)ビデオモーションセンサーでTello(ドローン)操作 AR「拡張現実」? (2024年1月31日)
- スクラッチ(Scratch3-Tello) & (マイコンボード)micro:bitを使って、Telllo(ドローン)をコントロールしてみた(^^♪ (2024年5月5日)
- マイコンでドローン感知ロボットを作ってみました(^^♪ microbit & arduino (2024年6月1日)
- mediapipe & Arduino で 自称ロボットのジェスチャーコントロール (2024年6月5日)
- M5Stackを内蔵のESP32でWiFiサーバーとして使い、コードレスで無線ジェスチャーコントロールをしてみました(^^)/ (2024年6月12日)
- ロボットアームのジェスチャーコントロールへの挑戦 からだアクション操作*目指せ老後の食事介助アーム* (2024年6月27日)
- LiteBee Wing/ SKY / Tello でドローンプログラミングを教えます。プログラミングしたい人集まれ(^^♪ (2024年7月3日)
- 自由研究に!「ドローンをつくろう!学ぼう!」by 神戸ロボットクラブ (2024年8月17日)
- 加速度センサーとジャイロセンサーをArduinoで使って学び、Telloの慣性ユニットに触れる(^_-)-☆ (2025年1月16日)
タグ
- IMU
- 特定非営利活動法人神戸ロボットクラブ
- ロボット、レーダー、トイドローン
- 神戸ロボットクラブ
- 自由研究
- 小学生
- 組立
- 仕組み
- NPO法人神戸ロボットクラブ
- ドローンプログラミング
- 教育
- python opencv
- ドローン自動追尾
- MPU6050
- ADLX345
- 加速度センサー
- ジャイロ
- 慣性ユニット
- arudino
- マイコン、microbit
- モーションセンサー
- 親子でプログラミング
- MediaPipe
- プログラミング、自動操縦
- プログラミング、顔認識、自動操縦
- プログラミング 自動追尾
- ロボット
- Otto
- 楽しい
- 知育教育
- マッキーの趣味のドローン
- litebee
- litebeewing
- Scratch
- ドローン
- スクラッチ
- 子供
- OpenCv
- プログラミング
- tello
- プログラミング、大人の趣味、老後対策
- 食事介助、ロボットアーム、mediapipe
- arduino