|
OwenLogic: эмулятор объекта управления (для отладки регуляторов)
1 ВВЕДЕНИЕ
При разработке регулятора актуальным остаётся вопрос проверки и отладки алгоритма до начала ПНР на объекте.
Для регулятора с управлением исполнительным механизмом через аналоговый выход можно собрать макет из датчика температуры, твердотельного реле с регулируемым выходом, нагревательного элемента (лампы накаливания или керамического резистором).
Для регулятора с трёхпозиционным исполнительным механизмом собрать простой макет уже затруднительно.
Хорошую идею предлагают разработчики ПЛК Siemens S7-300 - библиотека этого ПЛК содержит три функциональных блока (ФБ) эмулятора объекта управления FB100, FB101 и FB102, соответственно для случаев непрерывного, трёхпозизионного и ШИМ управления исполнительным механизмом.
Основой данных ФБ является FB100, на вход которого подаётся состояние выхода регулятора и производятся последующие вычисления. Для ФБ FB101 и FB102 состояния управляющих входов сначала преобразуются в положение регулирующего органа исполнительного механизма, а потом производятся вычисления как в FB100.
Алгоритм FB100 эмулирует объект управления, который описывается тремя последовательно соединёнными апериодическими звеньями 1-го порядка. Общий коэффициент усиления позволяет сделать приведение выхода эмулятора к любым единицам измерения.
С подробным описанием ФБ FB100, FB101 и FB102 можно ознакомиться в документации к ПЛК.
Предлагаю самостоятельные реализации эмуляторов для среды разработки OwenLogic, появившиеся благодаря идеям FB100, FB101. Каждый из эмуляторов реализован в двух вариантах - на языках программирования ST и FBD, что связано с неравноценной реализацией отсчёта времени и возможностей вложения полученных ФБ в другие ФБ в среде Owen Logic.
2 ЭМУЛЯТОР ОБЪЕКТА УПРАВЛЕНИЯ С "НЕПРЕРЫВНЫМ" УПРАВЛЕНИЕМ
2.1 Состав алгоритма
Определимся со структурой алгоритма. ФБ будет состоять из двух частей: инициализация, три последовательных апериодических звена. Для эмуляции помех, добавлен вход, суммирующийся с позицией регулирующего клапана перед апериодическими звеньями.
Структура эмулятора объекта управления с "непрерывным" регулированием показана на рисунке

