Умный дом - климат (1 этаж)

Формула ПИД-регулятора








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

ПИД регулятор

Классический ПИД регулятор представляет собой один из самых распространенных автоматических регуляторов. Он настолько универсален, что применяется практически везде, где нужно автоматическое управление. Например температурой: специальные печи, холодильники, инкубаторы, паяльники, сопло и стол 3D принтера, ИК паяльные станции и прочее. Поддержание частоты оборотов мотора, например для станков. Всевозможные балансирующие штуки, гироскутеры, сигвеи, левитирующие магнитные платформы, и конечно же квадрокоптеры и самолёты с автопилотом. Это всё ПИД регулятор. Существуют и другие регуляторы, превосходящие ПИД по адаптивности к управляемой системе и стабильности, например линейно квадратичный. Но, для нашего примитивного управления был выбран именно он.

Составляющие сигнала ПИД-регулятора

Управляющий сигнал, формируемый ПИД-регулятором, сумма трех составляющих:
  • Пропорциональной;
  • Интегральной;
  • Дифференциальной. 

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

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

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

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

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




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




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


где Kp, Ki, Kd – пропорциональный, интегральный, дифференциальный коэффициенты соответственно, e(t) – ошибка рассогласования.

Так выглядит процесс стабилизации параметра температуры при заданной целевой величине и различных вариациях пропорциональной/интегральной/дифференциальной составляющих.

Особенности

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

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

Настройка пропорционального коэффициента

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

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

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

Настройка дифференциального коэффициента

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

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

Настройка интегрального коэффициента

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

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

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

Теплый пол и "идеальная кривая"

К сожалению, максимальная температура теплоносителя в тёплом полу ограничена. Не рекомендуется прогревать поверхность выше +35ºС. Это означает, что мы вынуждены нагревать тёплый пол очень долго (зелёная кривая на графике выше). При таких режимах, пропорциональная и дифференциальная составляющая теряют свою значимость. 

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

Напомню уважаемым читателям, что мы не только не можем произвольно выбирать температуру теплоносителя водяного тёплого пола, но ещё и должны правильно интерпретировать аналоговое значение на выходе PID регулятора. Нам доступны функции закрыть/открыть клапан контура, а получаем мы число от 0 до 10 (настраиваемый диапазон). Добавим новый пропорциональный коэффициент Kt, отвечающий за время работы насоса. Т.е. чем больше аналоговое значение на выходе PID регулятора, тем дольше мы держим открытым клапан (работает насос, идёт подача теплоносителя, и т.д.). 

Инкапсуляция

Как уже было сказано, вся автоматизация собрана на базе Wirenboard контроллера. У него есть свои особенности и способы описания правил/устройств/конфигурации/... В основе описания поведения лежит JavaScript. 

В терминах Wirenboard очень удобно представлять отдельное помещение в виде виртуального устройства, инкапсулируя в описании и атрибуты и методы (по аналогии с ООП). Не забываем снабжать комнаты сообщениями для логов, семафорами открытых дверей/окон, целевыми значениями температуры и прочими важными для работы логики параметрами. 

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


Код самого PID регулятора достаточно прост: 

// Начало кода PID регулятора

var Pid = function(opts) { //Конструктор объектов

  opts = opts || {};

  this._target = opts.target //|| 0;

  this._kp = opts.kp || 0;

  this._ki = opts.ki || 0;

  this._kd = opts.kd || 0;

  this._outputMin = opts.outputMin || 0;

  this._outputMax = opts.outputMax === undefined ? 1 : opts.outputMax;

  this._lastTime = null;

  this._intervalId = null;

};

Pid.prototype.clip = function(x, min, max) { //Функция ограничения выходных значений регулирующего устройства

  if (x < min){

    return min;

  } else if (x > max) {

    return max;

  } else {

    return x;

  }

};

Pid.prototype._clearErrors = function() { //Функция очистки накопленной ошибки PID регулятора

  this._sumError = 0;

  this._lastError = 0;

  this._lastTime = null;

};

Pid.prototype.setup = function(opts) {

  this._target = opts.target === undefined ? this._target : opts.target;

  this._kp = opts.kp === undefined ? this._kp : opts.kp;

  this._ki = opts.ki === undefined ? this._ki : opts.ki;

  this._kd = opts.kd === undefined ? this._kd : opts.kd;

  this._outputMin = opts.outputMin === undefined ? this._outputMin : opts.outputMin;

  this._outputMax = opts.outputMax === undefined ? this._outputMax : opts.outputMax;

  this._clearErrors();

};

Pid.prototype.tune = function(opts) {

  this._kp += opts.kp || 0;

  this._ki += opts.ki || 0;

  this._kd += opts.kd || 0;

  this._clearErrors();

};

Pid.prototype.update = function(input) { //Функция PID регулятора

  var date = new Date();

  var dt = date.getTime() - this._lastTime;

  var error = this._target - input;

  var dError = 0;

  var integralNormalized = 0;

  var differential = 0;

  if (this._lastTime) {

    dError = error - this._lastError;

    this._sumError += error;

    integralNormalized = this._ki * this._sumError * dt;

    differential = (this._kd * dError) / dt;

    integralNormalized = this.clip(integralNormalized,this._outputMin,this._outputMax);

  } else {

    this._clearErrors();

  }

  var output = this._kp * error + integralNormalized - differential;

  output = this.clip(output, this._outputMin, this._outputMax);

  this._lastError = error;

  var date = new Date();

  this._lastTime = date.getTime();

  return output;

};

Pid.prototype.run = function(repeat, interval) {

  if (!this._intervalID) {

    this._intervalID = setInterval(repeat, interval);

    this._clearErrors();

  }

};

Pid.prototype.stop = function() {

  if (this._intervalID) {

    clearInterval(this._intervalID);

  }

  this._intervalID = null;

};

//Создаем объект с нужными параметрами PID регулятора

var myControl = new Pid({

  target: 23, // требуемая величина выходного значения

  kp: 0.5, // пропорциональная составляющая

  ki: 5, // интегральная составляющая

  kd: 0.1, // дифференциальная составляющая

  outputMin: 0, // минимальное значение выхода

  outputMax: 10 // максимальное значение выхода

});

myControl.run(function() {

  var input = dev["wb-msw-v3_23"]["Temperature"]; // Входное значение от датчика в гостиной над диваном

  var output = myControl.update(input); // Выходное значение

  if (output>0) { // Не забываем продлить время открытия клапана на кратную Kt величину миллисекунд

    if (dev["0xa4c138c3412f97e1"]["state"]=="OFF") {

      setTimeout(function () {

        publish("zigbee2mqtt/0xa4c138c3412f97e1/set", JSON.stringify({ "state":"ON" }), 2, false); // включаем насос тёплого пола

      }, 1000);

    }

  } else {

    if (dev["0xa4c138c3412f97e1"]["state"]=="ON") {

      setTimeout(function () {

        publish("zigbee2mqtt/0xa4c138c3412f97e1/set", JSON.stringify({ "state":"OFF" }), 2, false); // выключаем насос тёплого пола

      }, 1000);

    }

  }

  myControl.target = dev["LIVING_ROOM"]["targetTemperature"]; // Обновляем значение целевой температуры

  myControl.setup(myControl); // Для подбора параметров PID

}, 2000); //Интервал запуска ПИД-регулятора каждые 2000 миллисекунд 


Выше приведён код для Wirenboard контроллера, пожалуйста используйте его для примера и адаптируйте под свою специфику. 

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