В этом примере показано, как сгенерировать код 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;
mpcmoveCodeGeneration
mpcmoveCodeGeneration
функция позволяет вам симулировать контроллер 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