П пи пд пид регуляторы. Действия в программном меню

П,ПИ,ПИД,ПД ЗАКОН РЕГУЛИРОВАНИЯ.

Общее описание

Принцип ПИД-регуляторов

Для позиционных регуляторов процесс регулирования представляет собой колебания вокруг заданной точки. Естественно это связано с «релейной» статической характеристикой Y(U-X).

РЕГУЛЯТОРЫ
С ПИД-ЗАКОНОМ РЕГУЛИРОВАНИЯ На рисунке показана линейная статическая Y(U-X) характеристика.

пропорционального регулятора

Если входная Е = U-X (невязка) и выходная величина сигнала регулятора Y связаны простым соотношением Y=K·(U-X), такой регулятор называется пропорциональным. Естественно что линейный участок статической характеристики не бесконечен, он ограничен максимально возможным значением выходной величины: Ymax. Например, при регулировании температуры воды в баке: Х — температура воды; U — заданное значение требуемой температуры; Y — выходной сигнал регулятора (мощность нагревателя, Вт); Ymax, например, 750 Вт. Если при максимальной мощности величина Е = 75оС, то К = 0,1оС/Вт.
При очень большом коэффициенте усиления К пропорциональный регулятор вырождается в позиционный с нулевой зоной нечувствительности. При меньшем значении К регулирование происходит без колебаний
(см.рис. 2).



П-регулятором при скачкообразном изменении
задания с 0 до U (разгонная кривая)

Отметим, что значение регулируемой величины Х никогда не достигнет задания U. Образуется, так называемая статическая ошибка: d (см. рис. 2). Действительно, при приближении температуры воды Х к заданию U постепенно уменьшается подаваемая мощность Y, т.к. Y=К·(U-X). Но теплота, рассеиваемая в окружающую среду, увеличивается, и равновесие наступит при Y = K·d и d не достигнет 0, т.к. если d будет равно 0, то и Y=0 и Х=0. Таким образом на выходе регулятора устанавливается некоторое значение Y=K·d , которое приводит регулируемую величину Х в состояние отличное от задания. Чем больше К, тем меньше d. Однако при достаточно большом К САР и объект могут перейти в автоколебания. Этот предельный коэффициент усиления определяется соотношением наклона разгонной кривой R и транспортным запаздыванием to объекта: Kmax = 2/(R·to) (см. рис. 2).
В ряде случаев, при малом транспортном запаздывании, статическая ошибка находится в необходимых пределах, поэтому П-регуляторы находят некоторое применение. Для устранения статической ошибки d при формировании выходной величины Y вводят интегральную составляющую отклонения от задания:
Y = K·(U-X) + In(U-X)/Ti ,
где Тi — постоянная интегрирования.
Таким образом, чем больше время, в течение которого величина Х меньше задания, тем больше интегральная составляющая, тем больше выходной сигнал. Регулятор с таким законом формирования выходного сигнала называется пропорционально-интегральным ПИ-регулятором.
В установившемся режиме (d=0) в интеграторе содержится величина In/Т, которая равна выходной мощности, требуемой для получения необходимой Х. Таким образом интегратор как бы находит статический коэффициент передачи объекта. Для достижения установившегося режима в интеграторе требуется достаточно большее время. Поэтому ПИ-регулятор можно применять в случае, когда и внешние воздействия достаточно медленные.
В случае резких изменений внешних и внутренних факторов (например, налили холодной воды в бак или резко изменили задание) ПИ-регулятору требуется время для компенсации этих изменений.
Для ускорения реакции САР на внешние воздействия и изменения в задании в регулятор вводят дифференциальную составляющую D(U-X):
Y = K·(U-X) + In(U-X)/Ti+Тd·D(U-X),
где Тd — постоянная дифференцирования.
Чем быстрее растет Е, тем больше D(U-X). Регулятор с таким законом управления называется ПИД-регулятором. Подобрав для конкретного объекта К,Тi и Td можно оптимизировать качество работы регулятора: уменьшить время выхода на задание, снизить влияние внешних возмущений, уменьшить отклонение от задания. При очень большом Тi регулятор очень медленно выводит объект на задание. При малом Тi происходит перерегулирование, т.е. регулируемый параметр Х проскакивает задание (рис.7), а затем сходится к нему. Ниже описаны методики настройки регуляторов, т.е. расчет коэффициентов в зависимости от динамических свойств объекта. Без настройки ПИ-регулятор может обладать худшим качеством работы, чем даже Т-регулятор. Приведем передаточные функции П-, ПИ- и ПИД-регуляторов, принятые в теории автоматического управления.
Пропорциональный регулятор – П:
y = К(u -x) , т.е. в обратную связь заводится отклонение от уставки.
Пропорционально-Интегральный – ПИ:
y = (u-x)(Kp + /pTi) , т.е. в обратную связь заводится также интеграл от отклонения, это позволяет избежать статической ошибки.
Пропорционально-Интегрально- Дифференциальный – ПИД:
y = (u-x)·(Kp + 1/pTi + p·Td) , т.е. в обратную связь заводится также производная отклонения, это позволяет улучшить динамические характеристики регулятора.
Блок схема ПИД регулятора показана на рис. 3.


Структурная схема ПИД-регулятора

Величина рассогласования Е подвергается диференцированию и интегрированию. Выходная вели-чина — Y ПИД-регулятора формируется суммированием с весовыми коэффициентами дифференциальной, пропорциональной и интегральной составляющих. По наличию этих составляющих регуляторы и имеют сокращенное название П, ПИ, ПИД.
Существуют модификации ПИД-регуляторов:
а) при наличии интегратора на выходе или в исполнительном механизме (например сервопривод задвижки водяного отопления) ПД-регулятор как бы превращается в ПИ-регулятор, а вычислительная схема ПИД-регулятора требует двойного дифференцирования;
б) дифференциальная составляющая часто вычисляется только по Х, что дает более плавный выход на режим при изменении задания U.

Настройка регуляторов При применении ПИД- регуляторов для каждого конкретного объекта необходимо настраивать от одного до трех коэффициентов. Возможны САР с автоматизированной настройкой. Для типовых регуляторов известны простейшие аналитические и табличные методы настройки (например две методики Цидлера).

Настройка по реакции на входной скачок Алгоритм настройки:
— на вход САР подается новое задание (уставка) – нагреватель включается на максимальную мощность, и по переходному процессу X(t) определяются t0, R, tи (см. рис. 4):


Разгонная кривая для объекта с транспортным запаздыванием:
to — время транспортного запаздывания;
tи — постоянная времени (время согласования) определяется инерционностью объекта;
Xy — установившееся значение;
R — наклон разгонной кривой dX/dt (макс. скорость изменения Х)

— вычисляются коэффициенты настройки согласно следующим примерным соотношениям:
для П-регулятора К= 1/R·t0
для ПД-регулятора К= 1/R·t0, Td=0.25·t0
для ПИ-регулятора К= 0.8/R·t0, Ti= 3·t0
для ПИД-регулятора К= 1.2/R·t0, Ti= 2·t0, Td=0.4·t0.
Не обязательно выводить объект на максимально возможную величину Х. Однако, следует иметь в виду, что слишком маленький скачок не позволяет определить R с достаточно высокой точностью.

Настройка по методу максимального коэффициента усиления Этот способ применяется, если допустим колебательный процесс, при котором значения регулируемой величины значительно выходят за пределы задания U.


