从模板创建自定义MATLAB环境
创建模板类
环境属性
所需功能
样本构造函数
采样复位函数
采样步函数
可选函数
环境可视化
创建自定义环境

您可以通过创建和修改模板环境类来定义自定义的强化学习环境。可以使用自定义模板环境来
实现更复杂的环境动态。
向环境添加自定义可视化。
创建用c++、Java或Python等语言定义的第三方库的接口。
创建模板类
要定义您的自定义环境,首先要创建模板类文件,并指定类的名称。对于本例,将类命名为MyEnvironment。

rlCreateEnvTemplate("MyEnvironment")

该软件创建并打开模板类文件。template类是rl.env的一个子类。MATLABEnvironment抽象类,如模板文件开头的类定义中所示。这个抽象类与其他MATLAB强化学习环境对象所使用的抽象类是相同的。

classdef MyEnvironment < rl.env.MATLABEnvironment

默认情况下,模板类实现一个简单的车柱平衡模型,类似于Load预定义控制系统环境中描述的车柱预定义环境。

要定义环境动态修改模板类,请指定以下内容:

环境属性
需要环境的方法
可选环境方法
环境属性


在模板的properties部分中,指定创建和模拟环境所需的任何参数。这些参数可以包括:

物理常数-样例环境定义了由于重力(重力)引起的加速度。
环境几何-样本环境定义了推车和杆的质量(CartMass和PoleMass)以及杆的一半长度(HalfPoleLength)。
环境约束-示例环境定义了极角和推车距离阈值(AngleThreshold和DisplacementThreshold)。 环境使用这些值来检测训练情节何时结束。
需要用于评估的环境变量 - 将样品环境定义状态向量(状态)和一个标志,用于当一个插曲结束(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

所需功能

强化学习环境需要定义以下功能。getObservationInfo、getActionInfo、sim和validateEnvironment函数已经在基抽象类中定义了。要创建环境,必须定义构造函数、重置和步骤函数。
在这里插入图片描述

样本构造函数

样本cart-pole构造函数通过以下方法创建环境:

  1. 定义的动作和观察指标。有关创建这些规范的详情。

  2. 调用基本抽象类的构造函数。

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

这个示例构造函数不包含任何输入参数。但是,您可以为自定义构造函数添加输入参数。

采样复位函数

样品重置功能设置模型的初始条件,并返回观测值的初始值。 它还通过调用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

采样步函数

采样车摆步函数:

  1. 处理输入动作。
  2. 一次评估环境动力学方程式。
  3. 计算并返回更新的观测值。
  4. 计算并返回奖励信号。
  5. 检查情节是否完成,并IsDone适当地返回信号。
  6. 生成有关环境已更新的通知。
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调用的helper函数。车杆模板模型实现了一个getReward函数,用于计算每个时间步长的奖励。

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

环境可视化

您可以通过实现plot功能将可视化效果添加到自定义环境中 。在plot函数中:

  1. 创建您自己的实现的图形或可视化工具类的实例。对于此示例,您将创建一个图形并将该图形的句柄存储在环境对象中。
  2. 调用该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

对于本例,将图形句柄存储为environment对象的受保护属性。

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)

验证环境对象后,您可以使用它来训练强化学习智能体。