Перевод статьи "Просто о ПИД-алгоритмах" — различия между версиями

Материал из roboforum.ru Wiki
Перейти к: навигация, поиск
(Отмена правки 13886 участника Ipodsoft (обсуждение))
 
(не показаны 73 промежуточные версии 6 участников)
Строка 4: Строка 4:
 
<center>Исходная статья: [[http://www.embedded.com/2000/0010/0010feat3.htm http://www.embedded.com/2000/0010/0010feat3.htm]]</center>
 
<center>Исходная статья: [[http://www.embedded.com/2000/0010/0010feat3.htm http://www.embedded.com/2000/0010/0010feat3.htm]]</center>
  
<p align=center><b>Автор: Tim Wescott</b><br><br><i>Перевод начал: Ботов Антон aka =DeaD=</i></p>
+
<p align=center><b>Автор: Tim Wescott</b><br><br><i>Перевод: © Ботов Антон aka =DeaD=, 2008<br><br>Эксклюзивно для www.roboforum.ru<br> копирование на другие ресурсы и публикация перевода<br>без разрешения его автора запрещены</i></p>
  
== Введение ==
+
= Введение =
  
 
''Алгоритмы ПИД (PID = proportional, integral, derivative) управления не так сложны, как кажется некоторым с первого взгляда. В этой статье мы попробуем рассказать как они работают на нескольких простых примерах. Изучив эти примеры, вы сможете самостоятельно применять эти алгоритмы в своих проектах.''
 
''Алгоритмы ПИД (PID = proportional, integral, derivative) управления не так сложны, как кажется некоторым с первого взгляда. В этой статье мы попробуем рассказать как они работают на нескольких простых примерах. Изучив эти примеры, вы сможете самостоятельно применять эти алгоритмы в своих проектах.''
Строка 12: Строка 12:
 
Моя профессиональная деятельность непосредственно связана с реализацией
 
Моя профессиональная деятельность непосредственно связана с реализацией
 
управляющих циклов в программном обеспечении для различных устройств. Исходя из
 
управляющих циклов в программном обеспечении для различных устройств. Исходя из
накопленного опыта, могу сказать, что не смотря на огромное количество
+
накопленного опыта, могу сказать, что несмотря на огромное количество
 
алгоритмов и методов управления, которыми я владею - большая часть проблем
 
алгоритмов и методов управления, которыми я владею - большая часть проблем
 
такого сорта решается простейшими контроллерами без привлечения полного
 
такого сорта решается простейшими контроллерами без привлечения полного
Строка 21: Строка 21:
 
себя методом, который можно успешно применять на большинстве задач управления.
 
себя методом, который можно успешно применять на большинстве задач управления.
  
== ПИД управление ==
+
= ПИД управление =
  
 
PID=ПИД означает "proportional=пропорциональный", "integral=интегральный",
 
PID=ПИД означает "proportional=пропорциональный", "integral=интегральный",
Строка 33: Строка 33:
 
элементов складываются между собой и формируют управляющий сигнал для устройства.
 
элементов складываются между собой и формируют управляющий сигнал для устройства.
  
<center>[[Изображение:pid_fig_1.jpg|Рисунок 1. Простейший ПИД-контроллер]]</center>
+
 
 +
<center>[[Изображение:pid_fig_1.gif|Рисунок 1. Простейший ПИД-контроллер]]<br>
 +
'''Рисунок 1. Простейший ПИД-контроллер'''</center>
 +
 
  
 
В приведенном на рисунке примере дифференциальный элемент оперирует только
 
В приведенном на рисунке примере дифференциальный элемент оперирует только
Строка 45: Строка 48:
 
выбрать только на конкретном устройстве и задаче управления.
 
выбрать только на конкретном устройстве и задаче управления.
  
== Объекты управления ==
+
= Объекты управления =
 
Чтобы в обсуждении темы не уходить далеко от реальных задач нам понадобятся
 
Чтобы в обсуждении темы не уходить далеко от реальных задач нам понадобятся
 
типичные объекты управления. В этой статье я буду использовать для примеров
 
типичные объекты управления. В этой статье я буду использовать для примеров
Строка 51: Строка 54:
 
алгоритмы ПИД-управления:
 
алгоритмы ПИД-управления:
 
* Двигатель с редуктором;
 
* Двигатель с редуктором;
* Безконтактная система сверхточного позиционирования;
+
* Бесконтактная система сверхточного позиционирования;
 
* Термосистема;
 
* Термосистема;
  
Строка 59: Строка 62:
 
== Двигатель с редуктором ==
 
== Двигатель с редуктором ==
 
Первым рассмотрим двигатель с редуктором, на выходном валу которого
 
Первым рассмотрим двигатель с редуктором, на выходном валу которого
установлен потенциометр или любым другим датчиком положения вала. Такое решение
+
установлен потенциометр или любой другой датчик положения вала. Такое решение
 
применяется в устройствах позиционирования печатной головки в струйных
 
применяется в устройствах позиционирования печатной головки в струйных
принтерах, или в системе управления дроссельной заглушкой в автомобильной
+
принтерах, или в системе управления дроссельной заслонкой в автомобильной
 
системе круиз-контроля (поддержание заданной скорости на трассе), или в любой
 
системе круиз-контроля (поддержание заданной скорости на трассе), или в любой
 
другой современной системе управления точным позиционированием.
 
другой современной системе управления точным позиционированием.
  
<p align=center><img src='pid/fig2.gif' border=1><br><b>Рисунок 2. Схема управления двигателем с редуктором</b></p>
+
 
 +
<center>[[Изображение:pid_fig_2.gif|Рисунок 2. Схема управления двигателем с редуктором]]<br>
 +
'''Рисунок 2. Схема управления двигателем с редуктором'''</center>
 +
 
  
 
Двигатель управляется уровнем напряжения задаваемым управляющим алгоритмом.
 
Двигатель управляется уровнем напряжения задаваемым управляющим алгоритмом.
Строка 74: Строка 80:
 
Коллекторный двигатель постоянного тока вращается с постоянной скоростью
 
Коллекторный двигатель постоянного тока вращается с постоянной скоростью
 
пропорциональной поданному напряжению. Реальный двигатель с редуктором
 
пропорциональной поданному напряжению. Реальный двигатель с редуктором
не могут мгновенное изменять скорость вращения, поэтому между подачей на
+
не может мгновенно изменять скорость вращения, поэтому между подачей на
 
двигатель напряжения и установлением соответствующей скорости существует
 
двигатель напряжения и установлением соответствующей скорости существует
 
некоторая задержка. Редуктор в этой схеме просто умножает скорость вращения
 
некоторая задержка. Редуктор в этой схеме просто умножает скорость вращения
 
двигателя на некоторую константу.
 
двигателя на некоторую константу.
  
<p align=center><img src='pid/fig3.gif' border=1><br><b>Рисунок 3. График положения вала при старте</b></p>
+
 
 +
<center>[[Изображение:pid_fig_3.gif|Рисунок 3. График положения вала при старте]]<br>
 +
'''Рисунок 3. График положения вала при старте'''</center>
 +
 
  
 
На рисунке показано поведение системы при подаче некоторого фиксированого
 
На рисунке показано поведение системы при подаче некоторого фиксированого
Строка 87: Строка 96:
 
дальше он её поддерживает.
 
дальше он её поддерживает.
  
== Безконтактная система сверхточного позиционирования ==
+
== Бесконтактная система сверхточного позиционирования ==
 
В некоторых случаях необходимо с сверхвысокой точностью управлять положением
 
В некоторых случаях необходимо с сверхвысокой точностью управлять положением
 
некоторого объекта. Систему, решающую эту задачу, можно построить из
 
некоторого объекта. Систему, решающую эту задачу, можно построить из
 
свободно перемещающейся механической платформы, пары "катушка + магнит"
 
свободно перемещающейся механической платформы, пары "катушка + магнит"
(аналогичной применяющимся в громкоговорителях) и безконтактного датчика
+
(аналогичной применяющимся в громкоговорителях) и бесконтактного датчика
 
положения. Такие решения применяются в механизмах оптической стабилизации
 
положения. Такие решения применяются в механизмах оптической стабилизации
 
в фото/видеотехнике, или в других системах, где нужно с высокой точностью
 
в фото/видеотехнике, или в других системах, где нужно с высокой точностью
 
перемещать небольшой элемент устройства.
 
перемещать небольшой элемент устройства.
  
<p align=center><img src='pid/fig4.gif' border=1><br><b>Рисунок 4. Безконтактная система сверхточного позиционирования</b></p>
+
 
 +
<center>[[Изображение:pid_fig_4.gif|Рисунок 4. Бесконтактная система сверхточного позиционирования]]<br>
 +
'''Рисунок 4. Бесконтактная система сверхточного позиционирования'''</center>
 +
 
  
 
Программное обеспечение управляет подачей тока на обмотки катушки, который
 
Программное обеспечение управляет подачей тока на обмотки катушки, который
 
создает магнитное поле соответствующей плотности и направления, которое
 
создает магнитное поле соответствующей плотности и направления, которое
 
втягивает или выталкивает магнит вместе с платформой, на которой он закреплен.
 
втягивает или выталкивает магнит вместе с платформой, на которой он закреплен.
Обратную связь по положению платформы обеспечивает безконтактный датчик.
+
Обратную связь по положению платформы обеспечивает бесконтактный датчик.
  
 
При таком устройстве сила, прикладываемая к магниту не зависит от положения
 
При таком устройстве сила, прикладываемая к магниту не зависит от положения
Строка 108: Строка 120:
 
платформа становится очень неустойчивой, что затрудняет задачу управления.
 
платформа становится очень неустойчивой, что затрудняет задачу управления.
 
В добавок к этом нам окажется необходим усилитель с большим выходным током и
 
В добавок к этом нам окажется необходим усилитель с большим выходным током и
высокоточный безконтактный датчик, что тоже может создать дополнительные
+
высокоточный бесконтактный датчик, что тоже может создать дополнительные
 
трудности в проекте. Создание качественной и надежной системы такого типа
 
трудности в проекте. Создание качественной и надежной системы такого типа
 
достаточно проблемно без применения высокоточного оборудования и тщательного
 
достаточно проблемно без применения высокоточного оборудования и тщательного
Строка 120: Строка 132:
 
парабола:
 
парабола:
  
<p align=center><img src='pid/fig5.gif' border=1><br><b>Рисунок 5. График движения при фиксированном воздействии</b></p>
+
 
 +
<center>[[Изображение:pid_fig_5.gif|Рисунок 5. График движения при фиксированном воздействии]]<br>
 +
'''Рисунок 5. График движения при фиксированном воздействии'''</center>
 +
 
  
 
Как мы увидим позже - такое поведение платформы создаст дополнительные проблемы,
 
Как мы увидим позже - такое поведение платформы создаст дополнительные проблемы,
Строка 129: Строка 144:
 
В этом примере вместо двигателя мы будем использовать нагреватель.
 
В этом примере вместо двигателя мы будем использовать нагреватель.
  
<p align=center><img src='pid/fig6.gif' border=1><br><b>Рисунок 6. Типичная термосистема</b></p>
 
  
Котел снабжен электрическим нагревателем, and the temperature of its contents is sensed by a temperature-sensing device.  
+
<center>[[Изображение:pid_fig_6.gif|Рисунок 6. Типичная термосистема]]<br>
 +
'''Рисунок 6. Типичная термосистема'''</center>
 +
 
 +
 
 +
Котел снабжен электрическим нагревателем, температура содержимого котла отслеживается с помощью соответствующего датчика температуры.
 +
 
 +
Вообще, математические модели термосистем достаточно сложны, однако, в нашем примере мы примем значительно упрощенную модель поведения такой системы. В той части случаев, когда вам не нужно получить выдающихся результатов обычно можно пользоваться менее точными моделями.
 +
 
 +
 
 +
<center>[[Изображение:pid_fig_7.gif|Рисунок 7. График поведения термосистемы при нагреве котла]]<br>
 +
'''Рисунок 7. График поведения термосистемы при нагреве котла'''</center>
  
Thermal systems tend to have very complex responses. I'm going to ignore quite a bit of detail and give a very approximate model. Unless your performance requirements are severe, an accurate model isn't necessary.
 
  
Figure 7 shows the step response of the system to a change in Vd. I've used time constants of t1 = 0.1s and t2 = 0.3s. The response tends to settle out to a constant temperature for a given drive, but it can take a great deal of time doing it. Also, without lots of insulation, thermal systems tend to be very sensitive to outside effects. This effect is not shown in the figure, but we'll be investigating it later in the article.  
+
Рисунок 7 показывает зависимость поведения системы от изменения Vd. Как видно в итоге система приходит к требуемому состоянию, но это занимает очень много времени. Кроме того, без значительной теплоизоляции термосистемы очень чуствительны к внешнему воздействию. Этот эффект не показан в приведенном примере, но мы в этой статье позже рассмотрим его подробней.
  
== Controllers ==
+
= Элементы контроллера =
The elements of a PID controller presented here either take their input from the measured plant output or from the error signal, which is the difference between the plant output and the system command. I'm going to write the control code using floating point to keep implementation details out of the discussion. It's up to you to adapt this if you are going to implement your controller with integer or other fixed-point arithmetic.  
+
Элементы представляемого здесь ПИД-контроллера получают вход либо с датчика состояния управляемой системы, либо с датчика отклонения состояния системы от требуемого. Я буду писать код управляющего контроллера используя арифметику с плавающей точкой, чтобы не отвлекаться в этой статье на вопросы технической реализации, если вам нужно - вы можете легко адаптировать все приведенные здесь примеры к арифметике с фиксированной точкой.
  
I'm going to assume a function call as shown below. As the discussion evolves, you'll see how the data structure and the internals of the function shapes up.  
+
Я буду предполагать, что всё функция управления будет определена нижеуказанным способом. По мере продвижения по тексту статьи вы увидите, как будет вырисовываться содержимое передаваемой структуры данных и внутренности функции.
  
 
<source lang="c">
 
<source lang="c">
Строка 152: Строка 175:
 
</source>
 
</source>
  
The reason I pass the error to the PID update routine instead of passing the command is that sometimes you want to play tricks with the error. Leaving out the error calculation in the main code makes the application of the PID more universal. This function will get used like this:  
+
Причина по которой я передаю в процедуру управления отклонение от целевого состояния, а не состояние системы заключается в том, что иногда нам будет полезно как-то "поиграть" с этим параметром (речь идет о том, что регулятор не сам рассчитывает отклонение error, а оно передается извне, так как может быть вычеслено не простой разностью, а иначе - примечание переводчика). Поэтому оставление рассчета отклонения в основном коде, вне нашей функции, делает нашу функцию более универсальной. В коде эта функция может быть использована, например, так:
  
 
<source lang="c">
 
<source lang="c">
Строка 158: Строка 181:
 
   .
 
   .
 
   position = ReadPlantADC();
 
   position = ReadPlantADC();
   drive = UpdatePID(&plantPID,  
+
   drive = UpdatePID(&plantPID, plantCommand - position, position);
    plantCommand - position,  
 
    position);
 
 
   DrivePlantDAC(drive);
 
   DrivePlantDAC(drive);
 
   .
 
   .
Строка 166: Строка 187:
 
</source>
 
</source>
  
 
+
== Пропорциональное управление ==
== Proportional ==
+
Пропорциональное управление является самым легким в реализации и наиболее часто используется в управляющих циклах. В этом режиме контроллер просто берет отклонение, умножает его на константу и выдает его в качестве управляющего воздействия. Пропорциональный компонент в контроллере рассчитывается кодом следующего вида:  
Proportional control is the easiest feedback control to implement, and simple proportional control is probably the most common kind of control loop. A proportional controller is just the error signal multiplied by a constant and fed out to the drive. The proportional term gets calculated with the following code:  
 
  
 
<source lang="c">
 
<source lang="c">
Строка 182: Строка 202:
 
</source>  
 
</source>  
  
Figure 8 shows what happens when you add proportional feedback to the motor and gear system. For small gains (kp = 1) the motor goes to the correct target, but it does so quite slowly. Increasing the gain (kp = 2) speeds up the response to a point. Beyond that point (kp = 5, kp = 10) the motor starts out faster, but it overshoots the target. In the end the system doesn't settle out any quicker than it would have with lower gain, but there is more overshoot. If we kept increasing the gain we would eventually reach a point where the system just oscillated around the target and never settled out-the system would be unstable.  
+
Рисунок 8 показывает что происходит, когда пропорциональное управление применяется к системе двигателя с редуктором.
 +
 
 +
 
 +
<center>[[Изображение:pid_fig_8.gif|Рисунок 8. Пропорциональное управление двигателем с редуктором]]<br>
 +
'''Рисунок 8. Пропорциональное управление двигателем с редуктором'''</center>
 +
 
 +
 
 +
Для малого значения коэффициента (pGain = 1) двигатель приходит к нужному положению, но достаточно медленно. Увеличение коэффициента (pGain = 2) приводит к более быстрой реакции системы. Однако если дальше увеличивать коэффициент (pGain = 5, pGain = 10), то двигатель конечно более быстро достигает требуемого положения, но дальше идёт "перелёт" (общепринятый термин которым обозначается этот эффект в [[ТАУ]] - "[[Перерегулирование]]", примечание переводчика), из-за чего система не приходит к требуемому положению быстрее, чем при меньших коэффициентах. Если мы продолжим увеличивать коэффициент, то мы достигнем ситуации, когда система станет бесконечно осциллировать (колебаться) вокруг заданной точки и никогда не придет в нужное состояние.
 +
 
 +
Система двигателя с редуктором "перелетает" необходимое положение при больших коэффициентах из-за задержки с реакцией на управляющее воздействие. Если вы вернетесь к рисунку 2, то вы увидите, что двигатель не сразу начинает вращаться при подаче на него управляющего сигнала. Эта задержка, плюс задержка обратной связи по датчику - вот что приводит к "перелёту" через требуемое положение на рисунке 8 (возможно более понятным будет следующее объяснение: перерегулирование связано с инерцией мотора и редуктора - прим. переводчика).
 +
 
  
The motor and gear start to overshoot with high gains because of the delay in the motor response. If you look back at Figure 2, you can see that the motor position doesn't start ramping up immediately. This delay, plus high feedback gain, is what causes the overshoot seen in Figure 8. Figure 9 shows the response of the precision actuator with proportional feedback only. Proportional control alone obviously doesn't help this system. There is so much delay in the plant that no matter how low the gain is, the system will oscillate. As the gain is increased, the frequency of the output will increase but the system just won't settle.
+
<center>[[Изображение:pid_fig_9.gif|Рисунок 9. Пропорциональное управление системой сверхточного позиционирования]]<br>
 +
'''Рисунок 9. Пропорциональное управление системой сверхточного позиционирования'''</center>
  
Figure 10 shows what happens when you use pure proportional feedback with the temperature controller. I'm showing the system response with a disturbance due to a change in ambient temperature at t = 2s. Even without the disturbance you can see that proportional control doesn't get the temperature to the desired setting. Increasing the gain helps, but even with kp = 10 the output is still below target, and you are starting to see a strong overshoot that continues to travel back and forth (this is called ringing).
 
  
As the previous examples show, a proportional controller alone can be useful for some things, but it doesn't always help. Plants that have too much delay, like the precision actuator, can't be stabilized with proportional control. Some plants, like the temperature controller, cannot be brought to the desired set point. Plants like the motor and gear combination may work, but they may need to be driven faster than is possible with proportional control alone. To solve these control problems you need to add integral or differential control or both.  
+
Рисунок 9 показывает как действует пропорциональное управление на систему сверхточного поцизионирования. Как видно этот метод управления в чистом виде вообще не помогает в случае этой задачи. Система обладает настолько большой задержкой восприятия управляющего воздействия, что неважно насколько малый коэффициент вы выберите - система всё равно будет осциллировать. С ростом коэффициента просто увеличивается частота колебаний, но система не приходит в требуемое состояние.  
  
== Integral ==
 
Integral control is used to add long-term precision to a control loop. It is almost always used in conjunction with proportional control.
 
  
The code to implement an integrator is shown below. The integrator state, iState is the sum of all the preceding inputs. The parameters iMin and iMax are the minimum and maximum allowable integrator state values.  
+
<center>[[Изображение:pid_fig_10.gif|Рисунок 10. Пропорциональное управление термосистемой]]<br>
 +
'''Рисунок 10. Пропорциональное управление термосистемой'''</center>
 +
 
 +
 
 +
Рисунок 10 показывает что происходит, когда вы строите контроллер температуры на основе метода пропорционального управления. Кроме всего прочего на графиках я показал реакцию системы на внешнее воздействие в виде повышения температуры окружающей среды в момент времени t=2с. Однако видно, что независимо от этого воздействия пропорциональное управление не позволяет установить желаемую температуру. Увеличение коэффициента помогает, но даже при pGain=10 температура котла остается ниже требуемой, и вы начинаете наблюдать сильные "перелёты" через требуемую величину, которые продолжаются без конца (это называется "ringing").
 +
 
 +
Как видно из приведенных выше примеров пропорцинальное управление даже в одиночку может быть полезно для ряда задач, однако так происходит не всегда. Системы в которых существует значительная задержка реакции на управляющее воздействие, такие как система сверхточного позиционирования, не могут быть стабилизированы с помощью этого метода. Некоторые системы, типа рассмотренного контроллера температуры вообще не достигают требуемого положения. Системы типа двигателя с редуктором вполне работоспособы под таким управлением, но может потребоваться меньшее время вывода системы на требуемое состояние. Чтобы решить все эти проблемы нам потребуется добавить интегральную или дифференциальную составляющу, или обе одновременно.
 +
 
 +
== Интегральное управление ==
 +
Интегральное управление используется, чтобы добавить "долгосрочной точности" управляющему циклу. Оно практически всегда используется совместно с пропорциональным управлением.
 +
 
 +
Реализующий интегратор код приведен ниже. Состояние интегратора iState является суммой всех предыдущих входов. Параметры iMin и iMax это минимально и максимально разрешенные значения состояния интегратора.  
  
 
<source lang="c">
 
<source lang="c">
Строка 204: Строка 243:
 
   pid->iState += error;
 
   pid->iState += error;
 
   if (pid->iState > pid->iMax)  
 
   if (pid->iState > pid->iMax)  
     pid->iState =
+
     pid->iState =  pid->iMax;
  pid->iMax;
+
   else if (pid->iState <  pid->iMin)  
   else if (pid->iState  
 
<
 
  pid->
 
    iMin)  
 
 
     pid->iState = pid->iMin;
 
     pid->iState = pid->iMin;
 
   iTerm = pid->iGain * iState;   
 
   iTerm = pid->iGain * iState;   
Строка 218: Строка 253:
 
</source>
 
</source>
  
Integral control by itself usually decreases stability, or destroys it altogether. Figure 11 shows the motor and gear with pure integral control (pGain = 0). The system doesn't settle. Like the precision actuator with proportional control, the motor and gear system with integral control alone will oscillate with bigger and bigger swings until something hits a limit. (Hopefully the limit isn't breakable.)
+
Интегральное управление само по себе обычно снижает стабильность системы или вообще делает систему нестабильной.
  
Figure 12 shows the temperature control system with pure integral control. This system takes a lot longer to settle out than the same plant with proportional control (see Figure 10), but notice that when it does settle out, it settles out to the target value-even with the disturbance added in. If your problem at hand doesn't require fast settling, this might be a workable system.
 
  
Figure 12 shows why we use an integral term. The integrator state "remembers" all that has gone on before, which is what allows the controller to cancel out any long term errors in the output. This same memory also contributes to instability-the controller is always responding too late, after the plant has gotten up speed. To stabilize the two previous systems, you need a little bit of their present value, which you get from a proportional term.  
+
<center>[[Изображение:pid_fig_11.gif|Рисунок 11. Интегральное управление двигателем с редуктором]]<br>
 +
'''Рисунок 11. Интегральное управление двигателем с редуктором'''</center>
  
Figure 13 shows the motor and gear with proportional and integral (PI) control. Compare this with Figures 8 and 11. The position takes longer to settle out than the system with pure proportional control, but it will not settle to the wrong spot.
 
  
Figure 14 shows what happens when you use PI control on the heater system. The heater still settles out to the exact target temperature, as with pure integral control (see Figure 12), but with PI control, it settles out two to three times faster. This figure shows operation pretty close to the limit of the speed attainable using PI control with this plant.  
+
На рисунке 11 приведены результаты управления двигателя с редуктором контроллером реализующим чисто интегральное управление (pGain = 0). Как видно система вообще не стабилизируется. Как и в случае с системой сверхточного позиционирования с пропорциональным управлением у двигателя с редуктором под чистым интегральным управлением колебания будут становиться только больше и больше, пока это во что-нибудь не упрётся (хорошо если это будет программное ограничение, а не разрушение механической системы).  
  
Before we leave the discussion of integrators, there are two more things I need to point out. First, since you are adding up the error over time, the sampling time that you are running becomes important. Second, you need to pay attention to the range of your integrator to avoid windup.
 
  
The rate that the integrator state changes is equal to the average error multiplied by the integrator gain multiplied by the sampling rate. Because the integrator tends to smooth things out over the long term you can get away with a somewhat uneven sampling rate, but it needs to average out to a constant value. At worst, your sampling rate should vary by no more than ?ver any 10-sample interval. You can even get away with missing a few samples as long as your average sample rate stays within bounds. Nonetheless, for a PI controller I prefer to have a system where each sample falls within ? ? the correct sample time, and a long-term average rate that is right on the button.  
+
<center>[[Изображение:pid_fig_12.gif|Рисунок 12. Интегральное управление термосистемой]]<br>
 +
'''Рисунок 12. Интегральное управление термосистемой'''</center>
  
If you have a controller that needs to push the plant hard, your controller output will spend significant amounts of time outside the bounds of what your drive can actually accept. This condition is called saturation. If you use a PI controller, then all the time spent in saturation can cause the integrator state to grow (wind up) to very large values. When the plant reaches the target, the integrator value is still very large, so the plant drives beyond the target while the integrator unwinds and the process reverses. This situation can get so bad that the system never settles out, but just slowly oscillates around the target position.
 
  
Figure 15 illustrates the effect of integrator windup. I used the motor/controller of Figure 13, and limited the motor drive to ?Not only is controller output much greater than the drive available to the motor, but the motor shows severe overshoot. The motor actually reaches its target at around five seconds, but it doesn't reverse direction until eight seconds, and doesn't settle out until 15 seconds have gone by.  
+
Рисунок 12 показывает как себя ведёт термосистема под чистым интегральным управлением. Как видно время стабилизации системы стало значительно больше, чем при пропорциональном управлении (см. рисунок 10), но зато теперь система стабилизируется при требуемом состоянии, даже при некоторых внешних воздействиях. Если вам не требуется малое время выхода на требуемое состояние - этот метод вам вполне подойдет.
  
The easiest and most direct way to deal with integrator windup is to limit the integrator state, as I showed in my previous code example. Figure 16 shows what happens when you take the system in Figure 15 and limit the integrator term to the available drive output. The controller output is still large (because of the proportional term), but the integrator doesn't wind up very far and the system starts settling out at five seconds, and finishes at around six seconds.  
+
Из последнего графика ясно, как используется интегральный компонент управления. В состоянии интегратора "запоминается" всё что произошло в предыдущие моменты времени и это позволяет контроллеру избегать "долгосрочных ошибок", т.е. поведения при котором мы видим что не достигли требуемого положения, а никакого управляющего воздействия не вносим. Однако у этой медали есть и обратная сторона - контроллер всегда реагирует с некоторым запозданием, когда система уже длительное время получает совершенно неправильные команды. Чтобы стабилизировать предыдущие две системы нам потребуется добавить в принятие решения немного информации о текущем состоянии системы, которое мы имеем в пропорциональной компоненте.
  
Note that with the code example above you must scale iMin and iMax whenever you change the integrator gain. Usually you can just set the integrator minimum and maximum so that the integrator output matches the drive minimum and maximum. If you know your disturbances will be small and you want quicker settling, you can limit the integrator further.
 
  
== Differential ==
+
<center>[[Изображение:pid_fig_13.gif|Рисунок 13. Пропорционально-интегральное управление двигателем с редуктором]]<br>
 +
'''Рисунок 13. Пропорционально-интегральное управление двигателем с редуктором'''</center>
  
I didn't even show the precision actuator in the previous section. This is because the precision actuator cannot be stabilized with PI control. In general, if you can't stabilize a plant with proportional control, you can't stabilize it with PI control. We know that proportional control deals with the present behavior of the plant, and that integral control deals with the past behavior of the plant. If we had some element that predicts the plant behavior then this might be used to stabilize the plant. A differentiator will do the trick.
 
  
The code below shows the differential term of a PID controller. I prefer to use the actual plant position rather than the error because this makes for smoother transitions when the command value changes. The differential term itself is the last value of the position minus the current value of the position. This gives you a rough estimate of the velocity (delta position/sample time), which predicts where the position will be in a while.  
+
Рисунок 13 показывает как ведёт себя двигатель с редуктором под пропорционально-интегральном (ПИ) управлением. Сравните это с рисунками 8 и 11. Время на стабилизацию увеличилось по сравнению с чисто пропорциональной схемой, но стабилизация идёт в правильное положение, которое и требовалось.
 +
 
 +
 
 +
<center>[[Изображение:pid_fig_14.gif|Рисунок 14. Пропорционально-интегральное управление термосистемой]]<br>
 +
'''Рисунок 14. Пропорционально-интегральное управление термосистемой'''</center>
 +
 
 +
 
 +
Рисунок 14 показывает, что будет происходить, если применить к термосистеме ПИ-управление. Котёл так же придёт к требуемой температуре, как и в случае чистого интегрального управления (см. рисунок 12), но с ПИ-управлением произойдёт это в два-три раза быстрее. График показывает время стабилизации до требуемой температуры близкое к возможному пределу достигаемому с помощью ПИ-регуляторов на такого типа системах.
 +
 
 +
Перед тем, как мы закончим рассматривать интеграторы, я хотел бы указать на следующие два важных момента. Во-первых, так как вы добавили интеграцию отклонения по времени, становится важным частота с которой вы запускаете цикл управления. Во-вторых нужно быть внимательным к допустимому диапазону значений интегратора, чтобы избежать "вылетания".
 +
 
 +
Скорость изменения состояния интегратора равна среднему отклонению умноженному на коэффициент интегратора умноженному на частоту цикла управления. Так как интегратор сглаживает замеры отклонения по времени, допустимы некотороые отклонения от нормальной частоты вызова управляющего цикла, но в любом случае эти отклонения должны быть чем-то ограничены. В худшем случае рекомендуется, чтобы частота вызова цикла управления не отклонялась более чем на 20% на каждом участке из 10 вызовов. Иногда лучше пропустить часть значений, чтобы сохранить требуемую частоту вызова управляющего цикла. Однако несмотря на это я для ПИ-контроллера предпочитаю системы, в которых точность вызова цикла управления лежит в пределах 1-5%.
 +
 
 +
Если вашему контроллеру требуется значительно изменить состояние управлямой системы, которе не может быть произведено за короткое время - тогда всё это время отклонение будет велико и это огромное отклонение накопится в состоянии интегратора, что вызовет в свою очередь его "вылетание". Когда система достигнет своего целевого положения в интеграторе будет находится огромное накопленное отклонение, которое вызовете дальнейший значительный "перелёт" через требуемое положение и система так же значительное время будет продолжать двигаться уже за пределами целевого значения. В лучшем случае это будут затухающие колебания, в худшем - система никогда не стабилизируется и будет осциллировать с огромной амплитудой.
 +
 
 +
 
 +
<center>[[Изображение:pid_fig_15.gif|Рисунок 15. "Вылетание" пропорционально-интегрального управления]]<br>
 +
'''Рисунок 15. "Вылетание" пропорционально-интегрального управления'''</center>
 +
 
 +
 
 +
Рисунок 15 показывает эффект "вылетания" интегратора. Я использовал двигатель с редуктором и контроллер с примера рисунка 13 и ограничил скорость мотора до 0.2. Не только контроллер выдаёт управляющий сигнал, который не может быть реализован двигателем, но и вся система показывает значительный "перелёт". Реально требуемое положение достигается за 5 секунд, он обратный сигнал не подаётся еще в течение 3 секунд, поскольку в интеграторе еще осталось накопленное отклонение, указывающее на то, что надо продолжать двигаться вперёд, и проходит порядка 15 секунд, пока система не стабилизируется.
 +
 
 +
<center>[[Изображение:pid_fig_16.gif|Рисунок 16. Ограничение "вылетания" пропорционально-интегрального управления]]<br>
 +
'''Рисунок 16. Ограничение "вылетания" пропорционально-интегрального управления'''</center>
 +
 
 +
Простейший и самый прямой способ борьбы с "вылетанием" интегратора это установка ограничений на его накопленное значение, как я показал в примере кодирования такого интегратора. Рисунок 16 показывает что происходит когда в приведенных выше условиях на интегратор наложены ограничения в размере максимально допустимого управляющего воздействия на двигатель (iMin=-0.2, iMax=0.2). Выход контроллера всё еще больше допустимого для двигателя (из-за пропорциональной части), но теперь интегратор "вылетает" значительно меньше и система начинает стабилизироваться на 5-й секунде и заканчивает примерно на 6-й секунде.
 +
 
 +
Обратите внимание, что в примерах указанных выше надо масштабировать iMin и iMax, если вы изменяете коэффициент интегратора (iGain). Обычно достаточно установить ограничения значиний минимума и максимума интегратора такие, чтобы интегрирующий компонент управления выдавал соответственно минимальное и максимальное управляющее воздействие. Если вы знаете, что вам потребуется еще более малые интегрирующий компонент - вы можете еще больше ограничить значения интегратора.
 +
 
 +
== Дифференциальное управление ==
 +
 
 +
Я не стал рассматривать сверхточное позиционирование в предыдущем разделе по той причине, что эту систему нельзя стабилизировать с помощью ПИ-управления. В общем если вы не можете стабилизировать какую-то систему с помощью пропорционального управления из-за слишком большой задержки воздействия на систему, тогда при использовании ПИ-управления увеличивающего эту задержку всё станет только хуже.
 +
 
 +
Мы знаем что пропорциональное управление соответствует использованию "сиюминутной" информации о системе, интегральное управление использует информацию о "прошлом" системы. Если бы мы получили элемент который соответствует использованию "прогнозной" информации о системе, мы смогли бы попробовать использовать его для стабилизации нашей платформы в системе сверхточного позиционирования. И таким искомым элементом является дифференциатор.
 +
 
 +
Код приведенный ниже показывает, как рассчитывается дифференциальная компонента ПИД-контроллера. Я предпочитаю использовать текущее состояние системы, а не отклонение от требуемого положения для мягкости управления при резкой смене целевого состояния системы. Дифференциальная компонента сама по себе представляет разность между предыдущим состоянием системы и текущим её состоянием. Это даёт нам возможность оценить скорость изменения состояния системы и предугадать в каком состоянии окажется система в следующий момент времени.
  
 
<source lang="c">
 
<source lang="c">
Строка 258: Строка 325:
 
</source>
 
</source>
  
With differential control you can stabilize the precision actuator system. Figure 17 shows the response of the precision actuator system with proportional and derivative (PD) control. This system settles in less than 1/2 of a second, compared to multiple seconds for the other systems. Figure 18 shows the heating system with PID control. You can see the performance improvement to be had by using full PID control with this plant.  
+
При использовании дифференциальной компоненты становится возможным стабилизация платформы в системе сверхточного позиционирования.
  
Differential control is very powerful, but it is also the most problematic of the control types presented here. The three problems that you are most likely going to experience are sampling irregularities, noise, and high frequency oscillations. When I presented the code for a differential element I mentioned that the output is proportional to the position change divided by the sample time. If the position is changing at a constant rate but your sample time varies from sample to sample, you will get noise on your differential term. Since the differential gain is usually high, this noise will be amplified a great deal.
 
  
When you use differential control you need to pay close attention to even sampling. I'd say that you want the sampling interval to be consistent to within 1% of the total at all times-the closer the better. If you can't set the hardware up to enforce the sampling interval, design your software to sample with very high priority. You don't have to actually execute the controller with such rigid precision-just make sure the actual ADC conversion happens at the right time. It may be best to put all your sampling in an ISR or very high-priority task, then execute the control code in a more relaxed manner.
+
<center>[[Изображение:pid_fig_17.gif|Рисунок 17. Пропорционально-дифференциальное управление системой сверхточного позиционирования]]<br>
 +
'''Рисунок 17. Пропорционально-дифференциальное управление системой сверхточного позиционирования'''</center>
  
Differential control suffers from noise problems because noise is usually spread relatively evenly across the frequency spectrum. Control commands and plant outputs, however, usually have most of their content at lower frequencies. Proportional control passes noise through unmolested. Integral control averages its input signal, which tends to kill noise. Differential control enhances high frequency signals, so it enhances noise. Look at the differential gains that I've set on the plants above, and think of what will happen if you have noise that makes each sample a little bit different. Multiply that little bit by a differential gain of 2,000 and think of what it means.
 
  
You can low-pass filter your differential output to reduce the noise, but this can severely affect its usefulness. The theory behind how to do this and how to determine if it will work is beyond the scope of this article. Probably the best that you can do about this problem is to look at how likely you are to see any noise, how much it will cost to get quiet inputs, and how badly you need the high performance that you get from differential control. Once you've worked this out, you can avoid differential control altogether, talk your hardware folks into getting you a lower noise input, or look for a control systems expert.  
+
Рисунок 17 показывает как ведёт себя эта система под пропорционально-дифференциальным (ПД) управлением. Система стабилизируется меньше чем за 1/2 секунды по сравнению с несколькими секундами требующимися для других систем.
  
The full text of the PID controller code is shown in Listing 1 and is available at www.embedded.com/code.html.
 
  
Listing 1: PID controller code 
+
<center>[[Изображение:pid_fig_18.gif|Рисунок 18. ПИД-управление термосистемой]]<br>
 +
'''Рисунок 18. ПИД-управление термосистемой'''</center>
  
 +
 +
Рисунок 18 показывает как себя ведёт термосистема под ПИД-управлением. Как видно из графиков этот подход существенно улучшает качество управления системой.
 +
 +
Дифференциальная компонента управления очень мощная, но она же и самая проблемная из всех типов управления представленных здесь. Три проблемы с которыми придётся столкнуться при реализации этого типа управления - нерегулярность частоты сбора данных, шумы и высокочастотные колебания. Когда я представлял код для дифференциального элемента я предположил, что выход управляющего воздействия должен быть пропорционален изменению положения деленному на время между итерациями цикла управления. Если состояние системы меняется с постоянной скоростью, а время между запуском управляющей итерации варьируется, вы будете получать неверную информацию о скорости системы. Поскольку обычно время между итерациями управления достаточно мало, шумы такого сорта могут быть очень значительными и будут сильно мешать задаче управления.
 +
 +
Когда вы используете дифференциальное управление нужно обращать внимание на точность временных интервалов между итерациями управляющего цикла. Я рекомендую поддерживать точность этих интервалов в пределах 1%, однако чем точнее, тем лучше. Если вы не можете обеспечить это на аппаратном уровне - постарайтесь сделать это на уровне программного обеспечения, отдав под задачу сбора информации максимальный приоритет (не нужно с такой точностью выполнять расчеты управляющего воздействия, достаточно собирать информацию в нужные моменты времени). Один из оптимальных вариантов - поместить сбор информации о системе в прерывание, а сами расчеты ПИД-алгоритма выполнять в свободное время.
 +
 +
Дифференциальное управление страдает от шумов больше других типов управления потому что оно эти шумы усиливает, в отличие от пропорционального управления, которое просто транслирует эти шумы или интегрального, которое вообще шумы подавляет. Посмотрите на коэффициенты дифференциальной компоненыт, которые я использовал выше и представьте, что произойдёт если у вас в системе будут небольшие шумы, которые возникать при каждом получении информации о системе. Умножьте эти небольшие шумы на коэффициент 2000 и представьте как это отразится на системе.
 +
 +
Вы можете применить фильтрацию дифференциальной компоненты управления, но это существенно снизит её полезность. Теория стоящая за тем, как это делать и как опредилить - будет ли это работать останется за рамками этой вводной статьи. Возможно лучшее, что вы можете сделать с этой проблемой - оценить насколько велики у вас шумы при получении информации о состоянии системы и насколько вам надо ускорение стабилизации системы с помощью дифференциальной компоненты и исходя из этого установить коэффициент этой компоненыт (dGain). Возможно вам вообще придётся отказаться от этой компоненты или еще можно попробовать переработать электронику так, чтобы снизить шумы или попробовать применить более сложные алгоритмы управления (обратиться к экспертам по автоматизированному управлению).
 +
 +
Полный код ПИД-контроллера:
 
<source lang="c">
 
<source lang="c">
 
typedef struct
 
typedef struct
 
{
 
{
   double dState;     // Last position input
+
   double dState;             // Last position input
   double iState;     // Integrator state
+
   double iState;             // Integrator state
 
   double iMax, iMin; 
 
   double iMax, iMin; 
 
   // Maximum and minimum allowable integrator state
 
   // Maximum and minimum allowable integrator state
Строка 285: Строка 363:
 
double UpdatePID(SPid * pid, double error, double position)
 
double UpdatePID(SPid * pid, double error, double position)
 
{
 
{
   double pTerm,
+
   double pTerm, dTerm, iTerm;
dTerm, iTerm;
+
 
   pTerm = pid->pGain * error;  
+
   pTerm = pid->pGain * error;   // calculate the proportional term
  // calculate the proportional term
+
  pid->iState += error;          // calculate the integral state with appropriate limiting
// calculate the integral state with appropriate limiting
+
 
  pid->iState += error;
+
   if (pid->iState > pid->iMax)  
   if (pid->iState > pid->iMax) pid->iState = pid->iMax;
+
      pid->iState = pid->iMax;    
   else if (pid->iState  
+
   else if (pid->iState < pid->iMin)  
<
+
      pid->iState = pid->iMin;
pid->iMin) pid->iState = pid->iMin;
+
   iTerm = pid->iGain * iState;   // calculate the integral term
   iTerm = pid->iGain * iState; // calculate the integral term
 
 
   dTerm = pid->dGain * (position - pid->dState);
 
   dTerm = pid->dGain * (position - pid->dState);
 
   pid->dState = position;
 
   pid->dState = position;
   return pTerm + iTerm - dTerm;
+
   return (pTerm + iTerm - dTerm);
 
}
 
}
 
</source>
 
</source>
 
== Tuning ==
 
The nice thing about tuning a PID controller is that you don't need to have a good understanding of formal control theory to do a fairly good job of it. About 90% of the closed-loop controller applications in the world do very well indeed with a controller that is only tuned fairly well.
 
  
If you can, hook your system up to some test equipment, or write in some debug code to allow you to look at the appropriate variables. If your system is slow enough you can spit the appropriate variables out on a serial port and graph them with a spreadsheet. You want to be able to look at the drive output and the plant output. In addition, you want to be able to apply some sort of a square-wave signal to the command input of your system. It is fairly easy to write some test code that will generate a suitable test command. Once you get the setup ready, set all gains to zero. If you suspect that you will not need differential control (like the motor and gear example or the thermal system) then skip down to the section that discusses tuning the proportional gain. Otherwise start by adjusting your differential gain.  
+
= Настройка ПИД-регулятора =
 +
ПИД-регуляторы замечательны тем, что для их хорошей настройки не требуется отличного понимания формальной теории управления системами. При этом они позволяют решить около 90% всех задач управления простыми системами замкнутого цикла.
 +
 
 +
Если можете, подцепите ваш контроллер к тестовому оборудованию или напишите отладочный код, чтобы можно было видеть, что происходит внутри, если возможно - соедините контроллер с ПК по последовательному порту и выведите отладочные графики в какой-нибудь программе, например в Excel. Кроме этого вам потребуется какой-то способ ступенько-образного задания управляюшего сигнала. Вполне может подойти опять же отладочный код, который будет брать управляющий сигнал скажем с последовательного порта. Как только вы закончили все приготовления установите все коэффициенты в 0. Если вы полагаете, что вам не нужно будет дифференциальную компоненту (как в случае с двигателем или термосистемой), пропустите следующую секцию и сразу приступайте к настройке пропорциональной компоненты. Иначе начинаем с настройки коэффициента дифференциального управления.
 +
 
 +
=== Настройка дифференциальной компоненты ===
 +
 
 +
Перед настройкой дифференциального управления выставьте коэффициент пропорционального управления в какое-нибудь небольшое значение (1 или немного меньше). Посмотрите как себя ведёт система. Если она колеблется при нулевом коэффициенте дифференциальной компоненты, тогда это можно исправить увеличением этого коэффициента. При постепенном увеличении смотрите как себя ведёт система, увеличиваейте коэффициент пока не увидите возникающие из-за малых шумов системы ошибочные колебания и вылеты по этой же причине за целевые значения. Обратите внимение, что колебания от слишком большого коэффициента значительно быстрее, чем колебания от недостаточного коэффициента. Я стараюсь устанавливать коэффициент в половину или четверть от того, при котором начинаются колебания от слишком большой его величины. Убедитесь что при этом управляющий сигнал выглядит адекватным. В этот момент система реагирует на управляющее воздействие очень лениво, так что самое время настроить пропорциональный и интегральный коэффициенты.
 +
 
 +
=== Настройка пропорциональной компоненты ===
  
The way the controller is coded you cannot use differential control alone. Set your proportional gain to some small value (one or less). Check to see how the system works. If it oscillates with proportional gain you should be able to cure it with differential gain. Start with about 100 times more differential gain than proportional gain. Watch your drive signal. Now start increasing the differential gain until you see oscillation, excessive noise, or excessive (more than 50%) overshoot on the drive or plant output. Note that the oscillation from too much differential gain is much faster than the oscillation from not enough. I like to push the gain up until the system is on the verge of oscillation then back the gain off by a factor of two or four. Make sure the drive signal still looks good. At this point your system will probably be responding very sluggishly, so it's time to tune the proportional and integral gains.  
+
Если вы еще не установили коэффициент пропорциональной компоненты, назначьте ему некоторое стартовое значение (от 1 до 100). Ваша управляемая система либо покажет ужасающе медленную реакцию на команды, либо начнет колебания. Если вы видите колебания - уменьшайте коэффициент в 10 раз, пока эти колебания не прекратятся. Если вы не наблюдаете колебания, увеличивайте коэффициент в 10 раз пока не начнутся колебания или значительные "перелёты" через целевое положение. Теперь уже с коэффициентом 2 найдите такой коэффициент, что он всё еще не вызывает колебаний или "перелётов", а умноженный на 2 уже вызывает, теперь можно немного его уменьшить пока вам не понравится действие системы.  
  
If it isn't set already, set the proportional gain to a starting value between 1 and 100. Your system will probably either show terribly slow performance or it will oscillate. If you see oscillation, drop the proportional gain by factors of eight or 10 until the oscillation stops. If you don't see oscillation, increase the proportional gain by factors of eight or 10 until you start seeing oscillation or excessive overshoot. As with the differential controller, I usually tune right up to the point of too much overshoot then reduce the gain by a factor of two or four. Once you are close, fine tune the proportional gain by factors of two until you like what you see.
+
=== Настройка интегральной компоненты ===
  
Once you have your proportional gain set, start increasing integral gain. Your starting values will probably be from 0.0001 to 0.01. Here again, you want to find the range of integral gain that gives you reasonably fast performance without too much overshoot and without being too close to oscillation.  
+
И наконец мы можем приступить к настройке коэффициента интегральной компоненты, начальные значения коэффициента рекомендуется брать от 0.0001 до 0.01. Ищем нужное нам значение так же как с пропорциональным коэффициентом, так же отступая немного назад, чтобы гарантированно не получить колебания от слишком большого коэффициента.
  
== Other issues ==
+
= Замечания =
Unless you are working on a project with very critical performance parameters you can often get by with control gains that are within a factor of two of the "correct" value. This means that you can do all your "multiplies" with shifts. This can be very handy when you're working with a slow processor.  
+
== Оптимизация производительности ПИД-регулятора ==
 +
Если вы не работаете над проектом в котором критически важно получить максимальную эффективность управления, тогда вам почти всегда будет достаточно найти коэффициенты ПИД-регулятора не более чем в 2 раза отличающиеся от оптимальных. Это означает что на совсем слабых микроконтроллерах без аппаратного умножителя вы сможете использовать побитовый сдвиг вместо умножения.
  
== Sampling rate ==
+
== Частота сбора данных и выполнения цикла управления ==
So far I've only talked about sample rates in terms of how consistent they need to be, but I haven't told you how to decide ahead of time what the sample rate needs to be. If your sampling rate is too low you may not be able to achieve the performance you want, because of the added delay of the sampling. If your sampling rate is too high you will create problems with noise in your differentiator and overflow in your integrator.  
+
Мы уже обсуждали как важен этот параметр, но до этого мы обсуждали как важно чтобы он был стабильным, однако ничего не говорили о том, каким он должен быть. Если она слишком маленькая, тогда вы не сможете получить нужную вам эффективность и более того можете получить систему, которую невозможно стабилизировать. Если же вы возьмете слишком большую частоту - вы получите серьезные шумы в дифференциальное компоненте и переполнение состояния интегратора.  
  
The rule of thumb for digital control systems is that the sample time should be between 1/10th and 1/100th of the desired system settling time. System settling time is the amount of time from the moment the drive comes out of saturation until the control system has effectively settled out. If you look at Figure 16, the controller comes out of saturation at about 5.2s, and has settled out at around 6.2s. If you can live with the one second settling time you could get away with a sampling rate as low as 10Hz.  
+
Есть простое правило для цифровых управляющих систем, которое гласит, что продолжительность итерации управляющего цикла должна быть между 1/10 и 1/100 желаемого времени стабилизации системы в новом положении. Если вы посмотрите на рисунок 16, там это время порядка 6.. Если время принятия системой нового положения нужно 1с, тогда вас может устроить частота даже такая низкая, как 10Гц.
  
You should treat the sampling rate as a flexible quantity. Anything that might make the control problem more difficult would indicate that you should raise the sampling rate. Factors such as having a difficult plant to control, or needing differential control, or needing very precise control would all indicate raising the sampling rate. If you have a very easy control problem you could get away with lowering the sampling rate somewhat (I would hesitate to lengthen the sample time to more than one-fifth of the desired settling time). If you aren't using a differentiator and you are careful about using enough bits in your integrator you can get away with sampling rates 1,000 times faster than the intended settling time.  
+
Вообще часто ряд проблем с управлением снимается, если вы повышаете эту частоту, может оказаться так, что в этом случае даже можно будет отказаться от дифференциальной компоненты управления. Так что если у вас нет дифференциальной компоненты и достаточно длины числа под состояние интегратора - делайте частоту хоть в 1/1000 от желаемого времени стабилизации системы.
  
== Exert control ==
+
= Послесловие =
This covers the basics of implementing and tuning PID controllers. With this information, you should be able to attack the next control problem that comes your way and get it under control.  
+
Статья преподносит основы разработки и настройки ПИД-контроллеров. Используя эту информацию вы сможете взяться за задачу управления и реализовать необходимую для неё систему управления.
  
Tim Wescott has a master's degree in electrical engineering and has been working in industry for more than a decade. His experience has included a number of control loops closed in software using 8- to 32-bit microprocessors, DSPs, assembly language, C, and C++. He is currently involved in control systems design at FLIR Systems where he specifies mechanical, electrical, and software requirements and does electrical and software design. You can contact him at tim@wescottdesign.com.
+
Tim Wescott является магистром электро инжинерии и более 10 лет проработал в это индустрии. Его опыт включает множество систем управления замкнутого цикла реализованных на 8-32 битных контроллерах, сигнальных процессорах, как на ассемблере, так и на C\C++. На момент написания статьи он участвовал в разработке систем управления компании FLIR Systems в которой он определял требования к механической, электрической и программной части. Вы можете связаться с ним по адресу tim@wescottdesign.com.

Текущая версия на 05:28, 11 апреля 2013

(перевод статьи "PID Without a PhD")


Исходная статья: [http://www.embedded.com/2000/0010/0010feat3.htm]

Автор: Tim Wescott

Перевод: © Ботов Антон aka =DeaD=, 2008

Эксклюзивно для www.roboforum.ru
копирование на другие ресурсы и публикация перевода
без разрешения его автора запрещены

Введение

Алгоритмы ПИД (PID = proportional, integral, derivative) управления не так сложны, как кажется некоторым с первого взгляда. В этой статье мы попробуем рассказать как они работают на нескольких простых примерах. Изучив эти примеры, вы сможете самостоятельно применять эти алгоритмы в своих проектах.

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

ПИД управление

PID=ПИД означает "proportional=пропорциональный", "integral=интегральный", "derivative=дифференциальный". Эти три термина описывают простейшие элементы ПИД-контроллера. Каждый из этих элементов выполняет свою задачу и оказывает свое специфическое воздействие на функционирование системы.

В типичном ПИД-контроллере эти элементы оперируют комбинацией как входных управляющих параметров, так и сигналами обратной связи с управляемого устройства (объекта управления, далее просто - устройство). Выходы этих элементов складываются между собой и формируют управляющий сигнал для устройства.


Рисунок 1. Простейший ПИД-контроллер
Рисунок 1. Простейший ПИД-контроллер


В приведенном на рисунке примере дифференциальный элемент оперирует только сигналом обратной связи от устройства. Этот сигнал вычитается из сигнала управляющего воздействия и полученная разность считается ошибкой управления. Эта разность подается на вход пропорциональному и интегральным элементам, получающиеся на их выходах сигналы складываются между собой и формируют управляющий сигнал. Я не описывал принцип работы этих элементов - мы вернемся к этому чуть позже. На схеме я указал альтернативный вариант включения пропорционального элемента (пунктиром) - оптимальную схему включения можно выбрать только на конкретном устройстве и задаче управления.

Объекты управления

Чтобы в обсуждении темы не уходить далеко от реальных задач нам понадобятся типичные объекты управления. В этой статье я буду использовать для примеров следующие три устройства, и покажу как на них будут работать те или иные алгоритмы ПИД-управления:

  • Двигатель с редуктором;
  • Бесконтактная система сверхточного позиционирования;
  • Термосистема;

Каждая из этих систем имеет различные характеристики и требует различных подходов в управлении для достижения оптимальных результатов.

Двигатель с редуктором

Первым рассмотрим двигатель с редуктором, на выходном валу которого установлен потенциометр или любой другой датчик положения вала. Такое решение применяется в устройствах позиционирования печатной головки в струйных принтерах, или в системе управления дроссельной заслонкой в автомобильной системе круиз-контроля (поддержание заданной скорости на трассе), или в любой другой современной системе управления точным позиционированием.


Рисунок 2. Схема управления двигателем с редуктором
Рисунок 2. Схема управления двигателем с редуктором


Двигатель управляется уровнем напряжения задаваемым управляющим алгоритмом. Усилие через редуктор поступает на его выходной вал и приводит в действие некоторый механизм. На выходном валу находится потенциометр, через который алгоритм управления получает информацию о положении выходного вала.

Коллекторный двигатель постоянного тока вращается с постоянной скоростью пропорциональной поданному напряжению. Реальный двигатель с редуктором не может мгновенно изменять скорость вращения, поэтому между подачей на двигатель напряжения и установлением соответствующей скорости существует некоторая задержка. Редуктор в этой схеме просто умножает скорость вращения двигателя на некоторую константу.


Рисунок 3. График положения вала при старте
Рисунок 3. График положения вала при старте


На рисунке показано поведение системы при подаче некоторого фиксированого напряжения в момент времени t = 0 (мы рассматриваем общие примеры, поэтому примем напряжение в 1). Из графика видно, что мотор не сразу набирает соответствующую напряжению скорость, но после того, как набрал (при t=0.2), дальше он её поддерживает.

Бесконтактная система сверхточного позиционирования

В некоторых случаях необходимо с сверхвысокой точностью управлять положением некоторого объекта. Систему, решающую эту задачу, можно построить из свободно перемещающейся механической платформы, пары "катушка + магнит" (аналогичной применяющимся в громкоговорителях) и бесконтактного датчика положения. Такие решения применяются в механизмах оптической стабилизации в фото/видеотехнике, или в других системах, где нужно с высокой точностью перемещать небольшой элемент устройства.


Рисунок 4. Бесконтактная система сверхточного позиционирования
Рисунок 4. Бесконтактная система сверхточного позиционирования


Программное обеспечение управляет подачей тока на обмотки катушки, который создает магнитное поле соответствующей плотности и направления, которое втягивает или выталкивает магнит вместе с платформой, на которой он закреплен. Обратную связь по положению платформы обеспечивает бесконтактный датчик.

При таком устройстве сила, прикладываемая к магниту не зависит от положения платформы и её движения. Плюс этого в том, что платформа ни от каких других воздействий не движется относительно всего устройства, а минус в том, что платформа становится очень неустойчивой, что затрудняет задачу управления. В добавок к этом нам окажется необходим усилитель с большим выходным током и высокоточный бесконтактный датчик, что тоже может создать дополнительные трудности в проекте. Создание качественной и надежной системы такого типа достаточно проблемно без применения высокоточного оборудования и тщательного проектирования.

Уравнения, описывающие движение такой системы достоточно просты. Сила, действующая на платформу пропорциональна только уровню напряженности магнитного поля, а значит силе тока, протекающего через катушку. Таким образом ускорение платформы прямо пропорционально управляющему воздействию. График движения платформы при подаче фиксированного ненулевого управляющего воздействия это парабола:


Рисунок 5. График движения при фиксированном воздействии
Рисунок 5. График движения при фиксированном воздействии


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

Термосистема

В этом примере вместо двигателя мы будем использовать нагреватель.


Рисунок 6. Типичная термосистема
Рисунок 6. Типичная термосистема


Котел снабжен электрическим нагревателем, температура содержимого котла отслеживается с помощью соответствующего датчика температуры.

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


Рисунок 7. График поведения термосистемы при нагреве котла
Рисунок 7. График поведения термосистемы при нагреве котла


Рисунок 7 показывает зависимость поведения системы от изменения Vd. Как видно в итоге система приходит к требуемому состоянию, но это занимает очень много времени. Кроме того, без значительной теплоизоляции термосистемы очень чуствительны к внешнему воздействию. Этот эффект не показан в приведенном примере, но мы в этой статье позже рассмотрим его подробней.

Элементы контроллера

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

Я буду предполагать, что всё функция управления будет определена нижеуказанным способом. По мере продвижения по тексту статьи вы увидите, как будет вырисовываться содержимое передаваемой структуры данных и внутренности функции.

<source lang="c"> double UpdatePID(SPid * pid,

 double error, double position)

{

 .
 .
 .

} </source>

Причина по которой я передаю в процедуру управления отклонение от целевого состояния, а не состояние системы заключается в том, что иногда нам будет полезно как-то "поиграть" с этим параметром (речь идет о том, что регулятор не сам рассчитывает отклонение error, а оно передается извне, так как может быть вычеслено не простой разностью, а иначе - примечание переводчика). Поэтому оставление рассчета отклонения в основном коде, вне нашей функции, делает нашу функцию более универсальной. В коде эта функция может быть использована, например, так:

<source lang="c">

 .
 .
 position = ReadPlantADC();
 drive = UpdatePID(&plantPID, plantCommand - position, position);
 DrivePlantDAC(drive);
 .
 .

</source>

Пропорциональное управление

Пропорциональное управление является самым легким в реализации и наиболее часто используется в управляющих циклах. В этом режиме контроллер просто берет отклонение, умножает его на константу и выдает его в качестве управляющего воздействия. Пропорциональный компонент в контроллере рассчитывается кодом следующего вида:

<source lang="c">

 double pTerm;
 .
 .
 .
 pTerm = pid->pGain * error;
 .
 .
 .
 return pTerm;

</source>

Рисунок 8 показывает что происходит, когда пропорциональное управление применяется к системе двигателя с редуктором.


Рисунок 8. Пропорциональное управление двигателем с редуктором
Рисунок 8. Пропорциональное управление двигателем с редуктором


Для малого значения коэффициента (pGain = 1) двигатель приходит к нужному положению, но достаточно медленно. Увеличение коэффициента (pGain = 2) приводит к более быстрой реакции системы. Однако если дальше увеличивать коэффициент (pGain = 5, pGain = 10), то двигатель конечно более быстро достигает требуемого положения, но дальше идёт "перелёт" (общепринятый термин которым обозначается этот эффект в ТАУ - "Перерегулирование", примечание переводчика), из-за чего система не приходит к требуемому положению быстрее, чем при меньших коэффициентах. Если мы продолжим увеличивать коэффициент, то мы достигнем ситуации, когда система станет бесконечно осциллировать (колебаться) вокруг заданной точки и никогда не придет в нужное состояние.

Система двигателя с редуктором "перелетает" необходимое положение при больших коэффициентах из-за задержки с реакцией на управляющее воздействие. Если вы вернетесь к рисунку 2, то вы увидите, что двигатель не сразу начинает вращаться при подаче на него управляющего сигнала. Эта задержка, плюс задержка обратной связи по датчику - вот что приводит к "перелёту" через требуемое положение на рисунке 8 (возможно более понятным будет следующее объяснение: перерегулирование связано с инерцией мотора и редуктора - прим. переводчика).


Рисунок 9. Пропорциональное управление системой сверхточного позиционирования
Рисунок 9. Пропорциональное управление системой сверхточного позиционирования


Рисунок 9 показывает как действует пропорциональное управление на систему сверхточного поцизионирования. Как видно этот метод управления в чистом виде вообще не помогает в случае этой задачи. Система обладает настолько большой задержкой восприятия управляющего воздействия, что неважно насколько малый коэффициент вы выберите - система всё равно будет осциллировать. С ростом коэффициента просто увеличивается частота колебаний, но система не приходит в требуемое состояние.


Рисунок 10. Пропорциональное управление термосистемой
Рисунок 10. Пропорциональное управление термосистемой


Рисунок 10 показывает что происходит, когда вы строите контроллер температуры на основе метода пропорционального управления. Кроме всего прочего на графиках я показал реакцию системы на внешнее воздействие в виде повышения температуры окружающей среды в момент времени t=2с. Однако видно, что независимо от этого воздействия пропорциональное управление не позволяет установить желаемую температуру. Увеличение коэффициента помогает, но даже при pGain=10 температура котла остается ниже требуемой, и вы начинаете наблюдать сильные "перелёты" через требуемую величину, которые продолжаются без конца (это называется "ringing").

Как видно из приведенных выше примеров пропорцинальное управление даже в одиночку может быть полезно для ряда задач, однако так происходит не всегда. Системы в которых существует значительная задержка реакции на управляющее воздействие, такие как система сверхточного позиционирования, не могут быть стабилизированы с помощью этого метода. Некоторые системы, типа рассмотренного контроллера температуры вообще не достигают требуемого положения. Системы типа двигателя с редуктором вполне работоспособы под таким управлением, но может потребоваться меньшее время вывода системы на требуемое состояние. Чтобы решить все эти проблемы нам потребуется добавить интегральную или дифференциальную составляющу, или обе одновременно.

Интегральное управление

Интегральное управление используется, чтобы добавить "долгосрочной точности" управляющему циклу. Оно практически всегда используется совместно с пропорциональным управлением.

Реализующий интегратор код приведен ниже. Состояние интегратора iState является суммой всех предыдущих входов. Параметры iMin и iMax это минимально и максимально разрешенные значения состояния интегратора.

<source lang="c"> double iTerm;

 .
 .
 .

// calculate the integral state // with appropriate limiting

 pid->iState += error;
 if (pid->iState > pid->iMax) 
   pid->iState =  pid->iMax;
 else if (pid->iState <  pid->iMin) 
   pid->iState = pid->iMin;
 iTerm = pid->iGain * iState;  
  // calculate the integral term
 .
 .
 .

</source>

Интегральное управление само по себе обычно снижает стабильность системы или вообще делает систему нестабильной.


Рисунок 11. Интегральное управление двигателем с редуктором
Рисунок 11. Интегральное управление двигателем с редуктором


На рисунке 11 приведены результаты управления двигателя с редуктором контроллером реализующим чисто интегральное управление (pGain = 0). Как видно система вообще не стабилизируется. Как и в случае с системой сверхточного позиционирования с пропорциональным управлением у двигателя с редуктором под чистым интегральным управлением колебания будут становиться только больше и больше, пока это во что-нибудь не упрётся (хорошо если это будет программное ограничение, а не разрушение механической системы).


Рисунок 12. Интегральное управление термосистемой
Рисунок 12. Интегральное управление термосистемой


Рисунок 12 показывает как себя ведёт термосистема под чистым интегральным управлением. Как видно время стабилизации системы стало значительно больше, чем при пропорциональном управлении (см. рисунок 10), но зато теперь система стабилизируется при требуемом состоянии, даже при некоторых внешних воздействиях. Если вам не требуется малое время выхода на требуемое состояние - этот метод вам вполне подойдет.

Из последнего графика ясно, как используется интегральный компонент управления. В состоянии интегратора "запоминается" всё что произошло в предыдущие моменты времени и это позволяет контроллеру избегать "долгосрочных ошибок", т.е. поведения при котором мы видим что не достигли требуемого положения, а никакого управляющего воздействия не вносим. Однако у этой медали есть и обратная сторона - контроллер всегда реагирует с некоторым запозданием, когда система уже длительное время получает совершенно неправильные команды. Чтобы стабилизировать предыдущие две системы нам потребуется добавить в принятие решения немного информации о текущем состоянии системы, которое мы имеем в пропорциональной компоненте.


Рисунок 13. Пропорционально-интегральное управление двигателем с редуктором
Рисунок 13. Пропорционально-интегральное управление двигателем с редуктором


Рисунок 13 показывает как ведёт себя двигатель с редуктором под пропорционально-интегральном (ПИ) управлением. Сравните это с рисунками 8 и 11. Время на стабилизацию увеличилось по сравнению с чисто пропорциональной схемой, но стабилизация идёт в правильное положение, которое и требовалось.


Рисунок 14. Пропорционально-интегральное управление термосистемой
Рисунок 14. Пропорционально-интегральное управление термосистемой


Рисунок 14 показывает, что будет происходить, если применить к термосистеме ПИ-управление. Котёл так же придёт к требуемой температуре, как и в случае чистого интегрального управления (см. рисунок 12), но с ПИ-управлением произойдёт это в два-три раза быстрее. График показывает время стабилизации до требуемой температуры близкое к возможному пределу достигаемому с помощью ПИ-регуляторов на такого типа системах.

Перед тем, как мы закончим рассматривать интеграторы, я хотел бы указать на следующие два важных момента. Во-первых, так как вы добавили интеграцию отклонения по времени, становится важным частота с которой вы запускаете цикл управления. Во-вторых нужно быть внимательным к допустимому диапазону значений интегратора, чтобы избежать "вылетания".

Скорость изменения состояния интегратора равна среднему отклонению умноженному на коэффициент интегратора умноженному на частоту цикла управления. Так как интегратор сглаживает замеры отклонения по времени, допустимы некотороые отклонения от нормальной частоты вызова управляющего цикла, но в любом случае эти отклонения должны быть чем-то ограничены. В худшем случае рекомендуется, чтобы частота вызова цикла управления не отклонялась более чем на 20% на каждом участке из 10 вызовов. Иногда лучше пропустить часть значений, чтобы сохранить требуемую частоту вызова управляющего цикла. Однако несмотря на это я для ПИ-контроллера предпочитаю системы, в которых точность вызова цикла управления лежит в пределах 1-5%.

Если вашему контроллеру требуется значительно изменить состояние управлямой системы, которе не может быть произведено за короткое время - тогда всё это время отклонение будет велико и это огромное отклонение накопится в состоянии интегратора, что вызовет в свою очередь его "вылетание". Когда система достигнет своего целевого положения в интеграторе будет находится огромное накопленное отклонение, которое вызовете дальнейший значительный "перелёт" через требуемое положение и система так же значительное время будет продолжать двигаться уже за пределами целевого значения. В лучшем случае это будут затухающие колебания, в худшем - система никогда не стабилизируется и будет осциллировать с огромной амплитудой.


Рисунок 15. "Вылетание" пропорционально-интегрального управления
Рисунок 15. "Вылетание" пропорционально-интегрального управления


Рисунок 15 показывает эффект "вылетания" интегратора. Я использовал двигатель с редуктором и контроллер с примера рисунка 13 и ограничил скорость мотора до 0.2. Не только контроллер выдаёт управляющий сигнал, который не может быть реализован двигателем, но и вся система показывает значительный "перелёт". Реально требуемое положение достигается за 5 секунд, он обратный сигнал не подаётся еще в течение 3 секунд, поскольку в интеграторе еще осталось накопленное отклонение, указывающее на то, что надо продолжать двигаться вперёд, и проходит порядка 15 секунд, пока система не стабилизируется.

Рисунок 16. Ограничение "вылетания" пропорционально-интегрального управления
Рисунок 16. Ограничение "вылетания" пропорционально-интегрального управления

Простейший и самый прямой способ борьбы с "вылетанием" интегратора это установка ограничений на его накопленное значение, как я показал в примере кодирования такого интегратора. Рисунок 16 показывает что происходит когда в приведенных выше условиях на интегратор наложены ограничения в размере максимально допустимого управляющего воздействия на двигатель (iMin=-0.2, iMax=0.2). Выход контроллера всё еще больше допустимого для двигателя (из-за пропорциональной части), но теперь интегратор "вылетает" значительно меньше и система начинает стабилизироваться на 5-й секунде и заканчивает примерно на 6-й секунде.

Обратите внимание, что в примерах указанных выше надо масштабировать iMin и iMax, если вы изменяете коэффициент интегратора (iGain). Обычно достаточно установить ограничения значиний минимума и максимума интегратора такие, чтобы интегрирующий компонент управления выдавал соответственно минимальное и максимальное управляющее воздействие. Если вы знаете, что вам потребуется еще более малые интегрирующий компонент - вы можете еще больше ограничить значения интегратора.

Дифференциальное управление

Я не стал рассматривать сверхточное позиционирование в предыдущем разделе по той причине, что эту систему нельзя стабилизировать с помощью ПИ-управления. В общем если вы не можете стабилизировать какую-то систему с помощью пропорционального управления из-за слишком большой задержки воздействия на систему, тогда при использовании ПИ-управления увеличивающего эту задержку всё станет только хуже.

Мы знаем что пропорциональное управление соответствует использованию "сиюминутной" информации о системе, интегральное управление использует информацию о "прошлом" системы. Если бы мы получили элемент который соответствует использованию "прогнозной" информации о системе, мы смогли бы попробовать использовать его для стабилизации нашей платформы в системе сверхточного позиционирования. И таким искомым элементом является дифференциатор.

Код приведенный ниже показывает, как рассчитывается дифференциальная компонента ПИД-контроллера. Я предпочитаю использовать текущее состояние системы, а не отклонение от требуемого положения для мягкости управления при резкой смене целевого состояния системы. Дифференциальная компонента сама по себе представляет разность между предыдущим состоянием системы и текущим её состоянием. Это даёт нам возможность оценить скорость изменения состояния системы и предугадать в каком состоянии окажется система в следующий момент времени.

<source lang="c"> double dTerm;

 .
 .
 .

dTerm = pid->dGain * (position - pid->dState);

 pid->dState = position;
 .
 .
 .

</source>

При использовании дифференциальной компоненты становится возможным стабилизация платформы в системе сверхточного позиционирования.


Рисунок 17. Пропорционально-дифференциальное управление системой сверхточного позиционирования
Рисунок 17. Пропорционально-дифференциальное управление системой сверхточного позиционирования


Рисунок 17 показывает как ведёт себя эта система под пропорционально-дифференциальным (ПД) управлением. Система стабилизируется меньше чем за 1/2 секунды по сравнению с несколькими секундами требующимися для других систем.


Рисунок 18. ПИД-управление термосистемой
Рисунок 18. ПИД-управление термосистемой


Рисунок 18 показывает как себя ведёт термосистема под ПИД-управлением. Как видно из графиков этот подход существенно улучшает качество управления системой.

Дифференциальная компонента управления очень мощная, но она же и самая проблемная из всех типов управления представленных здесь. Три проблемы с которыми придётся столкнуться при реализации этого типа управления - нерегулярность частоты сбора данных, шумы и высокочастотные колебания. Когда я представлял код для дифференциального элемента я предположил, что выход управляющего воздействия должен быть пропорционален изменению положения деленному на время между итерациями цикла управления. Если состояние системы меняется с постоянной скоростью, а время между запуском управляющей итерации варьируется, вы будете получать неверную информацию о скорости системы. Поскольку обычно время между итерациями управления достаточно мало, шумы такого сорта могут быть очень значительными и будут сильно мешать задаче управления.

Когда вы используете дифференциальное управление нужно обращать внимание на точность временных интервалов между итерациями управляющего цикла. Я рекомендую поддерживать точность этих интервалов в пределах 1%, однако чем точнее, тем лучше. Если вы не можете обеспечить это на аппаратном уровне - постарайтесь сделать это на уровне программного обеспечения, отдав под задачу сбора информации максимальный приоритет (не нужно с такой точностью выполнять расчеты управляющего воздействия, достаточно собирать информацию в нужные моменты времени). Один из оптимальных вариантов - поместить сбор информации о системе в прерывание, а сами расчеты ПИД-алгоритма выполнять в свободное время.

Дифференциальное управление страдает от шумов больше других типов управления потому что оно эти шумы усиливает, в отличие от пропорционального управления, которое просто транслирует эти шумы или интегрального, которое вообще шумы подавляет. Посмотрите на коэффициенты дифференциальной компоненыт, которые я использовал выше и представьте, что произойдёт если у вас в системе будут небольшие шумы, которые возникать при каждом получении информации о системе. Умножьте эти небольшие шумы на коэффициент 2000 и представьте как это отразится на системе.

Вы можете применить фильтрацию дифференциальной компоненты управления, но это существенно снизит её полезность. Теория стоящая за тем, как это делать и как опредилить - будет ли это работать останется за рамками этой вводной статьи. Возможно лучшее, что вы можете сделать с этой проблемой - оценить насколько велики у вас шумы при получении информации о состоянии системы и насколько вам надо ускорение стабилизации системы с помощью дифференциальной компоненты и исходя из этого установить коэффициент этой компоненыт (dGain). Возможно вам вообще придётся отказаться от этой компоненты или еще можно попробовать переработать электронику так, чтобы снизить шумы или попробовать применить более сложные алгоритмы управления (обратиться к экспертам по автоматизированному управлению).

Полный код ПИД-контроллера: <source lang="c"> typedef struct {

 double dState;      	        // Last position input
 double iState;      	        // Integrator state
 double iMax, iMin;  	
 // Maximum and minimum allowable integrator state
 double	iGain,    	// integral gain
       	pGain,    	// proportional gain
        	dGain;     	// derivative gain

} SPid; double UpdatePID(SPid * pid, double error, double position) {

 double pTerm, dTerm, iTerm;
 pTerm = pid->pGain * error;    // calculate the proportional term
 pid->iState += error;          // calculate the integral state with appropriate limiting
 if (pid->iState > pid->iMax) 
     pid->iState = pid->iMax;     
 else if (pid->iState < pid->iMin) 
     pid->iState = pid->iMin;
 iTerm = pid->iGain * iState;    // calculate the integral term
 dTerm = pid->dGain * (position - pid->dState);
 pid->dState = position;
 return (pTerm + iTerm - dTerm);

} </source>

Настройка ПИД-регулятора

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

Если можете, подцепите ваш контроллер к тестовому оборудованию или напишите отладочный код, чтобы можно было видеть, что происходит внутри, если возможно - соедините контроллер с ПК по последовательному порту и выведите отладочные графики в какой-нибудь программе, например в Excel. Кроме этого вам потребуется какой-то способ ступенько-образного задания управляюшего сигнала. Вполне может подойти опять же отладочный код, который будет брать управляющий сигнал скажем с последовательного порта. Как только вы закончили все приготовления установите все коэффициенты в 0. Если вы полагаете, что вам не нужно будет дифференциальную компоненту (как в случае с двигателем или термосистемой), пропустите следующую секцию и сразу приступайте к настройке пропорциональной компоненты. Иначе начинаем с настройки коэффициента дифференциального управления.

Настройка дифференциальной компоненты

Перед настройкой дифференциального управления выставьте коэффициент пропорционального управления в какое-нибудь небольшое значение (1 или немного меньше). Посмотрите как себя ведёт система. Если она колеблется при нулевом коэффициенте дифференциальной компоненты, тогда это можно исправить увеличением этого коэффициента. При постепенном увеличении смотрите как себя ведёт система, увеличиваейте коэффициент пока не увидите возникающие из-за малых шумов системы ошибочные колебания и вылеты по этой же причине за целевые значения. Обратите внимение, что колебания от слишком большого коэффициента значительно быстрее, чем колебания от недостаточного коэффициента. Я стараюсь устанавливать коэффициент в половину или четверть от того, при котором начинаются колебания от слишком большой его величины. Убедитесь что при этом управляющий сигнал выглядит адекватным. В этот момент система реагирует на управляющее воздействие очень лениво, так что самое время настроить пропорциональный и интегральный коэффициенты.

Настройка пропорциональной компоненты

Если вы еще не установили коэффициент пропорциональной компоненты, назначьте ему некоторое стартовое значение (от 1 до 100). Ваша управляемая система либо покажет ужасающе медленную реакцию на команды, либо начнет колебания. Если вы видите колебания - уменьшайте коэффициент в 10 раз, пока эти колебания не прекратятся. Если вы не наблюдаете колебания, увеличивайте коэффициент в 10 раз пока не начнутся колебания или значительные "перелёты" через целевое положение. Теперь уже с коэффициентом 2 найдите такой коэффициент, что он всё еще не вызывает колебаний или "перелётов", а умноженный на 2 уже вызывает, теперь можно немного его уменьшить пока вам не понравится действие системы.

Настройка интегральной компоненты

И наконец мы можем приступить к настройке коэффициента интегральной компоненты, начальные значения коэффициента рекомендуется брать от 0.0001 до 0.01. Ищем нужное нам значение так же как с пропорциональным коэффициентом, так же отступая немного назад, чтобы гарантированно не получить колебания от слишком большого коэффициента.

Замечания

Оптимизация производительности ПИД-регулятора

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

Частота сбора данных и выполнения цикла управления

Мы уже обсуждали как важен этот параметр, но до этого мы обсуждали как важно чтобы он был стабильным, однако ничего не говорили о том, каким он должен быть. Если она слишком маленькая, тогда вы не сможете получить нужную вам эффективность и более того можете получить систему, которую невозможно стабилизировать. Если же вы возьмете слишком большую частоту - вы получите серьезные шумы в дифференциальное компоненте и переполнение состояния интегратора.

Есть простое правило для цифровых управляющих систем, которое гласит, что продолжительность итерации управляющего цикла должна быть между 1/10 и 1/100 желаемого времени стабилизации системы в новом положении. Если вы посмотрите на рисунок 16, там это время порядка 6.2с. Если время принятия системой нового положения нужно 1с, тогда вас может устроить частота даже такая низкая, как 10Гц.

Вообще часто ряд проблем с управлением снимается, если вы повышаете эту частоту, может оказаться так, что в этом случае даже можно будет отказаться от дифференциальной компоненты управления. Так что если у вас нет дифференциальной компоненты и достаточно длины числа под состояние интегратора - делайте частоту хоть в 1/1000 от желаемого времени стабилизации системы.

Послесловие

Статья преподносит основы разработки и настройки ПИД-контроллеров. Используя эту информацию вы сможете взяться за задачу управления и реализовать необходимую для неё систему управления.

Tim Wescott является магистром электро инжинерии и более 10 лет проработал в это индустрии. Его опыт включает множество систем управления замкнутого цикла реализованных на 8-32 битных контроллерах, сигнальных процессорах, как на ассемблере, так и на C\C++. На момент написания статьи он участвовал в разработке систем управления компании FLIR Systems в которой он определял требования к механической, электрической и программной части. Вы можете связаться с ним по адресу tim@wescottdesign.com.