第11章

PID:すべてを解決する

ドループを消しつつ、ふらつきも止めるには?

第11章:PID:すべてを解決する ↗

消えないドループ

テオ: 第2章を覚えてる? Pコントローラーではドローンが2 mより下にぶら下がったままで、KpK_pをどういじっても直らなかった。何なら直せるのか、ここで見つけよう。

ドローンを支えるには、モーターがmg≈4.9mg \approx 4.9 Nをずっと押し続けないといけない。P制御は偏差があるときしか押さない:T=Kp e\eff{T} = K_p\,\err{e}。だから4.9 Nを出すには、e=mg/Kp\err{e} = mg/K_pの偏差がどうしても必要になる。KpK_p = 20 N/mならe\err e = 4.9/20 ≈ 24.5 cm、それがずっと続く。ドループは調整ミスじゃない。何かを支えるためにPが取り立てる代金なんだ。

ジューン: だから、偏差ゼロのまま4.9 Nを出せる部品がコントローラーに必要なんだ。記憶を持つ何かが。

I:過去の偏差の積み重ね

考え方はこう。偏差をずっと足し込んでいく。偏差の曲線の下の面積、つまり第3章の「積み上がる面積」そのものだ。その積み重ねに比例して押す:

TI=Ki∫0te dt\eff{T_I} = K_i \int_0^t \err{e}\,dt

ドローンが2 mより下にいる間は偏差が正で、積み重ねはどんどん増えるから、押す力もどんどん増える。積み重ねが増えるのをやめるのは、偏差がちょうどゼロのときだけ。そのとき積み重ねはそのままとどまって、それまでにためた推力を保ち続ける。これがジューンの欲しがっていた記憶だ。

テオ: おお、ずるいな。ドローンは2 m以外のどこにも落ち着けないってことか。ほかの場所だと、積み重ねがまだ変わり続けるから。

第11章:PID:すべてを解決する ↗

まず予想しよう! ミカはドループをすぐに消したいから、KiK_iを思いっきり上げるつもりだ。どうなる?

ウィジェットはKiK_i = 10 N/(m·s)から始まる。見るところは3つ:赤く塗られた面積(積み重なっていく偏差)、オレンジの破線の推力の積分部分が紫の重力の線まで上がっていくところ、そしてドループの表示。KiK_iを0まで下げると第2章のドループが戻ってくる。それからもっと大きな値も試してみよう。KpK_pは20 N/mに固定だ。

第11章:PID:すべてを解決する ↗

第11章:PID:すべてを解決する ↗

ミカ: 上げちゃえ! Ki=50K_i = 50! 一気にやっつけろ!

ミカ: …なんで止まらないの? 跳ね返りがどんどん大きくなって、今は半メートルも上下にヨーヨーしてる。ずっと!

テオ: 50で何かの境目を越えたんだ。いくつか試してみた:だいたい40より下なら落ち着くけど、上だと落ち着かない(それにヨーヨーは1往復に約1秒かかる)。理由はすぐにわかる。積み重ねはいつも少し遅れている。ドローンが2 mを通り過ぎたあとも、まだ上に押し続けるんだ。

これがミカの間違いで、すごくよくあるやつだ。積分はドループを直すけど、遅れを加える。そして遅れは揺れを生む(シャワーで学んだよね)。必要なのは、速さに逆らって押し返す何かだ。(数学どおりなら、ミカの揺れはいつまでも大きくなるはず。半メートルくらいで止まるのは、揺れのたびに推力が0 Nに当たるからにすぎない。プロペラは下に引けない。第10章の限界だ。)

D:仮想のショックアブソーバー

ジューン: 第7章では、ダンパーがばねを落ち着かせてくれた。コントローラーがダンパーのふりをしたらどうだろう?

ダンパーは速度に逆らって押す。だからドローンの動く速さに逆らって押す項を足す:

TD=−Kd dhdt\eff{T_D} = -K_d\,\frac{d\out{h}}{dt}

ドローンの式を見てみよう:空気抵抗がすでに−c h˙-c\,\dot hを与えている。D項がその上に−Kd h˙-K_d\,\dot hを足すから、ドローンはあたかも空気抵抗がc+Kdc + K_dであるかのように振る舞う。ソフトウェアで空気抵抗を足しているんだ。

第11章:PID:すべてを解決する ↗

第11章:PID:すべてを解決する ↗

ミカの大きなIゲインをオンにして、減衰を足してみよう。Kd=0.5K_d = 0.5 N·s/mだけでも安定に戻る(境目がKi=60K_i = 60まで広がる)。終わらないヨーヨーが、消えていく跳ねに変わる。でもDをどれだけ足しても、オーバーシュートは少なくとも4分の1は残る。あの巨大な積み重ねは、とにかく覚えすぎているんだ。今度はミカのKiK_iをオフにして(10に戻して)、Kd≈3K_d \approx 3〜5を試そう。落ち着いた。IとDは引き換えの関係だ。DはIのための余裕をくれるけど、その余裕は無限じゃない。

ジューン: 4でいいなら、10はもっといいはず。ショックアブソーバー全開!

ミカ: すごくゆっくり上がっていく…それなのに結局2 mを越えちゃうの? 遅れて?

テオ: ジューン、それって第7章のはちみつドローンの再来だよ! Kd≈5.3K_d \approx 5.3を超えると速いペアは過減衰になる。でも今は積み重ねもある。ドローンがのろいと、積み重ねがたまりすぎる時間ができちゃうんだ。

臨界減衰はζ = 1のところ:Kd=2mKp−c≈5.3K_d = 2\sqrt{m K_p} - c \approx 5.3 N·s/m(KpK_p = 20のとき)。KiK_i = 10でKdK_dを4から10にすると、オーバーシュートは0から約8%に、整定時間は1秒未満から約5 sになる。Dは多ければいいわけじゃない。やりすぎると、ウィジェットがそう教えてくれるようになった。

ミカ: つまりDは未来を予測するんだ! ドローンがどこへ向かっているかを見て、先回りする。

テオ: そうでもないよ。Dが知っているのは今の傾きだけ。ボールがまっすぐ進み続けると決めつけて、落ちる場所を当てるようなものだ。たいていはまあまあの推測だけど、魔法じゃない。ゆらぎのあるセンサーをつないだらわかるよ。

それぞれのノブが極に何をするか

第10章の地図を使うときだ。e=r−h\err{e} = \sp{r} - \out{h}として、ループ全体を書き下そう:

mh¨+ch˙=Kp e+Ki ⁣∫ ⁣e dt−Kd h˙⏟T−mgm\ddot{\out h} + c\dot{\out h} = \underbrace{K_p\,\err e + K_i\!\int\!\err e\,dt - K_d\,\dot{\out h}}_{\eff{T}} - \dis{mg}

積分が扱いにくいから、両辺の傾きを取ろう。傾きと面積は打ち消し合う(第3章)から、∫e dt\int \err e\,dtの傾きはただのe\err e。重力は一定だから、その傾きはゼロ:あっさり消える。目標値が一定ならe˙=−h˙\dot{\err e} = -\dot{\out h}。1項ずつ見ていこう:

ddt(Kp e)=−Kp h˙ddt(Ki ⁣∫ ⁣e dt)=Ki (r−h)ddt(−Kd h˙)=−Kd h¨\begin{aligned} \tfrac{d}{dt}\big(K_p\,\err e\big) &= -K_p\,\dot{\out h} \\ \tfrac{d}{dt}\Big(K_i\!\int\!\err e\,dt\Big) &= K_i\,(\sp r - \out h) \\ \tfrac{d}{dt}\big(-K_d\,\dot{\out h}\big) &= -K_d\,\ddot{\out h} \end{aligned}

全部を元に戻して、h\out hを含む項をすべて左へ移す。h...\dddot{\out h}の3つの点は「傾きの傾きの傾き」という意味だ:

mh...+(c+Kd) h¨+Kp h˙+Ki h=Ki r\begin{aligned} m\dddot{\out h} + (c + K_d)\,\ddot{\out h} &+ K_p\,\dot{\out h} + K_i\,\out h \\ &= K_i\,\sp r \end{aligned}

テオ: 重力が式から消えた。これが式の形になったドループ退治だ。最終的な高さはmgmgをまったく気にしない。もっとも、そもそも落ち着けばの話。ミカのKi=50K_i = 50のドローンは落ち着かなかった。

もう一度este^{st}と予想しよう。Iが効いているときは式が3次式だから、極は3つ。Ki=0K_i=0なら積分器はない。傾きを取ったせいでs=0s = 0に偽の根が加わっただけで、共通因数のssが約分されて、PDドローンの極は2つになる。

ms3+(c+Kd) s2+Kp s+Ki=0m s^3 + (c + K_d)\,s^2 + K_p\,s + K_i = 0

係数がすべて正の3次式a3s3+a2s2+a1s+a0a_3 s^3 + a_2 s^2 + a_1 s + a_0には、昔からある判定法(ラウス・フルビッツの安定判別法)がある。3つの極が全部左半分にあるのは、ちょうどa2a1>a3a0a_2 a_1 > a_3 a_0のときだ、というものだ。私たちのドローンでは、これが崖っぷちになる:

(c+Kd) Kp>m Ki⟺Ki<(c+Kd) Kpm(c + K_d)\,K_p > m\,K_i \quad\Longleftrightarrow\quad K_i < \frac{(c+K_d)\,K_p}{m}

ミカ: 2人の名前がついたルールかあ。信じるしかないの?

テオ: いや。境目は自分たちで見つけられるよ。

揺れるペアがちょうど縦軸に届いた瞬間、実部はゼロになる。だから3次式にs=iωs=i\omegaを入れてみよう。i2=−1i^2 = -1、i3=−ii^3 = -iだから、実数の部分と横向きの部分が、それぞれ足してゼロにならないといけない:

