PID 可簡單記成:P 看 current deviation,I 看 accumulated deviation,D 看 deviation trend。
-------------------------------------------------------------------------------------------------
PID 控制,全名是 Proportional–Integral–Derivative Control,
它是一種很常見的回授控制方法,
PID 的基本想法是:
先比較「目標值」和「目前值」差多少,再根據這個差距決定要輸出多少控制力。
例如:
我們希望馬達轉速是 100 rpm,但目前只有 90 rpm。
這時系統就知道:「目前太慢了,應該增加控制輸出。」
這個「目標值和目前值的差距」,就叫做 error,也就是誤差。
$$
error = target - current
$$
例如:
$$
error = 100 - 90 = 10
$$
一、PID 的基本公式
標準 PID 公式可以寫成:$$
u(t)=K_p e(t)+K_i \int e(t)dt+K_d \frac{de(t)}{dt}
$$
其中:
\(u(t)\):控制器輸出,例如馬達 PWM、加熱功率、閥門開度
\(e(t)\):誤差,也就是目標值減目前值
\(K_p\):比例增益
\(K_i\):積分增益
\(K_d\):微分增益
這個公式看起來很抽象,但其實可以拆成三個部分:
$$
u(t)=P+I+D
$$
也就是:
$$
控制輸出 = P項 + I項 + D項
$$
在標準 PID 裡,每一次控制迴圈都會同時計算 P、I、D,
二、P 項:比例控制,看「現在差多少」
P 是 Proportional,比例控制。
公式是:
$$P = K_p \times error
$$P 項只看一件事:現在的誤差有多大?
假設目標速度是 100,目前速度是 90:
$$
error = 100 - 90 = 10
$$
如果:
$$
K_p = 2
$$
那麼:
$$
P = 2 \times 10 = 20
$$
意思是:
目前差 10,所以根據比例增益 \(K_p\),控制器給出 20 的修正量。
P 的直覺是:現在偏差越大,修正力道越大。
如果目前速度是 95:
$$
error = 100 - 95 = 5
$$
那 P 項就會變小。
因為系統已經比較接近目標,不需要像剛才那麼用力修正。
所以 P 項的特性是:
反應快
直接根據當下誤差修正
誤差大,輸出大
- 誤差小,輸出小
這時誤差只剩 2,P 項覺得「差不多了」,
輸出可能不夠大,導致系統一直卡在 98,而不是精準到 100。這種現象叫做穩態誤差。
三、I 項:積分控制,看「過去累積欠了多少」
I 是 Integral,積分控制。
公式是:
$$
I = K_i \times \int e(t)dt
$$
在實際程式裡,通常會寫成:
integral += error * dt;
I = Ki * integral;
I 項看的不是「現在差多少」,而是:
過去一段時間,誤差累積了多少?
這就是「過去累積的偏差」。
假設目標速度是 100,系統每一輪控制都低於目標:
時間 | 實際速度 | 誤差 |
t1 | 90 | 10 |
t2 | 95 | 5 |
t3 | 98 | 2 |
t4 | 100 | 0 |
如果先不管 \(dt\) 和 \(K_i\),只看「累積誤差」的概念:
時間 | 誤差 | I 累積誤差 |
t1 | 10 | 10 |
t2 | 5 | 10 + 5 = 15 |
t3 | 2 | 15 + 2 = 17 |
t4 | 0 | 17 |
這就是 I 項的重點。
P 項在 t2 的時候只看到「現在還差 5」。
但 I 項會記得:「前面曾經差過 10,現在又差 5,所以總共累積了 15。」
所以 I 項有點像是在記帳:
系統過去一直沒有達到目標,所以 I 項會把這些欠帳累積起來,逼系統繼續修正。
這就是為什麼 I 項可以消除穩態誤差。
例如目標速度是 100,但系統一直卡在 98。
P 項可能覺得誤差只有 2,不太夠力。
但 I 項會因為「長時間都差 2」而不斷累積,最後把輸出推高,讓系統真正接近 100。
四、I 項不是只會越來越大
I 項會根據誤差的正負方向累積。
假設目標速度是 100:
時間 | 實際速度 | 誤差 | I 累積誤差 |
t1 | 90 | +10 | 10 |
t2 | 95 | +5 | 15 |
t3 | 105 | -5 | 10 |
t4 | 102 | -2 | 8 |
當實際速度低於目標時:
$$
error = target - current
$$
會是正值。
I 項會往正方向累積。
但當實際速度超過目標時,例如目前速度是 105:
$$
error = 100 - 105 = -5
$$
這時誤差變成負值,I 項就會被往回扣。
所以 I 項不是永遠只會變大。
它會根據系統是「低於目標」還是「高於目標」來累積或抵消。
五、I 項的風險:Integral Windup
I 項雖然可以消除穩態誤差,但如果 \(K_i\) 太大,或者累積誤差沒有被限制,就可能造成問題。
例如系統長時間達不到目標,I 項一直累積。
等到系統終於開始接近目標時,I 項已經累積得太大,導致輸出過強,直接衝過頭。
這叫做 integral windup,可以翻成「積分飽和」或「積分累積過度」。
因此實務上常常會對 integral 做限制,例如:
integral += error * dt;
if (integral > max_integral)
integral = max_integral;
if (integral < min_integral)
integral = min_integral;
這樣可以避免 I 項累積到失控。
六、D 項:微分控制,看「誤差變化有多快」
D 是 Derivative,微分控制。
公式是:
$$
D = K_d \times \frac{de(t)}{dt}
$$
在程式裡通常會寫成:
derivative = (error - previous_error) / dt;
D = Kd * derivative;
D 項看的不是現在差多少,也不是過去累積多少,而是:
誤差正在變大還是變小?變化速度有多快?
假設目標速度是 100。
上一輪誤差是 10,這一輪誤差是 3:
$$
derivative = \frac{3 - 10}{dt}
$$
這代表誤差正在快速變小。也就是說,系統正在快速接近目標。
這時 D 項通常會產生一種「煞車」效果,避免系統衝過頭。
用開車比喻:
你要把車速控制在 60 km/h。
如果現在只有 40 km/h,當然要踩油門。
但如果車速已經從 40 快速上升到 58,而且還在快速上升,你就不能繼續大力踩油門。
因為再踩下去可能會衝到 70。
D 項做的事情就像是:看到系統正在快速接近目標,所以提前減少控制力,避免超調。
七、Kp、Ki、Kd 是什麼?
PID 裡面的 \(K_p\)、\(K_i\)、\(K_d\) 都叫做增益,也就是調整各項影響力的參數。
可以把它們想成三個旋鈕:
參數 | 控制哪一項 | 意思 |
$$K_p$$ | P 項 | 現在誤差要修正多用力 |
$$K_i$$ | I 項 | 過去累積誤差要算多重 |
$$K_d$$ | D 項 | 誤差變化速度要算多重 |
\(K_p\):比例增益
$$
P = K_p \times error
$$
\(K_p\) 越大,系統對當下誤差反應越強。
但如果太大,系統可能會震盪或衝過頭。
\(K_i\):積分增益
$$
I = K_i \times 累積誤差
$$
\(K_i\) 越大,系統越積極消除長期偏差。
但如果太大,容易造成 integral windup、超調和震盪。
\(K_d\):微分增益
$$
D = K_d \times 誤差變化速度
$$
\(K_d\) 越大,系統越會抑制快速變化。它可以減少超調,但也容易放大雜訊。
八、P、I、D 是同時作用,不是依序作用
PID 很容易被誤解成:先用 P 修正,P 不夠再用 I,最後再用 D。
但這不是標準 PID 的運作方式。
在標準 PID 裡,每一輪控制迴圈都會同時計算:
error = target - current;
P = Kp * error;
integral += error * dt;
I = Ki * integral;
derivative = (error - previous_error) / dt;
D = Kd * derivative;
output = P + I + D;
previous_error = error;
也就是:
$$
output = P + I + D
$$
P、I、D 是同時計入最後輸出的。
只是它們的「時間感」不同:
項目 | 它看的東西 | 時間感 |
P | 現在的誤差 | 現在 |
I | 過去累積的誤差 | 過去 |
D | 誤差變化速度 | 趨勢 / 未來傾向 |
所以可以簡單記成:P 看現在,I 記過去,D 看趨勢。
九、用速度控制做完整例子
假設目標速度是 100,目前速度是 90。
$$
error = 100 - 90 = 10
$$
假設:
$$
K_p = 2
$$
那麼:
$$
P = 2 \times 10 = 20
$$
這表示 P 項根據「現在差 10」給出 20 的修正量。
接著,I 項會累積這個誤差:
integral += error * dt;
如果先簡化,不考慮 \(dt\),前幾次控制可能像這樣:
時間 | 實際速度 | 誤差 | P 看的是 | I 累積的是 |
t1 | 90 | 10 | 10 | 10 |
t2 | 95 | 5 | 5 | 15 |
t3 | 98 | 2 | 2 | 17 |
t4 | 100 | 0 | 0 | 17 |
P 項會隨著當下誤差變小而變小。
但 I 項記得過去曾經有一段時間低於目標,所以它仍然保留累積量。
如果後來速度變成 105:
$$
error = 100 - 105 = -5
$$
I 項就會被扣回來:
時間 | 實際速度 | 誤差 | I 累積 |
t1 | 90 | +10 | 10 |
t2 | 95 | +5 | 15 |
t3 | 105 | -5 | 10 |
這表示系統已經超過目標,I 項開始往反方向修正。
接著來看 D 項的例子,重點是「誤差變化速度」。
假設目標速度是 100:
時間 | 實際速度 | 誤差 | 誤差變化 | D 的感覺 |
t1 | 90 | 10 | — | 剛開始 |
t2 | 95 | 5 | -5 | 誤差快速變小 → 開始減力 |
t3 | 98 | 2 | -3 | 還在快速接近 → 繼續煞車 |
t4 | 100 | 0 | -2 | 很接近目標 → 更小輸出 |
t5 | 103 | -3 | -3 | 已經超過 → 強烈反向修正 |
這裡的重點是:
誤差從 10 → 5 → 2,代表系統正在「快速接近目標」
D 項看到這個趨勢,就會提前減少輸出,像踩煞車
如果沒有 D,系統可能會直接衝過頭,例如衝到 105
所以可以這樣理解:
P:現在差多少,就修多少
I:過去累積差多少,要補回來
D:看你接近目標的速度,太快就先踩煞車
十、總結:PID 的核心直覺
PID 的目標不是單純「越用力修正越好」。
它真正想達到的是:讓系統快、準、穩地接近目標值。
三個項目各自負責不同任務:
項目 | 功能 |
P | 根據現在的偏差立即修正 |
I | 根據過去累積的偏差消除長期誤差 |
D | 根據誤差變化速度抑制超調 |
最簡單的理解是:
P:現在差多少,就修多少。
I:過去一直沒修好的部分,要補回來。
D:看你接近目標的速度,必要時提前煞車。
所以 PID 公式雖然看起來像數學式,但本質上是一個很直覺的控制策略:
$$
控制輸出 = 現在的修正 + 過去欠帳的補償 + 趨勢的預判
$$
也就是:
$$
u(t)=K_p e(t)+K_i \int e(t)dt+K_d \frac{de(t)}{dt}
$$
這就是 PID 控制的核心。








