Используйте графический процессор, чтобы вычислить перемещения MPC в MATLAB

В этом примере показано, как сгенерировать код CUDA и использовать графический процессор, чтобы вычислить оптимальные перемещения MPC в MATLAB™, с помощью mpcmoveCodeGeneration функция.

Создайте модель объекта управления и спроектируйте контроллер MPC

Зафиксируйте начальное значение генератора для воспроизводимости.

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

Сгенерируйте MEX-функцию для выполнения графического процессора

Создайте объект параметра конфигурации Кодера 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

Сгенерируйте MEX-функцию для выполнения центрального процессора

Создайте объект параметра конфигурации кодера использование 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

Сравните перемещения MPC

Во-первых, сравните вводы и выводы объекта, полученные из 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

Похожие темы