Инициализация определится по результатам реализации алгоритма интегрирования диференциальных уравнений.
Для интегрирования дифференциальных уравнений выбираю метод Эйлера по причине простоты реализации и предположительного использования ФБ для эмуляции объектов регулирования с постоянными времени значительно превышающими машинный цикл, т.е. удовлетворительной точности вычислений.
2.2 Интегрирование дифференциальных уравнений
Для вычисления значения выхода апериодического звена нужно интегрировать дифференциальное уравнение.
Вывод формулы для численного интегрирования
Передаточная функция апериодического звена 1-го порядка в операторной форме
Уравнение в операторной форме
Дифференциальное уравнение
Приняв начальные условия нулевыми и решая методом Эйлера получаем значение выхода на каждом цикле вычислений.
Пусть длительность цикла равна h.
Подставляя полученное значение y первого звена в качестве параметра x второго звена, и проведя аналогичные вычисления, сможем получить выход из второго звена. Аналогично получим выход из третьего звена.
2.2 Реализация эмулятора с "непрерывным" управляющим входом
На языке ST
| Pascal | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
| ///<Description>Эмулятор объекта управления. Эмулируется последовательное соединение трёх апериодических звеньев 1-го порядка.</Description>
///<Author>!!FPA!!</Author>
///<GroupName>Управляющие и регулирующие модули</GroupName>
function_block Emulator_Cont_ST_
var_input
///<Description>Перезапуск работы блока (инициализация всех переменных состояния) по фронту</Description>
xReset: bool := false;
///<Description>Входная переменная. Управляющий сигнал с ПИД</Description>
rVLV_Pos: real;
///<Description>Внешнее возмущающее воздействие (суммируется с rVLV_Pos для вычислений внутри ФБ)</Description>
rDisturbance: REAL;
///<Description>Значение выхода при rVLV_Pos=0</Description>
rPV_0: REAL:=20.0;
///<Description>Коэффициент передачи объекта управления (трёх последовательных апериодических звеньев 1-го порядка)</Description>
rGain: REAL:=1.5;
///<Description>Постоянная времени первого апериодического звена 1-го порядка, [мс]</Description>
dwTime_T1: udint:=60000;
///<Description>Постоянная времени второго апериодического звена 1-го порядка, [мс]</Description>
dwTime_T2: udint:=10000;
///<Description>Постоянная времени третьего апериодического звена 1-го порядка, [мс]</Description>
dwTime_T3: udint:=0;
end_var
var_output
///<Description>Выходное значение переменной процесса</Description>
rPV: REAL;
end_var
var
dwCurrent, dwCycle: udint;
dwPrevious: udint := 0;
bReset_previous: bool := false;
rCycle: REAL;
rT1: REAL;
rT2: REAL;
rT3: REAL;
rPV_Prev1: real;
rPV_Prev2: real;
rPV_Prev3: real;
rPV_Inner: real;
end_var
// вычисление длительности предыдущего цикла
dwCurrent := time_to_udint(get_time());
dwCycle := dwCurrent - dwPrevious;
dwPrevious := dwCurrent;
if (xReset and (not bReset_previous)) or (dwCycle = 0) then
rPV_Prev1 := (rVLV_Pos + rDisturbance) * rGain;
rPV_Prev2 := rPV_Prev1;
rPV_Prev3 := rPV_Prev1;
rPV := rPV_Prev1 + rPV_0;
else
rCycle := udint_to_real(dwCycle);
rT1 := udint_to_real(dwTime_T1);
rT2 := udint_to_real(dwTime_T2);
rT3 := udint_to_real(dwTime_T3);
// вычисление выхода
rPV_Inner := (rVLV_Pos + rDisturbance) * rGain;
if rT1 >= rCycle then
rPV_Inner := rPV_Prev1 + rCycle * (rPV_Inner - rPV_Prev1) / rT1;
rPV_Prev1 := rPV_Inner;
end_if;
if rT2 >= rCycle then
rPV_Inner := rPV_Prev2 + rCycle * (rPV_Inner - rPV_Prev2) / rT2;
rPV_Prev2 := rPV_Inner;
end_if;
if rT3 >= rCycle then
rPV_Inner := rPV_Prev3 + rCycle * (rPV_Inner - rPV_Prev3) / rT3;
rPV_Prev3 := rPV_Inner;
end_if;
rPV := rPV_0 + rPV_Inner;
end_if;
bReset_previous := xReset;
end_function_block |
|
2.3 Описание функционального блока Emulator_Cont_
На входы функционального блока Emulator_Cont_ подаются следующие сигналы
| Обозначение | Тип | Описание |
|---|
| xStart | BOOL | По переднему фронту входа xStart произойдёт перезапуск всех переменных состояния.
Значение выхода rPV станет равным установившемуся значению
rPV := (rVLV_Pos + rDisturbance) × rGain + rPV_0 | | rVLV_Pos | REAL | Входной сигнал от регулятора (требуемое положение регулирующего клапана) | | rDisturbance | REAL | Значение внешнего возмущающего воздействия (помехи), приведённое к положению клапана. | | rPV_0 | REAL | Значение выхода, которое установится при нулевом сигнале от регулятора (rVLV_Pos=0). | | rGain | REAL | Коэффициент передачи объекта управления (трёх последовательных апериодических звеньев 1-го порядка). | | dwTime_T1 | UDINT | Постоянная времени первого апериодического звена 1-го порядка. Единицы измерения: мс. | | dwTime_T2 | UDINT | Постоянная времени второго апериодического звена 1-го порядка. Единицы измерения: мс. | | dwTime_T3 | UDINT | Постоянная времени третьего апериодического звена 1-го порядка. Единицы измерения: мс. |
С выходов функционального блока Emulator_Cont_ принимаются сигналы
| Обозначение | Тип | Описание |
|---|
| rPV | REAL | Выходное значение переменной процесса. |
Для эмуляции внешних помех на вход rDisturbance подаётся значение, отличное от нулевого. Это значение суммируется с входным положением регулирующего органа и полученная сумма участвует в вычислении переменной процесса. Т.е. установившееся значение переменной процесса стремится к
rPV := (rVLV_Pos + rDisturbance) × rGain + rPV_0
Имеется возможность эмулировать выходные значения различных диапазонов.
Примеры настройки диапазона переменной процесса
Пример 1.
Диапазон входного сигнала от регулятора (выхода регулятора) от 0 до 100 %.
Соответствующий ему диапазон изменения выхода объекта от 20 до 80 °C.
Для получения требуемого диапазона необходимо задать rGain=0.6, rPV_0=20.
Пример 2.
Диапазон входного сигнала от регулятора (выхода регулятора) от 0 до 100 %.
Соответствующий ему диапазон изменения выхода объекта от 0 до 10000 Па.
Для получения требуемого диапазона необходимо задать rGain=100, rPV_0=0.
3 ЭМУЛЯТОР ОБЪЕКТА УПРАВЛЕНИЯ С ТРЁХПОЗИЦИОННЫМ УПРАВЛЕНИЕМ
3.1 Состав алгоритма
Определимся со структурой алгоритма. ФБ будет состоять из двух частей: эмуляция привода с трёхпозиционным управлением (на вход которого поступают сигналы "открыть" и "закрыть", а на выходе формируются сигналы положения регулирующего клапана и состояния концевых выключателей "открыт" и "закрыт") и эмуляция объекта управления с непрерывным управлением. Итого - из четырёх частей: инициализация, пересчёт управляющих импульсов в положение регулирующего органа, эмуляция концевых выключателей "открыт" и "закрыт", три последовательных апериодических звена.
Структура эмулятора объекта управления с трёхпозиционным регулированием показана на рисунке

