~適当な工作情報を投げるブログ

ゲーム、音楽なども作ってるよ~



フィードバック制御の基礎, PID制御について

 ロボコンにもロボカップにも使うであろう, PID制御について適当に書いていきます。ただ, どっちの界隈でももっと単純な制御で十分だと思う事も無いことも無いですね^^; ああいう競技ロボットって, シンプルなハード&シンプルな制御の組み合わせが最強だってn回言われてますし(笑)

 

まず制御とは何か

 簡単な話, 「ある物(制御対象)を現在の状態から目的の状態になるまで動かす事」です。例えばモータ軸に接続されたカメラがあったとして, 只今カメラは西方向を向いてるとすればそれを東方向に向けるようモータに印加する電圧を適切に設定するのは制御です。さらにボイラー内の温度を20℃のから240℃一定にしようとする操作も制御になります。このように, 制御できる制御対象はモータなどのアクチュエータだけでなく温度湿度, 電圧電流, 周波数, 磁束などさまざまな事象も含まれます。

フィードフォワード制御とは

 例えばモータを使って何かしらのデバイスを0°から90°の方向に向けたいとします。この制御を達成しようとしてまず思いつくのは, 「12Vでこの回転速度なら, 1秒くらいかければ90°になるやろ」って感じだと思います。また, カーラジコンを今の位置から5m先に停止させたい場合は, 「10秒くらい前進ボタンを押せば5mくらいで止まるやろ」ってなるでしょう。このように, 制御対象の特性を予め把握しておき, その特性から目的を達成できる操作を予測し制御することを「フィードフォワード制御(オープンループ制御)」と言います。

f:id:Kamomesan:20190209212407p:plain

フィードフォワード制御のイメージ

 オープンループ制御は簡単ですが, 問題があります。それは, 高速に目的を達成できない事, 外乱に対応できないことです。例えば, モータの話では, 0°から90°に動かすという目的をできるだけ早く達成するために, モータ電圧を高くしようとすると, モータ軸や負荷の慣性で90°を通り越しやすくなってしまうのは容易に想像できると思います。当然ゆっくり回した方が90°でぴったり止めやすいですよね。このように, 制御対象を目標の状態にもっていく時間をどれだけ短くできるかという能力を, 制御システムの速応性と言います。例えば人の方向を追尾するカメラを作ったとしたとき, 速応性が高いほど人のいる方向にピッタリと張り付きます。逆に, 速応性が低いと人のいる方向にカメラが向くまで時間がかかります。

f:id:Kamomesan:20190209213440p:plain

速応性

 外乱に対応できない, という話は簡単で, 先のモータの話だと例えばモータ回転中に人がモータ軸を握ったりした場合, 目的の90°にはたどり着けないよね, という事です。単にある時間だけ電圧を印加してるだけですので, 軸をロックされると目的の角度にたどり着けないのは当たり前の話ですね。外乱に対する制御系の適応能力を, 制御システムのロバストと言います。

f:id:Kamomesan:20190209213455p:plain

ロバスト

フィードバック制御とは

 それでは, オープンループ制御では不十分である場合どうすれば良いかといえば, それは「現在の状態を監視し, それに応じて制御する」という事でしょう。オープンループ制御で速応性とロバスト性が不十分となる原因は, 制御コントローラ(マイコンなど)が現在の制御対象の状態を把握できていないという部分が大きいでしょう。例えば人に目隠しをして, 10m歩けと指示する場合はオープンループ制御となり, 歩く人は自分が1歩あたり進む量から推測して止まるしかありませんし, 10mピッタリに止まるのは難しい事です。しかし, 目隠しを外して地面に10m測れる定規が置いてあれば10mピッタリ歩くのは簡単ですよね。このように, 制御コントローラが制御対象の状態を監視し, 目的の状態に制御する方法を「フィードバック制御(クローズドループ制御)」と呼びます。

f:id:Kamomesan:20190209214510p:plain

フィードバック制御の例

 フィードバック制御を用いれば, 先のモータの話のように0°から90°に回したい場合に人がモータ軸を握っても, 離せば90°に向かうよう制御が行えます。なぜなら, 制御コントローラはセンサなどによりモータ軸の位置を把握しているので, 途中で軸をロックしても「まだ90°になっていない」という事が分かるからです。

f:id:Kamomesan:20190209215414p:plain

モータの角度を制御する例

PID制御とは

 それでは本題のPID制御です。先に述べたとおり, フィードバック制御は制御対象の状態をモニタリングすることでより正確な制御を可能にするものですが, その方法は色々ありますが, ここでは自動制御, フィードバック制御の基礎とされ, 工学では最も多く利用されるPID制御について書きます。

 PID制御は,

・比例制御 (P制御 : Proportional Control)

積分制御 (I制御 : Integral Control)

微分制御 (D制御 : Derivative Control)

を組み合わせた制御方式です。この3つの制御方法を理解すればPID制御も分かると思います。それぞれの制御方法はそれほど難しいものではありません。

比例制御 (P制御)

 比例制御は, 簡単に言うと「制御対象が目的の状態から離れていれば離れているほど, 強く目的の状態にしようとする制御」です。

f:id:Kamomesan:20190209220041j:plain

P制御のイメージ

現在の状態が目的の状態からどれだけ離れているか, という値は偏差 と言い, 現在の状態を y , 目的の状態を r とすると, 

e = r - y

と表せます。たとえば, 目的の角度が90°とするとき, 現在の角度が88°なら

e = 90 - 88 = 2

です。この偏差 は後々説明する I制御, D制御でも使用します。

 P制御は「制御対象が目的の状態から離れていれば離れているほど, 強く目的の状態にしようとする制御」なので, つまりは偏差 e に比例して操作する量を大きくしよう, ということです。 P制御を数式であらわすと次のようになります。

