Этот пример показывает, как использовать команду 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 с горизонтами по умолчанию.
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')
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')
getCodeGenerationData
| mpcmoveCodeGeneration