Сгенерируйте код, чтобы вычислить оптимальные перемещения MPC в MATLAB

В этом примере показано, как использовать mpcmoveCodeGeneration команда, чтобы сгенерировать код С, чтобы вычислить оптимальные перемещения MPC управления для приложений реального времени.

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

Модель объекта управления

Объект является одно входом, одно выходом, устойчивый, 2-й порядок линейный объект.

plant = tf(5,[1 0.8 3]);

Установите время выборки одной секунды, преобразуйте объект в дискретное время, форму пространства состояний, и задайте нулевой вектор начальных состояний.

Ts = 1;      
plant = ss(c2d(plant,Ts));
x0 = zeros(size(plant.B,1),1);

Спроектируйте контроллер MPC

Создайте контроллер MPC с горизонтами по умолчанию и заданное время выборки.

mpcobj = mpc(plant,Ts);
-->The "PredictionHorizon" property of "mpc" object is empty. Trying PredictionHorizon = 10.
-->The "ControlHorizon" property of the "mpc" object is empty. Assuming 2.
-->The "Weights.ManipulatedVariables" property of "mpc" object is empty. Assuming default 0.00000.
-->The "Weights.ManipulatedVariablesRate" property of "mpc" object is empty. Assuming default 0.10000.
-->The "Weights.OutputVariables" property of "mpc" object is empty. Assuming default 1.00000.

Задайте контроллер, настраивающий веса.

mpcobj.Weights.MV = 0;
mpcobj.Weights.MVrate = 0.5;
mpcobj.Weights.OV = 1;

Задайте начальные ограничения на переменную, которой управляют, и объект выход. Эти ограничения будут обновлены во время выполнения.

mpcobj.MV.Min = -1;
mpcobj.MV.Max = 1;
mpcobj.OV.Min = -1;
mpcobj.OV.Max = 1;

Симулируйте онлайновые ограничительные изменения с mpcmove Команда

В симуляции с обратной связью ограничения обновлены и поданы в mpcmove команда в каждом контрольном интервале.

yMPCMOVE = [];
uMPCMOVE = [];

Установите время симуляции.

Tsim = 20;

Инициализируйте онлайновые ограничительные данные.

MVMinData = -0.2-[1 0.95 0.9 0.85 0.8 0.75 0.7 0.65 0.6 0.55 0.5 ...
    0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1];
MVMaxData = 0.2+[1 0.95 0.9 0.85 0.8 0.75 0.7 0.65 0.6 0.55 0.5 ...
    0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1];
OVMinData = -0.2-[1 0.95 0.9 0.85 0.8 0.75 0.7 0.65 0.6 0.55 0.5 ...
    0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1];
OVMaxData = 0.2+[1 0.95 0.9 0.85 0.8 0.75 0.7 0.65 0.6 0.55 0.5 ...
    0.55 0.6 0.65 0.7 0.75 0.8 0.85 0.9 0.95 1];

Инициализируйте состояния объекта.

x = x0;

Инициализируйте состояния MPC. Обратите внимание на то, что xmpc объект указателя, указывающий на ток (всегда обновляемый) состояние контроллера.

xmpc = mpcstate(mpcobj);
-->Assuming output disturbance added to measured output channel #1 is integrated white noise.
-->The "Model.Noise" property of the "mpc" object is empty. Assuming white noise on each measured output channel.

Запустите симуляцию с обратной связью путем вызова mpcmove в цикле.

options = mpcmoveopt;
for ct = 1:round(Tsim/Ts)+1
    % Update and store plant output.
    y = plant.C*x;
    yMPCMOVE = [yMPCMOVE y];
    % Update constraints.
    options.MVMin = MVMinData(ct);
    options.MVMax = MVMaxData(ct);
    options.OutputMin = OVMinData(ct);
    options.OutputMax = OVMaxData(ct);
    % Compute control actions and store plant input.
    u = mpcmove(mpcobj,xmpc,y,1,[],options);
    uMPCMOVE = [uMPCMOVE u];
    % Update plant state.
    x = plant.A*x + plant.B*u;
end

Подтвердите результаты симуляции с mpcmoveCodeGeneration Команда

Чтобы подготовиться к генерации кода, который вычисляет перемещения оптимального управления из MATLAB, рекомендуется воспроизвести те же результаты управления с mpcmoveCodeGeneration команда перед использованием codegen команда от продукта MATLAB Coder.

yCodeGen = [];
uCodeGen = [];

Инициализируйте состояния объекта.

x = x0;

Создайте структуры данных, чтобы использовать с mpcmoveCodeGeneration using getCodeGenerationData.

[coredata,statedata,onlinedata] = getCodeGenerationData(mpcobj);

Запустите симуляцию с обратной связью путем вызова mpcmoveCodeGeneration в цикле.

