exponenta event banner

Настройка PI-контроллера с помощью обучения усилению

В этом примере показано, как настроить PI-контроллер с использованием алгоритма обучения с двойным отложенным глубоким детерминированным градиентом (TD3) усиления. Производительность настроенного контроллера сравнивается с производительностью контроллера, настроенного с помощью приложения Control System Tuner. Использование приложения Control System Tuner для настройки контроллеров в Simulink ® требует программного обеспечения Simulink Control Design™.

Для относительно простых задач управления с небольшим количеством настраиваемых параметров методы настройки на основе модели могут получить хорошие результаты с более быстрым процессом настройки по сравнению с методами на основе RL без модели. Однако способы RL могут быть более подходящими для высоколинейных систем или адаптивной настройки контроллера.

Для облегчения сравнения контроллеров оба метода настройки используют линейную квадратичную целевую функцию Гаусса (LQG).

В этом примере для вычисления выигрышей для PI-контроллера используется агент обучения усилению (RL). Пример замены контроллера PI контроллером нейронной сети см. в разделе Создание Simulink Environment and Train Agent.

Модель среды

Моделью среды для этого примера является модель резервуара для воды. Целью этой системы управления является поддержание уровня воды в резервуаре в соответствии с исходным значением.

open_system('watertankLQG')

Модель включает в себя технологический шум с дисперсией E (n2 (t)) = 1.

Поддержание уровня воды при минимизации усилий по контролю u, контроллеры в этом примере используют следующий критерий LQG.

J=limT⇒∞E (1T∫0T ((ref-y) 2 (t) + 0,01u2 (t)) dt)

Для моделирования контроллера в этой модели необходимо указать время моделирования. Tf и время выборки контроллера Ts в секундах.

Ts = 0.1;
Tf = 10;

Дополнительные сведения о модели резервуара для воды см. в разделе Модель резервуара для воды Simulink (Simulink Control Design).

Настройка контроллера PI с помощью тюнера системы управления

Чтобы настроить контроллер в Simulink с помощью настройки системы управления, необходимо указать блок контроллера как настроенный блок и определить цели процесса настройки. Дополнительные сведения об использовании тюнера системы управления см. в разделе Настройка системы управления с помощью тюнера системы управления (Simulink Control Design).

В этом примере откройте сохраненный сеанс. ControlSystemTunerSession.mat с помощью тюнера системы управления. Этот сеанс определяет блок контроллера PID в watertankLQG модель в качестве настроенного блока и содержит цель настройки LQG.

controlSystemTuner("ControlSystemTunerSession")

Чтобы настроить контроллер, на вкладке Настройка нажмите кнопку Настройка.

Настроенные пропорциональные и интегральные коэффициенты усиления составляют приблизительно 9,8 и 1e-6 соответственно.

Kp_CST = 9.80199999804512;
Ki_CST = 1.00019996230706e-06;

Создание среды для агента обучения

Чтобы определить модель для обучения агента RL, измените модель резервуара для воды, выполнив следующие шаги.

  1. Удалите контроллер PID.

  2. Вставка блока агента RL.

  3. Создайте вектор наблюдения [∫e dte] T, где e = r-h, h - высота резервуара, а r - опорная высота. Подключите сигнал наблюдения к блоку агента RL.

  4. Определите функцию вознаграждения для агента RL как отрицательное значение стоимости LQG, то есть вознаграждение = - ((ref-h) 2 (t) + 0,01u2 (t)). Агент RL максимизирует это вознаграждение, таким образом минимизируя стоимость LQG.

Результирующая модель: rlwatertankPIDTune.slx.

mdl = 'rlwatertankPIDTune';
open_system(mdl)

Создайте объект интерфейса среды. Для этого используйте localCreatePIDEnv функция, определенная в конце этого примера.

[env,obsInfo,actInfo] = localCreatePIDEnv(mdl);

Извлеките измерения наблюдения и действия для этой среды.

numObservations = obsInfo.Dimension(1);
numActions = prod(actInfo.Dimension);

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

