Этот пример показов, как настроить ПИ-контроллер с помощью алгоритма TD3 глубокого детерминированного градиента ( обучения с подкреплением) с двумя задержками. Производительность настроенного контроллера сравнивается с эффективностью контроллера, настроенного с помощью приложения Control System Tuner. Для настройки контроллеров в Simulink ® требуется программное обеспечение Simulink Control Design™.
Для относительно простых задач управления с небольшим количеством настраиваемых параметров основанные на модели методы настройки могут получить хорошие результаты с более быстрым процессом настройки по сравнению с безмодельными методами на основе RL. Однако методы RL могут быть более подходящими для сильно нелинейных систем или адаптивной настройки контроллера.
Чтобы облегчить сравнение контроллеров, оба метода настройки используют линейную квадратичную целевую функцию Гауссова (LQG).
Этот пример использует агента обучения с подкреплением (RL), чтобы вычислить усиления для ПИ-контроллера. Для примера, который заменяет ПИ-контроллер на контроллер нейронной сети, смотрите Создать Окружение Simulink и Train Агента.
Модель окружения для этого примера является моделью бака с водой. Цель этой системы управления состоит в том, чтобы поддерживать уровень воды в баке, чтобы соответствовать ссылке значению.
open_system('watertankLQG')
Модель включает технологический шум с отклонением .
Поддержание уровня воды при минимизации усилий по управлению u
контроллеры в этом примере используют следующий критерий LQG.
Чтобы симулировать контроллер в этой модели, необходимо задать время симуляции Tf
и шаг расчета контроллером Ts
в секундах.
Ts = 0.1; Tf = 10;
Для получения дополнительной информации о модели бака с водой смотрите Модель Simulink (Simulink Control Design).
Чтобы настроить контроллер в Simulink с помощью Control System Tuner, необходимо задать блок контроллера как настроенный блок и определить цели процесса настройки. Для получения дополнительной информации об использовании Control System Tuner, смотрите Настроить Систему Управления Используя Control System Tuner (Simulink Control Design).
В данном примере откройте сохраненный сеанс ControlSystemTunerSession.mat
использование Control System Tuner. Этот сеанс задает блок ПИД-регулятор в watertankLQG
модель как настроенный блок и содержит цель настройки LQG.
controlSystemTuner("ControlSystemTunerSession")
Чтобы настроить контроллер, на вкладке Tuning, нажмите Tune.
Настроенные пропорциональные и интегральные составляющие составляют приблизительно 9,8 и 1e-6, соответственно.
Kp_CST = 9.80199999804512; Ki_CST = 1.00019996230706e-06;
Чтобы определить модель для обучения агента RL, измените модель бака с водой с помощью следующих шагов.
Удалите ПИД-регулятор.
Вставьте блок агента RL.
Создайте вектор наблюдения где , - высота бака, и - высота ссылки. Подключите сигнал наблюдения к блоку 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.StandardDeviation = sqrt(0.1); agentOpts.TargetPolicySmoothModel.StandardDeviation = sqrt(0.1);
Создайте агента TD3 с помощью заданного представления актера, представления критика и опций агента. Для получения дополнительной информации смотрите rlTD3AgentOptions
.
agent = rlTD3Agent(actor,critic,agentOpts);
Чтобы обучить агента, сначала задайте следующие опции обучения.
Запускайте каждое обучение самое большее для 1000
эпизоды с каждым эпизодом, длящимся самое большее 1 00
временные шаги.
Отображение процесса обучения в Диспетчере эпизодов (установите 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 контроллер дает несколько более оптимальное решение.
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