Перейти к содержанию
    

c ПИД регулятором работаю впервые, так когда необходимо вызывать данную ф-ию?
Почитайте пожалуйста теорию, хотя бы немного...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может значить, а может и нет (я утрировал).

Предупреждать надо. Вы же не утром писали...

 

вызывать pid_Reset_Integrator() при error == 0 или когда???

Можете вызывать джинна Обнулятора и в этот момент. Только один раз.

Или держать интегральный член нулевым до уменьшения скорости в ... X раз.

А еще лучше - плавно менять задатчик, не вызывая джинна.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Предупреждать надо. Вы же не утром писали...
Когда встал - тогда и утро!

Тем не менее, бью челом! Простите холопа:-)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот реализация ПИД алгоритма.

В процедуре 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;

Изменено пользователем Jenyok2

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...