Ki−(c+Kd) ω2=0,ω (Kp−m ω2)=0K_i - (c+K_d)\,\omega^2 = 0, \qquad \omega\,\big(K_p - m\,\omega^2\big) = 0

2つ目の式からω2=Kp/m\omega^2 = K_p/m。これを1つ目に入れると:

ω2=Kpm,Ki=(c+Kd)ω2=(c+Kd)Kpm\omega^2=\frac{K_p}{m},\qquad K_i=(c+K_d)\omega^2=\frac{(c+K_d)K_p}{m}

第11章:PID:すべてを解決する ↗

最初の値(KpK_p = 20、Dなし)だと境目は40。ミカのドローンが暴れ出したのはまさにそこで、そのヨーヨーは1往復に約1秒かかっていた。6.32 rad/sは第7章で見たPドローン自身のωnだ。Kd=4K_d = 4を足すと、境目は200まで広がる。うのみにしないで。上の数字や下のスライダーを変えて、極とミニ地図とステップ応答を見てみよう。

第11章:PID:すべてを解決する ↗

  • Iのノブ(KiK_i)はループに3つ目の極を持ち込み、ペアを右へ押しやることがある。上げすぎると線を越える。
  • Dのノブ(KdK_d)は減衰を加えて、Iゲインの安定限界を引き上げる。極の通り道は曲がることがある。Dを増やしても、すべての極が左へ動くわけじゃない。
  • Pのノブ(KpK_p)は主に揺れるペアを上下に広げる。速くなるけど、Dが追いつかないと、もっと揺れる。

チューニングの遊び場

さあ本番。本物のモーター(0〜20 N)で、地面から2 mまで離陸しよう。星を4つ全部集めよう。ゲインを変えるたびに、直前の飛行が薄いゴーストとして残る。

第11章:PID:すべてを解決する ↗

ジューン: アンチワインドアップをオフにして、KpK_p = 30、KiK_i = 60、KdK_d = 2にしてみたら…ドローンが4 mまで飛び上がって、絵の外に飛び出しちゃった!

テオ: モーターが全開の間じゅう、積み重ねが増え続けていたんだ。アンチワインドアップをオンにすれば、同じゲインでも最高点は2.8 m。ノブは同じでも、記憶がまるで違う。

Dについての2つの警告

警告1:微分キック

ドローンは1 mでホバリングしている。t=1t = 1 sで目標値を1.5 mに動かす。Dが偏差の傾きを使うと、偏差は一瞬で半メートル跳ぶ。その傾きは巨大で、押す力も巨大になる。

第11章:PID:すべてを解決する ↗

第11章:PID:すべてを解決する ↗

ミカ: 偏差を使うと200 N以上も要求するの? 20 Nが上限のモーターに?

ジューン: しかもモーターは上品に断れない。一瞬全開でガツンと押して、ドローンはお尻をけとばされるの。

代わりに測定した高さの傾きを使えば解決する(測定値微分、微分先行型とも呼ぶ)。ドローンはテレポートできないから、高さは跳ばない。減衰は同じで、キックなし。実際のPIDはほぼ全部こうしている。

警告2:ノイズ

本物の高さセンサーは数センチゆらぐ。数センチのゆらぎが毎秒千回もあれば、傾きは巨大になる。Dはそれをそのままモーターへ増幅して送る。対策は、傾きを取る前に測定値をならすこと(時定数τf\tau_fのフィルター)。その代わり、反応が少し遅れる。

第11章:PID:すべてを解決する ↗

第11章:PID:すべてを解決する ↗

ミカ: わかった、Dは未来を予測しない。1ミリ秒前にノイズがどんな気分だったかを予測するだけだ。

直したこと

わかったこと

  • Pは偏差に比例して押すが、ドローンを支えるためにドループを残さないといけない。
  • Iは過去の偏差を積み重ねる。止まっていられるのは偏差ゼロのときだけだから、ドループを消す。ドループは時定数約Kp/KiK_p/K_iで消えていく。遅れを加えるので、増やしすぎると揺れる。
  • Dは速さに逆らって押す。抵抗ccに足される仮想のダンパーで、ζ=(c+Kd)/(2mKp)\zeta = (c+K_d)/(2\sqrt{mK_p})になる。Dは多ければいいわけじゃない。過減衰だとドローンはのろのろ進み、積み重ねがたまりすぎる。
  • 閉ループはms3+(c+Kd)s2+Kps+Kim s^3 + (c + K_d)s^2 + K_p s + K_i。安定なのはちょうど(c+Kd)Kp>mKi(c+K_d)K_p > mK_iのとき。
  • Dは測定値から取り(キックなし)、フィルターをかける(ノイズが減る)。

ジューンが私たちのドローン式PIDをシャワーで試したら…第0章の私たちとまったく同じように揺れた。遅れって、いったい何なんだろう?

第11章:PID:すべてを解決する ↗