demiurg_spb 0 24 мая, 2010 Опубликовано 24 мая, 2010 · Жалоба c ПИД регулятором работаю впервые, так когда необходимо вызывать данную ф-ию?Почитайте пожалуйста теорию, хотя бы немного... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Tanya 4 24 мая, 2010 Опубликовано 24 мая, 2010 · Жалоба Может значить, а может и нет (я утрировал). Предупреждать надо. Вы же не утром писали... вызывать pid_Reset_Integrator() при error == 0 или когда??? Можете вызывать джинна Обнулятора и в этот момент. Только один раз. Или держать интегральный член нулевым до уменьшения скорости в ... X раз. А еще лучше - плавно менять задатчик, не вызывая джинна. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 24 мая, 2010 Опубликовано 24 мая, 2010 · Жалоба Предупреждать надо. Вы же не утром писали...Когда встал - тогда и утро! Тем не менее, бью челом! Простите холопа:-) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Jenyok2 0 9 октября, 2011 Опубликовано 9 октября, 2011 (изменено) · Жалоба Вот реализация ПИД алгоритма. В процедуре DoChart 4-е цикла с разными реализациями ПИД алгоритма. Язык программирования Delphi 7.0 . Функция для регулироания fPID внутри процедуры DoChart. Для тестирования и применения в ваших программах. . function TForm1.ChangeValPoint(s : String) : String; var i : Integer; begin Result:=s; i:=Length(s); while (i > 0) and (Result[i] <> '.') do Dec(i); if (i > 0) then Result[i]:=','; end; procedure TForm1.DoChart; var f : array[1..4000] of Real; f1 : array[1..4000] of Real; f2 : array[1..4000] of Real; f3 : array[1..4000] of Real; A, B : Real; i : Integer; n : integer; min_integ_error, max_integ_error, integral : Real; diapazon : Real; T0 : Real; { Ïåðèîä êâàíòîâàíèÿ (äèñêðåòèçàöèè) } Ti : Real; { Ïîñòîÿííàÿ èíòåãðèðîâàíèÿ } Td : Real; { Ïîñòîÿííàÿ äèôåðåíöèðîâàíèÿ } q0 : Real; q1 : Real; q2 : Real; Uk : Real; { Òåêóùåå çíà÷åíèå U(k) } Uk1 : Real; { Ïðåäûäóùåå çíà÷åíèå U(k-1) } ek : Real; { Òåêóùåå çíà÷åíèå îøèáêè e(k) } ek1 : Real; { Ïðåäûäóùåå çíà÷åíèå îøèáêè e(k-1) } ek2 : Real; { Ïðåäûäóùåå çíà÷åíèå îøèáêè íà äâà øàãà íàçàä e(k-2) } Uust : Real; { Çíà÷åíèå óñòàâêè (âõîäíîé âåëå÷èíû) } Kp : Real; Ki : Real; Kd : Real; Ku : Real; function fPID(i : Integer; Uk : Real) : Real; begin B:=0.2; A:=i / 10.0; // Result:=Uk * ((1.0 / A) / (B + 1.0 / A)); // t:=(i - 1) / 250000.0; // f[i]:=k * (1.0 - Exp(-1.0 * t / Tau)); // Result:=10.0 * sin(((i - 1) - Uk) / 40.0); Result:=sin(((i - 1) - Uk) / 40.0); end; begin { Series1 - Ôóíêöèÿ äëÿ ðåãóëèðîâàíèÿ } { Series2 - PID } { Series3 - PID + Ôóíêöèÿ ðåãóëèðîâàíèÿ } { Series4 - Îøèáêà } Form1.LabeledEdit1.Text:=ChangeValPoint(Form1.LabeledEdit1.Text); Form1.LabeledEdit2.Text:=ChangeValPoint(Form1.LabeledEdit2.Text); Form1.LabeledEdit3.Text:=ChangeValPoint(Form1.LabeledEdit3.Text); Form1.LabeledEdit4.Text:=ChangeValPoint(Form1.LabeledEdit4.Text); Form1.LabeledEdit5.Text:=ChangeValPoint(Form1.LabeledEdit5.Text); Form1.LabeledEdit6.Text:=ChangeValPoint(Form1.LabeledEdit6.Text); Form1.LabeledEdit7.Text:=ChangeValPoint(Form1.LabeledEdit7.Text); Form1.LabeledEdit8.Text:=ChangeValPoint(Form1.LabeledEdit8.Text); Form1.LabeledEdit9.Text:=ChangeValPoint(Form1.LabeledEdit9.Text); Uust:=StrToFloat(Form1.LabeledEdit1.Text); Kp:=StrToFloat(Form1.LabeledEdit2.Text); Ki:=StrToFloat(Form1.LabeledEdit3.Text); Kd:=StrToFloat(Form1.LabeledEdit4.Text); T0:=StrToFloat(Form1.LabeledEdit5.Text); n:=StrToInt(Form1.LabeledEdit6.Text); Ku:=StrToFloat(Form1.LabeledEdit7.Text); min_integ_error:=StrToFloat(Form1.LabeledEdit8.Text); max_integ_error:=StrToFloat(Form1.LabeledEdit9.Text); // n:=200; for i:=1 to n do begin f[i]:=Ku * fPID(i, 0.0); Series1.AddXY(i, f[i]); end; diapazon:=Uust; Uk:=0.0; Uk1:=0.0; ek:=0.0; ek1:=0.0; ek2:=0.0; integral:=0.0; if (CheckBox1.State = cbChecked) then begin for i:=1 to n do begin ek:=Uust - Uk; f1[i]:=ek; Series4.AddXY(i, f1[i]); // integral:=integral + ek; if ((min_integ_error < ek) and (ek < max_integ_error)) then integral:=integral + ek else integral:=0.0; Uk:=Kp * ek + Ki * integral * T0 + (Kd * (ek - 2.0 * ek1 + ek2)) / T0; // Uk:=Kp * ek + Ki * integral + (Kd * (ek - 2.0 * ek1 + ek2)); if (-1.0 * diapazon > Uk) then Uk:=-1.0 * diapazon; if (Uk > diapazon) then Uk:=diapazon; f2[i]:=Uk; Series2.AddXY(i, f2[i]); f[i]:=Ku * fPID(i, Uk); Series3.AddXY(i, f[i]); ek2:=ek1; ek1:=ek; Uk:=f[i]; { http://kazus.ru/forums/showthread.php?t=11558 } { http://kazus.ru/forums/showthread.php?t=11558&page=4 } end; end else begin Series2.Clear; Series3.Clear; Series4.Clear; end; Uk:=0.0; Uk1:=0.0; ek:=0.0; ek1:=0.0; ek2:=0.0; integral:=0.0; if (CheckBox2.State = cbChecked) then begin for i:=1 to n do begin ek:=Uust - Uk; f1[i]:=ek; Series7.AddXY(i, f1[i]); integral:=ek; if ((min_integ_error < integral) and (integral < max_integ_error)) then integral:=integral else integral:=0.0; Uk:=Uk1 + Kp * (ek - ek1) + Kp * Ki * integral + Kp * Kd * (ek - 2.0 * ek1 + ek2); if ((-1.0 * diapazon) > Uk) then Uk:=-1.0 * diapazon; if (Uk > diapazon) then Uk:=diapazon; f2[i]:=Uk; Series5.AddXY(i, f2[i]); f[i]:=Ku * fPID(i, Uk); Series6.AddXY(i, f[i]); ek2:=ek1; ek1:=ek; Uk:=f[i]; Uk1:=Uk; { http://ru.wikipedia.org/wiki/%D0%9F%D0%98%D0%94-%D1%80%D0%B5%D0%B3%D1%83%D0%BB%D1%8F%D1%82%D0%BE%D1%80 } end; end else begin Series5.Clear; Series6.Clear; Series7.Clear; end; { Ñêîðîñòíîé ìåòîä } q0:=Kp * (1.0 + Kd); q1:=Kp * (-1.0 - 2.0 * Kd + Ki); q2:=Kp * Kd; Uk:=0.0; Uk1:=0.0; ek:=0.0; ek1:=0.0; ek2:=0.0; if (CheckBox3.State = cbChecked) then begin for i:=1 to n do begin ek:=Uust - Uk; f1[i]:=ek; Series10.AddXY(i, f1[i]); Uk:=Uk1 + q0 * ek + q1 * ek1 + q2 * ek2; if (-1.0 * diapazon > Uk) then Uk:=-1.0 * diapazon; if (Uk > diapazon) then Uk:=diapazon; f2[i]:=Uk; Series8.AddXY(i, f2[i]); f[i]:=Ku * fPID(i, Uk); Series9.AddXY(i, f[i]); ek2:=ek1; ek1:=ek; Uk:=f[i]; Uk1:=Uk; { http://www.rlda.ru/PID_Control_Tutor.htm } end; end else begin Series8.Clear; Series9.Clear; Series10.Clear; end; { Ìåòîä òðàïåöèè } q0:=Kp * (1.0 + 0.5 * Ki + Kd); q1:=Kp * (-1.0 - 2.0 * Kd + 0.5 * Ki); q2:=Kp * Kd; Uk:=0.0; Uk1:=0.0; ek:=0.0; ek1:=0.0; ek2:=0.0; if (CheckBox4.State = cbChecked) then begin for i:=1 to n do begin ek:=Uust - Uk; f1[i]:=ek; Series13.AddXY(i, f1[i]); Uk:=Uk1 + q0 * ek + q1 * ek1 + q2 * ek2; if (-1.0 * diapazon > Uk) then Uk:=-1.0 * diapazon; if (Uk > diapazon) then Uk:=diapazon; f2[i]:=Uk; Series11.AddXY(i, f2[i]); f[i]:=Ku * fPID(i, Uk); Series12.AddXY(i, f[i]); ek2:=ek1; ek1:=ek; Uk:=f[i]; Uk1:=Uk; { http://www.rlda.ru/PID_Control_Tutor.htm } end; end else begin Series11.Clear; Series12.Clear; Series13.Clear; end; end; Изменено 9 октября, 2011 пользователем Jenyok2 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться