В этом примере показано, как использовать 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});
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')
getCodeGenerationData
| mpcmoveCodeGeneration