Создайте пользовательское окружение MATLAB из шаблона

Можно задать пользовательское окружение обучения с подкреплением путем создания и изменения класса окружения шаблона. Вы можете использовать пользовательское окружение шаблона для:

  • Реализуйте более сложную динамику окружения.

  • Добавьте пользовательские визуализации в ваше окружение.

  • Создайте интерфейс для сторонних библиотек, определенных на языках, таких как C++, Java®, или Python®. Для получения дополнительной информации см. раздел Интерфейсы к внешним языкам.

Для получения дополнительной информации о создании MATLAB® классы см. «Пользовательские классы».

Можно создать менее сложные пользовательские окружения обучения с подкреплением с помощью пользовательских функций, как описано в разделе «Создание окружения MATLAB с использованием пользовательских функций».

Создание класса шаблона

Чтобы определить пользовательское окружение, сначала создайте файл класса шаблона, задав имя класса. В данном примере назовите класс MyEnvironment.

rlCreateEnvTemplate("MyEnvironment")

Программа создает и открывает файл класса шаблона. Класс шаблона является подклассом rl.env.MATLABEnvironment абстрактный класс, как показано в определении класса в начале файла шаблона. Этот абстрактный класс является тем же самым, который используется другими объектами окружения обучения с подкреплением MATLAB.

classdef MyEnvironment < rl.env.MATLABEnvironment

По умолчанию класс шаблона реализует простую модель балансировки тележки с шестом, подобную предопределённым окружениям тележки с шестом, описанным в Load Predefined Control System Environments.

Чтобы задать динамику окружения, измените класс шаблона, задайте следующее:

  • Свойства окружения

  • Необходимые методы окружения

  • Дополнительные методы окружения

Свойства окружения

В properties раздел шаблона, задайте любые параметры, необходимые для создания и симуляции окружения. Эти параметры могут включать:

  • Физические константы - окружение расчета задаёт ускорение из-за силы тяжести (Gravity).

  • Геометрия окружения - окружение расчета задает массы тележки и полюса (CartMass и PoleMass) и половинную длину шеста (HalfPoleLength).

  • Ограничения окружения - Среда расчета задает пороги угла шеста и расстояния до тележки (AngleThreshold и DisplacementThreshold). Эти значения используются окружением, чтобы обнаружить, когда эпизод тренировки закончен.

  • Переменные, необходимые для оценки окружения - Выборка окружения задает вектор состояния (State) и флаг для указания, когда эпизод закончен (IsDone).

  • Константы для определения действий или пространств наблюдений - окружение расчета определяет максимальную силу для пространства действий (MaxForce).

  • Константы для вычисления сигнала вознаграждения - окружение расчета задаёт константы RewardForNotFalling и PenaltyForFalling.

properties
    % Specify and initialize the necessary properties of the environment  
    % 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
    
    % Angle at which to fail the episode (radians)
    AngleThreshold = 12 * pi/180
        
    % 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 
end
    
properties
    % Initialize system state [x,dx,theta,dtheta]'
    State = zeros(4,1)
end

properties(Access = protected)
    % Initialize internal flag to indicate episode termination
    IsDone = false        
end

Необходимые функции

Окружение обучения с подкреплением требует, чтобы были определены следующие функции. The getObservationInfo, getActionInfo, sim, и validateEnvironment функции уже определены в базовом абстрактном классе. Чтобы создать ваше окружение, вы должны задать конструктор, reset, и step функций.

ФункцияОписание
getObservationInfoВозвращает информацию о наблюдениях окружения
getActionInfoВозврат информации о действиях окружения
simМоделируйте окружение с помощью агента
validateEnvironmentПроверьте окружение путем вызова reset функция и симуляция окружения для одного временного шага с помощью step
resetИнициализируйте состояние окружения и очистите любую визуализацию
stepПрименить действие, моделировать окружение на один шаг и выдать наблюдения и вознаграждения; также установите флаг, указывающий, завершен ли эпизод
Функция конструктораФункция с таким же именем, как и класс, который создает образец класса

Образец функции конструктора

