В этом примере показано, как создать среду CART-полюса путем предоставления пользовательских динамических функций в MATLAB ®.
Использование rlFunctionEnv функция, можно создать среду обучения усилению MATLAB из спецификации наблюдения, спецификации действия и определяемой пользователем step и reset функции. Затем в этой среде можно обучить агента обучения усилению. Необходимое step и reset для этого примера уже определены функции.
Создание среды с использованием пользовательских функций полезно для сред с менее сложной динамикой, сред без особых требований к визуализации или сред с интерфейсами к библиотекам сторонних производителей. Для более сложных сред можно создать объект среды с помощью класса шаблона. Дополнительные сведения см. в разделе Создание пользовательской среды MATLAB из шаблона.
Дополнительные сведения о создании учебных сред для усиления см. в разделах Создание учебных сред для усиления MATLAB и Создание учебных сред для усиления Simulink.
Среда «телега-полюс» представляет собой столб, прикрепленный к неактивированному соединению на тележке, которое движется по безфрикционной дорожке. Цель тренировки - сделать маятник стоящим вертикально, не заваливаясь.

Для этой среды:
Уравновешенное вверх положение маятника 0 радианы, и положение подвешивания вниз pi радианы.
Маятник начинается вертикально с начального угла между -0,5 и 0,05.
Сигнал силового воздействия от агента к окружающей среде составляет от -10 до 10 Н.
Наблюдениями из окружающей среды являются положение тележки, скорость тележки, угол маятника и производная угла маятника.
Эпизод заканчивается, если полюс находится более чем на 12 градусов от вертикали, или если телега перемещается более чем на 2,4 м от исходного положения.
Вознаграждение + 1 предусмотрено за каждый шаг времени, когда столб остается в вертикальном положении. При падении маятника применяется штраф -10.
Дополнительные сведения об этой модели см. в разделе Загрузка предопределенных сред системы управления.
Наблюдениями из окружающей среды являются положение тележки, скорость тележки, угол маятника и производная угла маятника.
ObservationInfo = rlNumericSpec([4 1]); ObservationInfo.Name = 'CartPole States'; ObservationInfo.Description = 'x, dx, theta, dtheta';
Среда имеет пространство дискретных действий, в котором агент может применить одно из двух возможных значений силы к корзине: -10 или 10 N.
ActionInfo = rlFiniteSetSpec([-10 10]);
ActionInfo.Name = 'CartPole Action';Дополнительные сведения об указании действий и наблюдений среды см. в разделе rlNumericSpec и rlFiniteSetSpec.
Чтобы определить пользовательскую среду, сначала укажите пользовательскую среду step и reset функции. Эти функции должны находиться в текущей рабочей папке или в пути MATLAB.
Обычай reset устанавливает состояние среды по умолчанию. Эта функция должна иметь следующую подпись.
[InitialObservation,LoggedSignals] = myResetFunction()
Чтобы передать информацию с одного шага на следующий, например состояние среды, используйте LoggedSignals. Для этого примера: LoggedSignals содержит состояния среды телега-полюса: положение и скорость тележки, угол маятника и производную угла маятника. reset задает случайное значение угла тележки при каждом сбросе среды.
Для этого примера используйте пользовательскую функцию сброса, определенную в myResetFunction.m.
type myResetFunction.mfunction [InitialObservation, LoggedSignal] = myResetFunction() % Reset function to place custom cart-pole environment into a random % initial state. % Theta (randomize) T0 = 2 * 0.05 * rand() - 0.05; % Thetadot Td0 = 0; % X X0 = 0; % Xdot Xd0 = 0; % Return initial environment state variables as logged signals. LoggedSignal.State = [X0;Xd0;T0;Td0]; InitialObservation = LoggedSignal.State; end
Обычай step определяет способ перехода среды в следующее состояние на основе данного действия. Эта функция должна иметь следующую подпись.
[Observation,Reward,IsDone,LoggedSignals] = myStepFunction(Action,LoggedSignals)
Чтобы получить новое состояние, среда применяет динамическое уравнение к текущему состоянию, сохраненному в LoggedSignals, что аналогично заданию начального условия дифференциальному уравнению. Новое состояние сохраняется в LoggedSignals и возвращено в виде выходных данных.
Для этого примера используйте пользовательскую функцию шага, определенную в myStepFunction.m. Для простоты реализации эта функция каждый раз переопределяет физические константы, такие как масса корзины. step выполняется.
type myStepFunction.mfunction [NextObs,Reward,IsDone,LoggedSignals] = myStepFunction(Action,LoggedSignals)
% Custom step function to construct cart-pole environment for the function
% name case.
%
% This function applies the given action to the environment and evaluates
% the system dynamics for one simulation step.
% Define the environment constants.
% Acceleration due to gravity in m/s^2
Gravity = 9.8;
% Mass of the cart
CartMass = 1.0;
% Mass of the pole
PoleMass = 0.1;
% Half the length of the pole
HalfPoleLength = 0.5;
% Max force the input can apply
MaxForce = 10;
% Sample time
Ts = 0.02;
% Pole angle at which to fail the episode
AngleThreshold = 12 * pi/180;
% Cart distance at which to fail the episode
DisplacementThreshold = 2.4;
% Reward each time step the cart-pole is balanced
RewardForNotFalling = 1;
% Penalty when the cart-pole fails to balance
PenaltyForFalling = -10;
% Check if the given action is valid.
if ~ismember(Action,[-MaxForce MaxForce])
error('Action must be %g for going left and %g for going right.',...
-MaxForce,MaxForce);
end
Force = Action;
% Unpack the state vector from the logged signals.
State = LoggedSignals.State;
XDot = State(2);
Theta = State(3);
ThetaDot = State(4);
% Cache to avoid recomputation.
CosTheta = cos(Theta);
SinTheta = sin(Theta);
SystemMass = CartMass + PoleMass;
temp = (Force + PoleMass*HalfPoleLength*ThetaDot*ThetaDot*SinTheta)/SystemMass;
% Apply motion equations.
ThetaDotDot = (Gravity*SinTheta - CosTheta*temp) / ...
(HalfPoleLength*(4.0/3.0 - PoleMass*CosTheta*CosTheta/SystemMass));
XDotDot = temp - PoleMass*HalfPoleLength*ThetaDotDot*CosTheta/SystemMass;
% Perform Euler integration.
LoggedSignals.State = State + Ts.*[XDot;XDotDot;ThetaDot;ThetaDotDot];
% Transform state to observation.
NextObs = LoggedSignals.State;
% Check terminal condition.
X = NextObs(1);
Theta = NextObs(3);
IsDone = abs(X) > DisplacementThreshold || abs(Theta) > AngleThreshold;
% Get reward.
if ~IsDone
Reward = RewardForNotFalling;
else
Reward = PenaltyForFalling;
end
end
Создайте пользовательскую среду, используя определенную спецификацию наблюдения, спецификацию действия и имена функций.
env = rlFunctionEnv(ObservationInfo,ActionInfo,'myStepFunction','myResetFunction');
Для проверки работы среды rlFunctionEnv автоматические вызовы validateEnvironment после создания среды.
Можно также определить пользовательские функции, которые имеют дополнительные входные аргументы, превышающие минимально необходимый набор. Например, передать дополнительные аргументы arg1 и arg2 для функции step и rest используйте следующий код.
[InitialObservation,LoggedSignals] = myResetFunction(arg1,arg2) [Observation,Reward,IsDone,LoggedSignals] = myStepFunction(Action,LoggedSignals,arg1,arg2)
Использование этих функций с rlFunctionEnv, необходимо использовать анонимные дескрипторы функций.
ResetHandle = @()myResetFunction(arg1,arg2); StepHandle = @(Action,LoggedSignals) myStepFunction(Action,LoggedSignals,arg1,arg2);
Дополнительные сведения см. в разделе Анонимные функции.
Использование дополнительных входных аргументов может создать более эффективную реализацию среды. Например, myStepFunction2.m содержит пользовательскую step функция, принимающая константы среды в качестве входного аргумента (envConstants). При этом эта функция позволяет избежать переопределения постоянных среды на каждом шаге.
type myStepFunction2.mfunction [NextObs,Reward,IsDone,LoggedSignals] = myStepFunction2(Action,LoggedSignals,EnvConstants)
% Custom step function to construct cart-pole environment for the function
% handle case.
%
% This function applies the given action to the environment and evaluates
% the system dynamics for one simulation step.
% Check if the given action is valid.
if ~ismember(Action,[-EnvConstants.MaxForce EnvConstants.MaxForce])
error('Action must be %g for going left and %g for going right.',...
-EnvConstants.MaxForce,EnvConstants.MaxForce);
end
Force = Action;
% Unpack the state vector from the logged signals.
State = LoggedSignals.State;
XDot = State(2);
Theta = State(3);
ThetaDot = State(4);
% Cache to avoid recomputation.
CosTheta = cos(Theta);
SinTheta = sin(Theta);
SystemMass = EnvConstants.MassCart + EnvConstants.MassPole;
temp = (Force + EnvConstants.MassPole*EnvConstants.Length*ThetaDot*ThetaDot*SinTheta)/SystemMass;
% Apply motion equations.
ThetaDotDot = (EnvConstants.Gravity*SinTheta - CosTheta*temp)...
/ (EnvConstants.Length*(4.0/3.0 - EnvConstants.MassPole*CosTheta*CosTheta/SystemMass));
XDotDot = temp - EnvConstants.MassPole*EnvConstants.Length*ThetaDotDot*CosTheta/SystemMass;
% Perform Euler integration.
LoggedSignals.State = State + EnvConstants.Ts.*[XDot;XDotDot;ThetaDot;ThetaDotDot];
% Transform state to observation.
NextObs = LoggedSignals.State;
% Check terminal condition.
X = NextObs(1);
Theta = NextObs(3);
IsDone = abs(X) > EnvConstants.XThreshold || abs(Theta) > EnvConstants.ThetaThresholdRadians;
% Get reward.
if ~IsDone
Reward = EnvConstants.RewardForNotFalling;
else
Reward = EnvConstants.PenaltyForFalling;
end
end
Создайте структуру, содержащую константы среды.
% Acceleration due to gravity in m/s^2 envConstants.Gravity = 9.8; % Mass of the cart envConstants.MassCart = 1.0; % Mass of the pole envConstants.MassPole = 0.1; % Half the length of the pole envConstants.Length = 0.5; % Max force the input can apply envConstants.MaxForce = 10; % Sample time envConstants.Ts = 0.02; % Angle at which to fail the episode envConstants.ThetaThresholdRadians = 12 * pi/180; % Distance at which to fail the episode envConstants.XThreshold = 2.4; % Reward each time step the cart-pole is balanced envConstants.RewardForNotFalling = 1; % Penalty when the cart-pole fails to balance envConstants.PenaltyForFalling = -5;
Создание анонимного дескриптора функции для пользовательского step функция, прохождение envConstants в качестве дополнительного входного аргумента. Поскольку envConstants доступен в то время, когда StepHandle создается, дескриптор функции включает эти значения. Значения сохраняются в дескрипторе функции, даже если удалить переменные.
StepHandle = @(Action,LoggedSignals) myStepFunction2(Action,LoggedSignals,envConstants);
Использовать то же самое reset , указав его как дескриптор функции, а не используя его имя.
ResetHandle = @() myResetFunction;
Создайте среду с помощью пользовательских дескрипторов функций.
env2 = rlFunctionEnv(ObservationInfo,ActionInfo,StepHandle,ResetHandle);
Перед обучением агента в среде рекомендуется проверить поведение пользовательских функций. Для этого можно инициализировать среду с помощью reset и выполните один этап моделирования с помощью step функция. Для воспроизводимости задайте начальное число случайного генератора перед проверкой.
Проверка среды, созданной с использованием имен функций.
rng(0); InitialObs = reset(env)
InitialObs = 4×1
0
0
0.0315
0
[NextObs,Reward,IsDone,LoggedSignals] = step(env,10); NextObs
NextObs = 4×1
0
0.1947
0.0315
-0.2826
Проверка среды, созданной с помощью дескрипторов функций.
rng(0); InitialObs2 = reset(env2)
InitialObs2 = 4×1
0
0
0.0315
0
[NextObs2,Reward2,IsDone2,LoggedSignals2] = step(env2,10); NextObs
NextObs = 4×1
0
0.1947
0.0315
-0.2826
Обе среды успешно инициализируются и моделируются, создавая одинаковые значения состояний в NextObs.