В этом примере показано, как сгенерировать код CUDA и использовать графический процессор, чтобы вычислить оптимальные перемещения MPC в MATLAB™, с помощью mpcmoveCodeGeneration функция.
Зафиксируйте начальное значение генератора для воспроизводимости.
rng(0);
Создайте дискретное время строго соответствующий объект с 10 состояниями, 3 входными параметрами и 3 выходными параметрами.
plant = drss(10,3,3); plant.D = 0;
Создайте случайное начальное состояние для объекта, чтобы использоваться позже в симуляции.
x0 = rand(10,1);
Создайте контроллер MPC со временем выборки 0,1 секунды и предсказание по умолчанию и управляйте горизонтами.
mpcobj = mpc(plant,0.1);
-->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.
Задайте случайные ограничения на которыми управляют и измеренные переменные.
for ct=1:3 mpcobj.MV(ct).Min = -1*rand; mpcobj.MV(ct).Max = 1*rand; end for ct=1:3 mpcobj.OV(ct).Min = -10*rand; mpcobj.OV(ct).Max = 10*rand; end
Получите указатель на mpcobj внутреннее состояние.
xmpc=mpcstate(mpcobj);
-->No sample time provided for plant model. Assuming sample time = controller's sample time = 0.1. -->Assuming output disturbance added to measured output channel #1 is integrated white noise. -->Assuming output disturbance added to measured output channel #2 is integrated white noise. -->Assuming output disturbance added to measured output channel #3 is integrated white noise. -->The "Model.Noise" property of the "mpc" object is empty. Assuming white noise on each measured output channel.
mpcmoveПрежде, чем сгенерировать код, симулируйте объект в замкнутом цикле с помощью mpcmove чтобы убедиться поведение приемлемо. В данном примере результат симуляции с mpcmove хранится так, это может быть позже по сравнению с симуляцией с помощью сгенерированного кода.
Инициализируйте массивы, которые сохранят перемещения и выходные параметры для более позднего графического вывода.
yMV = []; uMV = [];
Инициализируйте состояния контроллера и объект.
x = x0; xmpc.Plant=x0;
Запустите симуляцию с обратной связью путем вызова mpcmove в цикле для 5 шагов.
for ct = 1:5 % Update and store the plant output. y = plant.C*x; yMV = [yMV y]; % Compute control actions with ref = ones(1,3) u = mpcmove(mpcobj,xmpc,y,ones(1,3)); % Update and store the plant state. x = plant.A*x + plant.B*u; uMV = [uMV u]; end
Сбросьте начальные условия контроллера.
xmpc.Plant=x0; xmpc.Disturbance=zeros(1,3); xmpc.LastMove=zeros(1,3);
Используйте getCodeGenerationData создать эти три структуры, необходимые для генерации кода и симуляции от объекта MPC и его начального состояния. coredata структура содержит основные параметры конфигурации контроллера MPC, которые являются постоянными во время выполнения. statedata структура содержит состояния контроллера MPC, такой что касается примера состояние модели объекта управления, предполагаемого воздействия, ковариационной матрицы и последнего перемещения управления. onlinedata структура содержит данные, которые необходимо обновить в каждом контрольном интервале, таком как измерение и опорные сигналы, ограничения и веса модели.
[coredata,statedata,onlinedata] = getCodeGenerationData(mpcobj,'InitialState',xmpc);Сохраните структуру данных начального состояния для более поздней реинициализации.
statedata0=statedata;
mpcmoveCodeGenerationmpcmoveCodeGeneration функция позволяет вам симулировать контроллер MPC в замкнутом цикле способом, похожим на mpcmove. Это берет в трех структурах данных контроллера, где statedata и onlinedata представляйте текущие значения состояний контроллера и входных сигналов, соответственно, и вычисляет перемещение оптимального управления и новое значение состояний контроллера. Можно затем сгенерировать код от mpcmoveCodeGeneration (в этом примере также код CUDA) и компиляция это к исполняемому файлу (в этом примере одна работа графического процессора), который имеет те же вводы и выводы и поэтому может быть назван из MATLAB точно таким же образом.
Инициализируйте массивы, чтобы сохранить перемещения и выходные параметры для более позднего графического вывода.
yCDG = []; uCDG = [];
Инициализируйте состояния контроллера и объект.
x = x0; statedata=statedata0;
Запустите симуляцию с обратной связью путем вызова mpcmoveCodeGeneration в цикле для 5 шагов.
for ct = 1:5 % Update and store the plant output. y = plant.C*x; yCDG = [yCDG y]; % Update measured output and reference in online data. onlinedata.signals.ym = y; onlinedata.signals.ref = ones(1,3); % Compute control actions. [u,statedata] = mpcmoveCodeGeneration(coredata,statedata,onlinedata); % Update and store the plant state. x = plant.A*x + plant.B*u; uCDG = [uCDG u]; end
Создайте объект параметра конфигурации Кодера GPU использование coder.gpuConfig функция, и конфигурирует опции генерации кода.
CfgGPU = coder.gpuConfig('mex'); CfgGPU.TargetLang = 'C++'; CfgGPU.EnableVariableSizing = false; CfgCPU.ConstantInputs = 'IgnoreValues';
Сгенерируйте MEX-функцию mympcmoveGPU от mpcmoveCodeGeneration Функция MATLAB, с помощью codegen команда. Эта команда генерирует код CUDA и компилирует его, чтобы получить исполняемый файл MEX mympcmoveGPU который работает на графическом процессоре.
codegen('-config',CfgGPU,'mpcmoveCodeGeneration','-o','mympcmoveGPU','-args',{coder.Constant(coredata),statedata,onlinedata});
Code generation successful.
mympcmoveGPUИнициализируйте массивы, которые сохранят перемещения и выходные параметры для более позднего графического вывода.
yGPU = []; uGPU = [];
Инициализируйте состояния контроллера и объект.
x = x0; statedata=statedata0;
Запустите симуляцию с обратной связью путем вызова mympcmoveGPU в цикле для 5 шагов.
for ct = 1:5 % Update and store the plant output. y = plant.C*x; yGPU = [yGPU y]; % Update measured output and reference in online data. onlinedata.signals.ym = y; onlinedata.signals.ref = ones(1,3); % Compute control actions. [u,statedata] = mympcmoveGPU(coredata,statedata,onlinedata); % Update and store the plant state. x = plant.A*x + plant.B*u; uGPU = [uGPU u]; end
Создайте объект параметра конфигурации кодера использование coder.Config функция, и конфигурирует опции генерации кода.
CfgCPU = coder.config('mex'); CfgCPU.DynamicMemoryAllocation='off'; CfgCPU.EnableVariableSizing = false; CfgCPU.ConstantInputs = 'IgnoreValues';
Сгенерируйте MEX-функцию mympcmoveCPU от mpcmoveCodeGeneration Функция MATLAB, с помощью codegen команда. Эта команда генерирует код С и компилирует его, чтобы получить исполняемый файл MEX mympcmoveCPU который работает на центральном процессоре.
codegen('-config',CfgCPU,'mpcmoveCodeGeneration','-o','mympcmoveCPU','-args',{coder.Constant(coredata),statedata,onlinedata});
Code generation successful.
mympcmoveCPUИнициализируйте массивы, которые сохранят перемещения и выходные параметры для более позднего графического вывода.
yCPU = []; uCPU = [];
Инициализируйте состояния контроллера и объект.
x = x0; statedata=statedata0;
Запустите симуляцию с обратной связью путем вызова mympcmoveCPU в цикле для 5 шагов.
for ct = 1:5 % Update and store the plant output. y = plant.C*x; yCPU = [yCPU y]; % Update measured output and reference in online data. onlinedata.signals.ym = y; onlinedata.signals.ref = ones(1,3); % Compute control actions. [u,statedata] = mympcmoveCPU(coredata,statedata,onlinedata); % Update and store the plant state. x = plant.A*x + plant.B*u; uCPU = [uCPU u]; end
Во-первых, сравните вводы и выводы объекта, полученные из mpcmove, и те получили использование графического процессора.
uGPU-uMV
ans = 3×5
10-15 ×
0.3886 0.1110 0.3886 -0.2220 -0.7772
-0.2776 -0.0555 -0.3886 -0.7494 0.0694
-0.0035 0.0555 0.2359 0.0278 -0.0833
yGPU-yMV
ans = 3×5
10-14 ×
0 -0.1110 -0.0333 -0.1332 -0.0333
0 -0.1776 -0.0444 -0.4219 -0.2665
0 -0.0222 0.0222 -0.0666 0.1332
Результаты симуляции идентичны, за исключением незначительных числовых ошибок, тем, которые используют mpcmove.
uCPU-uMV
ans = 3×5
10-14 ×
0.0278 0.0389 -0.0167 -0.0389 -0.0167
0.0611 -0.0056 -0.0749 -0.1013 0.0291
0 0.0333 0.0833 -0.0111 -0.0611
yCPU-yMV
ans = 3×5
10-14 ×
0 0.0111 -0.0777 0.1554 -0.0444
0 0.2331 0 -0.2887 -0.1998
0 -0.1332 -0.0444 -0.1332 0.0666
Так же различие между результатами, полученными путем выполнения mpcmoveCodeGeneration в MATLAB и выполнении сгенерированного кода на центральном процессоре незначительно.
uCPU-uCDG
ans = 3×5
10-14 ×
0 -0.1554 -0.1887 -0.1055 -0.0500
-0.0444 0 -0.0111 -0.0985 -0.0180
0 0.0278 -0.0111 -0.0444 -0.1027
yCPU-yCDG
ans = 3×5
10-14 ×
0 -0.0555 0.4663 0.3997 0.3553
0 -0.1443 0.1332 0.0444 -0.2220
0 0.0666 0.0888 0.0666 0.3331