for ct = 1:round(Tsim/Ts)+1
    % Update and store plant output.
    y = plant.C*x;
    yCodeGen = [yCodeGen y];
    % Update measured output in online data.
    onlinedata.signals.ym = y;    
    % Update reference in online data.
    onlinedata.signals.ref = 1;    
    % Update constraints in online data.
    onlinedata.limits.umin = MVMinData(ct);
    onlinedata.limits.umax = MVMaxData(ct);
    onlinedata.limits.ymin = OVMinData(ct);
    onlinedata.limits.ymax = OVMaxData(ct);
    % Compute and store control action.
    [u,statedata] = mpcmoveCodeGeneration(coredata,statedata,onlinedata);
    uCodeGen = [uCodeGen u];
    % Update plant state.
    x = plant.A*x + plant.B*u;
end

Результаты симуляции идентичны тем полученное использование mpcmove.

t = 0:Ts:Tsim;
figure;
subplot(1,2,1)
plot(t,yMPCMOVE,'--*',t,yCodeGen,'o');
grid
legend('mpcmove','codegen')
title('Plant Output')
subplot(1,2,2)
plot(t,uMPCMOVE,'--*',t,uCodeGen,'o');
grid
legend('mpcmove','codegen')
title('Controller Moves')

Figure contains 2 axes objects. Axes object 1 with title Plant Output contains 2 objects of type line. These objects represent mpcmove, codegen. Axes object 2 with title Controller Moves contains 2 objects of type line. These objects represent mpcmove, codegen.

Сгенерируйте MEX-функцию от mpcmoveCodeGeneration Команда

Сгенерировать код С от mpcmoveCodeGeneration команда, используйте codegen команда от продукта MATLAB Coder. В этом примере сгенерируйте MEX-функцию mpcmoveMEX воспроизвести результаты симуляции в MATLAB. Можно изменить цель генерации кода в C/C++ статическая библиотека, динамическая библиотека, исполняемый файл, и т.д. при помощи различного набора coder.config настройки.

При генерации кода С для mpcmoveCodeGeneration команда:

  • Поскольку никакие проверки целостности данных не выполняются на входных параметрах, необходимо убедиться, что все входные данные имеют правильные типы, размерности и значения.

  • Необходимо задать первый входной параметр, mpcmove_struct, как константа при использовании codegen команда.

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

% check MATLAB coder license
if ~license ('test', 'MATLAB_Coder')
    disp('MATLAB Coder(TM) is required to run this example.')
    return
end

Сгенерируйте MEX-функцию.

fun = 'mpcmoveCodeGeneration';
funOutput = 'mpcmoveMEX';
Cfg = coder.config('mex');
Cfg.DynamicMemoryAllocation = 'off';
codegen('-config',Cfg,fun,'-o',funOutput,'-args',...
    {coder.Constant(coredata),statedata,onlinedata});
Code generation successful.

Инициализируйте хранение данных.

yMEX = [];
uMEX = [];

Инициализируйте состояния объекта.

x = x0;

Используйте getCodeGenerationData создать структуры данных, чтобы использовать с mpcmoveCodeGeneration.

[coredata,statedata,onlinedata] = getCodeGenerationData(mpcobj);

Запустите симуляцию с обратной связью путем вызова сгенерированного mpcmoveMEX функции в цикле.

for ct = 1:round(Tsim/Ts)+1
    % Update and store the plant output.
    y = plant.C*x;
    yMEX = [yMEX y];
    % Update measured output in online data.
    onlinedata.signals.ym = y;    
    % Update reference in online data.
    onlinedata.signals.ref = 1;    
    % Update constraints in online data.
    onlinedata.limits.umin = MVMinData(ct);
    onlinedata.limits.umax = MVMaxData(ct);
    onlinedata.limits.ymin = OVMinData(ct);
    onlinedata.limits.ymax = OVMaxData(ct);
    % Compute and store control action.
    [u,statedata] = mpcmoveMEX(coredata,statedata,onlinedata);
    uMEX = [uMEX u];
    % Update plant state.
    x = plant.A*x + plant.B*u;
end

Результаты симуляции идентичны тем полученное использование mpcmove.

figure
subplot(1,2,1)
plot(t,yMPCMOVE,'--*',t,yMEX,'o')
grid
legend('mpcmove','mex')
title('Plant Output')
subplot(1,2,2)
plot(t,uMPCMOVE,'--*',t,uMEX,'o')
grid
legend('mpcmove','mex')
title('Controller Moves')

Figure contains 2 axes objects. Axes object 1 with title Plant Output contains 2 objects of type line. These objects represent mpcmove, mex. Axes object 2 with title Controller Moves contains 2 objects of type line. These objects represent mpcmove, mex.

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

|

Похожие темы