Функция конструктора тележки с шестом для расчета создает окружение следующим образом:

  • Определение спецификаций действий и наблюдений. Для получения дополнительной информации о создании этих спецификаций см. rlNumericSpec и rlFiniteSetSpec.

  • Вызов конструктора базового абстрактного класса.

function this = MyEnvironment()
    % Initialize observation settings
    ObservationInfo = rlNumericSpec([4 1]);
    ObservationInfo.Name = 'CartPole States';
    ObservationInfo.Description = 'x, dx, theta, dtheta';

    % Initialize action settings   
    ActionInfo = rlFiniteSetSpec([-1 1]);
    ActionInfo.Name = 'CartPole Action';

    % The following line implements built-in functions of the RL environment
    this = this@rl.env.MATLABEnvironment(ObservationInfo,ActionInfo);

    % Initialize property values and precompute necessary values
    updateActionInfo(this);
end

Этот пример функции конструктора не содержит входных параметров. Однако можно добавить входные параметры для пользовательского конструктора.

Выборка reset Функция

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

% Reset environment to initial state and return initial observation
function InitialObservation = reset(this)
    % Theta (+- .05 rad)
    T0 = 2 * 0.05 * rand - 0.05;  
    % Thetadot
    Td0 = 0;
    % X 
    X0 = 0;
    % Xdot
    Xd0 = 0;

    InitialObservation = [X0;Xd0;T0;Td0];
    this.State = InitialObservation;

    % (Optional) Use notifyEnvUpdated to signal that the 
    % environment is updated (for example, to update the visualization)
    notifyEnvUpdated(this);
end

Выборка step Функция

Образец тележки с шестом step функция:

  • Обрабатывает вход действие.

  • Оценивает динамические уравнения окружения для одного временного шага.

  • Вычисляет и возвращает обновленные наблюдения.

  • Вычисляет и возвращает сигнал вознаграждения.

  • Проверяет, завершен ли эпизод, и возвращает IsDone сигнал при необходимости.

  • Генерирует уведомление об обновлении окружения.

function [Observation,Reward,IsDone,LoggedSignals] = step(this,Action)
    LoggedSignals = [];

    % Get action
    Force = getForce(this,Action);            

    % Unpack state vector
    XDot = this.State(2);
    Theta = this.State(3);
    ThetaDot = this.State(4);

    % Cache to avoid recomputation
    CosTheta = cos(Theta);
    SinTheta = sin(Theta);            
    SystemMass = this.CartMass + this.PoleMass;
    temp = (Force + this.PoleMass*this.HalfPoleLength*ThetaDot^2*SinTheta)...
        /SystemMass;

    % Apply motion equations            
    ThetaDotDot = (this.Gravity*SinTheta - CosTheta*temp)...
        / (this.HalfPoleLength*(4.0/3.0 - this.PoleMass*CosTheta*CosTheta/SystemMass));
    XDotDot  = temp - this.PoleMass*this.HalfPoleLength*ThetaDotDot*CosTheta/SystemMass;

    % Euler integration
    Observation = this.State + this.Ts.*[XDot;XDotDot;ThetaDot;ThetaDotDot];

    % Update system states
    this.State = Observation;

    % Check terminal condition
    X = Observation(1);
    Theta = Observation(3);
    IsDone = abs(X) > this.DisplacementThreshold || abs(Theta) > this.AngleThreshold;
    this.IsDone = IsDone;

    % Get reward
    Reward = getReward(this);

    % (Optional) Use notifyEnvUpdated to signal that the 
    % environment has been updated (for example, to update the visualization)
    notifyEnvUpdated(this);
end

Дополнительные функции

При необходимости можно задать любые другие функции в классе шаблона. Например, можно создать вспомогательные функции, которые вызываются любым из step или reset. Модель шаблона тележки с шестом реализует getReward функция для вычисления вознаграждения на каждом временном шаге.

function Reward = getReward(this)
    if ~this.IsDone
        Reward = this.RewardForNotFalling;
    else
        Reward = this.PenaltyForFalling;
    end          
end

Визуализация окружения

