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

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

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

Чтобы упростить сравнение контроллера, оба настраивающих метода используют целевую функцию линейного квадратичного гауссова (LQG).

Этот пример использует агента обучения с подкреплением (RL), чтобы вычислить усиления для ПИ-контроллера. Для примера, который заменяет ПИ-контроллер на контроллер нейронной сети, смотрите, Создают окружение Simulink и Обучают Агента.

Модель среды

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

open_system('watertankLQG')

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

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

J=limTE(1T0T((ref-y)2(t)+0.01u2(t))dt)

Чтобы симулировать контроллер в этой модели, необходимо задать время симуляции Tf и шаг расчета контроллера Ts в секундах.

Ts = 0.1;
Tf = 10;

Для получения дополнительной информации о модели бака с водой, см. watertank Модель Simulink (Simulink Control Design).

Настройте ПИ-контроллер с помощью Control System Tuner

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

В данном примере откройте сохраненный сеанс ControlSystemTunerSession.mat использование Control System Tuner. Этот сеанс задает блок PID Controller в watertankLQG модель как настроенный блок и содержит LQG настраивающаяся цель.

controlSystemTuner("ControlSystemTunerSession")

Чтобы настроить контроллер, на вкладке Tuning, нажимают Tune.

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

Kp_CST = 9.80199999804512;
Ki_CST = 1.00019996230706e-06;

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

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

  1. Удалите ПИД-регулятор.

  2. Вставьте блок RL Agent.

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

  4. Задайте премиальную функцию для агента RL как отрицание стоимости LQG, то есть, Reward=-((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.

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

u=[edte]*[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);

Интеграл и пропорциональные составляющие ПИ-контроллера являются абсолютными весами представления актера. Чтобы получить веса, сначала извлеките настраиваемые параметры из агента.

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 до исходного блока ПИ-контроллера, и запустите симуляцию переходного процесса.

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

Примените усиления, полученные с помощью Control System Tuner для исходного блока ПИ-контроллера, и запустите симуляцию переходного процесса.

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-tuned производит немного более оптимальное решение.

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

Оба контроллера производят устойчивые ответы с контроллером, настроенным с помощью Control System Tuner, производящего более быстрый ответ. Однако 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

Смотрите также

|

Похожие темы