rng(0)

Создать агент TD3

Учитывая наблюдения, агент TD3 решает, какое действие предпринять, используя представление актера. Чтобы создать актера, сначала создайте глубокую нейронную сеть с входом наблюдения и выходом действия. Дополнительные сведения см. в разделе rlDeterministicActorRepresentation.

Можно моделировать PI-контроллер как нейронную сеть с одним полностью подключенным слоем с наблюдениями интеграла ошибок и ошибок.

u = [∫e dte] * [KiKp] T

Здесь:

  • u - выход акторной нейронной сети.

  • Kp и Ki - абсолютные значения весов нейронной сети.

  • e = r-h, h - высота резервуара, r - опорная высота.

Оптимизация градиентного спуска может привести веса к отрицательным значениям. Во избежание отрицательных весов замените нормальные fullyConnectedLayer с fullyConnectedPILayer. Этот уровень гарантирует, что веса будут положительными, реализуя функцию Y = abs (WEIGHTS) * X. Этот слой определен вfullyConnectedPILayer.m.

initialGain = single([1e-3 2]);
actorNetwork = [
    featureInputLayer(numObservations,'Normalization','none','Name','state')
    fullyConnectedPILayer(initialGain, 'Action')];
actorOptions = rlRepresentationOptions('LearnRate',1e-3,'GradientThreshold',1);
actor = rlDeterministicActorRepresentation(actorNetwork,obsInfo,actInfo,...
    'Observation',{'state'},'Action',{'Action'},actorOptions);

Агент TD3 аппроксимирует долгосрочное вознаграждение, данное наблюдениям и действиям, используя два представления «значение-функция» критика. Чтобы создать критиков, сначала создайте глубокую нейронную сеть с двумя входами, наблюдением и действием, и одним выходом. Дополнительные сведения о создании глубокого представления функции значений нейронной сети см. в разделе Создание представлений политик и функций значений.

Чтобы создать критиков, используйте localCreateCriticNetwork функция, определенная в конце этого примера. Используйте одну и ту же структуру сети для обоих представлений критиков.

criticNetwork = localCreateCriticNetwork(numObservations,numActions);
criticOpts = rlRepresentationOptions('LearnRate',1e-3,'GradientThreshold',1);

critic1 = rlQValueRepresentation(criticNetwork,obsInfo,actInfo,...
    'Observation','state','Action','action',criticOpts);
critic2 = rlQValueRepresentation(criticNetwork,obsInfo,actInfo,...
    'Observation','state','Action','action',criticOpts);
critic = [critic1 critic2];

Настройте агент с помощью следующих параметров.

  • Настройка агента для использования времени выборки контроллера Ts.

  • Установите размер мини-партии равным 128 образцам опыта.

  • Задайте длину буфера опыта 1e6.

  • Задайте модель исследования и модель сглаживания целевой политики для использования гауссова шума с дисперсией 0,1.

Укажите параметры агента TD3 с помощью rlTD3AgentOptions.

agentOpts = rlTD3AgentOptions(...
    'SampleTime',Ts,...
    'MiniBatchSize',128, ...
    'ExperienceBufferLength',1e6);
agentOpts.ExplorationModel.StandardDeviation = sqrt(0.1);
agentOpts.TargetPolicySmoothModel.StandardDeviation = sqrt(0.1);

Создайте TD3 агент, используя указанное представление актера, критическое представление и параметры агента. Дополнительные сведения см. в разделе rlTD3AgentOptions.

agent = rlTD3Agent(actor,critic,agentOpts);

Агент поезда

