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

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

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

Это объект линейного объекта 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 = 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.
    u = mpcmove(mpcobj,xmpc,y,1,[],options);
    % Update and store plant state.
    x = plant.A*x + plant.B*u;
    uMPCMOVE = [uMPCMOVE 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 control actions.
    [u,statedata] = mpcmoveCodeGeneration(coredata,statedata,onlinedata);
    % Update and store plant state.
    x = plant.A*x + plant.B*u;
    uCodeGen = [uCodeGen 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. Axes 1 with title Plant Output contains 2 objects of type line. These objects represent mpcmove, codegen. Axes 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, обновляется командой и возвращается как второй выход. В большинстве случаев вам не нужно изменять его содержимое и нужно просто передать его обратно в команду в следующем контрольном интервале. Единственным исключением является включение пользовательской оценки состояния, в этом случае необходимо предоставить текущую оценку состояния с помощью этого аргумента.

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 control actions.
    [u,statedata] = mpcmoveMEX(coredata,statedata,onlinedata);
    % Update and store the plant state.
    x = plant.A*x + plant.B*u;
    uMEX = [uMEX 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. Axes 1 with title Plant Output contains 2 objects of type line. These objects represent mpcmove, mex. Axes 2 with title Controller Moves contains 2 objects of type line. These objects represent mpcmove, mex.

См. также

|

Похожие темы