一個誤差,三個時間點
想像一陣風把你的車吹偏,你正要把它導回車道中央。你的大腦同時做三件事。它看你現在偏了多遠,按比例打方向盤——偏得多就打得多。它注意到你已經持續往右漂了一陣子,於是加上一個穩定的固定修正去抵消這個偏向。它還盯著縫隙閉合得多快,在你衝過中線前就先鬆手。當下的誤差、累積的過去誤差、預測的未來誤差。這就是PID的全部。
正式地說,回授迴路中的控制器量測誤差 e(t) = 設定值 − 量測值,並產生一個控制訊號 u(t)——油門、加熱功率、馬達電壓——去驅動受控體(plant)。PID 結合三項,每項各由一個可調增益加權:比例項 Kp·e、積分項 Ki·∫e dt、微分項 Kd·de/dt。三個數字,三種行為。控制工程的藝術,就在於如何選它們。
setpoint error e control u output y
r ───►(+)───────► e ───►[ PID ]───► u ───►[ PLANT ]───┬───► y
▲ − │
│ │
└───────────────────[ SENSOR ]◄────────────────────┘
(measured output)
u(t) = Kp·e(t) + Ki·∫e(t)dt + Kd·de(t)/dt
└─PRESENT─┘ └──PAST────┘ └──FUTURE───┘比例項:快,但留下一道缺口
從最簡單的控制器開始:純比例,u = Kp·e。誤差越大,你推得越用力。把 Kp 調高,系統反應就越來越快——階躍響應會陡峭地爬向目標。那為何不乾脆用一個巨大的 Kp 了事?兩個原因,而它們正是 PID 存在的核心。
首先,比例控制器幾乎總會留下一道永久的缺口——你在第 4 級遇過的穩態誤差。想像一個馬達轉速迴路:馬達要對抗摩擦、需要穩定的 6 V 才能轉到目標 1000 rpm。在純 P 之下,要持續產生 6 V 控制量的唯一辦法,就是讓誤差保持非零:u = Kp·e 意味著若 u 必須是 6 V 且 Kp = 2,那 e 就得永遠停在相當於 3 rpm 的位置。控制器需要一點殘留誤差來「養活」自己的輸出。把 Kp 調高能縮小缺口,但你永遠到不了零——而把 Kp 推得太遠,就引來第二個問題。
其次,大的 Kp 會讓迴路振盪、最終失穩。真實受控體有遲滯——馬達的慣性、加熱器的熱質量——所以輸出是在你推之後才反應。等量測追上來,誤差早已反號,而強勢的控制器又往反方向過度修正。推得夠猛,擺動就不減反增。第 4 級的穩定性準則,正是限制你能用多少 P 的那道牆。
rpm Kp too LOW: slow, big steady gap
1000 ┤- - - - - - - - - - - - - - - - - setpoint
│ ________________________
│ _____/ ↑ leftover error
│ ____/
0 ┤__/
└──────────────────────────────────► t
rpm Kp too HIGH: fast but rings, smaller gap
1000 ┤- - - -/\- - - -/‾\- - - - - - - - setpoint
│ / \ /‾\ / \___/‾‾‾‾
│ / \/ v
0 ┤__/
└──────────────────────────────────► t積分消滅缺口;微分馴服擺動
積分項正是那道頑固殘餘誤差的解藥。I 項輸出 Ki·∫e dt——它把誤差隨時間累積起來。只要還有任何誤差殘留,積分就持續增長,把控制訊號推得越來越用力,直到誤差被逼到剛好為零。此時積分停止變化,並守住受控體所需的固定值——馬達那 6 V。妙處在於積分記住了偏向,控制器不再需要活的誤差來維持輸出。在數學上,積分器替迴路加上一個位於原點的極點(s = 0),由第 4 級的誤差分析可知,這保證了對階躍命令的穩態誤差為零。
但積分脾氣不好。因為只要誤差存在它就一直推,它傾向過衝——等輸出終於到達設定值時,積分早已累積了一大坨「推力庫存」,要花時間才能釋放掉,於是系統會先衝過目標再折返。積分讓迴路更準,卻更慢穩定、更易振鈴。它是那個拿速度換精度的項。
於是輪到微分項出場,它是煞車。D 輸出 Kd·de/dt——它對誤差變化得多快作反應。當輸出正衝向設定值時,誤差快速縮小,de/dt 又大又負,D 便在系統抵達之前就先把控制訊號拉回。這是純粹的預測:D 作用於預測的未來,加入阻尼以壓制過衝,讓你能安全地使用比原本更高的 Kp 與 Ki。一個調得好的 D 項,能把搖晃振鈴的迴路變成俐落、阻尼良好的迴路。
EFFECT OF RAISING EACH GAIN (hold the others fixed):
rise time overshoot settling time steady-state err
↑ Kp faster ↓ larger ↑ small change smaller ↓
↑ Ki faster ↓ larger ↑ longer ↑ ELIMINATED ↓↓
↑ Kd little smaller ↓ faster ↓ no effect
(these are tendencies, not laws — the terms interact)一個實作的馬達轉速迴路
讓我們套上數字。一台驅動飛輪的直流馬達,可建模為一階受控體,轉移函數為 G(s) = K/(τs + 1),其中 K 是穩態增益(每伏特多少 rpm),τ 是機械時間常數(慣性反應要多久)。設 K = 200 rpm/V、τ = 0.5 s,我們下達一個從 0 到 1000 rpm 的階躍命令。逐項看著控制器演化。
Plant: G(s) = 200 / (0.5 s + 1) target = 1000 rpm
(1) P only, Kp = 0.01
steady output settles at ~667 rpm → 333 rpm SHORT.
(loop gain Kp·K = 2, error = r/(1+2) = 333)
(2) P + I, Kp = 0.01, Ki = 0.05
output now reaches 1000 rpm exactly, but OVERSHOOTS to
~1150 rpm and rings for ~3 s before settling.
(3) P + I + D, Kp = 0.01, Ki = 0.05, Kd = 0.004
output reaches 1000 rpm, overshoot trimmed to ~3%,
settles cleanly in ~1.2 s. Zero steady-state error.
1150 ┤ ,-. (2) PI: overshoot + ring
1000 ┤----/---`-.__________ ← (3) PID: crisp
667 ┤ / (1) P-only floor (gap!)
0 ┤__/
└───────────────────────► t仔細讀第一行——這正是第 4 級誤差公式的實戰。只有比例增益時,迴路增益是 Kp·K = 0.01 × 200 = 2,一階階躍會穩定到 r·(迴路增益)/(1 + 迴路增益) = 1000 × 2/3 ≈ 667 rpm。短少的 333 rpm 就是穩態誤差,由有限增益所烙下。步驟 (2) 的積分項讓這個誤差在數學上不可能存在:任何殘留誤差只要給足時間,都會積分到輸出剛好落在目標上。
一套你真能用上的調校配方
理論很美,但在實驗台上你是手動調的。以下是多數工程師最先採用的手動配方——它依靠上面那張速查表,並在每一步都尊重第 4 級的穩定性極限。
- 全部歸零。設 Ki = 0、Kd = 0。先調純 P。
- 調高 Kp,直到迴路反應俐落、剛開始振盪,然後退回到約一半的值。你現在有了快速但略短少的響應。
- 加入 Ki 以消除穩態缺口。逐步加大,直到殘餘誤差在可接受時間內消失。Ki 太多,過衝與振鈴會回頭——往回退一點。
- 僅在過衝或振鈴仍惹人厭時加入 Kd。一點點微分就能換來大量阻尼;加到響應俐落為止,但一旦控制訊號開始看起來抖動,就立刻停手。
- 反覆迭代。三項會互相影響——加 I 可能逼你微調 P,加 D 可能讓你把兩者都調高。驗證最終的階躍響應符合你對過衝、穩定時間與誤差的目標。
若想要更有系統的起點,經典的 Ziegler–Nichols 法只用一個實驗就給你大致的增益。把 I 與 D 設為零,調高 Kp 直到迴路以穩定、持續不衰減的振幅振盪——稱該增益為臨界增益 Ku、振盪週期為 Tu。然後直接從表中讀出增益。它很少剛好命中(Z–N 經典版給的調校相當激進、易過衝),但它能在幾分鐘內把你帶到正確的鄰里,準備好做手動微調。
ZIEGLER–NICHOLS (closed-loop / ultimate-gain method)
Find Ku (gain at sustained oscillation) and Tu (its period).
Controller │ Kp Ki = Kp/Ti Kd = Kp·Td
───────────┼──────────────────────────────────────────
P │ 0.50·Ku — —
PI │ 0.45·Ku Ti = Tu/1.2 —
PID │ 0.60·Ku Ti = Tu/2 Td = Tu/8
(a starting point, not a final answer — always hand-trim)PID 反咬你的地方:積分飽和與雜訊
有兩個現實世界的小妖怪,把教科書上的 PID 和真正能在現場存活的 PID 分了開來。第一個是積分飽和(windup)。每個真實致動器都會飽和——馬達驅動器只能輸出那麼多伏特,閥門最多只能開到 100%。假設你下達一個大階躍,輸出被限制在全速,卻離目標還很遠。誤差持續很大,於是積分項不斷累積——即使致動器早已到頂、再推也沒用,積分仍捲到一個巨大的值。等輸出終於到達設定值,那一大坨儲存的積分仍繼續猛推致動器,在它慢慢釋放期間,造成巨大而拖沓的過衝。
第二個小妖怪住在微分項裡。D 對誤差的變化率作反應——而量測雜訊,按定義就是一個快速變化的訊號。一個哪怕只帶一點高頻雜訊的感測器,都可能有微小卻極快速的抖動,而 de/dt 放大的正是這個。結果是控制訊號充滿劇烈的尖刺,猛敲你的致動器、浪費能量,還可能激起共振。這就是為何純教科書式的 D 很少被原樣使用。
解藥是濾波微分(filtered derivative):實務控制器不用純 Kd·s,而是實作 Kd·s/(1 + s/N)——微分後接一個低通濾波器(典型 N ≈ 8–20),把有用的預測保留在重要的頻率,同時把高頻雜訊衰減掉。再配上抗飽和,這就是人們所謂的「實務 PID」,也正是運行在你將設計的運動控制器、無人機飛控與製程迴路裡的東西。