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

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

mpcmoveCodeGeneration | getCodeGenerationData