Используйте графический процессор для вычисления перемещений 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 и его начального состояния. The coredata структура содержит основные параметры конфигурации контроллера MPC, которые являются постоянными во время исполнения. The statedata структура содержит состояния контроллера MPC, такие как, например, состояние модели объекта управления, предполагаемое нарушение порядка, ковариационная матрица и последний ход управления. The onlinedata структура содержит данные, которые вы должны обновлять на каждом контрольном интервале, такие как измерения и опорные сигналы, ограничения и веса модели.

[coredata,statedata,onlinedata] = getCodeGenerationData(mpcobj,'InitialState',xmpc);

Сохраните начальную структуру данных о состоянии для последующей повторной инициализации.

statedata0=statedata;

Симулируйте замкнутый цикл с помощью mpcmoveCodeGeneration

The 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;

Запустите симуляцию с обратной связью, позвонив в мой 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

Сгенерируйте 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;

Запустите симуляцию с обратной связью, позвонив в мой 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

Сравнение перемещений 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

Похожие темы