モーターでPID制御を使う,といった場合,何をしたいかというと,前回も述べたとおり
- 一定の速度で回したい
- ある角度で合わせたい
- 指定した動作をさせたい
前回は,指定された角度と現在の角度を引き算して,その差の分だけ入力するのがP制御という話をしました(したと思う).
今回は,PIDの二つ目のI制御(積分制御)について.
I制御は,目標値に現在の値をぴったり一致させる(偏差ゼロといいます)ための方法です.
またまた昔のレポートの使いまわし図で.
P制御では,図5のような初期状態から図6のような急に目標の値が変化した(この場合では5Vに変化)場合,その差(このときは5V)に応じた値を,制御対象(モータ)に与えるというものでした.
次に,図6から一瞬後になると,モータが5Vを与えられたことによってちょっと回った(このときは3V),図7の状態になります.
すると,目標値(5V)と現在の値(3V)の差が2Vになるので,さっきよりは少し小さな2Vがモータに入力されます.
図7の一瞬後はさっきより遅く,少しだけ回って,最終的に図8の目標値と現在の値が一致した状態になります.
あれ?P制御(比例制御)があれば十分なんじゃないの?
その通りです.
今述べたような理想的な状態では,P制御だけで問題ないんです.
じゃあなぜI制御(積分制御)が必要なの?
それは,制御対象が完全には線形ではないからです.
制御対象が線形ではない,とは,モータで言うところの,
①小さな電圧を加えても回らない範囲(不感帯)がある
②モータに何か負荷(外乱)がかかっている
状態が現実には存在するためです.
まず,①の小さな電圧を加えても回らない範囲がある,ということの説明から.
たとえば,適当なモータに電池をつないだとき,モータは回転します.
これはモータなんだから当たり前.
じゃあ,どれだけ電圧を小さくしても回るのか?
答えはノーです.
体験したことがあると思いますが,一定の電圧を下回ると,モータは回らなくなります.
ジェネレーションギャップがあるかもしれませんが,ミニ四駆で使えなくなった電池を時計に入れるとしばらく使える,とかいう話.
ミニ四駆が動かなくなったとき,電池は0Vになっているのではなく,電圧が下がっているだけです.
この電池の電圧がモータを動かすために必要な電圧を下回ると,モータが回らなくなります.
このモータが回らない範囲のことを不感帯といいます.
不感帯があると,P制御で現在の値と目標の値がどんどん近づいていって,差が小さくなると,いずれ回らなくなるということがわかります.
たとえば,1V以下では回らないモータなら,現在の値と目標の値の差が1Vより小さくなった時点で止まってしまいます.
これでは,1V分の差が残ったままになってしまいます.
これでは,P制御では十分とはいえません.
次に,②のモータに負荷がかかっている状態について.
モータに負荷がかかっている状態とは,たとえばモータに棒がついている場合を考えます.
この状態で,モータはぴったりと目標の角度になっているとします.
このモータについている棒に重りを吊り下げると,棒は下向きに傾きます.
目標の値である,モータの角度が3Vのところまで下がってきました.
このとき,モータに入ってくる電圧は,図7と一緒で,2Vです.
でも,重りを吊り下げたせいで2Vでは回らなくなってしまったらどうでしょう?
モータの角度は2Vのところで止まってしまいます.
このように,制御対象(モータ)の外側に何かが起こる(付けられる)ことで,元のモータ単体の状態と変わってしまうことを外乱といいます.
これも①のときと同じように,P制御だけでは十分ではなくなってしまいます.
これを解決できるのがI制御(積分制御)です.
何度も書いているのでわかるかもしれませんが,I制御は積分することで,この①小さな電圧では回らない範囲,②モータにかかっている負荷の影響を無くすことができます.
積分,というと構えてしまいますが,コンピュータで制御する場合,基本的に足し算しているだけです.
積分は大雑把に言うと足し算です.
積分は大雑把に言うと足し算です.
そもそも,なぜ,P制御だけでは不十分なのかというと,
P制御では,目標値と現在の値しか使わないので,何らかの要因で目標値に達しなかった場合,その位置と目標値の差がずっと同じになってしまうので,いつまでたってもモータにかかる電圧が目標に達しない電圧にしかならないことが問題となっています.
100g吊り下げてようが,1kg吊り下げてようが,角度が一緒ならモータの電圧も一緒.
これを解決するには,
①重い重りを吊り下げたときに,モータに与える電圧を上げる.
②いま,2Vを入力する角度で4Vが入力されるように倍率(ゲイン)を上げる.
③目標値と現在の値の差を時間ごとに足していく
の3つがあります(実際にはもっとあると思うけど).
まず,①の重い重りを吊り下げたときに,モータに与える電圧を上げる,から.
この場合,大抵うまくいきます.
ただし,一番の問題は,どのくらいの重りを吊り下げたか,新しく重さセンサとかを付けて測る必要があるということ.
これはハード面からもソフト面からも馬鹿にならないコストです.
センサは買わなきゃいけないし,プログラムもセンサを使うために書き換えなきゃならない.
しかもこの方法では,小さな電圧では回らない範囲を解決できていません.
次に,②の入力電圧の倍率を上げる方法について.
1kgの重りを吊り下げたとき,2Vじゃダメなら4Vにすればいいじゃない!
これもひとつの正解です.
でもこの方法だと,倍率を上げすぎると,ちょっとしか差がなくても大きい電圧がかかってしまうことになります.
すると,目標の角度付近でもモータへの電圧の値が大きすぎて行き過ぎてしまいます.
行き過ぎると,目標と現在の値の差がマイナスになるので,再び目標値に戻ろうとしますが,これも電圧が大きすぎて行き過ぎ…
を繰り返します(振動的な応答).
これでは目標値付近で,行ったり来たりを繰り返してとてもロボットに使える状態ではありません.
そこで,目標値と現在地の差を時間ごとに足していく.
という方法を考えるわけです.
たとえば,重りを吊り下げて3Vのところで止まってしまった場合,P制御なら5V-3Vで2Vが入力され続けるだけです.
このとき,重りのせいでモータは2Vでは動かない状態になってしまっているので,いくら待っていてもモータは動いてくれません.
たとえば,重りを吊り下げたとき,4Vで動くとしましょう.
P制御ではずっと2Vしか入力できないので,動くことはありませんが,ここで,
この差(2V)を一定の時間ごとに足していけばどうなるでしょうか?
重りを吊り下げて,3Vのところで止まった瞬間には,P制御と同じで5V-3Vの2Vしか入力されません.
でも,1秒後(実際はもっと短いことが多い)には,また,5V-3Vの2Vが足されます.
すると,モータへの入力は,4Vとなります.
これによってモータに与えられる入力が4Vとなり,モータはまた回り始めます.
結果的に,モータの現在の値は目標値にぴったりと一致することができます.
では,重りが乗っていない場合には,行き過ぎたりしないのか?
P制御で②入力電圧の倍率を上げた場合には,モータの先に重りを付けていなくても,倍率をかけることによって,大きな電圧が入力され,目標値を超えて行ったり来たりしてしまいました.
でも,この方法(一定の時間ごとに足し算)なら,なにも重りを付けていなければ目標値と現在の値の差が足される前に目標の角度まで到達してしまうので,実質的には通常のP制御と同じようになります.
(実際には目標値に到達するまでの差が足し算されていますが簡略のため)
このようにして,目標の値と現在の値の差(偏差)を,時間ごとに足し算していくことで,ぴったりと目標の値に到達することができます.
これは,重りを吊り下げた場合に限らず,小さな電圧では回らない状態でも有効です.
(時間がたつにつれてどんどん入力電圧が大きくなるため)
このように,偏差を時間ごとに足す(時間積分)ことで,不感帯や外乱の影響があっても,最終的な偏差をゼロにする制御を,I制御(積分制御)といいます.
基本的には,このI制御はP制御と一緒に使われます.
P制御では差が残ってしまうのを補助するのがI制御といった感じです.
こんな感じで,PI制御がによって偏差のない制御を行うことができます.
今回はこのあたりで.
予告
D制御(微分制御)については,記事にする予定はありません.
というのも,PI制御だけで大抵の場合問題ないということと,PI制御では問題が出るような制御をする人は,もっと高度な説明をたくさん参照できると思うからです.
なのでP制御もI制御もここでは概念しか説明しませんでしたし,D制御(微分制御)も必要がないと考えています.
希望があれば添いたいですが,こんなところ参照している人もいないと思うので...
0 件のコメント:
コメントを投稿