Для обучения агента сначала укажите следующие варианты обучения.

  • Запускать каждое обучение максимум для 1000 эпизоды, причем каждый эпизод длится не более 100 временные шаги.

  • Просмотр хода обучения в менеджере эпизодов (установите Plots и отключите отображение командной строки (установите Verbose опция).

  • Прекратите обучение, когда агент получит среднее совокупное вознаграждение, превышающее -355 за 100 последовательных эпизодов. В этот момент агент может контролировать уровень воды в резервуаре.

Дополнительные сведения см. в разделе rlTrainingOptions.

maxepisodes = 1000;
maxsteps = ceil(Tf/Ts);
trainOpts = rlTrainingOptions(...
    'MaxEpisodes',maxepisodes, ...
    'MaxStepsPerEpisode',maxsteps, ...
    'ScoreAveragingWindowLength',100, ...
    'Verbose',false, ...
    'Plots','training-progress',...
    'StopTrainingCriteria','AverageReward',...
    'StopTrainingValue',-355);

Обучение агента с помощью train функция. Обучение этого агента - интенсивный вычислительный процесс, который занимает несколько минут. Чтобы сэкономить время при выполнении этого примера, загрузите предварительно подготовленный агент путем установки doTraining кому false. Чтобы обучить агента самостоятельно, установите doTraining кому true.

doTraining = false;

if doTraining
    % Train the agent.
    trainingStats = train(agent,env,trainOpts);
else
    % Load pretrained agent for the example.
    load('WaterTankPIDtd3.mat','agent')
end

Проверка обученного агента

Проверка полученного агента на соответствие модели с помощью моделирования.

simOpts = rlSimulationOptions('MaxSteps',maxsteps);
experiences = sim(env,agent,simOpts);

Интегральные и пропорциональные коэффициенты усиления PI-контроллера являются абсолютными весами представления актера. Для получения весов сначала извлеките обучаемые параметры из актера.

actor = getActor(agent);
parameters = getLearnableParameters(actor);

Получите выигрыш контроллера.

Ki = abs(parameters{1}(1))
Ki = single
    0.3958
Kp = abs(parameters{1}(2))
Kp = single
    8.0822

Примените выигрыши, полученные от агента RL, к исходному блоку PI-контроллера и выполните пошаговое моделирование.

mdlTest = 'watertankLQG';
open_system(mdlTest);
set_param([mdlTest '/PID Controller'],'P',num2str(Kp))
set_param([mdlTest '/PID Controller'],'I',num2str(Ki))
sim(mdlTest)

Извлеките информацию ответа на шаг, стоимость LQG и запас устойчивости для моделирования. Для вычисления запаса устойчивости используйте localStabilityAnalysis функция, определенная в конце этого примера.

rlStep = simout;
rlCost = cost;
rlStabilityMargin = localStabilityAnalysis(mdlTest);

Примените коэффициенты усиления, полученные с помощью тюнера системы управления, к исходному блоку контроллера PI и выполните пошаговое моделирование.

set_param([mdlTest '/PID Controller'],'P',num2str(Kp_CST))
set_param([mdlTest '/PID Controller'],'I',num2str(Ki_CST))
sim(mdlTest)
cstStep = simout;
cstCost = cost;
cstStabilityMargin = localStabilityAnalysis(mdlTest);

Сравнение производительности контроллера

Постройте график ответа на шаг для каждой системы.

figure
plot(cstStep)
hold on
plot(rlStep)
grid on
legend('Control System Tuner','RL','Location','southeast')
title('Step Response')

Figure contains an axes. The axes with title Step Response contains 2 objects of type line. These objects represent Control System Tuner, RL.

Проанализируйте отклик шага для обоих моделей.

rlStepInfo = stepinfo(rlStep.Data,rlStep.Time);
cstStepInfo = stepinfo(cstStep.Data,cstStep.Time);
stepInfoTable = struct2table([cstStepInfo rlStepInfo]);
stepInfoTable = removevars(stepInfoTable,{...
    'SettlingMin','SettlingMax','Undershoot','PeakTime'});
stepInfoTable.Properties.RowNames = {'Control System Tuner','RL'};
stepInfoTable
stepInfoTable=2×4 table
                            RiseTime    SettlingTime    Overshoot     Peak 
                            ________    ____________    _________    ______

    Control System Tuner    0.77322        1.3594        0.33125     9.9023
    RL                      0.97617        1.7408        0.40451     10.077

Проанализируйте стабильность для обоих моделей.

stabilityMarginTable = struct2table([cstStabilityMargin rlStabilityMargin]);
stabilityMarginTable = removevars(stabilityMarginTable,{...
    'GMFrequency','PMFrequency','DelayMargin','DMFrequency'});
stabilityMarginTable.Properties.RowNames = {'Control System Tuner','RL'};
stabilityMarginTable
stabilityMarginTable=2×3 table
                            GainMargin    PhaseMargin    Stable
                            __________    ___________    ______

    Control System Tuner      8.1616        84.122       true  
    RL                        9.9226        84.241       true  

Сравните совокупную стоимость LQG для двух контроллеров. Контроллер с RL-настройкой обеспечивает несколько более оптимальное решение.

rlCumulativeCost  = sum(rlCost.Data)
rlCumulativeCost = -375.9135
cstCumulativeCost = sum(cstCost.Data)
cstCumulativeCost = -376.9373

Оба контроллера дают стабильные отклики, при этом контроллер настраивается с помощью настройки системы управления, создавая более быстрый отклик. Однако способ RL-настройки обеспечивает более высокий запас усиления и более оптимальное решение.

Локальные функции

Функция для создания среды резервуара для воды RL.

function [env,obsInfo,actInfo] = localCreatePIDEnv(mdl)

% Define the observation specification obsInfo and action specification actInfo.
obsInfo = rlNumericSpec([2 1]);
obsInfo.Name = 'observations';
obsInfo.Description = 'integrated error and error';

actInfo = rlNumericSpec([1 1]);
actInfo.Name = 'PID output';

% Build the environment interface object.
env = rlSimulinkEnv(mdl,[mdl '/RL Agent'],obsInfo,actInfo);

% Set a cutom reset function that randomizes the reference values for the model.
env.ResetFcn = @(in)localResetFcn(in,mdl);
end

Функция для рандомизации опорного сигнала и начальной высоты резервуара для воды в начале каждого эпизода.

function in = localResetFcn(in,mdl)

% randomize reference signal
blk = sprintf([mdl '/Desired \nWater Level']);
hRef = 10 + 4*(rand-0.5);
in = setBlockParameter(in,blk,'Value',num2str(hRef));

% randomize initial height
hInit = 0;
blk = [mdl '/Water-Tank System/H'];
in = setBlockParameter(in,blk,'InitialCondition',num2str(hInit));

end

Функция линеаризации и вычисления пределов устойчивости системы резервуаров для воды SISO.

function margin = localStabilityAnalysis(mdl)

io(1) = linio([mdl '/Sum1'],1,'input');
io(2) = linio([mdl '/Water-Tank System'],1,'openoutput');
op = operpoint(mdl);
op.Time = 5;
linsys = linearize(mdl,io,op);

margin = allmargin(linsys);
end

Функция создания сети критиков.

function criticNetwork = localCreateCriticNetwork(numObservations,numActions)
statePath = [
    featureInputLayer(numObservations,'Normalization','none','Name','state')
    fullyConnectedLayer(32,'Name','fc1')];
actionPath = [
    featureInputLayer(numActions,'Normalization','none','Name','action')
    fullyConnectedLayer(32,'Name','fc2')];
commonPath = [
    concatenationLayer(1,2,'Name','concat')
    reluLayer('Name','reluBody1')
    fullyConnectedLayer(32,'Name','fcBody')
    reluLayer('Name','reluBody2')
    fullyConnectedLayer(1,'Name','qvalue')];

criticNetwork = layerGraph();
criticNetwork = addLayers(criticNetwork,statePath);
criticNetwork = addLayers(criticNetwork,actionPath);
criticNetwork = addLayers(criticNetwork,commonPath);

criticNetwork = connectLayers(criticNetwork,'fc1','concat/in1');
criticNetwork = connectLayers(criticNetwork,'fc2','concat/in2');
end

См. также

|

Связанные темы