В этом примере показано, как настроить 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')![]()
Модель включает в себя технологический шум с дисперсией = 1.
Поддержание уровня воды при минимизации усилий по контролю u, контроллеры в этом примере используют следующий критерий LQG.
(t)) dt)
Для моделирования контроллера в этой модели необходимо указать время моделирования. Tf и время выборки контроллера Ts в секундах.
Ts = 0.1; Tf = 10;
Дополнительные сведения о модели резервуара для воды см. в разделе Модель резервуара для воды Simulink (Simulink Control Design).
Чтобы настроить контроллер в 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, измените модель резервуара для воды, выполнив следующие шаги.
Удалите контроллер PID.
Вставка блока агента RL.
Создайте вектор наблюдения , где r-h, h - высота резервуара, а r - опорная высота. Подключите сигнал наблюдения к блоку агента RL.
Определите функцию вознаграждения для агента RL как отрицательное значение стоимости LQG, то есть 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 решает, какое действие предпринять, используя представление актера. Чтобы создать актера, сначала создайте глубокую нейронную сеть с входом наблюдения и выходом действия. Дополнительные сведения см. в разделе rlDeterministicActorRepresentation.
Можно моделировать PI-контроллер как нейронную сеть с одним полностью подключенным слоем с наблюдениями интеграла ошибок и ошибок.
] T
Здесь:
u - выход акторной нейронной сети.
Kp и Ki - абсолютные значения весов нейронной сети.
r-h, h - высота резервуара, r - опорная высота.
Оптимизация градиентного спуска может привести веса к отрицательным значениям. Во избежание отрицательных весов замените нормальные fullyConnectedLayer с fullyConnectedPILayer. Этот уровень гарантирует, что веса будут положительными, реализуя функцию ) * 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')
![]()
Проанализируйте отклик шага для обоих моделей.
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'};
stepInfoTablestepInfoTable=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'};
stabilityMarginTablestabilityMarginTable=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