-
1. Data: 2010-05-10 21:29:11
Temat: Algorytm regulatora PID
Od: "roxy" <k...@o...pl>
Znalazlem na stronie Atmel'a fragment programu realizujacy regulator PID dla
uC.
Czy w linii 93 nie ma aby bledu?
Wedlug mnie powinna ona wygladac raczej tak
d_term = pid_st->D_Factor * (processValue - pid_st->lastProcessValue);
czy ktos moze potwierdzic poprawnosc ktores z wersji?
00060 {
00061 int16_t error, p_term, d_term;
00062 int32_t i_term, ret, temp;
00063
00064 error = setPoint - processValue;
00065
00066 // Calculate Pterm and limit error overflow
00067 if (error > pid_st->maxError){
00068 p_term = MAX_INT;
00069 }
00070 else if (error < -pid_st->maxError){
00071 p_term = -MAX_INT;
00072 }
00073 else{
00074 p_term = pid_st->P_Factor * error;
00075 }
00076
00077 // Calculate Iterm and limit integral runaway
00078 temp = pid_st->sumError + error;
00079 if(temp > pid_st->maxSumError){
00080 i_term = MAX_I_TERM;
00081 pid_st->sumError = pid_st->maxSumError;
00082 }
00083 else if(temp < -pid_st->maxSumError){
00084 i_term = -MAX_I_TERM;
00085 pid_st->sumError = -pid_st->maxSumError;
00086 }
00087 else{
00088 pid_st->sumError = temp;
00089 i_term = pid_st->I_Factor * pid_st->sumError;
00090 }
00091
00092 // Calculate Dterm
00093 d_term = pid_st->D_Factor * (pid_st->lastProcessValue -
processValue);
00094
00095 pid_st->lastProcessValue = processValue;
00096
00097 ret = (p_term + i_term + d_term) / SCALING_FACTOR;
00098 if(ret > MAX_INT){
00099 ret = MAX_INT;
00100 }
00101 else if(ret < -MAX_INT){
00102 ret = -MAX_INT;
00103 }
00104
00105 return((int16_t)ret);
00106 }
__________ Informacja programu ESET NOD32 Antivirus, wersja bazy sygnatur wirusow
5103 (20100510) __________
Wiadomosc zostala sprawdzona przez program ESET NOD32 Antivirus.
http://www.eset.pl lub http://www.eset.com
-
2. Data: 2010-05-10 22:32:21
Temat: Re: Algorytm regulatora PID
Od: J.F. <j...@p...onet.pl>
On Mon, 10 May 2010 23:29:11 +0200, roxy wrote:
>Czy w linii 93 nie ma aby bledu?
>Wedlug mnie powinna ona wygladac raczej tak
>d_term = pid_st->D_Factor * (processValue - pid_st->lastProcessValue);
>czy ktos moze potwierdzic poprawnosc ktores z wersji?
Raczej jest dobrze
>00064 error = setPoint - processValue;
>00074 p_term = pid_st->P_Factor * error;
jesli wejscie jest ponizej wartosci zadanej - to mamy wyjscie
dodatnie.
Jesli jednak sygnal wejsciowy [szybko] rosnie, to nalezy _zmiejszyc_
wartosc wyjsciowa.
>00093 d_term = pid_st->D_Factor * (pid_st->lastProcessValue -
>processValue);
i ten czlon bedzie wtedy ujemny.
J.
-
3. Data: 2010-05-11 03:45:56
Temat: Re: Algorytm regulatora PID
Od: SM <b...@k...com.pl>
>
> ...
Albo tak:
d_term = pid_st->D_Factor * (pid_st->lastProcessValue - processValue);
ret = (p_term + i_term + d_term)
Albo tak:
d_term = pid_st->D_Factor * (processValue - pid_st->lastProcessValue);
ret = (p_term + i_term - d_term)
W tym algorytmie PID część różniczkująca jest obliczana jako
pochodna wartości wyjściowej z obiektu, a nie jako pochodna
uchybu. Ta modyfikacja powoduje to, iż nie mamy w sygnale
wyjściowym z PID dużego piku wartości w momencie zmiany
wartości zadanej.
Gdybyśmy obliczali część różniczkującą "tradycyjnie"
(pochodna uchybu) wtedy trzeba by zmienić znak
(czyli tak jak ty chciałeś to zrobić).
SM


do góry
Jak kupić pierwsze mieszkanie? Eksperci podpowiadają