К настройке по методу максимального
коэффициента усиления

Алгоритм настройки:
— определяется предельный коэффициент Кмах усиления при котором САР и объект переходят в колебательный режим, т.е. без интегральной и дифференциальной части (Тd=0, Тi=Ґ). Вначале К=0, затем он увеличивается до тех пор, пока САР и объект переходит в колебательный режим. САР соответствует схеме П-регулятора (см.рис.2).
— определяется период колебаний tc (см. рис. 5);

для П-регулятора К= 0.5·Kмах
для ПД-регулятора К= 0.5·Кмах, Td=0.05·tc
для ПИ-регулятора К= 0.45·Кмах, Ti= 0.8·tс
для ПИД -регулятора К= 0.6·Кмах, Ti= 0.5·tс, Td=0.12·tc.

Настройка по процессу двухпозиционного регулирования по релейному закону

К настройке по процессу двухпозиционного
регулирования

Эта методика удобна, если применялся Т-регулятор, который затем заменяется на ПИД- регулятор:
— система переводится в режим двухпозиционного регулирования по релейному закону (см. рис. 6);
определяется амплитуда — А и период колебаний tс;
— вычисляются коэффициенты настройки согласно следующим примерным соотношениям:
для П-регулятора К = 0.45/А
для ПД-регулятора К = 0.45/А, Td=0.05·tc
для ПИ-регулятора К = 0.4/А, Ti= 0.8·tc
для ПИД-регулятора К = 0.55/А, Ti= 0.5·tс, Td=0.12·tc.
Если объект не меняет структуру и свои параметры, то системы с ПИД-регуляторами обеспечивают необходимое качество регулирования при больших внешних возмущающих воздействиях и помехах, то есть близкое к 0 рассогласование Е (см. рис. 7). Как правило, точно согласовать параметры регулятора и объекта сразу не удается. Если Ti меньше оптимального в два раза, процесс регулирования может перейти в колебательный режим. Если Ti существенно больше оптимального, то регулятор медленно выходит на новый режим и слабо реагирует на быстрые возмущения — G. Таким образом, как правило необходима дополнительная подстройка. На рис. 7 показано влияние неоптимальных настроек ПИД-регуляторов на вид переходной функции (реакции САР и объекта на единичный скачок в задании).

Системы автоматического управления (САУ) предназначены для автоматического изменения одного или нескольких параметров объекта управления с целью установления требуемого режима его работы. САУ обеспечивает поддержание постоянства заданных значений регулируемых параметров или их изменение по заданному закону либо оптимизирует определенные критерии качества управления. Например, к таким системам относятся:

  • системы стабилизации,
  • системы программного управления,
  • следящие системы

Это достаточно широкий класс систем, которые можно найти где угодно. Но какое это отношение имеет к Unity3D и вероятно к играм в частности? В принципе прямое: в любой игре так или иначе использующей симуляцию как элемент геймплея реализуются САУ, к таким играм относятся, например, Kerbal Space Programm, Digital Combat Simulator (бывший Lock On), Strike Suit Zero и т.д. (кто знает еще примеры - пишите в комментариях). В принципе любая игра, моделирующая реальные физические процессы, в том числе и просто кинематику с динамикой движения, может реализовывать те или иные САУ - этот подход проще, естественнее, а у разработчика уже есть есть набор готовых инструментов, предоставленных всякими Вышнеградскими, Ляпуновыми, Калманами, Чебышевами и прочими Коломогоровами, поэтому можно обойтись без изобретения велосипеда, т.к. его уже изобрели, да так, что получилась отдельная наука: Теория автоматического управления. Главное тут не переусердствовать. Одна тут только проблема: рассказывают про ТАУ не везде, не всем, зачастую мало и не очень понятно.

Немножко теории

Классическая система автоматического управления представленная на следующем рисунке:



Ключевым элементом любой САУ является регулятор представляющий из себя устройство, которое следит за состоянием объекта управления и обеспечивает требуемый закон управления. Процесс управления включает в себя: вычисление ошибки управления или сигнала рассогласования e (t ) как разницы между желаемой уставкой (set point или SP ) и текущей величиной процесса (process vale или PV ), после чего регулятор вырабатывает управляющие сигналы (manipulated value или MV ).


Одной из разновидностью регуляторов является пропорционально-интегрально-дифференцирующий (ПИД) регулятор , который формирует управляющий сигнал, являющийся суммой трёх слагаемых: пропорционального, интегрального и дифференциального.



Где, ошибка рассогласования, а также, - пропорциональная, - интегральная, - дифференциальная составляющие (термы) закона управления, который в итоговом виде описывается следующими формулами




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


Интегральная составляющая I накапливает (интегрирует) ошибку регулирования, что позволяет ПИД-регулятору устранять статическую ошибку (установившуюся ошибку, остаточное рассогласование). Или другими словами: интегральное звено всегда вносит некоторое смещение и если система подвержена некоторыми постоянным ошибкам, то оно их компенсирует (за счет своего смещения). А вот если же этих ошибок нет или они пренебрежительно малы, то эффект будет обратным - интегральная составляющая сама будет вносить ошибку смещения. Именно по этой причине её не используют, например, в задачах сверхточного позиционирования. Ключевым недостатком интегрального закона управления является эффект насыщения интегратора (Integrator windup).


Дифференциальная составляющая D пропорциональна темпу изменения отклонения регулируемой величины и предназначена для противодействия отклонениям от целевого значения, которые прогнозируются в будущем . Примечательно то, что дифференциальная компонента устраняет затухающие колебания. Дифференциальное регулирование особенно эффективно для процессов, которые имеют большие запаздывания. Недостатком дифференциального закона управления является его неустойчивость к воздействую шумов (Differentiation noise).


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


Казалось бы, вопрос реализации ПИД-регуляторов уже давно избит и здесь на Хабре есть парочка неплохих статей на эту тему в том числе и на Unity3D , также есть неплохая статья PID Without a PhD (перевод) и цикл статей в журнале "Современные технологии автоматизации" в двух частях: первая и вторая . Также к вашим услугам статья на Википедии (наиболее полную читайте в английском варианте). А на форумах коммьюнити Unity3D нет-нет, да и всплывет PID controller как и на gamedev.stackexchange


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

Попытка номер раз

В качестве примера попытаемся реализовать схему регулирования на примере управления поворотом в простенькой космической 2D-аркаде, по шагам, начиная с самого начала (не забыли, что это туториал?).


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


Для начала создадим сам объект игровой объект космического корабля, который будет состоять из собственно самого объекта корабля на верхнем уровне иерархии, прикрепим к нему дочерний объект Engine (чисто спецэффектов ради). Вот как это выглядит у меня:



А на сам объект космического корабля накидаем в инспекторе всяческих компонент. Забегая вперед, приведу скрин того, как он будет выглядеть в конце:



Но это потом, а пока в нем еще нет никаких скриптов, только стандартный джентльменский набор: Sprite Render, RigidBody2D, Polygon Collider, Audio Source (зачем?).


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


Т.к. помимо самого космического корабля есть куча других, менее умных космических объектов, то сначала опишем родительский класс BaseBody , который в себе будет содержать ссылки на на наши компоненты, методы инициализации и уничтожения, а также ряд дополнительных полей и методов, например для реализации небесной механики:


BaseBody.cs