Инициализация определится по результатам выбора алгоритмов пересчёта и интегрирования диференциальных уравнений.
Пересчёт управляющих сигналов тоже не должен вызывать трудностей, можно усложнить модель, сделав различными длительности полного открытия и закрытия регулирующего органа.
На языке ST
| Pascal | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
| ///<Description>Эмулятор объекта управления. Эмулируется последовательное соединение трёх апериодических звеньев 1-го порядка. Выходной параметр изменяется под воздействием трехпозиционного ПИД регулятора.</Description>
///<Author>!!FPA!!</Author>
///<GroupName>Управляющие и регулирующие модули</GroupName>
function_block Emulator_3Pos_
var_input
///<Description>Перезапуск работы блока (инициализация всех переменных состояния) по фронту</Description>
xReset: bool := false;
///<Description>Сигнал Открыть</Description>
xOpen: BOOL;
///<Description>Сигнал Закрыть</Description>
xClose: BOOL;
///<Description>Время полного хода исполнительного устройства при открытии</Description>
dwFullStroke_Open: udint:=30000;
///<Description>Время полного хода исполнительного устройства при закрытии</Description>
dwFullStroke_Close: udint:=30000;
///<Description>Время выборки люфта исполнительного устройства при открытии</Description>
dwVLV_Backlash_Open: udint := 0;
///<Description>Время выборки люфта исполнительного устройства при закрытии</Description>
dwVLV_Backlash_Close: udint := 0;
///<Description>Верхний предел обратного сигнала клапана. Для клапана с контролем положения</Description>
rVLV_Max: REAL:=100.0;
///<Description>Нижний предел обратного сигнала клапана. Для клапана с контролем положения</Description>
rVLV_Min: REAL:=0.0;
///<Description>Внешнее возмущающее воздействие (суммируется с rVLV_Pos для вычислений внутри ФБ)</Description>
rDisturbance: REAL;
///<Description>Значение выхода при rVLV_Pos=0</Description>
rPV_0: REAL:=20.0;
///<Description>Коэффициент передачи объекта управления (трёх последовательных апериодических звеньев 1-го порядка)</Description>
rGain: REAL:=1.5;
///<Description>Постоянная времени первого апериодического звена 1-го порядка, [мс]</Description>
dwTime_T1: udint:=60000;
///<Description>Постоянная времени второго апериодического звена 1-го порядка, [мс]</Description>
dwTime_T2: udint:=10000;
///<Description>Постоянная времени третьего апериодического звена 1-го порядка, [мс]</Description>
dwTime_T3: udint:=0;
end_var
var_output
///<Description>Выходное значение переменной процесса</Description>
rPV: REAL;
///<Description>Обратный сигнал клапана. Для клапана с контролем положения</Description>
rVLV_Pos: REAL;
///<Description>Сигнал верхнего предела клапана</Description>
bVLV_Opened: BOOL;
///<Description>Сигнал нижнего предела клапана</Description>
bVLV_Closed: BOOL;
end_var
var
dwCurrent, dwCycle: udint;
dwPrevious: udint := 0;
bReset_previous: bool := false;
rCycle: REAL;
rFullStroke_Open: REAL;
rFullStroke_Close: REAL;
rPos: real;
rT1: REAL;
rT2: REAL;
rT3: REAL;
h: real;
rPV_Prev1: real;
rPV_Prev2: real;
rPV_Prev3: real;
rPV_Inner: real;
dwVLV_Backlash_Open_: udint; // выбранная часть люфта при открытии
dwVLV_Backlash_Close_: udint; // выбранная часть люфта при закрытии
dwRunTime: udint; // часть времени dwCycle, потраченная на перемещение
end_var
// вычисление времени текущего цикла
dwCurrent := time_to_udint(get_time());
dwCycle := dwCurrent - dwPrevious;
dwPrevious := dwCurrent;
if (xReset and (not bReset_previous)) or (dwCycle = 0) then
rPV_Prev1 := (rVLV_Pos - rVLV_Min + rDisturbance) * rGain;
rPV_Prev2 := rPV_Prev1;
rPV_Prev3 := rPV_Prev1;
rPV := rPV_Prev1 + rPV_0;
dwVLV_Backlash_Open_ := 0;
dwVLV_Backlash_Close_ := 0;
else
// проверка ограничений диапазонов входных переменных
if dwCycle <= 1 then
dwCycle := 1;
end_if;
if dwFullStroke_Open < dwCycle then
dwFullStroke_Open := dwCycle;
end_if;
if dwFullStroke_Close < dwCycle then
dwFullStroke_Close := dwCycle;
end_if;
rCycle := udint_to_real(dwCycle);
rT1 := udint_to_real(dwTime_T1);
rT2 := udint_to_real(dwTime_T2);
rT3 := udint_to_real(dwTime_T3);
rFullStroke_Open := udint_to_real(dwFullStroke_Open);
rFullStroke_Close := udint_to_real(dwFullStroke_Close);
// обработка люфта - часть сигнала перемещения расходуется на компенсацию люфта
dwRunTime := dwCycle;
if xOpen then
if dwRunTime <= dwVLV_Backlash_Close_ then
dwVLV_Backlash_Close_ := dwVLV_Backlash_Close_ - dwRunTime;
else
dwVLV_Backlash_Close_ := 0;
end_if;
if dwVLV_Backlash_Open_ < dwVLV_Backlash_Open then
dwVLV_Backlash_Open_ := dwVLV_Backlash_Open_ + dwRunTime;
if dwVLV_Backlash_Open_ > dwVLV_Backlash_Open then
dwRunTime := dwVLV_Backlash_Open_ - dwVLV_Backlash_Open;
dwVLV_Backlash_Open_ := dwVLV_Backlash_Open;
else
dwRunTime := 0;
end_if;
end_if;
end_if;
if xClose then
if dwRunTime <=dwVLV_Backlash_Open_ then
dwVLV_Backlash_Open_ := dwVLV_Backlash_Open_ - dwRunTime;
else
dwVLV_Backlash_Open_ := 0;
end_if;
if dwVLV_Backlash_Close_ < dwVLV_Backlash_Close then
dwVLV_Backlash_Close_ := dwVLV_Backlash_Close_ + dwRunTime;
if dwVLV_Backlash_Close_ > dwVLV_Backlash_Close then
dwRunTime := dwVLV_Backlash_Close_ - dwVLV_Backlash_Close;
dwVLV_Backlash_Close_ := dwVLV_Backlash_Close;
else
dwRunTime := 0;
end_if;
end_if;
end_if;
// вычисление положения клапана, концевых переключателей
h := (rVLV_Max - rVLV_Min) * udint_to_real(dwRunTime);
if xOpen then
rPos := rVLV_Pos + h / rFullStroke_Open;
elsif xClose then
rPos := rVLV_Pos - h / rFullStroke_Close;
else
rPos := rVLV_Pos;
end_if;
if rPos >= rVLV_Max then
rPos := rVLV_Max;
bVLV_Opened := true;
bVLV_Closed := false;
elsif rPos <= rVLV_Min then
rPos := rVLV_Min;
bVLV_Opened := false;
bVLV_Closed := true;
else
bVLV_Opened := false;
bVLV_Closed := false;
end_if;
rVLV_Pos := rPos;
// вычисление выхода
rPV_Inner := (rVLV_Pos - rVLV_Min + rDisturbance) * rGain;
if dwTime_T1 >= dwCycle then
rPV_Inner := rPV_Prev1 + rCycle * (rPV_Inner - rPV_Prev1) / rT1;
rPV_Prev1 := rPV_Inner;
end_if;
if dwTime_T2 >= dwCycle then
rPV_Inner := rPV_Prev2 + rCycle * (rPV_Inner - rPV_Prev2) / rT2;
rPV_Prev2 := rPV_Inner;
end_if;
if dwTime_T3 >= dwCycle then
rPV_Inner := rPV_Prev3 + rCycle * (rPV_Inner - rPV_Prev3) / rT3;
rPV_Prev3 := rPV_Inner;
end_if;
rPV := rPV_0 + rPV_Inner;
end_if;
bReset_previous := xReset;
end_function_block |
|
3.2 Описание функционального блока Emulator_3Pos_
На вход функционального блока Emulator_3Pos_ подаются следующие сигналы
| Обозначение | Тип | Описание |
|---|
| xStart | BOOL | По переднему фронту входа xStart произойдёт перезапуск всех переменных состояния.
Значение выхода rPV станет равным установившемуся значению
rPV := (rVLV_Pos - rVLV_Min + rDisturbance) × rGain + rPV_0
При этом, расчётное значение положения регулирующего органа останется без изменения. | | xOpen | BOOL | Команда "открыть" регулирующий орган от регулятора. | | xClose | BOOL | Команда "закрыть" регулирующий орган от регулятора. | | dwFullStroke_Open | UDINT | Время полного хода исполнительного устройства при открытии, мс. | | dwFullStroke_Close | UDINT | Время полного хода исполнительного устройства при закрытии, мс. | | dwVLV_Backlash_Open | UDINT | Время выборки люфта исполнительного устройства при открытии, мс. | | dwVLV_Backlash_Close | UDINT | Время выборки люфта исполнительного устройства при закрытии, мс. | | rVLV_Max | REAL | Верхний предел обратного сигнала клапана. Для клапана с контролем положения. | | rVLV_Min | REAL | Нижний предел обратного сигнала клапана. Для клапана с контролем положения. | | rDisturbance | REAL | Значение внешнего возмущающего воздействия (помехи), приведённое к положению клапана. | | rPV_0 | REAL | Значение выхода, которое установится при нулевом сигнале от регулятора (rVLV_Pos=rVLV_Min). | | rGain | REAL | Коэффициент передачи объекта управления (трёх последовательных апериодических звеньев 1-го порядка). | | dwTime_T1 | UDINT | Постоянная времени первого апериодического звена 1-го порядка. Единицы измерения: мс. | | dwTime_T2 | UDINT | Постоянная времени второго апериодического звена 1-го порядка. Единицы измерения: мс. | | dwTime_T3 | UDINT | Постоянная времени третьего апериодического звена 1-го порядка. Единицы измерения: мс. |
С выходов функционального блока Emulator_3Pos_ принимаются сигналы
| Обозначение | Тип | Описание |
|---|
| rPV | REAL | Выходное значение переменной процесса. | | rVLV_Pos | REAL | Расчётное положение регулирующего клапана. | | bVLV_Opened | BOOL | Состояние концевого выключателя "открыто". | | bVLV_Closed | BOOL | Состояние концевого выключателя "закрыто". |
Для эмуляции внешних помех на вход rDisturbance подаётся значение, отличное от нулевого. Это значение суммируется с расчётным положением регулирующего органа и полученная сумма участвует в вычислении переменной процесса. Т.е. установившееся значение переменной процесса стремится к
rPV := (rVLV_Pos - rVLV_Min + rDisturbance) × rGain + rPV_0
Имеется возможность эмулировать выходные значения различных диапазонов.
Примеры настройки диапазона переменной процесса
Пример 1.
Диапазон входного сигнала от регулятора (выхода регулятора) от rVLV_Min=0 до rVLV_Max=100 %.
Соответствующий ему диапазон изменения выхода объекта от 20 до 80 °C.
Для получения требуемого диапазона необходимо задать rGain=0.6, rPV_0=20.
Пример 2.
Диапазон входного сигнала от регулятора (выхода регулятора) от rVLV_Min=0 до rVLV_Max=100 %.
Соответствующий ему диапазон изменения выхода объекта от 0 до 10000 Па.
Для получения требуемого диапазона необходимо задать rGain=100, rPV_0=0.
4 ВЫВОДЫ И РЕКОМЕНДАЦИИ
Созданы эмуляторы объектов управления на основе трёх апериодических звеньев 1-го порядка для непрерывного и трёхпозиционного регулирования.
Эмуляторы позволяют экспериментально проверить работоспособность регуляторов на этапе создания программы до выхода на ПНР.
Алгоритм эмулятора с трёхпозиционным управлением получился достаточно сложным из-за добавившейся модели трёхпозиционного привода, программа на языке FBD оказалась бы излишне трудоёмкой, поэтому решил, что целесообразно реализовать только на ST.
Возможно, если нужда и ограничения среды программирования OwenLogic вынудят - в будущем реализую и на FBD.
Одной из причин неоправданного усложнения программы на FBD является то, что отсчёт времени в среде программирования OwenLogic очень по разному реализован для языков ST и FBD, и приводит к различиям в реализациях:- для ST возможно вызовом функции get_time() получить текущее время, вычислить длительность прошедшего машинного цикла и на основе этой длительности выполнять пересчёт состояний объекта,
- для FBD такой возможности нет и приходится период пересчёта реализовывать при помощи генератора BLINK и вычислений только в моменты появления фронта на выходе генератора,
- для FBD в режиме эмуляции минимальная длительность периодов в параметрах таймеров и генератора составляет около 100 мс, поэтому пересчёт выполняется с такой периодичностью,
- для ST в режиме эмуляции длительность машинного цикла вычисляется и, обычно, составляет 30 мс.
Полагаю, что указанные ограничения носят хоть и длительный, но всё же временный характер, и настанет время, когда реализации одного алгоритма на FBD будут строже соответствовать.
Возможно, есть смысл все положения регулирующего органа всегда вычислять в процентах, а если потребуется иные единицы измерения - масштабирование выполнять дополнительными элементами. Это сократит количество входов, переменных и упростит некоторые формулы.
5 ЛИТЕРАТУРА
1. Примеры программ для технологических функций. A5E00130042-01 (является частью документа 6ES7 398-8FA00-8AA0)
https://www.siemens-ru.com/doc... ogramm.pdf
6 ПРИЛОЖЕНИЕ
Тест эмулятора объекта управления от непрерывного регулятора
Test_Emu_Cont.owle.7z
Тест эмулятора объекта управления от трёхпозиционного регулятора
Test_EMU_3pos.owle.7z
|