В этом примере показано, как настроить ПИ-контроллер с помощью задержанного близнецами глубоко детерминированный градиент политики (TD3) алгоритм обучения с подкреплением. Эффективность настроенного контроллера по сравнению с тем из контроллера, настроенного с помощью приложения Control System Tuner. Используя приложение Control System Tuner, чтобы настроить контроллеры в Simulink® требует программного обеспечения Simulink Control Design™.
Для относительно простых задач управления с небольшим количеством настраиваемых параметров основанные на модели настраивающие методы могут получить хорошие результаты с более быстрым настраивающим процессом по сравнению с основанными на RL методами без моделей. Однако методы RL могут более подойти для очень нелинейных систем или адаптивного контроллера, настраивающегося.
Чтобы упростить сравнение контроллера, оба настраивающих метода используют целевую функцию линейного квадратичного гауссова (LQG).
Этот пример использует агента обучения с подкреплением (RL), чтобы вычислить усиления для ПИ-контроллера. Для примера, который заменяет ПИ-контроллер на контроллер нейронной сети, смотрите, Создают окружение Simulink и Обучают Агента.
Модель среды для этого примера является моделью бака с водой. Цель этой системы управления состоит в том, чтобы обеспечить уровень воды в баке, чтобы совпадать со ссылочным значением.
open_system('watertankLQG')
Модель включает шум процесса с отклонением .
Обеспечить уровень воды при минимизации усилия по управлению u
, диспетчеры в этом примере используют следующий критерий LQG.
Чтобы симулировать контроллер в этой модели, необходимо задать время симуляции Tf
и шаг расчета контроллера Ts
в секундах.
Ts = 0.1; Tf = 10;
Для получения дополнительной информации о модели бака с водой, см. watertank Модель Simulink (Simulink Control Design).
Чтобы настроить контроллер в 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, измените модель бака с водой использование следующих шагов.
Удалите ПИД-регулятор.
Вставьте блок RL Agent.
Создайте вектор наблюдения где , высота бака, и ссылочная высота. Соедините сигнал наблюдения с блоком RL Agent.
Задайте премиальную функцию для агента RL как отрицание стоимости LQG, то есть, . Агент 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 решает который действие взять использование представления актера. Чтобы создать агента, сначала создайте глубокую нейронную сеть с входом наблюдения и действием выход. Для получения дополнительной информации смотрите rlDeterministicActorRepresentation
.
Можно смоделировать ПИ-контроллер как нейронную сеть с одним полносвязным слоем с наблюдениями интеграла вероятности и интеграла вероятности.
Здесь:
u
выход нейронной сети агента.
Kp
и Ki
абсолютные значения весов нейронной сети.
, высота бака, и ссылочная высота.
Оптимизация градиентного спуска может управлять весами к отрицательным величинам. Чтобы избежать отрицательных весов, замените нормальный fullyConnectedLayer
с fullyConnectedPILayer
. Этот слой гарантирует, что веса положительны путем реализации функции . Этот слой задан в 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.Variance = 0.1; agentOpts.TargetPolicySmoothModel.Variance = 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')
Анализируйте переходной процесс для обеих симуляций.
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