ライン追従ロボットをプログラムする方法
- ルート追従ロボットをプログラムする方法 (robotresearchlab.com)
- PID チューニングの記事: http://robotresearchlab.com/2019/02/16/pid-line-follower-tuning/
追跡ロボットをワイヤープログラミングするために人々が選択する 2 つの主な方法を説明し、その 2 つを比較します。「簡易トラッキング」と「PIDトラッキング」を詳しく比較していきます。低速では、単純な追跡アルゴリズムは完全に許容されますが、速度が増加すると、単純な追跡アルゴリズムは PID 制御アルゴリズムほど優れたものではなくなります。
単純なライントレース
まず、単純なワイヤ トレースがあります。このタイプのトレースの背後にある一般前提は、1 ~ 2 個のセンサーがあり、センサーがワイヤーを認識した内容に基づいてモーターの応答をハードコーディングするということです。理解しやすく、プログラミングも簡単なため、これは通常、線をトレースするときに最初に学ぶ方法です。まずは、一般的なセンサーのオプションを確認してみましょう。
センサー
以下のセンサー ラインの背後にある一般的な考え方は、1 つのモーターをわずかに減速または増加させたモーター速度で動作するように設定し、ロボットが一方向 (ラインの方向に向かって) に偏るようにするというものです。センサーがラインを認識すると、ラインを横切るのを防ぐために、ラインに最も近いモーターを一時的に加速します。
**アドバンテージ
- 簡単な回路
- プログラムが簡単
- 最低レベルで仕事を終わらせる
- 直線の場合は悪くない解決策
欠点がある
- この一線を一度超えてしまうと大変な事になるかも知れません
- 滑らかなラインでのみ機能します (急な曲がりは不可)
- (直進せずに) 余分な距離を移動すると時間が無駄になります
- 全然早く歩けない
サンプルコード
以下は、このコードがどのようなものであるかについてのアイデアを提供するはずです。私はこのコードをテストしていないので、注意して進めてください。
#define L_MOTOR 9
#define R_MOTOR 10
#define MAX_SPEED 200
#define SET_SPEED 150
#define MIN_SPEED 135
#define MIDDLE_IR A1
#define TAPE_THRESHOLD 350 // Anything less is a Black reflectance
void setup() {
// Intialize pins
pinMode(MIDDLE_IR, INPUT);
}
void loop() {
if (analogRead(MIDDLE_IR) < TAPE_THRESHOLD) {
// We are seeing the line under the middle sensor
analogWrite(L_MOTOR, SET_SPEED);
analogWrite(R_MOTOR, MAX_SPEED);
} else {
// Drive slightly right to hug the line
analogWrite(L_MOTOR, SET_SPEED);
analogWrite(R_MOTOR, MIN_SPEED);
}
}
2つのセンサー
2 つのセンサー ワイヤーをトレースする一般的な考え方は、一方のセンサーがワイヤーを認識すると、ワイヤーを認識しているセンサーの反対側のモーターを減速または停止するというものです。センサーは連携してロボットを軌道に乗せます。この方法を使用する場合は、センサーを非常に近づけるようにしてください。センサーが近づくほど、運転中のロボットの揺れが少なくなります。これにより、より直接的な運転の外観が得られ、以前は距離を調整する際の無駄な時間が短縮されます。目標はもっと短かった。
アドバンテージ
- 簡単な回路
- プログラムが簡単
欠点がある
- ラインを失うと回復するのが困難になる可能性があります
- 左右に移動するのに時間を無駄にする
- 高速には適さない
サンプルコード
#define L_MOTOR 9
#define R_MOTOR 10
#define MAX_SPEED 250
#define SET_SPEED 200
#define MIN_SPEED 50
#define LEFT_IR A0
#define RIGHT_IR A2
#define TAPE_THRESHOLD 350 // Anything less is a Black reflectance
void setup() {
// Intialize pins
pinMode(LEFT_IR, INPUT);
pinMode(RIGHT_IR, INPUT);
}
void loop() {
if (analogRead(LEFT_IR) < TAPE_THRESHOLD) {
// We are seeing the line under the left sensor, turn left
analogWrite(L_MOTOR, MIN_SPEED);
analogWrite(R_MOTOR, SET_SPEED);
} else if (analogRead(RIGHT_IR) < TAPE_THRESHOLD) {
// We are seeing the line under the right sensor, turn right
analogWrite(L_MOTOR, SET_SPEED);
analogWrite(R_MOTOR, MIN_SPEED);
}
}
3 つ以上のセンサー
次の 3 つのセンサー シリーズの背後にある考え方は、2 つのセンサーよりも感度が高いということです。通常、3 番目のセンサーを中央に配置しますが、2 センサー トラッカーの場合と同様に調整するだけでなく、3 番目または 4 番目のケースを追加することもできます。3 番目のケースでは、ラインが中央のセンサーの下にある場合は、直線の経路を維持するために両方のモーターを同じ速度に設定します。オプションの 4 番目のケースでは、センサーがラインを検出しない場合、モーターがオフになるか、再びラインを検出するまで回転します。
また、センサーを追加する場合は、調整レイヤーを追加できます。センサーが 4 つあると仮定すると、左端のセンサーがラインを認識した場合は、右のモーターをオフにすることができます。また、左から 2 番目のセンサーがラインを認識した場合は、右のモーターの速度を落とすだけで、より急激に反応するようになります。鋭い角がある場合、または何らかの理由で線から遠く離れている場合。
アドバンテージ
- 最も堅牢なシンプルな追跡方法
- 回線が失われた場合に検出する機能
- 厳密なオン/オフまたは高速/低速による段階的な調整
- プログラムが簡単
欠点がある
- まだ、エラーに対する真のアナログ応答ではありません (ロボットがラインをたどる際に震えることがよくあります)
- 高速には適さない
サンプルコード
#define L_MOTOR 9
#define R_MOTOR 10
#define MAX_SPEED 200
#define SET_SPEED 200
#define MIN_SPEED 50
#define STOP_SPEED 0
#define LEFT_IR A0
#define MIDDLE_IR A1
#define RIGHT_IR A2
#define TAPE_THRESHOLD 350 // Anything less is a Black reflectance
void setup() {
// Intialize pins
pinMode(LEFT_IR, INPUT);
pinMode(MIDDLE_IR, INPUT);
pinMode(RIGHT_IR, INPUT);
}
void loop() {
if (analogRead(LEFT_IR) < TAPE_THRESHOLD) {
// We are seeing the line under the left sensor, turn left
analogWrite(L_MOTOR, MIN_SPEED);
analogWrite(R_MOTOR, SET_SPEED);
} else if (analogRead(MIDDLE_IR) < TAPE_THRESHOLD) {
// We are seeing the line under the middle sensor, go straight
analogWrite(L_MOTOR, SET_SPEED);
analogWrite(R_MOTOR, SET_SPEED);
} else if (analogRead(RIGHT_IR) < TAPE_THRESHOLD) {
// We are seeing the line under the right sensor, turn right
analogWrite(L_MOTOR, SET_SPEED);
analogWrite(R_MOTOR, MIN_SPEED);
} else {
// We don't see the line at all, let's stop
analogWrite(L_MOTOR, STOP_SPEED);
analogWrite(R_MOTOR, STOP_SPEED);
}
}
PID追跡
ここで、もう少し複雑ですが、より正確なライン トラッキング アルゴリズムである PID ライン トラッキングを紹介しましょう。多くの初心者は PID ライン トレースの複雑さに気を悪くし、PID 計算用のライブラリに依存する傾向があることに気づきました。何が起こっているかを理解するために、独自の単純な PID アルゴリズムから始めることをお勧めします。もちろん、PID ライブラリを使用して回避することもできますが、それがどのように機能するかを実際には理解していないため、値を微調整し、これが結果にどのような影響を与えるかを正確に知ることは困難です。
アドバンテージ
- 非常にスムーズで正確なライン追従
- 通常、「簡単な」方法よりも早くラインをたどることができます。
- さまざまな位置に沿ってトレースする場合の柔軟性が向上します (トレースの中心、わずかに左、わずかに右)
欠点がある
- 調整が必要です、時間がかかる場合があります
- ガイダンスがないと理解できないように見えるかもしれません (この記事でそれが解消されることを願っています)
- センサーが増えると、測定値を取得するのに時間がかかります
PIDとは何ですか?
まず、PID とは何かについて説明します。PID は Proportional、Integral、Derivative の頭字語ですが、怖がらせる必要はありません。簡単で微積分は必要ありません。PID の背後にある考え方は、実際の値と目標値または設定点があるということです。目標値と実際の値の差に基づいてシステムを調整できます。
P
その調整の最初の側面は P です。これは単なる係数です。つまり、誤差に乗算して調整として適用する数値です。車を運転していて、時速 55 マイルの一定速度を維持しようとしているとします。速度計を読んで現在時速 55 マイルになっていれば、時速 5 マイルが低いことがわかります。そのため、速度を上げるにはアクセルを踏む必要があります。スピードを戻します。スピードメーターを毎秒確認して調整しているとすると、ゆっくりとアクセルを戻していくことになるでしょう。したがって、P 値については、距離をスロットルの調整に必要な量に換算する値を決定する必要があります。
たとえば、通常、スロットルを 1 インチ動かすと、速度が 1 秒間に 1 マイル増加するとします。そうですね、簡単な計算を行うと、これに対する非常に簡単なアルゴリズムを思いつくことができます。誤差に MPH (マイル/時) を掛けると、P 値は 1 になります。
adjustment = P*error
adjustment = 1*error
速度が時速 6 マイル未満の場合、調整は (1 6) または 6 インチになり、時速 12 マイルの場合は (1 12) または 12 インチでスロットルを動かします。同様に、時速 8 マイルを超える場合は 8 インチ調整します。重要なのは、モーターに関する限り、ある程度の知識に基づいた調整ができたので、ロボットがほんの少しだけ小さければ、より小さな調整を行うことになるということです。
車を運転したことのある人なら誰でも、アクセルペダルをどれだけ動かすかと、1秒間にどれだけ速度が上がるかの間に線形関係がないことを知っています。ここで、PID の他の要素が関係します。
私
注意点が 1 つありますが、私は通常、この用語を行フォロワーに対しては使用しないということです。I 用語は初心者にとって最も複雑な用語なので、経験がない限り、ここではライブラリを使用します。ただし、繰り返しになりますが、私は通常 i を使用しないので、この用語を使用せずに優れた追跡を提供する例を示します。
P 値は素晴らしいですが、それは完璧なシステムではありませんか? 真実は、車両が低速で走行しているときの加速は、高速で走行しているときと同じではありません。また、6 インチのスロットルに足を置いている場合、坂道に差し掛かったときに何が起こるかというと、同じスロットル位置では速度が維持できなくなり、そこで I 項が登場します。I 項の特徴は、エラーを追跡し、外部要因を考慮に入れることです。P 値が適切な割合で変化していないように見える場合、I 項はゆっくりと大きくなり、各誤差を合計して調整に適用するため、調整がより大きくなる必要があります。したがって、PI コントローラーのアルゴリズムは次のようになります。
adjustment = P*error + I*sumOfErrors
ここで、合計誤差は、調整が計算されるたびの誤差の累積です。それで、先ほどの上り坂の問題に戻りますが、スロットルを動かさずに巡航できる場合、坂を登ると、実際の速度と目標に対する誤差は 1 つエラーが発生するたびに大きくなり、I 項がそれを示します。最終的に速度が上がるまで、さらにアクセルを踏み込む必要があります。丘の頂上に到達したら、スロットルをさらに追加しましたが、丘はなくなったので、スロットルを放し始める必要があります。通常、この時点で、I 項は平坦に戻ろうとし、終了です。ターゲットなので、誤差は負になり、I 値の合計から減算されます。I の問題は、いつリセットするか、あるいは自然に解決するかどうかを知る必要があることです。これが私が I を使用しない主な理由です。初心者にとっては理解しにくいため、ボットの追跡の場合にはあまりメリットがなく、結果に劇的な影響を与える可能性があります。
項目 I の部分は、ロボットがラインに従う場合に非常に役立ちます。それは、モーターが故障してロボットが片側に進み続ける場合です。I 用語では、すべてのエラーを合計し、最終的にはその合計が弱いモーターを補い、その方向に追加の調整を適用し続ける点に落ち着きます。
D
比例制御アルゴリズムはそれ自体が優れていますが、不安定であることに加えて、目標値にうまく到達することはありません。これは、実際には、目標を達成したときにその係数自体の有効性を潜在的に低下させる必要がある場合に、誤差の範囲に適用される単純な係数にすぎないためです。ここで D 値が登場し、最後のエラーと現在のエラーの差を計算します。したがって、たとえば、最初の読み取り値の誤差が 5 で、新しい読み取り値の誤差が 1 である場合、微分調整は D 係数に誤差の差 (1-5) を乗じた値、つまり -4 になります。項 D を PI コントローラーに追加すると、次のようになります。
adjustment = P*error + I*sumOfErrors + D*(error – lastError)
または、PD 制御アルゴリズムがあるだけの場合
adjustment = P*error + D*(lastError – error)
したがって、PD によって示された計算を分析しようとすると、すでにご存知のように、P 部分が誤差の量に応じて乗算係数を適用していることがわかります。ただし、D 値は誤差の差に乗算係数を適用しますが、これは何を意味するのでしょうか? D 値は、ターゲットに近づくにつれて P の効果を弱めるので、オーバーシュートしません。お気づきかと思いますが、この例には負の値が含まれているため、誤差 0 に近づくにつれて調整が効果的に減少します。
このように考えることもできます。誤差が増大している場合、P のパフォーマンスが十分ではありません。この場合、ターゲットから遠ざかっているため、新しい誤差は古い誤差よりも大きくなります。大きい数値から小さい数値を引くと正の値が得られ、軌道に戻るために P セクションに加算されます。一方、ターゲットに正しく近づいている場合、現在のエラーは前のエラーよりも小さくなり、ターゲットをオーバーシュートしないようにするために P 部分から差し引かれます。回線関連のエラーをよりよく理解するには、右側の画像を参照してください。
PID追跡アルゴリズム
PID とは何か、そして PID がどのように機能するかについて基本的な理解ができたので、これを追跡ロボットにどのように実装できるかについての説明に戻りましょう。
フローチャート
まずは、PID ライン トレースの基本的な側面を説明するフローチャートを見てみましょう。フローチャートがコードに関連するアルゴリズムを理解するのに役立つことを願っています。コード自体を読むことでコードをよりよく理解できる場合は、フローチャートの後にサンプル コードをいくつか示します。
サンプルコード
ここで先に述べておきたい点がいくつかありますが、このコードは Pololu QTR-8RCセンサー アレイの使用に基づいています。これを QTR-8A アレイ用に簡単に変更したり、単一の QTR-1RC またはQTR-1A IR センサーと組み合わせて使用したりすることもできます。私は PID ライン トラッカーで最大 4 つの IR センサーを使用し、大きな成功を収めました。QTRSensorsRC オブジェクトに渡される NUM_SENSORS とピン番号を調整するだけです。また、センサーの数が異なると、中心を追跡するかどうかの目標も異なります。重心を計算するには、(NUM_SENSORS – 1)*500 のアルゴリズムを使用します。もちろん、中心を追跡する必要はなく、センサーの範囲内のどこでも追跡できます。
QTR センサー ライブラリが必要です。このライブラリはここにあります。リンクは私の個人用バージョンのライブラリへのポインタです。バグを見つけたので修正することをお勧めしますが、修正されていないため、奇妙な値が発生する可能性があります。そのため、私の修正したライブラリとその修正を使用することをお勧めします。
readLine(sensorValues)
この関数は(NUM_SENSORS – 1)*1000
0 から までの値を返します。センサーが 8 個の場合、測定値は となり0-7000
、センサーが 6 個の場合は となります0-5000
。いずれの場合も、0 は左端のセンサーを意味し、その後の 1000 の増分は別のセンサーを意味します。0
== 最初のセンサー、1000
== 2 番目のセンサー、間にも範囲があります。500 はラインが 1 番目と 2 番目のセンサーの間にあることを意味し、1200 はラインが 2 番目と 3 番目のセンサーの間にあるが、2 番目のセンサーに近いことを意味します...あなたの考えは正しいですか?
ロボットはそれぞれ異なるため、最終的には、私の KP 値と KD 値はあなたのロボットには当てはまらない可能性が高くなります。これらの値は、モーター速度、ロボットの重量、車輪のサイズ、車輪に対するセンサーの位置などによって異なります。
#include <QTRSensors.h>
#define SETPOINT 3500 // The goal for readLine (center)
#define KP 0.2 // The P value in PID
#define KD 1 // The D value in PID
#define L_MOTOR 9 // Left motor pin
#define R_MOTOR 10 // Right motor pin
#define MAX_SPEED 200 // The max speed to set motors to
#define SET_SPEED 200 // The goal speed to set motors to
#define MIN_SPEED 0 // The min speed to set motors to
#define NUM_SENSORS 8 // The number of QTR sensors
#define TIMEOUT 2500 // Timeout for the QTR sensors to go low
#define EMITTER_PIN 2 // Emitter pin for QTR sensor emitters
// PID **************************************
int lastError = 0; // For storing PID error
// SENSORS **********************************
// sensors 0 through 7 are connected to digital pins 3 through 10, respectively
QTRSensorsRC qtrSensors((unsigned char[]) {3, 4, 5, 6, 7, 8, 9, 10}, NUM_SENSORS, TIMEOUT, EMITTER_PIN);
unsigned int sensorValues[NUM_SENSORS]; // For sensor values of readLine()
void setup() {
// Initialize Pins
pinMode(L_MOTOR, OUTPUT);
pinMode(R_MOTOR, OUTPUT);
}
void loop() {
// Take a reading
unsigned int linePos = qtrSensors.readLine(sensorValues);
// Compute the error
int error = SETPOINT - linePos;
// Compute the motor adjustment
int adjust = error*KP + KD*(error - lastError);
// Record the current error for the next iteration
lastError = error;
// Adjust motors, one negatively and one positively
analogWrite(L_MOTOR, constrain(SET_SPEED - adjust, MIN_SPEED, MAX_SPEED));
analogWrite(R_MOTOR, constrain(SET_SPEED + adjust, MIN_SPEED, MAX_SPEED));
}
PIDチューニング
PD 制御アルゴリズムの P 値と D 値の調整については、この文書の範囲外です。前述したように、ロボットはそれぞれ異なるため、これらの KP および KD 値はロボットに適用されない場合があります。PID 調整はアルゴリズムの重要な側面であり、各ロボットはそのロボットに固有のパラメーターのセットに従って調整する必要があります。今後数日以内に記事を追加し、準備ができたらリンクを提供します。この記事が公開される前のヒントとして、KD を 0 に設定し (これにより P コントローラーのみが得られます)、その線に従う KP 値を取得してみてください。KP が機能するまでは KD について心配しないでください。また、モーターを必要な速度の少なくとも半分に設定してチューニングしてみてください。すでにフルスピードが遅い場合を除き、フルスピードでチューニングするのは困難です。
更新: PID チューニングの記事はここにあります: http://robotresearchlab.com/2019/02/16/pid-line-follower-tuning/
PID ラインフォロワの調整
PID ラインフォロワのチューニング (robotresearchlab.com)
この記事は、ライン追従ロボットのプログラミング方法に関する前回の記事の続きで、 PID 追従ロボットのチューニングについて説明します。この記事は、PID とは何か、および PID または PD 制御ループを実装する方法を理解していることを前提としています。Pololu の QTRSensors ライブラリを使用して取得する値に固有の参照 (ターゲットやセットポイントなど) がいくつかあります。センサーを使用する必要はなく、この記事で作成された参照の一部にライブラリを使用するだけです。PID 追跡ロボットをチューニングする方法を学びましょう。
設立
Pのみを使用する
PID または PI と D の組み合わせを調整するには、常に P 自体を調整することから始めます。スケール値は正しいラインフォローに最も貢献するため、この値を正しく取得することが非常に重要です。I または D を含めた場合、P が問題の原因であるか他の何かが原因であるかがわかりません。そのため、他の 2 つを除外し、スケールまたは KP 値のみを考慮してください。
スピード
私が目にする最大の間違いの 1 つは、人々が期待される最大限の速度で調整しようとすることです。フルスピードで PID を調整することは非常に困難です。すでにフルスピードが非常に遅い場合を除き、速度を意図したフルスピードの少なくとも 50% まで下げることを常にお勧めします。速度を上げるにつれて PID 値を微調整する必要がある場合がありますが、すでに良好な値を使用するよりも、すでに良好な値を使用してフルスピードで調整する方がはるかに簡単です。また、速度が速くなると、チューニングが難しくなる可能性のある他の問題も伴います。そのうちの 1 つはトラクションです。十分なトラクションが得られているかどうか確信が持てない場合、KP 値をチューニングの問題の完全な要素として使用することはできません。いくつかの理由からフルスピードで調整しました。PID 値の効果は、より高速な速度でより多く表示されます (これが、より低速にすることをお勧めする理由です)。もう 1 つの理由は、私のボットがもともとそれほど高速ではなかったことです。
ここでもう 1 つ注意したいのは、いくつかの一般的なモーター ドライバーで動作し、「パワー」範囲が 0 ~ 100 である、私が作成したライブラリを使用しているため、速度は 0 ~ 100 であるということです。ライブラリを使用しなかった場合は、おそらく 0 ~ 255 の範囲になり、これが PWM の全範囲になります。
私の初速は100%(100)です
出発点を決める
センサー範囲について学ぶ
そこで私が抱く大きな疑問は、KP の開始値をどのように選択すればよいのかということです。私の方法は非常にシンプルで、基本的な数学のみを必要とします。QTRSensors ライブラリの readLine() 関数は1000*(NUM_SENSORS – 1)
0 から 7000 までの値を返します。つまり、私のロボットには 8 つのセンサーがあるため、readLine()
結果は 0 から 7000 までになります1000*(8-1)
。画像を例にすると、0 はラインが一番左のセンサーの下にあることを意味し、1000 はラインが 2 番目のセンサーの下にあることを意味し、8 番目のセンサーの値が 7000 になるまで同様に続きます。readLine()
この関数の優れた点は、値が 1200 の「アナログ」範囲を提供することです。これは、2 番目のセンサーよりも下ですが、3 番目のセンサーにわずかに近いことを意味します。可能な値は 3538 で、これは 4 番目と 5 番目のセンサーのほぼ中間であることを意味します。
私の範囲は0から7000です
ターゲットを決める
の値が理解できたのでreadLine()
、中央に焦点を当てたい場合、目標はMAX_VALUE/2 或 7000/2
または 3500 になります。8 つのセンサーがあり、中心を追跡するために 4 番目と 5 番目のセンサーの間を追跡したいと考えており、4 番目と 5 番目のセンサーの間の値は 3500 になるため、これは理にかなっていますreadLine()
。ここで注意してください。中央をたどる必要はありません。ラインの隣に障害物がある場合は、その障害物を通って中央の左または右をたどるだけで済みます。これも PID の利点であり、設定を変更するのは簡単です。標的。
目標は3500です
最初の KP を決定する
最後に、KP 値の適切な開始点を見つけることができます。私が行うことは、取得できる最大の誤差を計算し、最大誤差を速度に等しい値に変換する係数を見つけることです。これを明確にするために、さらに基本的な数学を説明します。ラインから右に逸れたと仮定すると、取得できる最も遠い点はreadLine()
0 を返すポイントです。その時点で左端のセンサーがラインを認識するからです。したがって、私の目標(3500)からこの最大誤差を引いた値は です3500 – 0 或 3500
。逆も同じで、左にドリフトした場合、最も遠くに到達できるのはreadLine()
7000 を返すポイントです。その時点で右端のセンサーがラインを認識するからです。したがって、この最大値を差し引く私の目標は です3500 – 7000 或 -3500
。いずれの場合も、私の最大誤差は次3500
の値です (負の数は無視します)。
ここで、モーターの速度が 100 (100% など) の場合、3500 を 100 に変換する値を考え出します。その理由を理解するには、次の文を読みながら画像を見てください。左端のセンサーまたは右端のセンサーがこのラインを認識すると、調整は(KP*error)
100 になります。そのため、ロボットがそれほど離れている場合は、モーターをオフにします。これは、1 つのモーターからその調整を減算し、別のモーターに追加するためです。開始 KP 値を決定するための基本的な計算は次のとおりです。
MAX_SPEED = MAX_ERROR * KP
- 既知の値を入力してください
100 = 3500 * KP
- KP を解決するには、3500 を反対側に移動して、
100 / 3500 = KP
私のKPは0.028です
最後に、通常は 1000 分の 1 でしか使用しませんが、100 分の 1 で指定することもありますが、この場合は粒度が必要なので、完全な 0.028 を使用します。
チューニングを始めましょう!
このセクションに入ると、次の情報がわかるはずです
- あなたのセンサーファミリー
- 目標地点(設定値)
- モーター速度が 50% 以下です
- 上記から計算されるKP
コード内の情報を使用して (この記事で例を見つけることができます)、最初の実行がどのように行われるかを見てみましょう。KP の調整方法について決定を開始する前に、少なくとも 2 回のテスト実行が必要であることに注意してください。
トライアル1
実験 1 の初期 KP 値は 0.028 です。
KP | 0.028 |
---|---|
K D | 0.0 |
マックス・スピード | 100 |
MIN_SPEED | 0 |
SET_SPEED | 100 |
分析する
私のボットが初期 KP 値のみを使用してラインを追跡する精度の高さに本当に驚きました。おそらく、私がより重いロボットに慣れているため、この軽量の小さなロボットほど反応性が低いためです。現時点では判断するものが何もないので、KP 値が最終的にどの方向に進むべきかを決定するために、どんどん下げていきたいと思います。ターゲットの KP は、ここに表示されている画像のようなトレイル パターンを提供します。パスは、ライン上でタイトなパターンで配線され、一貫した状態を維持する必要があります。
トライアル 2 に進みます…
トライアル2
まず、私は価値を下げて何が起こるかを見てみたいと思っています。KP を 0.018 に減らすと、エラーが ~5500 に達するまでモーターはオフになりませんが、最大エラーは 3500 であるため、モーターがオフになる点には決して到達しないことになります。私たちが行う最大の調整は、3500*0.018=63
モーターがこの KP で値 47 を下回らないようにすることです。
KP | 0.018 |
---|---|
K D | 0.0 |
マックス・スピード | 100 |
MIN_SPEED | 0 |
SET_SPEED | 100 |
分析する
ご覧のとおり、KP が低いとトラッキングのぐらつきの量が増加しますが、これは良くありません。初期値よりも積極的な値が必要でした。もう 1 つ注意すべき点は、KP が低いとロボットがラインから外れやすくなり、そうしないとコースから外れてしまうため、別の「トラック」を追加する必要があったことです。PD 値が低いと、画像に見られるようなパターンが得られます。一貫性がある場合とそうでない場合がありますが、より重要なのは、ラインにうまく追従していないことです。ターンに到達すると、KP が低すぎるロボットはターンを完全に逃し、ラインに戻れなくなる可能性があります。
トライアル3
ここで、初期値から反対方向に同じ距離を維持します。トライアル 1 とトライアル 2 を見ると、この KP がより厳密に追従すると予想できますが、KP が高すぎるでしょうか?
KP | 0.038 |
---|---|
K D | 0.0 |
マックス・スピード | 100 |
MIN_SPEED | 0 |
SET_SPEED | 100 |
分析する
ビデオではそれほど目立たないかもしれませんが、これは私の初期値よりも攻撃的です。これは良い線を超えていないので、この値を使用するつもりだと思います。KPだけなら元の0.028のままで良いと思いますが、KDを付けるのでKD値が少し柔らかくなるのでもう少し積極的にしたいと思います。
トライアル4
値が高すぎる例を含めなければ、ハウツー記事は完成しません。
KP | 0.8 |
---|---|
K D | 0.0 |
マックス・スピード | 100 |
MIN_SPEED | 0 |
SET_SPEED | 100 |
分析する
ご覧のとおり、ロボットは左右にオーバーシュートしています (冗談ではありません)。このボットを紹介できるほど KP を高くすることはできませんでしたが、重いボットでは KP が高すぎて短時間フォローできず、最終的に完全にオフラインになるほど不安定になることがよくあります。これは、KP が高すぎるかどうかを知る 1 つの方法です。画像を見てください。KP が高すぎる場合に発生する可能性のあるパターンが示されています。
トライアル5
一般に、KD 値の適切な開始点は、KP 値の 10 ~ 20 倍です。したがって、KP 値の 10 倍の KD から始めます。
KP | 0.038 |
---|---|
K D | 0.38 |
マックス・スピード | 100 |
MIN_SPEED | 0 |
SET_SPEED | 100 |
分析する
これは KD にとってかなり良い値です。ここで停止したいとさえ思うかもしれませんが、ボットがターンに到達したときの応答が少し遅れていることに気付きました。KD を増やすことでこの問題を解決できることはわかっています。
トライアル6
KP | 0.038 |
---|---|
K D | 0.76 |
マックス・スピード | 100 |
MIN_SPEED | 0 |
SET_SPEED | 100 |
分析する
私はそれ以上に優れているとは思いませんし、このボットの目的を考えれば、そうする必要はありません。おそらく、ロボットの微調整にもう少し時間を費やした方がよいでしょう。その多くは、移動速度と軌道がどのようになるかによって決まります。滑らかなターンのトラックよりも、急なターンのトラックの方がより多くの調整が必要になります。
トライアル7
KP が高い場合と同様、KD が高すぎる例がなければハウツー記事は完成しません。
KP | 0.038 |
---|---|
K D | 2.76 |
マックス・スピード | 100 |
MIN_SPEED | 0 |
SET_SPEED | 100 |
分析する
完全には明らかではないかもしれませんが、KP が高いときと同様に、ロボットは再び振動を開始し、ラップタイムが 0.5 秒増加します。それは大したことではないように思えるかもしれませんが、ボットと競争する場合、それがナンバー 1 とナンバー 2 の差になる可能性があります。
以下に例を示します。2 つの数値を同時に調整している場合、どちらが悪いのかを知るのは困難です。私は個別に KP を調整しているので、原因は私の KD 値であることがわかります。
エピローグ
PID アルゴリズムに影響を与える最も一般的な側面を理解することが重要であるため、最後に取り上げたいことがあります。以下の点にご注意ください。
- トラクション - トラクションが優れていない場合、KP はラインに従うことを決して許可しません。
- 速度 - 速度が速すぎる場合、特にトラックで方向転換するとき、以下のプロセッサ速度と同じ初期値を調整するのが難しくなります。
- センサーの位置 - センサーがホイールから遠い場合、変化点 (支点) からの距離が長くなり、影響が大きくなるため、より高い KP が必要になる場合があります。
- プロセッサ速度 - はい、これは大きな違いを生む可能性があります。プロセスが遅く、ロボットが高速である場合、サンプル レートは非常に低くなります。たとえば、3 フィート/秒で移動していて 1 秒間に 50 回調整できる場合、ラインを 3/4 インチごとに読み取ることになりますが、これは悪くありません。ただし、プロセッサが遅い場合、またはプログラム内で他の多くの処理が行われていて、1 秒あたり 10 回しか更新していない場合は、3.6 インチごとに行を読み取ることになります。つまり、実行する前にオフラインになる可能性があります。実現すると3.6インチ。PID を調整するときは、コードを PID コードのみに制限し、print ステートメントも避けるようにしてください。