using UnityEngine; using System.Collections; using System.Collections.Generic; namespace Assets.Scripts.SpaceShooter.Bodies { public class BaseBody: MonoBehaviour { readonly float _deafultTimeDelay = 0.05f; public static List _bodies = new List(); #region RigidBody public Rigidbody2D _rb2d; public Collider2D _c2d; #endregion #region References public Transform _myTransform; public GameObject _myObject; ///

/// Объект, который появляется при уничтожении /// public GameObject _explodePrefab; #endregion #region Audio public AudioSource _audioSource; /// /// Звуки, которые проигрываются при получении повреждения /// public AudioClip _hitSounds; /// /// Звуки, которые проигрываются при появлении объекта /// public AudioClip _awakeSounds; /// /// Звуки, которые воспроизводятся перед смертью /// public AudioClip _deadSounds; #endregion #region External Force Variables /// /// Внешние силы воздйствующие на объект /// public Vector2 _ExternalForces = new Vector2(); /// /// Текущий вектор скорости /// public Vector2 _V = new Vector2(); /// /// Текущий вектор силы гравитации /// public Vector2 _G = new Vector2(); #endregion public virtual void Awake() { Init(); } public virtual void Start() { } public virtual void Init() { _myTransform = this.transform; _myObject = gameObject; _rb2d = GetComponent(); _c2d = GetComponentsInChildren(); _audioSource = GetComponent(); PlayRandomSound(_awakeSounds); BaseBody bb = GetComponent(); _bodies.Add(bb); } /// /// Уничтожение персонажа /// public virtual void Destroy() { _bodies.Remove(this); for (int i = 0; i < _c2d.Length; i++) { _c2d[i].enabled = false; } float _t = PlayRandomSound(_deadSounds); StartCoroutine(WaitAndDestroy(_t)); } /// /// Ждем некоторое время перед уничтожением /// /// Время ожидания /// public IEnumerator WaitAndDestroy(float waitTime) { yield return new WaitForSeconds(waitTime); if (_explodePrefab) { Instantiate(_explodePrefab, transform.position, Quaternion.identity); } Destroy(gameObject, _deafultTimeDelay); } /// /// Проигрывание случайного звука /// /// Массив звуков /// Длительность проигрываемого звука public float PlayRandomSound(AudioClip audioClip) { float _t = 0; if (audioClip.Length > 0) { int _i = UnityEngine.Random.Range(0, audioClip.Length - 1); AudioClip _audioClip = audioClip[_i]; _t = _audioClip.length; _audioSource.PlayOneShot(_audioClip); } return _t; } /// /// Получение урона /// /// Уровень урона public virtual void Damage(float damage) { PlayRandomSound(_hitSounds); } } }


Вроде описали все что надо, даже больше чем нужно (в рамках этой статьи). Теперь отнаследуем от него класс корабля Ship , который должен уметь двигаться и поворачивать:


SpaceShip.cs

using UnityEngine; using System.Collections; using System.Collections.Generic; namespace Assets.Scripts.SpaceShooter.Bodies { public class Ship: BaseBody { public Vector2 _movement = new Vector2(); public Vector2 _target = new Vector2(); public float _rotation = 0f; public void FixedUpdate() { float torque = ControlRotate(_rotation); Vector2 force = ControlForce(_movement); _rb2d.AddTorque(torque); _rb2d.AddRelativeForce(force); } public float ControlRotate(Vector2 rotate) { float result = 0f; return result; } public Vector2 ControlForce(Vector2 movement) { Vector2 result = new Vector2(); return result; } } }


Пока в нем нет ничего интересно, на текущий момент это просто класс-заглушка.


Также опишем базовый(абстрактный) класс для всех контроллеров ввода BaseInputController:


BaseInputController.cs

using UnityEngine; using Assets.Scripts.SpaceShooter.Bodies; namespace Assets.Scripts.SpaceShooter.InputController { public enum eSpriteRotation { Rigth = 0, Up = -90, Left = -180, Down = -270 } public abstract class BaseInputController: MonoBehaviour { public GameObject _agentObject; public Ship _agentBody; // Ссылка на компонент логики корабля public eSpriteRotation _spriteOrientation = eSpriteRotation.Up; //Это связано с нестандартной // ориентации спрайта "вверх" вместо "вправо" public abstract void ControlRotate(float dt); public abstract void ControlForce(float dt); public virtual void Start() { _agentObject = gameObject; _agentBody = gameObject.GetComponent(); } public virtual void FixedUpdate() { float dt = Time.fixedDeltaTime; ControlRotate(dt); ControlForce(dt); } public virtual void Update() { //TO DO } } }


И наконец, класс контроллера игрока PlayerFigtherInput :


PlayerInput.cs

using UnityEngine; using Assets.Scripts.SpaceShooter.Bodies; namespace Assets.Scripts.SpaceShooter.InputController { public class PlayerFigtherInput: BaseInputController { public override void ControlRotate(float dt) { // Определяем позицию мыши относительно игрока Vector3 worldPos = Input.mousePosition; worldPos = Camera.main.ScreenToWorldPoint(worldPos); // Сохраняем координаты указателя мыши float dx = -this.transform.position.x + worldPos.x; float dy = -this.transform.position.y + worldPos.y; //Передаем направление Vector2 target = new Vector2(dx, dy); _agentBody._target = target; //Вычисляем поворот в соответствии с нажатием клавиш float targetAngle = Mathf.Atan2(dy, dx) * Mathf.Rad2Deg; _agentBody._targetAngle = targetAngle + (float)_spriteOrientation; } public override void ControlForce(float dt) { //Передаем movement _agentBody._movement = Input.GetAxis("Vertical") * Vector2.up + Input.GetAxis("Horizontal") * Vector2.right; } } }


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


using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Assets.Scripts.Regulator { // Этот атрибут необходим для того что бы поля регулятора // отображались в инспекторе и сериализовывались public class SimplePID { public float Kp, Ki, Kd; private float lastError; private float P, I, D; public SimplePID() { Kp = 1f; Ki = 0; Kd = 0.2f; } public SimplePID(float pFactor, float iFactor, float dFactor) { this.Kp = pFactor; this.Ki = iFactor; this.Kd = dFactor; } public float Update(float error, float dt) { P = error; I += error * dt; D = (error - lastError) / dt; lastError = error; float CO = P * Kp + I * Ki + D * Kd; return CO; } } }

Значения коэффициентов по умолчанию возьмем с потолка: это будет тривиальный единичный коэффициент пропорционального закона управления Kp = 1, небольшое значение коэффициента для дифференциального закона управления Kd = 0.2, который должен устранить ожидаемые колебания и нулевое значение для Ki, которое выбрано потому, что в нашей программной модели нет никаких статичных ошибок (но вы всегда можете их внести, а потом героически побороться с помощью интегратора).


Теперь вернемся к нашему классу SpaceShip и попробуем заюзать наше творение в качестве регулятора поворота космического корабля в методе ControlRotate:


public float ControlRotate(Vector2 rotate) { float MV = 0f; float dt = Time.fixedDeltaTime; //Вычисляем ошибку float angleError = Mathf.DeltaAngle(_myTransform.eulerAngles.z, targetAngle); //Получаем корректирующее ускорение MV = _angleController.Update(angleError, dt); return MV; }

ПИД-регулятор будет осуществлять точное угловое позиционировая космического корабля только за счет крутящего момента . Все честно, физика и САУ, почти как в реальной жизни.


И без этих ваших Quaternion.Lerp

if (!_rb2d.freezeRotation) rb2d.freezeRotation = true; float deltaAngle = Mathf.DeltaAngle(_myTransform.eulerAngles.z, targetAngle); float T = dt * Mathf.Abs(_rotationSpeed / deltaAngle); // Трансформируем угол в вектор Quaternion rot = Quaternion.Lerp(_myTransform.rotation, Quaternion.Euler(new Vector3(0, 0, targetAngle)), T); // Изменяем поворот объекта _myTransform.rotation = rot;


Получившейся исходный код Ship.cs под спойлером

using UnityEngine; using Assets.Scripts.Regulator; namespace Assets.Scripts.SpaceShooter.Bodies { public class Ship: BaseBody { public GameObject _flame; public Vector2 _movement = new Vector2(); public Vector2 _target = new Vector2(); public float _targetAngle = 0f; public float _angle = 0f; public SimplePID _angleController = new SimplePID(); public void FixedUpdate() { float torque = ControlRotate(_targetAngle); Vector2 force = ControlForce(_movement); _rb2d.AddTorque(torque); _rb2d.AddRelativeForce(force); } public float ControlRotate(float rotate) { float MV = 0f; float dt = Time.fixedDeltaTime; _angle = _myTransform.eulerAngles.z; //Вычисляем ошибку float angleError = Mathf.DeltaAngle(_angle, rotate); //Получаем корректирующее ускорение MV = _angleController.Update(angleError, dt); return MV; } public Vector2 ControlForce(Vector2 movement) { Vector2 MV = new Vector2(); //Кусок кода спецэффекта работающего двигателя ради if (movement != Vector2.zero) { if (_flame != null) { _flame.SetActive(true); } } else { if (_flame != null) { _flame.SetActive(false); } } MV = movement; return MV; } } }


Все? Расходимся по домам?



WTF! Что происходит? Почему корабль поворачивается как-то странно? И почему он так резко отскакивает от других объектов? Неужели этот глупый ПИД-регулятор не работает?


Без паники! Давайте попробуем разобраться что происходит.


В момент получения нового значения SP, происходит резкий (ступенчатый) скачок рассогласования ошибки, которая, как мы помним, вычисляется вот так: соответственно происходит резкий скачок производной ошибки , которую мы вычисляем в этой строчке кода:


D = (error - lastError) / dt;

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


Думаю что настал момент построить графики переходного процесса : ступенчатое воздействие от S(t) = 0 в SP(t) = 90 градусов для тела массой в 1 кг, длинной плеча силы в 1 метр и шагом сетки дифференцирования 0.02 с - прям как в нашем примере на Unity3D (на самом деле не совсем, при построении этих графиков не учитывалось, что момент инерции зависит от геометрии твердого тела, поэтому переходный процесс будет немножко другой, но все же достаточно похожий для демонстрации). Все величены на грифике приведены в абсолютных значениях:


Хм, что здесь происходит? Куда улетел отклик ПИД-регулятора?


Поздравляю, мы только что столкнулись с таким явлением как "удар" (kick). Очевидно, что в момент времени, когда процесс еще PV = 0, а уставка уже SP = 90, то при численном дифференцировании получим значение производной порядка 4500, которое умножится на Kd=0.2 и сложится с пропорциональным теромом, так что на выходе мы получим значение углового ускорения 990, а это уже форменное надругательство над физической моделью Unity3D (угловые скорости будут достигать 18000 град/с… я думаю это предельное значение угловой скорости для RigidBody2D).


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

Впрочем можете поэкспериментировать.

Попытка номер два. Сатурация

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


public float ControlRotate(Vector2 rotate, float thrust) { float CO = 0f; float MV = 0f; float dt = Time.fixedDeltaTime; //Вычисляем ошибку float angleError = Mathf.DeltaAngle(_myTransform.eulerAngles.z, targetAngle); //Получаем корректирующее ускорение CO = _angleController.Update(angleError, dt); //Сатурируем MV = CO; if (MV > thrust) MV = thrust; if (MV< -thrust) MV = -thrust; return MV; }

А очередной раз переписанный класс Ship полностью выглядит так

namespace Assets.Scripts.SpaceShooter.Bodies { public class Ship: BaseBody { public GameObject _flame; public Vector2 _movement = new Vector2(); public Vector2 _target = new Vector2(); public float _targetAngle = 0f; public float _angle = 0f; public float _thrust = 1f; public SimplePID _angleController = new SimplePID(0.1f,0f,0.05f); public void FixedUpdate() { _torque = ControlRotate(_targetAngle, _thrust); _force = ControlForce(_movement); _rb2d.AddTorque(_torque); _rb2d.AddRelativeForce(_force); } public float ControlRotate(float targetAngle, float thrust) { float CO = 0f; float MV = 0f; float dt = Time.fixedDeltaTime; //Вычисляем ошибку float angleError = Mathf.DeltaAngle(_myTransform.eulerAngles.z, targetAngle); //Получаем корректирующее ускорение CO = _angleController.Update(angleError, dt); //Сатурируем MV = CO; if (MV > thrust) MV = thrust; if (MV< -thrust) MV = -thrust; return MV; } public Vector2 ControlForce(Vector2 movement) { Vector2 MV = new Vector2(); if (movement != Vector2.zero) { if (_flame != null) { _flame.SetActive(true); } } else { if (_flame != null) { _flame.SetActive(false); } } MV = movement * _thrust; return MV; } public void Update() { } } }


Итоговая схема нашего САУ тогда станет уже вот такой


При этом уже становится понятно, что выход контроллера CO(t) немного не одно и тоже, что управляемая величина процесса MV(t) .


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


Запустив игру, мы обнаружим, что космический корабль стал наконец управляемым:



Если построить графики, то можно увидеть, что реакция контроллера стала уже вот такой:


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

Ниже приведена известна таблица влияния увеличения параметров ПИД-регулятора (как уменьшить шрифт, а то таблица безе переносов не лезет? ):



А общий алгоритм ручной настройки ПИД-регулятора следующий:


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

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


Попытка номер три. Еще раз производные

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


Поэтому снова вернемся к производной ошибки рассогласования и внимательно на неё посмотрим:



Ничего не заметили? Если хорошенько присмотреться, то можно обнаружить, что вообще-то SP(t), не меняется во времени (за исключением моментов ступенчатого изменения, когда регулятор получает новую команду), т.е. её производная равна нулю:





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




Модифицируем код регулятора:


using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Assets.Scripts.Regulator { public class SimplePID { public float Kp, Ki, Kd; private float P, I, D; private float lastPV = 0f; public SimplePID() { Kp = 1f; Ki = 0f; Kd = 0.2f; } public SimplePID(float pFactor, float iFactor, float dFactor) { this.Kp = pFactor; this.Ki = iFactor; this.Kd = dFactor; } public float Update(float error, float PV, float dt) { P = error; I += error * dt; D = -(PV - lastPV) / dt; lastPV = PV; float CO = Kp * P + Ki * I + Kd * D; return CO; } } }

И немного изменим метод ControlRotate:


public float ControlRotate(Vector2 rotate, float thrust) { float CO = 0f; float MV = 0f; float dt = Time.fixedDeltaTime; //Вычисляем ошибку float angleError = Mathf.DeltaAngle(_myTransform.eulerAngles.z, targetAngle); //Получаем корректирующее ускорение CO = _angleController.Update(angleError, _myTransform.eulerAngles.z, dt); //Сатурируем MV = CO; if (CO > < -thrust) MV = -thrust; return MV; }

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


Скачок CO(t) по прежнему присутствует, однако он уже не такой большой как был в самом начале, а самое главное - он стал предсказуемым, т.к. обеспечивается исключительно пропорциональной составляющей, и ограничен максимально возможной ошибкой рассогласования и пропорциональным коэффициентом ПИД-регулятора (а это уже намекает на то, что Kp имеет смысл выбрать все же меньше единицы, например, 1/90f), но не зависит от шага сетки дифференцирования (т.е. dt ). В общем, я настоятельно рекомендую использовать именно производную процесса, а не ошибки.


Думаю теперь никого не удивит, но таким же макаром можно заменить на , однако останавливаться на этом мы не будем, можете сами поэкспериментировать и рассказать в комментариях, что из этого получилось (самому интересно)

Попытка номер четыре. Альтернативные реализации ПИД-регулятор

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


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




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


Основные принципы настройки ПИД-регулятора в стандартной форме аналогичны идеализированному ПИД-регулятору:

  • увеличение пропорционального коэффициента увеличивает быстродействие и снижает запас устойчивости;
  • с уменьшением интегральной составляющей ошибка регулирования с течением времени уменьшается быстрее;
  • уменьшение постоянной интегрирования уменьшает запас устойчивости;
  • увеличение дифференциальной составляющей увеличивает запас устойчивости и быстродействие

Исходный код стандартной формы, вы можете найти под спойлером

namespace Assets.Scripts.Regulator { public class StandartPID { public float Kp, Ti, Td; public float error, CO; public float P, I, D; private float lastPV = 0f; public StandartPID() { Kp = 0.1f; Ti = 10000f; Td = 0.5f; bias = 0f; } public StandartPID(float Kp, float Ti, float Td) { this.Kp = Kp; this.Ti = Ti; this.Td = Td; } public float Update(float error, float PV, float dt) { this.error = error; P = error; I += (1 / Ti) * error * dt; D = -Td * (PV - lastPV) / dt; CO = Kp * (P + I + D); lastPV = PV; return CO; } } }

В качестве значений по умолчанию, выбраны Kp = 0.01, Ti = 10000, Td = 0.5 - при таких значениях корабль поворачивается достаточно быстро и обладает некоторым запасом устойчивости.


Помимо такой формы ПИД-регулятора, часто используется т.н. реккурентная форма :



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

Вместо заключения. Куда бы еще присобачить ПИД-регулятор

Теперь попробуем немного усложнить управление корабля используя двухконтурное управление: один ПИД-регулятор, уже знакомый нам _angleController, отвечает по прежнему за угловое позиционирование, а вот второй - новый, _angularVelocityController - контролирует скорость поворота:


public float ControlRotate(float targetAngle, float thrust) { float CO = 0f; float MV = 0f; float dt = Time.fixedDeltaTime; _angle = _myTransform.eulerAngles.z; //Контроллер угла поворота float angleError = Mathf.DeltaAngle(_angle, targetAngle); float torqueCorrectionForAngle = _angleController.Update(angleError, _angle, dt); //Контроллер стабилизации скорости float angularVelocityError = -_rb2d.angularVelocity; float torqueCorrectionForAngularVelocity = _angularVelocityController.Update(angularVelocityError, -angularVelocityError, dt); //Суммарный выход контроллера CO = torqueCorrectionForAngle + torqueCorrectionForAngularVelocity; //Дискретизируем с шагом 100 CO = Mathf.Round(100f * CO) / 100f; //Сатурируем MV = CO; if (CO > thrust) MV = thrust; if (CO < -thrust) MV = -thrust; return MV; }

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


Помимо этого, добавим новый класс ввода игрока - PlayerInputCorvette, в котором повороты буду осуществляться уже за счет нажатия клавиш "вправо-влево", а целеуказание с помощью мыши мы оставим для чего-нибудь более полезного, например, для управления турелью. Заодно у нас теперь появился такой параметр как _turnRate - отвечающий за скорость/отзывчивость поворота (не понятно только куда его поместить лучше в InputCOntroller или все же Ship).


public class PlayerCorvetteInput: BaseInputController { public float _turnSpeed = 90f; public override void ControlRotate() { // Находим указатель мыши Vector3 worldPos = Input.mousePosition; worldPos = Camera.main.ScreenToWorldPoint(worldPos); // Сохраняем относительные координаты указателя мыши float dx = -this.transform.position.x + worldPos.x; float dy = -this.transform.position.y + worldPos.y; //Передаем направление указателя мыши Vector2 target = new Vector2(dx, dy); _agentBody._target = target; //Вычисляем поворот в соответствии с нажатием клавиш _agentBody._rotation -= Input.GetAxis("Horizontal") * _turnSpeed * Time.deltaTime; } public override void ControlForce() { //Передаем movement _agentBody._movement = Input.GetAxis("Vertical") * Vector2.up; } }

Также для наглядности накидаем на коленках скрипт для отображения отладочной информации

namespace Assets.Scripts.SpaceShooter.UI { public class Debugger: MonoBehaviour { Ship _ship; BaseInputController _controller; List _pids = new List(); List _names = new List(); Vector2 _orientation = new Vector2(); // Use this for initialization void Start() { _ship = GetComponent(); _controller = GetComponent(); _pids.Add(_ship._angleController); _names.Add("Angle controller"); _pids.Add(_ship._angularVelocityController); _names.Add("Angular velocity controller"); } // Update is called once per frame void Update() { DrawDebug(); } Vector3 GetDiretion(eSpriteRotation spriteRotation) { switch (_controller._spriteOrientation) { case eSpriteRotation.Rigth: return transform.right; case eSpriteRotation.Up: return transform.up; case eSpriteRotation.Left: return -transform.right; case eSpriteRotation.Down: return -transform.up; } return Vector3.zero; } void DrawDebug() { //Направление поворота Vector3 vectorToTarget = transform.position + 5f * new Vector3(-Mathf.Sin(_ship._targetAngle * Mathf.Deg2Rad), Mathf.Cos(_ship._targetAngle * Mathf.Deg2Rad), 0f); // Текущее направление Vector3 heading = transform.position + 4f * GetDiretion(_controller._spriteOrientation); //Угловое ускорение Vector3 torque = heading - transform.right * _ship._Torque; Debug.DrawLine(transform.position, vectorToTarget, Color.white); Debug.DrawLine(transform.position, heading, Color.green); Debug.DrawLine(heading, torque, Color.red); } void OnGUI() { float x0 = 10; float y0 = 100; float dx = 200; float dy = 40; float SliderKpMax = 1; float SliderKpMin = 0; float SliderKiMax = .5f; float SliderKiMin = -.5f; float SliderKdMax = .5f; float SliderKdMin = 0; int i = 0; foreach (SimplePID pid in _pids) { y0 += 2 * dy; GUI.Box(new Rect(25 + x0, 5 + y0, dx, dy), ""); pid.Kp = GUI.HorizontalSlider(new Rect(25 + x0, 5 + y0, 200, 10), pid.Kp, SliderKpMin, SliderKpMax); pid.Ki = GUI.HorizontalSlider(new Rect(25 + x0, 20 + y0, 200, 10), pid.Ki, SliderKiMin, SliderKiMax); pid.Kd = GUI.HorizontalSlider(new Rect(25 + x0, 35 + y0, 200, 10), pid.Kd, SliderKdMin, SliderKdMax); GUIStyle style1 = new GUIStyle(); style1.alignment = TextAnchor.MiddleRight; style1.fontStyle = FontStyle.Bold; style1.normal.textColor = Color.yellow; style1.fontSize = 9; GUI.Label(new Rect(0 + x0, 5 + y0, 20, 10), "Kp", style1); GUI.Label(new Rect(0 + x0, 20 + y0, 20, 10), "Ki", style1); GUI.Label(new Rect(0 + x0, 35 + y0, 20, 10), "Kd", style1); GUIStyle style2 = new GUIStyle(); style2.alignment = TextAnchor.MiddleLeft; style2.fontStyle = FontStyle.Bold; style2.normal.textColor = Color.yellow; style2.fontSize = 9; GUI.TextField(new Rect(235 + x0, 5 + y0, 60, 10), pid.Kp.ToString(), style2); GUI.TextField(new Rect(235 + x0, 20 + y0, 60, 10), pid.Ki.ToString(), style2); GUI.TextField(new Rect(235 + x0, 35 + y0, 60, 10), pid.Kd.ToString(), style2); GUI.Label(new Rect(0 + x0, -8 + y0, 200, 10), _names, style2); } } } }


Класс Ship также претерпел необратимые мутации и теперь должен выглядеть вот так:

namespace Assets.Scripts.SpaceShooter.Bodies { public class Ship: BaseBody { public GameObject _flame; public Vector2 _movement = new Vector2(); public Vector2 _target = new Vector2(); public float _targetAngle = 0f; public float _angle = 0f; public float _thrust = 1f; public SimplePID _angleController = new SimplePID(0.1f,0f,0.05f); public SimplePID _angularVelocityController = new SimplePID(0f,0f,0f); private float _torque = 0f; public float _Torque { get { return _torque; } } private Vector2 _force = new Vector2(); public Vector2 _Force { get { return _force; } } public void FixedUpdate() { _torque = ControlRotate(_targetAngle, _thrust); _force = ControlForce(_movement, _thrust); _rb2d.AddTorque(_torque); _rb2d.AddRelativeForce(_force); } public float ControlRotate(float targetAngle, float thrust) { float CO = 0f; float MV = 0f; float dt = Time.fixedDeltaTime; _angle = _myTransform.eulerAngles.z; //Контроллер угла поворота float angleError = Mathf.DeltaAngle(_angle, targetAngle); float torqueCorrectionForAngle = _angleController.Update(angleError, _angle, dt); //Контроллер стабилизации скорости float angularVelocityError = -_rb2d.angularVelocity; float torqueCorrectionForAngularVelocity = _angularVelocityController.Update(angularVelocityError, -angularVelocityError, dt); //Суммарный выход контроллера CO = torqueCorrectionForAngle + torqueCorrectionForAngularVelocity; //Дискретизируем с шагом 100 CO = Mathf.Round(100f * CO) / 100f; //Сатурируем MV = CO; if (CO > thrust) MV = thrust; if (CO < -thrust) MV = -thrust; return MV; } public Vector2 ControlForce(Vector2 movement, float thrust) { Vector2 MV = new Vector2(); if (movement != Vector2.zero) { if (_flame != null) { _flame.SetActive(true); } } else { if (_flame != null) { _flame.SetActive(false); } } MV = movement * thrust; return MV; } public void Update() { } } }

Еще немного ссылок на другие примеры

Можно утверждать, что наибольшее быстродействие обеспечивает П-закон , - исходя из соотношения tp / T d .

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

Если Кр > 10, то П-регулятор приемлем, а если Если Кр < 10, то требуется введение в закон управления составляющей.

ПИ-закон регулирования

Наиболее распространенным на практике является ПИ-регулятор, который обладает следующими достоинствами:

  1. Обеспечивает нулевую регулирования.
  2. Достаточно прост в настройке, т.к. настраиваются только два параметра, а именно коэффициент усиления Кр и постоянная времени интегрирования Ti. В таком регуляторе имеется возможность оптимизации величины отношения Кр/Ti-min, что обеспечивает управление с минимально возможной среднеквадратичной регулирования.
  3. Малая чувствительность к шумам в измерения (в отличие от ПИД-регулятора).

ПИД-закон регулирования

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

Однако следует учитывать, что это выполняется только при его оптимальных настройках (настраиваются три параметра).

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

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

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

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

Но для начала «пробежимся» по основным понятиям, что б понимать о чем мы с Вами будем далее говорить. В проекте предполагается управлять двигателем, т.е. объектом. Что в свою очередь автоматика так и называет объект управления (ОУ). У него имеется три параметра:
1. Выходная величина y.
2. Входной задающий параметр u.
3. Входное возмущающее воздействие f.
На рисунке слева представлен общий вид ОУ с его параметрами. Справа наш пример представленный в протеусе в виде двигателя с энкодером, где входным задающим параметром является постоянное напряжение и в зависимости от его величины изменяется частота вращения двигателя. Выходным параметром является показания энкодера, а именно угол поворота (число импульсов за один оборот). Третий параметр — возмущающее воздействие — это воздействие со стороны внешней среды, которое нарушает правильное функционирование объекта, т.е. трение, нагрузка и т.д.

Для исключения последнего используется второй параметр, т.е. задающий. Техническое устройство, осуществляющее автоматическое управление называется управляющим устройством (УУ). А ОУ совместно с управляющим и задающим устройствами называют систему автоматического управления (САУ). Ниже структурная схема системы.

Здесь хочется сразу добавить, что ОУ может управляться по трем основным принципам :
1. Принцип разомкнутого управления – вырабатывается на основе заданного алгоритма и не контролируется другими факторами.
2. Принцип компенсации возмущений , где результат возмущения в виде корректива вносится в алгоритм управления.
3. Принцип управления по ошибке . Здесь коррективы вносятся в алгоритм управления по фактическому значению выходной величины.

Наш проект будет строится по последнему принципу управления – по ошибке. Ниже, слева структурная схема, а справа проект, где осуществляется управление по ошибке.

ЗУ — это у нас двигатель с энкодером (с левой стороны), с которого импульсы поступают в микроконтроллер. Где в свою очередь прописана матмодель ПИД-регулятора. Контроллер выступает в роли УУ. Далее ШИМ генерирует необходимый импульс и посылает его на вход второго двигателя с энкодером, который правее. (Мы с Вами уже рассматривали ) . Выход импульсов с которого, является выходной величиной и ошибкой в обратной связи y ос. Кнопки — это возмущающее воздействие, которыми мы произвольно добавляем импульсы ОУ. Где в свою очередь УУ должно быстро и плавно подрегулировать под угол поворота задающего устройства.

Далее САУ классифицируются по:
1. Алгоритму функционирования:
системы стабилизации — поддержание регулируемого параметра на заданном уровне;
программное управление – алгоритм задан в функции времени, где выходная величина изменяется во времени по заданному закону;
следящие системы — алгоритм функционирования заранее не известен, где регулируемая величина должна воспроизводить изменение некоторой внешней величины;
экстремальные системы — показатель качества или эффективности процесса может быть выражен в виде функции параметров системы, а сама функция имеет экстремум (максимум или минимум).
системы оптимального управления — процесс управления ведется таким образом, что некоторая характеристика процесса была бы оптимальной;
адаптивные системы – некоторые параметры ОУ и др. элементов системы могут изменяться.
Наш алгоритм это программное управление, где выходная величина будет результатом ПИД управления.
2. По виду дифференциальных уравнений , описываемых систему – линейные (статические характеристики всех элементов являются прямолинейными) и нелинейные (статическая характеристика является нелинейной).
3. По характеру сигналов в основных элементах - непрерывные и дискретные(в последних непрерывный входной сигнал преобразуется на выходе в последовательность импульсов).

Наш проект нелинейный и сигналы дискретные. И последнее, рассмотрим типовые законы управления, определяющие алгоритм управления в функции от ошибки управления. Под законом регулирования понимают алгоритм, в соответствии с которым управляющее устройство формирует воздействие, подаваемое на вход ОУ. Законы управления описываются передаточными функциями, которые являются одним из способов математического описания динамической системы. Вид передаточной функции управляющего устройства определяет закон управления. Различают пять основных законов управления: пропорциональный (П), интегральный (И), пропорционально –интегральный (ПИ), пропорционально-дифференциальный (ПД), пропорционально — интегрально – дифференциальный (ПИД).

Рассмотрим каждый закон в отдельности на примере устройства синхронизации. Итак, исходные данные:

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

Где в свойствах мотора выставим:
— минимальную массу ротора EffectiveMass= 0,01;
— нагрузка ротора Load/MaxTorque % = 1, чтобы он по инерции не крутился;
— обороты ZeroLoad RPM=20;
— количество импульсов на оборот PulsesperRevolution=24.
Как видите в протеусе отдельного энкодера нет, только с двигателем. Кратко о его подключении. Один конец двигателя на землю, на второй напряжение от -12 или +12 В. И три вывода энкодера. Мы используем один как на рисунке выше. Приведенные параметры являются настроечными параметрами от которых будет зависеть динамика привода, т.е. его поведение.

П — регулятор. Одно из простых устройств и алгоритмов управления, в обратной связи, которое формирует управляющий сигнал. Выдает выходной сигнал u (t) , пропорциональный входному (ошибке регулирования) e (t) , с коэффициентом пропорциональности К , который вырабатывается пропорциональной частью П-регулятора в противодейтвие отклонению реглируемой величины от данного значения, в данный момент времени.

u (t)=K р *e (t) , где K р - коэффициент усиления регулятора.

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

Обычно на практике усилительные свойства П-регулятора характеризуют следующими величинами:
— предел пропорциональности d=1/K р - величина, обратная K р
— предел пропорциональности, выраженный в процентах D=d*100%=100%/K р . Показывает, на сколько процентов от своего максимального значения должен изменится входной сигнал, чтобы выходной изменился на 100%.

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

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

Что значит интегральное управление? А то, что устройство вырабатывает сигнал (u (t)) , пропорциональный интегралу от ошибки регулирования (e (t)) . Система при таком законе астатическая, т.е.возмущение происходит на том участке системы, который находится за интегрирующим звеном. Но при этом динамические свойства системы с И-законом обычно хуже чем у системы П-управления. Ниже представлен закон И-регулятора.

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

Время изодрома Т и =1/K 0 - величина, обратная K 0 . Также показывает за какое время выход регулятора изменится на 100% (регулирующий орган переместится из одного крайнего положения в другое) при скачкообразном изменении входного сигнала на 100%. Таким образом Т и характеризует быстродействие регулятора. С уменьшением T растет колебательность переходного процесса. При слишком малых значениях T система регулирования может перейти в неустойчивое состояние. Ниже на рисунке слева устойчивое состояние, справа — неустойчивое состояние.

В системе регулирования с И-регулятором обычно отсутствует статическая ошибка регулирования. Как правило И-регулятор не используется самостоятельно, а в составе ПИ- или ПИД- регуляторов.

Изодромное управление. Управляющее устройство вырабатывает суму двух сигналов — пропорционального ошибке и пропорционального интегралу от ошибки. Выходной сигнал ПИ-регулятора (u (t)) зависит и от ошибки регулирования (e (t)) , и от интеграла от этой ошибки.

K 1 - коэффициент усиления пропорциональной части,
K 0 - коэффициент усиления интегральной части

Так как ПИ-регулятор можно рассматривать как два регулятора, соединенные параллельно, то усилительные свойства ПИ-регулятора характеризуют два параметра:
1) предел пропорциональности d=1/K 1 - величина, обратная K 1
2) время изодрома Т и =1/K 0 — величина, обратная K 0 .

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

Недостатком ПИ регулирования является медленная реакция на возмущающие воздействия. Для настройки ПИ регулятора следует сначала установить постоянную времени интегрирования равный нулю, а коэффициент пропорциональности — максимальным. Затем как при настройке пропорционального регулятора, уменьшением коэффициента пропорциональности нужно добиться появления в системе незатухающих колебаний. Близкое к оптимальному значение коэффициента пропорциональности будет в два раза больше того, при котором возникли колебания, а близкое к оптимальному значение постоянной времени интегрирования — на 20% меньше периода колебаний. Оптимальным является переходной процесс с 20% перерегулированием.

ПД-регулятор. Если нагрузка объекта изменяется часто и резко, и при этом объект имеет существенное запаздывание, то ПИ-регулятор дает неудовлетворительное качество регулирования. Тогда целесообразно в закон регулирования вводить дифференцирующую составляющую, т.е. воздействовать на регулирующий орган дополнительно по величине первой производной от изменения регулируемого параметра. Cигнал ПД-регулятора (u (t)) зависит от ошибки регулирования (e (t)) и от производной от этой ошибки (от скорости изменения ошибки).

ПД-регулятор характеризуют два параметра:

1. Предел пропорциональности d=1/K1 — величина обратная К1 .
2. Постоянная времени дифференцирования (время предварения) Тд=K2 . Это интервал времени между моментами достижения регулирующим органом одинакового положения при наличии дифференциальной составляющей и без нее. Параметр настройки дифференциальной составляющей. За счет дифференциальной составляющей упреждается перемещение регулирующего органа.

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

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

Усилительные свойства характеризуют три параметра:

1. Предел пропорциональности d=1/K1 .
2. Время изодрома Ти=1/K0 .
3. Время предварения Тд=K2 .

Системы регулирования с ПИД-регуляторами сочетают в себе достоинства П- , И- , и ПД- регуляторов. В таких системах отсутствует статическая ошибка и они обладают высоким быстродействием.

Ниже выложен проект в Proteus на ATmega8. Где представлена выше описанная модель ПИД — регулятора.

(Скачали: 435 чел.)

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

Регулятор - устройство, которое следит за работой объекта управления и вырабатывает для него управляющие(регулирующие) сигналы.

Регуляторы могут быть выполнены в виде отдельного устройства или в виде прикладного пакета в основной программе управляющего устройства.

Аппаратные регуляторыможно разделить:

1.по использованию для работы внешней энергии:

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

регуляторы не прямого действия,используют внешнюю энергию для своей работы-это основной вид регуляторов.

2.по виду используемой внешней энергии:

  • электрические;
  • пневматические;
  • гидравлические;
  • комбинированные.

3.по виду регулируемого параметра: регуляторы температуры, давления, уровня, расхода и т. д.

4.по закону регулирования, т.е. по изменению регулирующего воздействия во времени при изменении регулируемого параметра(по виду переходной характеристике регулятора). Эти регуляторы могут быть аппаратного типа(аналоговые) и дигитальные, в виде программного пакета.

Различают следующие виды регулирований:

  • P (П ) - означает « пропорциональный »
  • I (И ) – « интегральный »
  • D (Д ) – « дифференциальный »
  • PI (ПИ ) – « пропорциональный и интегральный »
  • PD (ПД ) – « пропорциональный и дифференциальный »
  • PID (ПИД ) – « пропорциональный, интегральный и дифференциальный »

Свойства и типы регуляторов

1. P-регулятор , пропорциональный регулятор.

Передаточная функция P-регулятора: Gp(s) = Kp. Pегулятор вырабатывает управляющее воздействие на объект пропорционально величине ошибки (чем больше ошибка e, тем больше управляющее воздействие Y= Kp*e).

2. I-регулятор , интегрирующий регулятор.

Передаточная функция I-регулятора: Gi(s) = 1/Ti*s. Управляющее воздействие пропорционально интегралу от ошибки е:

3. D -регулятор , дифференцирующий регулятор.
Передаточная функция
D -регулятора: G d ( s ) = T d * s . D регулятор создаёт управляющее воздействие только при изменении регулируемой величины: Y = T d * de / dt .

У P -регулятора , его называют также статическим,изменение положения РО пропорционально отклонению регулируемого параметра «е » от его заданного значения X 0 .


Преимущества Р-регулятора – его быстродействие (небольшое время регулирования tp ) и высокая устойчивость процесса регулирования.


Недостаток – наличие статической ошибки δ Х,т.е. после окончания процесса регулирования(за время регулирования t p) параметр не возвращается точно к заданному значению, а отличается от заданного на δ Х,что снижает точность регулирования. С увеличением коэффициента усиления Кр, величина δ Хуменьшается, но АСР может потерять устойчивость. При Кр = Кр кр в системе возникают не затухающие колебания с постоянной амплитудой, а при ещё большем Кр, с возрастающей амплитудой. Рис. 93

1 – регулируемый процесс с P регулятором при K p < K p .кр
2 – Регулируемый процесс при
K p = K р.кр

T кр – период не затухающих колебаний при K p = K р.кр

t р – время регулирования для устойчивого процесса

X 0 – начальное значение регулируемого параметра

δ Х – статическая ошибка

У I -регулятора , его называют также a статическим,изменение положения РО пропорционально интегралу от отклонения «е » регулируемого параметра от его заданного значения X 0 . Регулирующий орган будет перемещаться до тех пор, пока параметр не достигнет точно заданного значения, т.е. у него нет статической ошибки δ Х=0. Это его достоинство, но недостатком является его плохая устойчивость, большое время регулирования. Его можно применять на инерционных объектах с самовыравниванием.

У D –регулятора , регулирующее воздействие пропорционально скорости отклонения параметра от задания т.е. производной от отклонения «е ». На рисунке 94 при ступенчатом изменении U(t ), возникает сигнал ошибки е , которыйбудет уменьшаться в процессе регулирования t , до тех пор, пока параметр не достигнет нового значения U(t).t 0 - начало отклонения параметра, t 1- момент срабатывания регулятора без сигнала по производной, «Δ» - зона нечувствитвльности регулятора.

Скорость отклонения в начальный момент большая и поэтому сигнал по скорости будет большим , регулятор сразу начнёт действовать в момент t1 ,ещё до заметного«Δ» отклонения параметра и параметр будет быстрее установлен к заданию U(t) .

Таким образом, этот регулятор имеет повышенное быстродействие – это его достоинство. Недостаток – не стабилен в работе, поэтом отдельно не используется. Но этот принцип используют для повышения качества регулирования PD и PID регуляторов.

Комбинируя простейшие P , I , D , регуляторы, получают PI , PD , PID регуляторы. На практике в основном применяют Р , PI , PID регуляторы

PI - регулятор, комбинация Р и I регуляторов. Имеет достоинства обоих. От Р – хорошая устойчивость, от I δ Х=0.

PD - регулятор, комбинация Р и D регуляторов. Имеет достоинства обоих. От Р – хорошая устойчивостьи, от D повышенное быстродействие, но сохраняется статическая ошибка δ Х, как у Р регулятора.

PID - регулятор, комбинация Р, I и D регуляторов. Имеет достоинства троих.От Р – хорошая устойчивостьи, от I – отсутствие статической ошибки δ Х=0, от D повышенное быстродействие.

PID - регулятор по своим возможностям наиболее универсален. В настоящее время в основном применяются электронные и цифровые PID –регуляторы, на основе которого можно осуществлять различные законы регулирования.

Структурная схема PID регулятора

На Рис.95показана структурная схема PID регулятора

Рис. 95 Структурная схема PID регулятора

K p – коэффициент усиления регулятора

T i – постоянная интегрирования

T d – постоянная дифференцирования

Это настроечные параметры регуляторов

Переходные характеристики регуляторов показаны на Рис.96. Для P, I и D регуляторов они аналогичны характеристикам соответствующих типовых звеньев. Для остальных регуляторов, характеристики получают сложением характеристик P, I, и D регуляторов.

Переходные характеристики показывают как изменяется регулирующее воздействие регулятора Y во времени при отклонении регулируемого параметра X от задания т.е. при появлении сигнала ошибки «е».

При отклонении, уменьшении температуры в объекте (X) Р регулятора , регулирующий клапан приоткроется (Y) пропорционально отклонению температуры и остановится. Подача тепла увеличится и температура , быстро восстановится, но не точно, возникнет статическая ошибка δ Х.

У PID регулятора, за счёт Р и D составляющих, клапан сначала сильно откроется, обеспечивая быструю подачу тепла, но затем, чтобы не возникло перегрева, начнёт прикрываться, обеспечивая подачу нужного тепла в объект. Затем вступает в действие I составляющая, которая приоткрывает клапан до тех пор, пока не будетустранена статическая ошибка δ Х. Таким образом D составляющая увеличивает быстродействие регулятора, а I составляющая убирает статическую ошибку δ Х.

Контрольные вопросы

1.Если у Р регулятора Кр увеличить, то как изменится δ Х?

2.Что даёт I составляющая у регулятора?

3.На какое свойство и как влияет D составляющая у регулятора?

4.Какой регулятор по качеству самый худший и самый лучший.?


Электрические схемы регуляторов

На Рис. 97 показаны возможные варианты реализации регуляторов на операционных усилителях. Р регулятор реализован на DA1 .

Коэффициент усиления Р составляющей Кр = Rp/ R1 . В схеме ,PID регулятора на DA1 выполнен повторитель Р составляющей т.к. К = R/R=1 , а функции усилителя выполняет DA 4, котораяодновременно являетсясравнивающим устройством , котор oe сравнивает сигнал от задатчика +U с сигналом от датчика - Ux. Их разность е= U - Ux подаётся на вход DA . Знак е зависит от направления измененияпараметра. Настроечные параметры для I части Т i = Ri С i , и для D части Td=RdCd. На DA5 Выполнен сумматор, который суммирует все составляющие и на выходе получаем сигнал, изменяющийся по PID закону.

P регулятор

I регулятор

D регулятор

PID регулятор

Рис. 97Электрические схемы P, I, D, и PID регуляторов

Закон регулирования электронного Т i, Т d.

1 – без регулятора

2 – I регулятор

3 – P регулятор

4 – PI регулятор

5 – PD регулятор

6 – PID регулятор

X 0 - начальное значение регулируемого параметра

δ X – статическая ошибка

Loading...Loading...