# PID

PID 是一種控制訊號輸出的系統，可以用來控制馬達轉動角度和速度。

## P、I、D是什麼？

PID 的輸出是由三個term決定的：Proportional，Integral，和Derivative

$$
output = K\_p*error(t) + K\_i*\int\_{0}^{t} error(t) ,dt + K\_d\*\frac{d}{dt}error(t)
$$

$$K\_p$$是Proportional Term的Coefficient，調高這個可以提升誤差的修正強度

$$K\_i$$是Integral Term的Coefficient，如果機器的Steady state error 不等於零（持續停在某個誤差值），可以調高這個讓機器突破Steady state

$$K\_d$$是Derivative Term的Coefficient，調高這個可以讓誤差接近零時減速的更快

## 概念

```cpp
float Kp = 1;
float Ki = 0.01;
float Kd = 0.1;

float total_error = 0;
float prev_error = 0;

void PID(target_value) {
    float actual_value = sensor.get(); // depends on whether you use PROS or Okapilib
    float error = actual_value - target_value;
    total_error += error;
    float deriv_error = error - prev_error;
    
    float output = Kp * error + Ki * total_error + Kd * deriv_error;
    motor.moveVoltage(output); // depends on whether you use PROS or Okapilib
    prev_error = error;
}
```

## 如何調整PID參數

1. 先調整Kp：如果機器修正太慢，提升Kp，持續提升直到機器開始修正過頭並搖擺
2. 調整Kd：提升以修正搖擺的問題，也可以同時降低一點Kp
3. 如果機器卡在一個誤差值，稍微提升一點Ki，但是不適合提升太多

## 範例

{% content-ref url="../../fan-li-cheng-shi/shi-yong-pid-kong-zhi-di-pan-qian-jin" %}
[shi-yong-pid-kong-zhi-di-pan-qian-jin](https://acezxn.gitbook.io/vex-ji-qi-ren-cheng-shi-jiao-xue/fan-li-cheng-shi/shi-yong-pid-kong-zhi-di-pan-qian-jin)
{% endcontent-ref %}
