産業用制御に携わる人にとって、比例・積分・微分 (PID) 理論はおそらく馴染みのある概念でしょう。ほとんどの人にとって、この言葉はまったく馴染みのないものですが、あなたが思っているよりも馴染みがあるかもしれません。車のアクセルペダルを踏むときは、理想の速度からどれだけ離れているか(PIDの比例部分)を考慮するだけでなく、特定の車両がどのように加速するか、坂道などの状況も考慮します。
これらのより微妙な効果は、I項とD項が数学的に考慮するものです。この例では、車の速度が上限から下限に跳ね上がるのを防ぎますが、同じ概念をさまざまな制御状況に適用できます。制限ベースの制御では大まかな範囲に到達できますが、システムは多少不規則に動作する傾向があります。
PID方程式
PID制御は、次の式で数学的に表現できます。P、I、Dは、ここで加算される3つの項によって表されます。Kp、Ki、およびKd は、システムが各要因にどのように反応するかを調整する定数です。
Ki とKd をそれぞれ1/Ti とTdに置き換えることもできます。この変更により、方程式とその物理的な意味との関係が改善され、単位が単位のない数値に適切に反映されるようになります。
また、方程式を転置してKp 値を抽出し、それを標準形式と呼ばれる形式で方程式全体に適用することもできます。この形式の利点の1つは、方程式全体のKp 定数を一度に調整できることです。
これらすべては、おそらく工学の学位を取得した人にとってさえ、少し威圧的に見えるかもしれません。幸いなことに、ここで何が起こっているのかを理解するために、 動的システムのモデリングと分析 の教科書を取り出す必要はありません。微積分ができなくても問題はありませんが、必ずしもできる必要はありません。
最初の方程式を分解すると、等号の右側に3つの数学要素P、I、Dを追加することで、方程式の左側にある単位のないコントローラ出力u(t)が生成されます。各要素の前には定数K値があります(K p、K私、およびK d) は、u(t) を形成する各要素の重み、つまり特定の時間における制御出力を表します。システム パフォーマンスを向上させるために、各K値を個別に調整できます。これについては、以下で詳しく説明します。
比例(P-K p)
この方程式の最初の、そして最も重要な項はe(t) です。そのため、K p 通常、その前に来る値は、式内の他のK値よりも大きくなります。ここで、e(t) は単にある時点での瞬間的な誤差、つまり制御対象デバイスの実際の値から目的の値を引いた値です。これにKp を掛けると、コントローラー全体の出力に対する寄与がわかります。
積分 (I—KI)
この式の2番目の項は、時間の経過に伴う複合誤差に関係します。これは、デバイスで発生したすべてのエラーの合計です。
- コントローラがu(t) を計算するたびに、瞬間的なエラーが実行中の集計に追加されます。
- この数値はKi で乗算され、u(t)に加算されます。
力がモーターを所定の位置に保持し、通常の状態では設定点に戻れない状況を考えてみましょう。仕様外の期間が長くなるにつれて、I項は増加し続け、最終的にこの力を克服するか、モーターの能力の限界に達します。
導関数 (D—Kd)
この式の3番目の項は、エラーがどれだけ速く変化するかに関係しています。
- コントローラーは瞬時にエラーを読み取ります。
- そこから前回の瞬間的な読み取り値を減算します。
- 結果の値にKd を掛けて、u(t)への寄与を計算します。
理論的には、この方程式にD項のみがあり、プロセスが 間違った 値を安定して維持する場合、この項はゼロのままになり、適切な出力には寄与しません。一方、他の2つの項のいずれかがデバイスの出力を元の位置に素早く戻そうとする場合、導関数はその影響を弱めるのに役立ちます。
この概念を微積分に基づいて表現することは有用ですが、PID制御の現実は、最初に思われるほど魔法的なものではありません。実際には、誤差と読み取り間の時間を考慮して、加算、減算、乗算のみを使用して出力を計算します。実際、私たちは空気圧システムを使用して、各「項」を入力する機械的な手段を使用して、初期の形式のPID制御を実装しました。
Arduino PIDコントローラー チュートリアル
多くの場合、専用のPIDコントローラーをプロセスに接続するのが最適ですが、Arduinoやその他の同様の開発ボードを使用して独自のコントローラーを作成することもできます。独自のPIDルーチンを作成することもできます。コード内の各項を次のように表現します。
- P:instanteneousError = 設定値 – 入力;
- I:累積エラー = += エラー * 経過時間;
- D:rateOfError = (エラー – errorLastCalculation)/経過時間;
必要な出力を得るには、これらの各項にそれぞれのK値を掛けて合計します。一方、車輪の再発明を避けたい場合は、 Brett BeuregardのPIDライブラリ を利用することもできます。このライブラリは細かい部分を処理し、必要に応じてP、I、Dの定数値を調整することに集中できるようにします。
PID理論の実際の動作を実証するために、私はツールボックスからArduino Nano Everyと以下のものを取り出しました。
- モータードライバーボード
- 赤外線センサー
- Hubsan H107Cドローンから回収したモーター
私は、モーターの回転時にパルスが失われないように、モーターのブレッドボード マウントと、時間の50% を光を遮断する「ファン」を印刷しました。モーター ドライバーは (それ以外は制御されていない) モーターへの入力であり、フィードバックはパルス間の時間に基づいています。
最終的に コードを解明し 、3Dプリントされた部品を入手したところ、一定のPWM (パルス幅変調) 出力で電源ボタンを操作するよりも洗練された方法でモーターを制御できるようになりました。
上記リンクのPIDルーチンからのコードスニペット
注目すべきコードには、ブロッキング デバイスが回転するときに各パルスを登録するための割り込みルーチンの使用と、millis() を使用してパルス間の時間を計算することが含まれます。関数外のコードの最初の部分でPIDを次のように設定しました。
PID myPID(&difference, &driverOut, &setPoint,Kp,Ki,Kd, DIRECT);。
Kp、 Ki、 Kd は、コード内のこの行の前に定義され、 &difference controls &driverOut、 &setPoint はシリアル モニターによって変更されます。この計算を操作してこの時間差をRPMに変換できますが、この特定のドライバーは入力が低くプルダウンされるとオンになるため、PID設定はDIRECT出力として機能します。アナログ出力が高くなると(モーターがオフ)、パルス間の遅延も増加します。
PIDルーチンの以前のバージョン。注意: CH1は入力パルスを読み取り、CH2はPIDルーチンを使用して計算された出力です—低いパルスはモーターへの入力です。
このシンプルなPIDコントローラーの例は、手元にある部品 (新しいArduino Nano Every を含む) と私が多少は理解しているモーターで動作しました。しかし、すべての事実がわからなくても、さまざまな状況でPID制御を適用する方法を示すことができました。モーター制御、オーブンの温度制御、ロボットのバランス調整など、PIDを少し設定して調整するだけで、無限の実験オプションが得られます。