c = K_p \cdot e (簡易形)

c(t) = K_p \cdot e(t) (時間関数形)

C(s) = K_p \cdot E(s) (s領域形)

 ここで, c は操作量, K_p は比例ゲインと呼ばれる定数パラメータです。先のモータの話では, 目的の状態は軸が90°になっている事を指します。モータに対する操作量 c は電圧なので, 例えば現在の状態が 0°としたときにモータに印加する電圧 v_m は次のようになります。

v_m = K_p \cdot e = K_p \cdot (90-0) = K_p \cdot 90 [V]

 比例ゲインは制御対象の特性を考慮して適切に設定する必要があります。↑の例だと, K_p = 1 とするとモータには 90 [V] の電圧をかけることになります。コレを3V用モータでやるとモータが焼けますよね(^_^;) ゲインの決定方法はいくつかありますので後述します。今回は適当に K_p = 0.1 として話を進めます。

 現在の状態が0°なので 9 [V]がモータに入力されます。これによりモータの軸が回転し, ある時軸が30°になったとします。このときモータに印加する電圧は,

v_m = K_p \cdot e = 0.1 \cdot (90-30) = 6 [V]

ですね。さらに回転し, ついに90°になった時には,

v_m = K_p \cdot e = 0.1 \cdot (90-90) = 0 [V]

となり電圧は印加されませんね。しかし, モータには回転子にも負荷にも慣性が存在しますので, K_pの値によっては目標値を通り過ぎるオーバーシュートが発生します。また, 制御開始からオーバーシュートのピーク時までの時間を行き過ぎ時間, ピーク時の目的値から離れた大きさを行き過ぎ量と言います。

例えばオーバーシュートして100°になってしまったときにモータに印加する電圧は,

v_m = K_p \cdot e = 0.1 \cdot (90-100) = -1 [V]

となり, 先ほどとは逆回転させて目標値に戻そうとする事がわかります。

 このように, 比例制御はこの式をマイコン等に計算させることで簡単に実現できる, 簡単な制御方法です。比例制御は現在の制御対象の状態を制御に反映させる制御方法と考える事ができます。

積分制御 (I制御)

 積分制御は, 簡単に言うと「制御対象が目的の状態から離れている時間が長ければ長くなるほど, 強く目的の状態にしようとする制御」です。

f:id:Kamomesan:20190209220105j:plain

I制御のイメージ

積分制御は次の式で表せます。

\displaystyle c = K_i \cdot \int_0^t e (簡易形)

\displaystyle c(t) = K_i \cdot \int_0^t e(t) dt (時間関数形)

\displaystyle C(s) = K_i \cdot \frac{E(s)}{s} (S領域形)

 ここで, K_i積分ゲインとよばれる定数で, これも比例ゲインと同じく制御対象に応じて適切に設定する必要があります。この積分制御は, 例えば先のモータの話では軸を手で握って止めると時間が経つにつれモータに印加する電圧を徐々に増加or減少させ, 拘束を逃れようとする働きをします。

 積分制御はほとんどの場合比例制御と組み合わせて比例積分制御(PI制御)として用いられます。PI制御ではモータに印加する電圧を v_m , 制御開始からの現在時間を t とするとき, 

\displaystyle v_m = K_p \cdot e + K_i \int_0^t e \cdot dt [V]

と求められます。積分ゲイン K_i も比例ゲインと同じく適切に設定する必要があります。基本的に制御系における積分要素は系全体を不安定にしやすいので, いきなり大きなゲインを設定すると簡単に制御対象を破壊してしまう場合がありますので, 慎重に検討しなければいけません。

 積分制御は今までの偏差を積分するため, 過去の制御対象の状態を考慮する制御方法と考える事ができます。

微分制御 (D制御)

 微分制御は, 簡単に言うと「制御対象早く動くほど逆方向に力をかける制御」です。つまりブレーキのような動作をします。

f:id:Kamomesan:20190209220126j:plain

D制御のイメージ

積分制御は次の式で表せます。

\displaystyle c = K_d \cdot \dot{e} (簡易形)

\displaystyle c(t) = K_i \cdot \frac{de}{dt} (時間関数形)

\displaystyle C(s) = K_i \cdot sE(S) (S領域形)

 ここで, K_d微分ゲインとよばれる定数で, 制御対象に応じて適切に設定する必要があります。この微分制御は, 例えばモータに何かが衝突するなどして回転速度が急激に変化しようとしたとき, それを抑えようとするブレーキのような働きをします。

微分制御も, 積分制御と同じく単体で使用されることはほとんどなく, 比例制御と組み合わせて比例微分制御 (PD制御) として用いられます。PD制御ではモータに印加する電圧を v_m , 制御開始からの現在時間を t とするとき, 

\displaystyle v_m = K_p \cdot e + K_d \frac{de}{dt} [V]

と求められます。微分ゲイン K_d も比例ゲインと同じく適切に設定する必要があります。微分ゲインは大きくしすぎると, 制御の速応性 (目標値に到達するまでにかかる時間)お大きくなってしまいますので, 比例ゲイン, 微分ゲインともに調整が必要です。

 微分制御は偏差の微分値(つまり, 傾き)に注目する, つまり未来の制御対象の状態を予見する制御方法と考える事ができます。

比例積分微分制御 (PID制御)

 これまで紹介した比例制御, 積分制御, 微分制御を単純に組み合わせる事で, PID制御とすることができます。数式で見ると, 

\displaystyle v_m = K_p \cdot e + K_i \int_0^t e dt + K_d \frac{de}{dt} [V]

となります。またS領域では,

\displaystyle C(s) = K_p \cdot E(s) + K_i \cdot \frac{E(s)}{s} + K_d \cdot sE(s)

となります。

 

(書き途中)