Отрегулируйте давление в бойлере барабана

В этом примере показано, как использовать программное обеспечение Simulink® Control Design™, с помощью бойлера барабана в качестве примера приложения. Используя функцию поиска рабочей точки, пример иллюстрирует линеаризацию модели, а также последующего наблюдателя состояния и проект LQR. В этой модели бойлера барабана проблема управления состоит в том, чтобы отрегулировать давление бойлера перед лицом случайных колебаний тепла от печи путем корректировки скорости потока жидкости подачи воды и номинального поданного тепла. В данном примере 95% случайных колебаний тепла меньше 50% номинальной теплоты сгорания, которая весьма обычна для запущенного печью бойлера.

Откройте модель

Откройте модель Simulink.

mdl = 'Boiler_Demo';
open_system(mdl)

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

Найдите номинальную рабочую точку и линеаризуйте модель

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

Создайте спецификацию рабочей точки, где значения состояния известны.

opspec = operspec(mdl);
opspec.States(1).Known = 1;
opspec.States(2).Known = 1;
opspec.States(3).Known = [1;1];

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

opspec.Inputs(1).Known = [0;0];     % Inputs unknown
opspec.Inputs(1).Min = [0;0];       % Input minimum value

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

opspec = addoutputspec(opspec,[mdl '/Boiler'],1);
opspec.Outputs(1).Known = 0;    % Outputs unknown
opspec.Outputs(1).Min = 0;      % Output minimum value

Вычислите рабочую точку и сгенерируйте отчет поиска рабочей точки.

[opSS,opReport] = findop(mdl,opspec);
 Operating point search report:
---------------------------------

opreport = 


 Operating point search report for the Model Boiler_Demo.
 (Time-Varying Components Evaluated at time t=0)

Operating point specifications were successfully met.
States: 
----------
    <strong>Min</strong>     <strong>x</strong>     <strong>Max</strong>    <strong>dxMin</strong>        <strong>dx</strong>         <strong>dxMax</strong>
    <strong>___</strong>    <strong>___</strong>    <strong>___</strong>    <strong>_____</strong>    <strong>___________</strong>    <strong>_____</strong>

(1.) Boiler_Demo/Boiler/Steam volume
    5.6    5.6    5.6      0       7.8501e-13      0  
(2.) Boiler_Demo/Boiler/Temperature
    180    180    180      0      -5.9262e-14      0  
(3.) Boiler_Demo/Observer/Internal
      0      0      0      0                0      0  
      0      0      0      0                0      0  

Inputs: 
----------
    <strong>Min</strong>        <strong>u</strong>         <strong>Max</strong>
    <strong>___</strong>    <strong>__________</strong>    <strong>___</strong>

(1.) Boiler_Demo/Input
     0     2.4107e+05    Inf
     0         100.13    Inf

Outputs: 
----------
    <strong>Min</strong>      <strong>y</strong>       <strong>Max</strong>
    <strong>___</strong>    <strong>______</strong>    <strong>___</strong>

(1.) Boiler_Demo/Boiler
     0     1002.4    Inf

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

Boiler_io(1) = linio([mdl '/Sum'],1,'input');
Boiler_io(2) = linio([mdl '/Demux'],2,'input');

Затем задайте выходные точки разомкнутого контура для линеаризации.

Boiler_io(3) = linio([mdl '/Boiler'],1,'openoutput');
setlinio(mdl,Boiler_io);

Найдите линейную модель вокруг выбранной рабочей точки.

Lin_Boiler = linearize(mdl,opSS,Boiler_io);

Наконец, использование minreal функционируйте, убедитесь, что модель является минимальной реализацией.

Lin_Boiler = minreal(Lin_Boiler);
1 state removed.

Спроектируйте регулятор и наблюдателя состояния

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

u0 = opReport.Inputs.u;
y0 = opReport.Outputs.y;

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

Q = diag(1e8);                  % Output regulation
R = diag([1e2,1e6]);            % Input limitation
[K,S,E] = lqry(Lin_Boiler,Q,R);

Спроектируйте Кальмана, утверждают наблюдателя, использующего kalman функция. В данном примере основной источник шума является шумом процесса. Шум вводит систему только через один вход, следовательно форма G и H.

[A,B,C,D] = ssdata(Lin_Boiler);
G = B(:,1);
H = 0;
QN = 1e4;
RN = 1e-1;
NN = 0;
[Kobsv,L,P] = kalman(ss(A,[B G],C,[D H]),QN,RN);

Модель симулируется

Симулируйте модель для спроектированного контроллера.

sim(mdl)

Постройте сигналы ввода и вывода процесса. Следующий рисунок показывает сигнал приведения в действие подачи воды в kg/s.

plot(FeedWater.time/60,FeedWater.signals.values)
title('Feedwater flow rate [kg/s]');
ylabel('Flow [kg/s]')
xlabel('time [min]')
grid on

Следующий график показывает сигнал приведения в действие тепла в kJ.

plot(Heat.time/60,Heat.signals.values/1000)
title('Applied heat [kJ]');
ylabel('Heat [kJ]')
xlabel('time [min]')
grid on

Следующий рисунок показывает воздействие тепла в kJ. Воздействие варьируется целых 50% номинальной теплотворности.

plot(HeatDist.time/60,HeatDist.signals.values/1000)
title('Heat disturbance [kJ]');
ylabel('Heat [kJ]')
xlabel('time [min]')
grid on

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

plot(DrumPressure.time/60,DrumPressure.signals.values)
title('Drum pressure [kPa]');
ylabel('Pressure [kPa]')
xlabel('time [min]')
grid on

bdclose(mdl)

Смотрите также

| | |

Похожие темы

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