目次 — 知りたいところから読む

PIDの式を読むだけでは、ゲインを上げたときや出力が頭打ちになったときの挙動を想像しにくい。ここでは条件を固定した小さなモデルを動かし、同じ目標値に対する応答を比較する。2026年9月7日にPython 3.12.3で実行した数値例であり、実際のモータの同定結果ではない。

比較するモデルと条件

制御対象は \ddot y+2\dot y+y=u とする。yは正規化した出力、uは正規化した操作量、時間は秒である。初期位置・速度・積分値は0。目標値は0秒から1、6秒から0.4へ変更する。刻み幅は0.005秒、計算区間は0〜12秒、各条件2,401サンプルである。

制御則は u=K_pe+K_iI-K_d\dot y_me=r-y_my_mは観測値であり、微分は目標値でなく観測値へかける。K_p=3K_i=2K_d=1を基準にする。刻み幅を陽に使って積分・微分を計算し、対象は半陰的Euler法で更新する。原理はPID制御入門を参照。

コードを実行する

pid_lab.pyを空の作業フォルダへ保存し、次を実行する。Python標準ライブラリだけで動作する。同名の結果ファイルは上書きされる。

python3 --version
python3 pid_lab.py

CSV集計JSONが生成される。グラフを再作成する場合は、同じフォルダへplot_pid.pyを保存して実行する。作図の検証環境はmatplotlib 3.6.3である。CSVの列は条件名、時刻、目標値、出力、操作量、積分値の順。

遅延と飽和を比較する

図1 · 横にスクロールして図を読む
二次遅れモデルのPID応答。0.4秒の観測遅延、出力上限0.8、アンチワインドアップの有無を比較したシミュレーション

図の上段は出力、下段は操作量。黒線が目標値で、英語の条件名はCSVと共通である。awはアンチワインドアップを表す。

条件 変更点 12秒の出力 誤差絶対値の時間積分
nominal 遅延なし、操作量±3 0.4008 1.7913
delay_0.4s 観測を0.4秒遅らせる 0.3883 1.8860
limit_0.8_aw 操作量±0.8、積分抑制あり 0.4003 3.3424
limit_0.8_no_aw 操作量±0.8、積分抑制なし 0.6602 5.0996

集計値は同じ計算から得たもので、誤差の時間積分は0〜12秒を左端の矩形則で求めた。正規化出力×秒の量であり、実機の位置誤差[m]ではない。12秒の一点だけで整定性能を判断せず、振動と操作量も見る。

積分を抑えても能力の上限は変わらない

この対象では定常時に y=u となるため、操作量上限0.8では目標1へ到達できない。誤差を積分し続けると、目標を0.4へ下げても蓄積分が大きな入力を要求する。コードでは、飽和を悪化させる方向への積分を止め、飽和から戻す方向は許可する。これが条件付き積分の具体例である。

積分抑制は電源やモータの能力を増やさない。目標値を実現可能な範囲へ変えることと、制御器の内部状態を扱うことを分ける。

ゲインを一つずつ変える演習

from pid_lab import simulate
for kp in (1., 3., 6.):
    rows = simulate("gain", kp=kp)
    print(kp, max(row[3] for row in rows if row[1] < 6))

この演習では最初の目標値区間の最大出力を比較する。次にkiだけ、kdだけを変え、操作量の最大値も記録する。ゲインが大きいほど必ず良いわけではない。遅延・飽和と組み合わせた結果を見てから判断する。

数値例の限界と次の確認

ここには測定ノイズ、摩擦、量子化、通信周期の揺らぎ、微分フィルタを入れていない。刻み幅を半分にして応答が大きく変わるなら、数値近似を先に疑う。実機へ移す際は、ここで使ったゲインを流用せず、対象の単位と時間スケールを合わせて同定する。MPCへ進むと、制約を制御問題の中で扱う考え方を学べる。

次に読む

P・I・Dの原理を確認する制御工学入門:PID制御 — 誤差を三つの時間スケールで扱う制約を含む制御へ進む制御工学入門:モデル予測制御 — 未来を予測して制約の中で動かすシリーズの次の内容へ進む制御工学入門:状態オブザーバと線形カルマンフィルタ — 見えない状態を推定する