追従・ばね・群れ

PD・PID制御

PD / PID Controller

誤差とその変化などから砲塔や乗り物の操作量を決める。

4 / 10

インタラクティブデモ

デモを準備しています…

PD・PID制御

ドラッグで視点を回転、Ctrl(⌘)+ スクロールでズーム。タッチ操作は 2 本指です。

ひとことで

目標値と現在値の誤差から、機械に与える操作量(力、トルク、スロットル)を決めるフィードバック制御です。誤差そのもの(P)、誤差の変化の速さ(D)、誤差の累積(I)の 3 つを重み付けして足します。ロボットやドローンの制御で最も広く使われている方式で、ゲームでも「物理で動くものを狙った値へ持っていく」ときの定番です。

ゲームでの使いどころ

  • 物理ベースの乗り物:ホバークラフトの高さ維持、ドローンの姿勢制御、車の自動運転 AI のハンドル操作。
  • 砲塔の旋回:目標角度へ向けてトルクをかけ、慣性があるのに行き過ぎずに止める。
  • 物理キャラクター:アクティブラグドールで、各関節をアニメーションの姿勢へ引き寄せるモーター。
  • カメラ:物理的な重さを感じさせるカメラの追従。

しくみ

誤差を e(t)=r(t)−y(t)e(t) = r(t) - y(t)(目標 − 現在)とすると、操作量 u(t)u(t) は

u(t)=Kp e(t)+Ki∫0te(τ) dτ+Kd de(t)dtu(t) = K_p\,e(t) + K_i \int_0^t e(\tau)\,d\tau + K_d\,\frac{de(t)}{dt}
項役割大きすぎると
P(比例)誤差が大きいほど強く押す。ばねと同じ振動が激しくなる
D(微分)誤差が縮む速さにブレーキをかける。ダンパーと同じ動きが鈍く、ノイズに敏感
I(積分)残り続ける誤差を積み上げて押し切る行き過ぎやゆっくりした振動(ワインドアップ)

PD 制御はばね・ダンパーそのものです。KpK_p がばね定数、KdK_d が減衰係数にあたります。

では、なぜ I が必要なのでしょうか。デモのドローンには常に重力がかかっています。PD だけだと、重力を打ち消す推力 mgmg を P 項で作るしかないため、釣り合う位置では必ず

Kp e=mg⇒ess=mgKpK_p\,e = m g \quad\Rightarrow\quad e_{\text{ss}} = \frac{m g}{K_p}

の定常偏差が残ります。I 項は誤差を積み上げていくので、やがて I 項だけで mgmg を肩代わりし、誤差を 0 にできます。

実装のポイント

  • 積分の上限(アンチワインドアップ):出力が上限に張り付いている間も積分が増え続けると、目標に着いた後に大きく行き過ぎます。積分値に上限を設けるか、出力が飽和している間は積分を止めます。
  • 微分は測定値から取る:目標値が急に変わると誤差の微分が一瞬巨大になり、操作量が跳ねます(微分キック)。−dy/dt-dy/dt(現在値の変化)を使うと避けられます。
  • フィードフォワード:重力のように分かっている外乱は、u=mg+PIDu = mg + \text{PID} のように先に足しておくと、I 項への負担が減り応答が良くなります。
  • 固定タイムステップで:可変の Δt\Delta t だと微分と積分の値が不安定になります。

つまずきやすい点

  • 調整が難しい:3 つのゲインは互いに影響し合います。まず P だけで振動するところまで上げ、D で揺れを止め、最後に I を少しずつ足すのが基本の手順です。
  • 角度のラップ:旋回の制御で誤差を単純な引き算で求めると、359° → 1° で逆回りします。誤差を [−180°,180°)[-180°, 180°) に正規化します。
  • 物理エンジンとの相互作用:制御の更新間隔と物理の更新間隔がずれると、見えない遅れが入って振動の原因になります。制御は物理ステップ内で計算します。

デモで試すこと

  1. 初期状態(P + D)では、ドローンは揺れずに止まりますが、目標の線より約 0.49 m 下で釣り合っています。
  2. 「Ki(積分)」を 5〜10 程度に上げると、ゆっくりと目標の高さまで上がり、定常偏差が消えます。
  3. 「Kd(微分)」を 0 にすると、上下に揺れ続けます。P だけの制御がばねと同じであることが分かります。
  4. 「下向きの突風」で外乱を与え、各ゲインの設定で回復の仕方がどう変わるかを比べてください。

参考資料

Spring-It-On ↗

分野全体の資料で、この項目を直接扱っているとは限りません。