Brise

여러 버전의 PID 계산 방법 본문

프로그램/C,C++

여러 버전의 PID 계산 방법

naudhizb 2020. 2. 18. 11:58
반응형


PID 제어기를 계산 할 때 이전 Iteration의 값을 어떤 방식으로 유지할 건지에 대한 계산 방법이 여러가지 있다. 

대부분 둘 중 한가지 방법을 이용하여 계산하는데 한가지 방법의 경우 이전 Iteration의 제어값을 유지하는 방법이 있고, 다른 한가지 방법은 이전 Iteration의 적분항을 유지하는 방법이 있다. 


이전 제어값을 유지하는 방법의 경우 Iteration의 계산하기 위하여 이전에 계산된 P항과 D항을 제외하고 계산해주어야 하고

이전 적분항을 유지하는 방법의 경우 Iteration을 계산하고 Output값과 적분항 모두에 anti-wind up 코드를 삽입해주어야 한다. 


아래 코드는 윤덕용의 직류전동이 책의 일부와

https://github.com/geekfactory/PID github에 공개되어 있는 오픈소스 중 일부 코드를 발췌하였다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
 
/* Global Variable / Macro*/
#define  Kp     0.1                // P gain
#define  Ki     5.0                // I gain
#define  Ts     0.01                // speed sampling time[sec]
volatile float PIconstant, PI = 0.;        // PI variables
 
 
/* Initialize */
 
void Initialize(){
      PIconstant = Kp + Ki*Ts;                      // calculate PI constant
}
 
/* 계산방법 1 */
/* Note :
    Wref : Setpoint 
    Wr   : Current FeedBack
    Werr : Current Error
    Werr0 : Previous Error 
    */
uint32_t Iterate(){
    Werr = Wref - Wr;                // PI controller
    PI = PI + PIconstant*Werr - Kp*Werr0; // 이전시간의 PI가 Kp*Werr0를 포함하고 있기 때문에 제외해줌. 
    Werr0 = Werr;
 
    /* Saturate Output */
    if(PI > 99.)       PI = 99.;            // PI control limiter
    else if(PI < -99.) PI = -99.;
    
    return PI;
}
 
/* 계산방법 2 */
void pid_compute(pid_t pid)
{
    // Check if control is enabled
    if (!pid->automode)
        return false;
    
    float in = *(pid->input);
    // Compute error
    float error = (*(pid->setpoint)) - in;
    // Compute integral
    pid->iterm += (pid->Ki * error);
    if (pid->iterm > pid->omax)
        pid->iterm = pid->omax;
    else if (pid->iterm < pid->omin)
        pid->iterm = pid->omin;
    // Compute differential on input
    float dinput = in - pid->lastin;
    // Compute PID output
    float out = pid->Kp * error + pid->iterm - pid->Kd * dinput;
    // Apply limit to output value
    if (out > pid->omax)
        out = pid->omax;
    else if (out < pid->omin)
        out = pid->omin;
    // Output to pointed variable
    (*pid->output) = out;
    // Keep track of some variables for next execution
    pid->lastin = in;
    pid->lasttime = tick_get();;
}
 
/* 윤용덕 마이크로프로세서 직류전동기 코드 */
cs


반응형
Comments