Сгенерируйте код, чтобы вычислить оптимальные перемещения 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')

Сгенерируйте 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});

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

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')

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

|

Похожие темы