반응형
Notice
Recent Posts
Recent Comments
Link
Brise
여러 버전의 PID 계산 방법 본문
반응형
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 |
반응형
'프로그램 > C,C++' 카테고리의 다른 글
[C++기본] 1. Hello world! (0) | 2022.01.14 |
---|---|
VS Code에서 uint32_t 타입 오류로 표시되는 경우(임베디드, stm32) (0) | 2021.02.02 |
모듈러 연산 시 음수가 나오는 경우 (0) | 2020.03.15 |
2차원 배열 동적할당 (0) | 2015.12.19 |
2차원 포인터의 값과 주소 접근 방식 (0) | 2015.12.12 |
C언어 표준매크로 (0) | 2015.08.20 |
C언어의 변수형 정리 (0) | 2015.08.14 |
Comments