В этом примере показано, как генерировать код 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) и скомпилировать его в исполняемый файл (в этом примере файл, работающий на GPU), который имеет одинаковые входы и выходы и, следовательно, может вызываться из 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
Создайте объект опции конфигурации кодера графического процессора с помощью coder.gpuConfig и сконфигурируйте параметры генерации кода.
CfgGPU = coder.gpuConfig('mex'); CfgGPU.TargetLang = 'C++'; CfgGPU.EnableVariableSizing = false; CfgCPU.ConstantInputs = 'IgnoreValues';
Создание функции MEX mympcmoveGPU от mpcmoveCodeGeneration Функция MATLAB с использованием codegen команда. Эта команда генерирует код CUDA и компилирует его для получения исполняемого файла MEX mympcmoveGPU который работает на GPU.
codegen('-config',CfgGPU,'mpcmoveCodeGeneration','-o','mympcmoveGPU','-args',{coder.Constant(coredata),statedata,onlinedata});
Code generation successful.
mympcmoveGPUИнициализируйте массивы, в которых будут храниться перемещения и выходные данные для последующей печати.
yGPU = []; uGPU = [];
Инициализация состояний установки и контроллера.
x = x0; statedata=statedata0;
Запуск моделирования с замкнутым контуром с помощью вызоваmpcmoveGPU в цикле на 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 команда. Эта команда генерирует код C и компилирует его для получения исполняемого файла MEX mympcmoveCPU который работает на CPU.
codegen('-config',CfgCPU,'mpcmoveCodeGeneration','-o','mympcmoveCPU','-args',{coder.Constant(coredata),statedata,onlinedata});
Code generation successful.
mympcmoveCPUИнициализируйте массивы, в которых будут храниться перемещения и выходные данные для последующей печати.
yCPU = []; uCPU = [];
Инициализация состояний установки и контроллера.
x = x0; statedata=statedata0;
Запуск моделирования с замкнутым контуром с помощью вызоваmpcmoveCPU в цикле на 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 и выполнение сгенерированного кода на CPU ничтожно мало.
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