Вы можете добавить визуализацию в пользовательское окружение, реализуя plot функция. В plot функция:

  • Создайте рисунок или образец класса визуализатора вашей собственной реализации. В данном примере вы создаете рисунок и храните указатель на рисунок в объекте окружения.

  • Вызовите envUpdatedCallback функция.

function plot(this)
    % Initiate the visualization
    this.Figure = figure('Visible','on','HandleVisibility','off');
    ha = gca(this.Figure);
    ha.XLimMode = 'manual';
    ha.YLimMode = 'manual';
    ha.XLim = [-3 3];
    ha.YLim = [-1 2];
    hold(ha,'on');
    % Update the visualization
    envUpdatedCallback(this)
end

В данном примере храните указатель на рисунок как защищенное свойство объекта окружения.

properties(Access = protected)
    % Initialize internal flag to indicate episode termination
    IsDone = false 

    % Handle to figure
    Figure
end

В envUpdatedCallbackпостройте график визуализации в рисунок или используйте пользовательский объект визуализатора. Для примера проверьте, установлен ли указатель на рисунок. Если это так, тогда постройте график визуализации.

function envUpdatedCallback(this)
    if ~isempty(this.Figure) && isvalid(this.Figure)
        % Set visualization figure as the current figure
        ha = gca(this.Figure);

        % Extract the cart position and pole angle
        x = this.State(1);
        theta = this.State(3);

        cartplot = findobj(ha,'Tag','cartplot');
        poleplot = findobj(ha,'Tag','poleplot');
        if isempty(cartplot) || ~isvalid(cartplot) ...
                || isempty(poleplot) || ~isvalid(poleplot)
            % Initialize the cart plot
            cartpoly = polyshape([-0.25 -0.25 0.25 0.25],[-0.125 0.125 0.125 -0.125]);
            cartpoly = translate(cartpoly,[x 0]);
            cartplot = plot(ha,cartpoly,'FaceColor',[0.8500 0.3250 0.0980]);
            cartplot.Tag = 'cartplot';

            % Initialize the pole plot
            L = this.HalfPoleLength*2;
            polepoly = polyshape([-0.1 -0.1 0.1 0.1],[0 L L 0]);
            polepoly = translate(polepoly,[x,0]);
            polepoly = rotate(polepoly,rad2deg(theta),[x,0]);
            poleplot = plot(ha,polepoly,'FaceColor',[0 0.4470 0.7410]);
            poleplot.Tag = 'poleplot';
        else
            cartpoly = cartplot.Shape;
            polepoly = poleplot.Shape;
        end

        % Compute the new cart and pole position
        [cartposx,~] = centroid(cartpoly);
        [poleposx,poleposy] = centroid(polepoly);
        dx = x - cartposx;
        dtheta = theta - atan2(cartposx-poleposx,poleposy-0.25/2);
        cartpoly = translate(cartpoly,[dx,0]);
        polepoly = translate(polepoly,[dx,0]);
        polepoly = rotate(polepoly,rad2deg(dtheta),[x,0.25/2]);

        % Update the cart and pole positions on the plot
        cartplot.Shape = cartpoly;
        poleplot.Shape = polepoly;

        % Refresh rendering in the figure window
        drawnow();
    end
end

Это окружение вызывает envUpdatedCallback функция, и поэтому обновляет визуализацию каждый раз, когда окружение обновляется.

Создание пользовательского окружения

После определения пользовательского класса окружения создайте его образец в рабочем пространстве MATLAB. В командной строке введите следующее.

env = MyEnvironment;

Если ваш конструктор имеет входные параметры, задайте их после имени класса. Для примера, MyEnvironment(arg1,arg2).

После создания окружения лучше всего проверить динамику окружения. Для этого используйте validateEnvironment функция, которая печатает ошибку в командном окне, если у вашей реализации окружения есть какие-либо проблемы.

validateEnvironment(env)

После проверки объекта окружения можно использовать его для обучения агента обучения с подкреплением. Для получения дополнительной информации о обучении агентов см. Train «Обучение агентов обучения с подкреплением».

См. также

|

Похожие темы