Суть
теории автоматического управления подразумевает построение такой
системы, которая поддерживает определенный параметр некоторого объекта в
заданном состоянии, например, температуру в печи, или уровень воды в
баке. Для лучшего понимания процесса, удобно сразу рассмотреть
конкретную модель управления, скажем, управление уровнем воды в баке.
Кстати, в учебниках и статьях по ТАУ этот процесс упоминается довольно
часто как отсылка к истории, потому что в далеком 1763 году русский
изобретатель Ползунов И.И. разработал для своего парового двигателя
систему контроля уровня воды. Своего рода классический регулятор,
который, кстати, и является по сути двухпозиционным регулятором как на
этой картинке (воды нет — клапан открыть, вода есть клапан закрыть).
Приоткрывая нижнюю трубу на слив воды, можно будет добиться такого состояния, когда клапан будет открыт полностью, а уровень воды не будет уменьшаться (то есть приток воды станет равным истоку) — система войдет в состояние равновесия. Но проблема в том, что это состояние очень шаткое — любой внешнее возмущающее воздействие может сломать это равновесие — скажем мы можем зачерпнуть из бака некоторое количество воды, и тогда может так получиться что вся вода после этого вытечет из бака (засчет изменения давления), либо труба пополнения забьется и поток уменьшится, либо поплавок сломается и вода перельется. В этом и заключается сложность построения систем управления — реальные системы довольно сложные и имеют много характеристик, которые нужно учитывать. Есть такая характеристика как инерционность системы — если отключить разогретую плиту то она будет оставаться горячей довольно продолжительное время, именно поэтому для управления температурой используют более сложные регуляторы, а именно ПИД — пропорционально интегрально дифференциальный. У каждой из составляющих есть свои особенности — они все по-разному себя ведут при разных условиях, но в совместном использовании позволяют добиться довольно четкого регулирования. Все эти системы просчитываются по формулам, но в данном случае просто важно понимать, как поведет себя система при изменении коэффициентов ПИД регулятора: при увеличении пропорционального звена — начальное воздействие увеличивается и таким образом система сможет быстрее достичь необходимых параметров. Но если переборщить с этим, то возможно появится перерегулирование, что может быть еще хуже чем малое быстродействие системы.
За время существования ТАУ были найдены математические описания многих процессов и теперь мы можем предугадать как поведет себя система при определенных обстоятельствах. Существует множество программ-симуляторов, где можно задать параметры системы, задать параметры регулятора и примерно увидеть что из этого выйдет. Гуляя по просторам интернета наткнулся на сайт Excel для инженеров, и там есть несколько симуляторов регуляторов, благодаря которым можно посмотреть на изменение в процессе при изменении коэффициентов регулирования. Наиболее простой для повторения был, естественно, регулятор ON-OFF, то есть по-русски двухпозиционный регулятор. Напоминаю принцип работы: если текущая величина процесса (Process value = PV) -температура, например — ниже уставки (SP), то регулятор включается (OP) — запускаются тэны на полную мощность. Как только температура достигает уставки — регулятор отключает подачу напряжения на тэны.
Делаем симулятор на JavaScript
Для построения графика буду использовать библиотеку ZingChart —
пользоваться ей оказалось довольно просто и легко. Есть много примеров в
документации по которым можно построить вообще все что угодно. Принцип
построения довольно простой — есть массив значений, которые
автоматически ложатся на график по порядку, и таким образом из пары
сотен точек появляется непрерывный график процесса. Кстати в оригинале в
экселе все делается точно так же — генерируется 300 значений и строится
график.
Собственно именно генерация значений и является самым сложным, а именно
сложность правильно описать процесс, который правильно реагирует на наши
управляющие воздействия — включение тэнов — температура растет,
выключение — падает, плюс сюда же нужно заложить инерционность системы.
Кроме того среда нагрева может быть разная и некоторые среды быстрее
нагреваются и остывают, а некоторые наоборот, а если регулируем уровень,
то при одинаковом потоке сверху, уровень подниматься будет выше в том
баке, где площадь дна меньше. Это все я веду к тому, что процесс будет
зависеть и от коэффициента передачи (усиления). В оригинале в процесс
введен еще параметр задержки (ну типа система не сразу реагирует на
управляющий сигнал), но я решил от него отказаться — достаточно и двух.
Зато добавил изменение уставки, хотя по сути получилось что уставка
может меняться от нуля до 100, свыше 100 процесс начинает вести себя не
так, и судя по всему причина в том что формула процесса универсальная и
не описывает частный случай. В общем приступаем:
Создаем 5 полей для ввода параметров, все это помещаем в таблицу,
которую выше в css окрашиваем в красивый цвет и помещаем по центру:
<table align="center" oninput="setvalues ();">
<tr>
<td>
Process parameters <br>
Gain: <input id="gain" type="number" value ="1" ><br>
Time Constant: <input id="time" type="number" value ="100" ><br>
</td>
<td>
Control parameters <br>
SetPoint(0-100): <input id="sp" type="number" value ="50"><br>
Hysteresis: <input id="hyst" type="number" value ="1">%<br>
</td>
<td>
Plot parameters <br>
Points: <input id="points" type="number" value ="200"><br>
</td>
</tr>
</table>
Как видно при каждом изменении значения полей внутри таблицы будет вызываться функция setvalues(). В ней мы считываем данные из каждого поля в специальные переменные
let gain = document.getElementById('gain').value;
let time = document.getElementById('time').value;
let sp = document.getElementById('sp').value;
let points = document.getElementById('points').value;
let hyst = document.getElementById('hyst').value;
Как уже говорилось для построения графика нужны массивы с данными на основании которых и будет строиться график, поэтому создаем кучку массивов:
let pv = []; // массив данных процесса
let pv100 = []; //то же но *100
let op = []; // управляющий сигнал 1 вкл, 0 выкл
let pvp = 0; //предыдущее значение процесса
let low = sp-sp*hyst/100;//нижняя граница гистерезиса
let high = +sp+(sp*hyst/100); // верхняя граница гистерезиса
let st=true; // старт нагрева
Немного поясню за гистерезис. Ситуация такая: когда температура достигает заданного значения, тэны отключаются и сразу же (на самом деле не сразу, т.к. есть инерция) начинается процесс остывания. И остыв на один градус а то и некоторую долю градуса — система понимает что уже снова вышла за рамки задания и нужно снова включать тэны. В таком режиме тэны будут включаться и выключаться очень часто, может быть и такое что несколько раз за минуту — для оборудования такой режим не очень хороший, и поэтому чтобы исключить такие колебания вводят так называемый гистерезис — deadband — зона нечувствительности — скажем 1 градус выше и ниже уставки мы не будем реагировать, и тогда количество переключений можно значительно сократить. Поэтому в переменной low находится нижняя граница уставки, а в high верхняя. Переменная st отслеживает достижение верхнего уровня и позволяет снизиться процессу до нижнего. Логика всего процесса находится в цикле:
for (var i=0;i<points;i++) {
if (pvp<=(low/100)) {
st=true;
op[i]=1;
}//
else if (pvp<=(high/100)&& st) op[i] = 1;
else { st=false; op[i]=0;}
let a = Math.pow(2.71828182845904, -1/time);
let b = gain*(1 -a);
pv[i] = op[i]*b+pvp*a;
pv100[i] = pv[i]*100;
pvp = pv[i];
}
По итогу мы получаем массив с заданным количеством точек, который отправляем скрипту построения графиков.
scaleX: {
zooming: true
},
series: [
{ values: op , text: 'OP' },
{ values: pv100 , text: 'PV'}
]
};
Полный код можно найти на моем гитхабе:https://github.com/boolkin/on-off-simulator
Ну а поскольку симулятор готов, самое время заценить как он работает. Потестить можно тут этот же код но на гитхабе: on-off control simulator
Стандартная настройка: усилительное звено 1, постоянная времени 100 секунд, гистерезис 2%
Теперь если задать уставку побольше, например 92, то внезапно процесс
сильно замедляется, хотя при этом уставку 50 он набирает за те же 71
секунды, но уже потом кривая начинает приближаться к заданию медленнее
по экспоненциальной зависимости, и доходит до уставки лишь за 278
секунд, из-за чего пришлось расширить диапазон построения графика до 300
точек
Данный пример очень показательный, переводя ситуацию на модель с
температурой можно сделать такой вывод, что не хватает мощности
нагревателя: нагреватель загружен на 100% но при этом температура
перестает расти после определенного момента. Решений может быть
несколько: поставить второй такой же нагревательный элемент, или
подавать напряжение на него в 2 раза больше (но это может повредить
тэн), либо поставить нагреватель в 2 раза большей мощности, либо залить в
систему более теплопроводящую жидкость если речь идет о нагреве
жидкости. Довольно интересно то, что если нужно поддерживать температуру
в районе 95-100 градусов, то не нужно даже ставить регулятор — поставил
такой маломощный нагреватель, врубил его на полную катушку и все —
через 300 секунд (условные 300 секунд) можно получить желаемые 100
градусов. Проблема такой системы в том что если открыть окно зимой в
минус 40, то температура тут же просядет и довольно существенно, да и
быстродействие такой системы очень малое.
Давайте увеличим усилительное звено gain в 2 раза — это как будто
поставить второй такой же нагревательный элемент, или добавить еще одну
трубу на пополнение бака.
График получился тоже довольно показательный — температура до 51 градуса
реально добралась в 2 раза быстрее, а вот до 92 добралось раза в 4
быстрее. Объясняется это тем что зависимость экспоненциальная, а
экспоненциальная она потому что в описании процесса присутствует
постоянная времени которая отвечает за описание свойства инерционности
системы ( в расчете текущего значения PV есть промежуточные вычисления
let a = Math.pow(2.71828182845904, -1/time);) Про это есть немного в
википедии ru.wikipedia.org/wiki/Динамическое_звено
Комментариев нет:
Отправить комментарий