セグウェイのRYNOモーターやその他のセルフバランススクーターに触発された後、私はいつも自分のArduinoセグウェイロボットを作りたいと思っていました。しばらく考えて、Arduinoを使ってセルフバランスロボットを作ることにしました。このようにして、これらすべてのスクーターの背後にある基本的な概念を把握し、PIDアルゴリズムがどのように機能するかを学ぶことができます。
構築を開始すると、このボットを構築するのは少し難しいことに気付きました。選択できるオプションは非常に多いため、混乱はモーターの選択から始まり、PID値を調整するまで続きます。そして、バッテリーの種類、バッテリーの位置、ホイールグリップ、モータードライバーの種類、CoG(重力中心)の維持など、考慮すべきことがたくさんあります。
しかし、私はあなたにそれを壊させてください、あなたがそれを構築したら、あなたはそれが思ったほど難しくないことに同意するでしょう。それでは、それに直面しましょう。このチュートリアルでは、セルフバランシングロボットを構築した私の経験を文書化します。あなたは、始めたばかりのまったくの初心者かもしれませんし、ボットが機能しないことへの長い欲求不満の後にここに上陸したかもしれません。この場所はあなたの最終目的地になることを目指しています。それでは始めましょう……
バランススクーター用部品の選択
ボットを構築するためのすべてのオプションを説明する前に、この自己バランスロボットプロジェクトで使用したアイテムをリストします。
- Arduino UNO
- ギヤードDCモーター(黄色)– 2Nos
- L298Nモータードライバーモジュール
- MPU6050
- ホイールのペア
- 7.4Vリチウムイオン電池
- 接続線
- 3Dプリントボディ
可用性に基づいて上記のコンポーネントのいずれかを組み合わせて選択し、独自の自己バランスロボットキットを作成できます。コンポーネントが次の基準を満たしていることを確認してください。
コントローラー: ここで使用したコントローラーはArduino UNOです。これは、単純に使いやすいためです。ArduinoNanoまたはArduinominiを使用することもできますが、外部ハードウェアなしで直接プログラムできるため、UNOを使用することをお勧めします。
モーター: セルフバランスロボットに使用できるモーターの最良の選択は、間違いなくステッピングモーターです。しかし、物事を簡単にするために、私はDCギアモーターを使用しました。はい、ステッパーは必須ではありません。ボットは、これらの安価で一般的に入手可能な黄色のDCギアモーターでも正常に動作します。
モータードライバー:私のようなDCギアモーターを選択した場合は、私のようなL298Nドライバーモジュールを使用するか、L293Dでさえ問題なく動作するはずです。L293DとArduinoを使用したDCモーターの制御の詳細をご覧ください。
ホイール:これらの人を過小評価しないでください。問題が自分のホイールにあることを理解するのに苦労しました。したがって、使用している床に対してホイールがしっかりとグリップしていることを確認してください。注意深く見てください、あなたのグリップはあなたの車輪が床で滑ることを決して許してはなりません。
加速度計とジャイロスコープ:ボットに最適な加速度計とジャイロスコープはMPU6050です。したがって、ADXL345などの通常の加速度計を使用して作成しようとしないでください。機能しません。この記事の最後でその理由がわかります。ArduinoでのMPU6050の使用に関する専用記事も確認できます。
バッテリー: ブーストモジュールなしでArduinoに直接電力を供給できるように、できるだけ軽量で動作電圧を5V以上にするバッテリーが必要です。したがって、理想的な選択は7.4Vリチウムポリマーバッテリーです。ここでは、7.4Vのリチウムイオン電池がすぐに手に入るので、それを使用しました。ただし、Li-poはLi-ionよりも有利であることを忘れないでください。
シャーシ: 妥協してはならないもう1つの場所は、ボットのシャーシです。段ボール、木、プラスチックなど、好きなものなら何でも使えます。ただし、シャーシが頑丈であり、ボットがバランスをとろうとしているときに揺れないようにしてください。他のボットから推測してSolidworksで独自のシャーシを設計し、3Dプリントしました。プリンタをお持ちの場合は、デザインを印刷することもできます。デザインファイルは次の見出しに添付されます。
セルフバランシングロボットの3Dプリントと組み立て
ボットの構築に使用しているのと同じシャーシを3D印刷することにした場合は、thingiverseからSTLファイルをダウンロードできます。また、デザインファイルも一緒に追加したので、担当者の好みに応じて変更することもできます。
パーツには張り出し構造がないため、サポートなしで簡単に印刷でき、25%の面材で問題なく機能します。デザインはかなりシンプルで、基本的なプリンターならどれでも簡単に処理できるはずです。Curaソフトウェアを使用してモデルをスライスし、TevoTarantulaを使用して印刷しました。設定を以下に示します。
ボディ部分と4つのモーター取り付け部分を印刷する必要があります。組み立ては非常に簡単です。3mmのナットとボルトを使用して、モーターとボードを所定の位置に固定します。組み立てると、下の写真のようになります。
実際の設計は、上記のように、Arduinoの下部ラックにL298Nドライブモジュールを配置し、その上部にバッテリーを配置して計画されました。同じ順序に従っている場合は、提供されている穴からボードを直接ねじ込み、Li-poバッテリーにワイヤータグを使用できます。後で交換しなければならなかったスーパープレーンホイールを除いて、この配置も機能するはずです。
私のボットでは、プログラミングを容易にするためにバッテリーとArduino UNOボードの位置を入れ替えました。また、接続を完了するためにパフォーマンスボードを導入する必要がありました。そのため、ボットは初期段階で計画したとおりに見えませんでした。配線プログラミングテストとすべてを完了した後、私の二輪ロボットは最終的に次のようになります
回路図
このArduinoベースのセルフバランシングロボットの接続は非常に簡単です。これはArduinoとMPU6050を使用したセルフバランシングロボットであるため、MPU6050をArduinoに接続し、モータードライバーモジュールを介してモーターを接続する必要があります。セットアップ全体は、7.4Vのリチウムイオン電池で駆動されます。その回路図を以下に示します。
ArduinoとL298Nモータードライバーモジュールは、それぞれVinピンと12V端子から直接給電されます。Arduinoボードのオンボードレギュレータは入力7.4Vを5Vに変換し、ATmegaICとMPU6050はそれによって電力を供給されます。DCモーターは、5Vから12Vの電圧で動作できます。ただし、バッテリーからの7.4Vのプラス線をモータードライバーモジュールの12V入力端子に接続します。これにより、モーターは7.4Vで動作します。次の表に、MPU6050およびL298NモータードライバーモジュールをArduinoに接続する方法を示します。
コンポーネントピン |
Arduinoピン |
MPU6050 |
|
Vcc |
+ 5V |
接地 |
Gnd |
SCL |
A5 |
SDA |
A4 |
INT |
D2 |
L298N |
|
1で |
D6 |
IN2 |
D9 |
IN3 |
D10 |
IN4 |
D11 |
MPU6050はI2Cインターフェースを介してArduinoと通信するため、ArduinoのSPIピンA4およびA5を使用します。DCモーターは、PWMピンD6、D9、D10、およびD11にそれぞれ接続されています。PWM信号のデューティサイクルを変化させることによってDCモーターの速度を制御するため、これらをPWMピンに接続する必要があります。これらの2つのコンポーネントに精通していない場合は、MPU6050インターフェイスとL298Nモータードライバーのチュートリアルを読むことをお勧めします。
自己バランスロボットコード
次に、ロボットのバランスをとるためにArduinoUNOボードをプログラムする必要があります。ここですべての魔法が起こります。その背後にある概念は単純です。ボットがMPU6050を使用して前に傾いているか後ろに傾いているかを確認する必要があります。次に、ボットが前に傾いている場合はホイールを前方向に回転させ、後ろに傾いている場合はホイールを回転させる必要があります。逆方向に。
同時に、ホイールが回転する速度も制御する必要があります。ボットが中心位置からわずかにずれている場合、ホイールはゆっくりと回転し、中心位置から離れるにつれて速度が増加します。このロジックを実現するために、PIDアルゴリズムを使用します。このアルゴリズムでは、中心位置が設定値として、見当識障害のレベルが出力として使用されます。
ボットの現在の位置を知るために、6軸の加速度計とジャイロスコープセンサーを組み合わせたMPU6050を使用します。センサーから信頼できる位置の値を取得するには、加速度計とジャイロスコープの両方の値を使用する必要があります。これは、加速度計の値にはノイズの問題があり、ジャイロスコープの値は時間とともにドリフトする傾向があるためです。したがって、両方を組み合わせて、ロボットのヨーピッチとロールの値を取得する必要があります。そのうち、ヨーの値のみを使用します。
頭が少し動いているようですね。ただし、心配しないでください。Arduinoコミュニティのおかげで、PID計算を実行し、MPU6050からヨーの値を取得できるライブラリをすぐに利用できます。ライブラリは、それぞれbr3ttbとjrowbergによって開発されています。先に進む前に、次のリンクからライブラリをダウンロードして、Arduinolibディレクトリに追加してください。
github.com/br3ttb/Arduino-PID-Library/blob/master/PID_v1.h
github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050
これで、ArduinoIDEにライブラリが追加されました。セルフバランスロボットのプログラミングを始めましょう。いつものように、MPU6050バランシングロボットの完全なコードはこのページの最後にあります。ここでは、コード内の最も重要なスニペットについて説明します。先に述べたように、コードはMPU6050サンプルコードの上に構築されており、目的に合わせてコードを最適化し、セルフバランシングロボットのPIDと制御技術を追加します。
まず、このプログラムが機能するために必要なライブラリを含めます。これには、ダウンロードしたばかりの組み込みのI2Cライブラリ、PIDライブラリ、およびMPU6050ライブラリが含まれます。
#include "I2Cdev.h" #include
次に、MPU6050センサーからデータを取得するために必要な変数を宣言します。重力ベクトルとクォータニオンの両方の値を読み取り、ボットのヨーピッチとロール値を計算します。 float配列のYPRは 、最終的な結果を保持します。
// MPUコントロール/ステータス varsbool dmpReady = false; // DMPの初期化が成功した場合はtrueに設定します uint8_tmpuIntStatus; // MPUからの実際の割り込みステータスバイトを保持します uint8_tdevStatus; //各デバイス操作後にステータスを返します(0 =成功、!0 =エラー) uint16_t packetSize; //予想されるDMPパケットサイズ(デフォルトは42バイト) uint16_t fifoCount; //現在FIFOにあるすべてのバイトのカウント uint8_tfifoBuffer; // FIFOストレージバッファ //方向/モーション変数 Quaternionq; //クォータニオンコンテナ VectorFloat重力; //重力ベクトル floatypr; //ヨー/ピッチ/ロールコンテナと重力ベクトル
次に、コードの非常に重要なセグメントがあります。ここで、適切な値のセットを調整するために長い時間を費やします。ロボットが非常に優れた重心で構築されており、コンポーネントが対称的に配置されている場合(ほとんどの場合そうではありません)、設定値は180になります。それ以外の場合は、ボットをArduinoシリアルモニターに接続し、適切なバランス位置を見つけたら、シリアルモニターに表示されている値を読み取ります。これが設定値です。 Kp、Kd、Kiの値は、ボットに応じて調整する必要があります。 2つの同一のボットが同じ値のKp、Kd、およびKiを持つことはないため、そこから逃れることはありません。このページの最後にあるビデオを見て、これらの値を調整する方法を理解してください。
/ *********これらの4つの値をBOTに合わせて調整します********* / double setpoint = 176; //シリアルモニターを使用してボットが地面に垂直な場合の値を設定します。 //これらの値を doubleKp = 21 に設定する方法については、circuitdigest.comのプロジェクトドキュメントをお読みください。 //この最初のdoubleKd = 0.8を設定します; //この2番目の doubleを 設定しますKi = 140; //最後にこれを設定します/ ******値の終了設定********* /
次の行では、入力変数input、output、set point、Kp、Ki、およびKdを渡すことにより、PIDアルゴリズムを初期化します。これらのうち、上記のコードスニペットで設定値Kp、Ki、およびKdの値をすでに設定しています。入力の値は、MPU6050センサーから読み取られたヨーの現在の値になり、出力の値は、PIDアルゴリズムによって計算された値になります。したがって、基本的にPIDアルゴリズムは、入力値を設定値に近くなるように修正するために使用する必要がある出力値を提供します。
PID pid (&input、&output、&setpoint、Kp、Ki、Kd、DIRECT);
ボイドセットアップ 機能内で、DMP(デジタルモーションプロセッサ)を設定してMPU6050を初期化します。これは、加速度計のデータとジャイロスコープのデータを組み合わせるのに役立ち、ヨー、ピッチ、ロールの信頼できる値を提供します。これはトピックをはるかに超えているため、これについてはあまり詳しく説明しません。とにかく、セットアップ関数で検索する必要があるコードの1つのセグメントは、ジャイロオフセット値です。各MPU6050センサーには独自のオフセット値があり、このArduinoスケッチを使用してセンサーのオフセット値を計算し、プログラムでそれに応じて次の行を更新できます。
//ここに独自のジャイロオフセットを指定し、最小感度に 合わせて スケーリングしますmpu.setXGyroOffset(220); mpu.setYGyroOffset(76); mpu.setZGyroOffset(-85); mpu.setZAccelOffset(1688);
また、モーターの接続に使用しているデジタルPWMピンを初期化する必要があります。私たちの場合、それはD6、D9、D10、およびD11です。したがって、これらのピンを初期化すると、出力ピンがデフォルトでLOWになります。
//モーター出力ピンを 初期化しますpinMode(6、OUTPUT); pinMode(9、OUTPUT); pinMode(10、OUTPUT); pinMode(11、OUTPUT); //デフォルトでは、両方のモーターをオフにします analogWrite(6、LOW); AnalogWrite(9、LOW); AnalogWrite(10、LOW); AnalogWrite(11、LOW);
メイン ループ 関数内で、MPU6050からのデータを読み取る準備ができているかどうかを確認します。はいの場合、それを使用してPID値を計算し、PIDの入力値と出力値をシリアルモニターに表示して、PIDがどのように応答しているかを確認します。次に、出力の値に基づいて、ボットが前方または後方に移動する必要があるか、静止する必要があるかを決定します。
ボットが直立している場合、MPU6050は180を返すと想定しているためです。ボットが前方に向かって落下している場合は補正値が正になり、ボットが後方に向かって落下している場合は負の値が得られます。そのため、この状態を確認し、適切な関数を呼び出してボットを前後に移動します。
while(!mpuInterrupt && fifoCount <packetSize) { // mpuデータなし-PID計算を実行し、モーターに出力 pid.Compute(); //入力と出力の値をシリアルモニターに出力して、動作を確認します。Serial.print(入力); Serial.print( "=>"); Serial.println(出力); if(input> 150 && input <200){//ボットが落下している場合if(output> 0)//正面に向かって落下Forward(); //ホイールを前方に回転しますelseif(output <0)//後方に落下Reverse(); //ホイールを後方に回転させます} else //ボットが落下しない場合Stop(); //ホイールを動かさないでください}
PID出力変数は、モータが回転する必要がありますどのくらいの速を決定します。ボットが落下しそうな場合は、ホイールをゆっくりと回転させて微調整を行います。これらのマイナーな修正が機能し、それでもボットが落下している場合は、モーターの速度を上げます。ホイールの回転速度の値は、PIアルゴリズムによって決定されます。逆関数では、負の値を正に変換できるように、出力の値に-1を掛けていることに注意してください。
void Forward()//ホイールを前方に回転させるコード { analogWrite(6、output); AnalogWrite(9,0); AnalogWrite(10、output); AnalogWrite(11,0); Serial.print( "F"); //デバッグ情報 } void Reverse()//ホイールを後方に回転させるコード { analogWrite(6,0); AnalogWrite(9、output * -1); AnalogWrite(10,0); AnalogWrite(11、output * -1); Serial.print( "R"); } void Stop()//両方のホイールを停止するコード { analogWrite(6,0); AnalogWrite(9,0); AnalogWrite(10,0); AnalogWrite(11,0); Serial.print( "S"); }
Arduinoセルフバランシングロボットの動作
ハードウェアの準備ができたら、コードをArduinoボードにアップロードできます。 Li-ionバッテリーを使用しているため、接続が適切であることを確認してください。細心の注意が必要です。したがって、短絡がないか再確認し、ボットに小さな影響があったとしても、端子が接触しないようにしてください。モジュールの電源を入れてシリアルモニターを開きます。ArduinoがMPU6050と正常に通信でき、すべてが期待どおりに機能している場合は、次の画面が表示されます。
ここでは、PIDアルゴリズムの入力値と出力値がinput => outputの形式で表示されます。ボットのバランスが完全に取れている場合、出力の値は0になります。入力値は、MPU6050センサーからの現在の値です。アルファベットの「F」はボットが前進していることを表し、「R」はボットが後退していることを表します。
PIDの初期段階では、Arduinoケーブルをボットに接続したままにして、入力と出力の値を簡単に監視できるようにすることをお勧めします。また、Kp、Ki、Kdの値をプログラムで修正してアップロードするのも簡単です。以下のビデオは、ボットの完全な動作を示し、PID値を修正する方法も示しています。
動作させるのに問題がある場合は、これが独自の自己バランスロボットの構築に役立つことを願っています。質問は下のコメントセクションに残すか、フォーラムを使用して技術的な質問をしてください。もっと楽しくしたい場合は、同じロジックを使用してボールバランシングロボットを構築することもできます。