Main Content

経路追従制御用の DDPG エージェントの学習

この例では、経路追従制御 (PFC) 用の深層決定論的方策勾配 (DDPG) エージェントの学習を Simulink® で実行する方法を説明します。DDPG エージェントの詳細については、Deep Deterministic Policy Gradient (DDPG) Agents (Reinforcement Learning Toolbox)を参照してください。

Simulink モデル

この例では、自車については単純な自転車モデル、先行車両については単純な前後方向のモデルを強化学習の環境として使用します。この学習の目的は、前後方向の加速と減速を制御して先行車両との安全な距離を維持しつつ、自車を設定速度で走行させること、およびフロント ステアリング角度を制御して車線のセンターラインに沿って自車を走行させ続けることです。PFC の詳細については、Path Following Control System (Model Predictive Control Toolbox)を参照してください。自車の車両運動は、次のパラメーターで指定します。

m = 1600;   % total vehicle mass (kg)
Iz = 2875;  % yaw moment of inertia (mNs^2)
lf = 1.4;   % longitudinal distance from center of gravity to front tires (m)
lr = 1.6;   % longitudinal distance from center of gravity to rear tires (m)
Cf = 19000; % cornering stiffness of front tires (N/rad)
Cr = 33000; % cornering stiffness of rear tires (N/rad)
tau = 0.5;  % longitudinal time constant

2 台の車両の初期位置と初期速度を指定します。

x0_lead = 50;   % initial position for lead car (m)
v0_lead = 24;   % initial velocity for lead car (m/s)
x0_ego = 10;    % initial position for ego car (m)
v0_ego = 18;    % initial velocity for ego car (m/s)

停止時の既定の間隔 (m)、時間ギャップ (s)、および運転手が設定した速度 (m/s) を指定します。

D_default = 10;
t_gap = 1.4;
v_set = 28;

車両運動の物理的な制約をシミュレートするため、加速度を [–3,2] (m/s^2) の範囲に制限し、ステアリング角度を [–0.2618,0.2618] (rad) の範囲 (-15 ~ 15 度) に制限します。

amin_ego = -3;
amax_ego = 2;
umin_ego = -0.2618; % +15 deg
umax_ego = 0.2618; % -15 deg

道路の曲率は定数 0.001 (m-1) で定義されます。横方向の偏差の初期値を 0.2 m とし、相対ヨー角の初期値を -0.1 rad とします。

rho = 0.001;
e1_initial = 0.2;
e2_initial = -0.1;

サンプル時間 Ts とシミュレーション期間 Tf を秒単位で定義します。

Ts = 0.1;
Tf = 60;

モデルを開きます。

mdl = 'rlPFCMdl';
open_system(mdl)
agentblk = [mdl '/RL Agent'];

このモデルの場合、次のようにします。

  • アクション信号は、加速度のアクションとステアリング角度のアクションで構成される。加速度のアクション信号は、-3 ~ 2 (m/s^2) の値を取る。ステアリングのアクション信号は、-15 度 (-0.2618 rad) ~ 15 度 (0.2618 rad) の値を取る。

  • 自車の基準速度 Vref を次のように定義する。相対距離が安全距離未満の場合、自車は先行車両の速度と運転手が設定した速度の最小値に追従する。この方法により、自車は先行車両からある程度の距離を維持する。相対距離が安全距離より大きい場合、自車は運転手が設定した速度に追従する。この例では、安全距離は自車の前後方向の速度 V の線形関数、つまり、tgap*V+Ddefault として定義される。安全距離によって、自車の追従速度が決まる。

  • 環境からの観測値には、前後方向の測定値、つまり、速度誤差 eV=Vref-Vego、その積分 e、および自車の前後方向の速度 V が含まれる。また、この観測値には、横方向の測定値、つまり、横方向の偏差 e1、相対ヨー角 e2、これらの微分 e˙1 および e˙2、これらの積分 e1 および e2 が含まれる。

  • シミュレーションは、横方向の偏差が |e1|>1 となるか、前後方向の速度が Vego<0.5 となるか、先行車両と自車との相対距離が Drel<0 となったときに終了する。

  • 各タイム ステップ t で与えられる報酬 rt は次のとおりとする。

rt=-(100e12+500ut-12+10eV2+100at-12)×1e-3-10Ft+2Ht+Mt

ここで、ut-1 は前のタイム ステップ t-1 からのステアリングの入力、at-1 は前のタイム ステップからの加速度の入力です。この 3 つの論理値は次のようになります。

  • Ft=1 (シミュレーションが終了した場合)、Ft=0 (それ以外の場合)

  • Ht=1 (横方向の誤差が e12<0.01 の場合)、Ht=0 (それ以外の場合)

  • Mt=1 (速度の誤差が eV2<1 の場合)、Mt=0 (それ以外の場合)

報酬に含まれるこの 3 つの論理項は、横方向の誤差と速度の誤差の両方を小さくするようエージェントに促す一方、シミュレーションが早期に終了した場合はエージェントにペナルティを課します。

環境インターフェイスの作成

Simulink モデル用の環境インターフェイスを作成します。

観測値の仕様を作成します。

observationInfo = rlNumericSpec([9 1],'LowerLimit',-inf*ones(9,1),'UpperLimit',inf*ones(9,1));
observationInfo.Name = 'observations';

アクションの仕様を作成します。

actionInfo = rlNumericSpec([2 1],'LowerLimit',[-3;-0.2618],'UpperLimit',[2;0.2618]);
actionInfo.Name = 'accel;steer';

環境インターフェイスを作成します。

env = rlSimulinkEnv(mdl,agentblk,observationInfo,actionInfo);

初期条件を定義するには、無名関数ハンドルを使用して環境リセット関数を指定します。例の終わりに定義されているリセット関数 localResetFcn は、先行車両の初期位置、横方向の偏差、相対ヨー角をランダム化します。

env.ResetFcn = @(in)localResetFcn(in);

再現性をもたせるために、乱数発生器のシードを固定します。

rng(0)

DDPG エージェントの作成

DDPG エージェントは、観測値とアクションが与えられると、クリティック価値関数表現を使用して長期報酬を近似します。クリティックを作成するには、まず、2 つの入力 (状態およびアクション) と 1 つの出力をもつ深層ニューラル ネットワークを作成します。深層ニューラル ネットワークの値関数表現の作成の詳細については、Create Policies and Value Functions (Reinforcement Learning Toolbox)を参照してください。

L = 100; % number of neurons
statePath = [
    featureInputLayer(9,'Normalization','none','Name','observation')
    fullyConnectedLayer(L,'Name','fc1')
    reluLayer('Name','relu1')
    fullyConnectedLayer(L,'Name','fc2')
    additionLayer(2,'Name','add')
    reluLayer('Name','relu2')
    fullyConnectedLayer(L,'Name','fc3')
    reluLayer('Name','relu3')
    fullyConnectedLayer(1,'Name','fc4')];

actionPath = [
    featureInputLayer(2,'Normalization','none','Name','action')
    fullyConnectedLayer(L,'Name','fc5')];

criticNetwork = layerGraph(statePath);
criticNetwork = addLayers(criticNetwork,actionPath);    
criticNetwork = connectLayers(criticNetwork,'fc5','add/in2');

criticNetwork = dlnetwork(criticNetwork);

クリティック ネットワークの構成を表示します。

figure
plot(layerGraph(criticNetwork))

Figure contains an axes object. The axes object contains an object of type graphplot.

rlOptimizerOptions を使用して、クリティック オプティマイザーのオプションを指定します。

criticOptions = rlOptimizerOptions('LearnRate',1e-3,'GradientThreshold',1,'L2RegularizationFactor',1e-4);

指定した深層ニューラル ネットワークを使用して、クリティック関数を作成します。また、クリティックのアクションと観測値の情報も指定しなければなりません (これらは環境インターフェイスから取得します)。詳細については、rlQValueFunction (Reinforcement Learning Toolbox)を参照してください。

critic = rlQValueFunction(criticNetwork,observationInfo,actionInfo,...
    'ObservationInputNames','observation','ActionInputNames','action');

DDPG エージェントは、観測値が与えられると、どのアクションを実行するかをアクター表現を使用して決定します。アクターを作成するには、まず、1 つの入力 (観測値) と 1 つの出力 (アクション) をもつ深層ニューラル ネットワークを作成します。

クリティックと同様にアクターを作成します。詳細については、rlContinuousDeterministicActor (Reinforcement Learning Toolbox)を参照してください。

actorNetwork = [
    featureInputLayer(9,'Normalization','none','Name','observation')
    fullyConnectedLayer(L,'Name','fc1')
    reluLayer('Name','relu1')
    fullyConnectedLayer(L,'Name','fc2')
    reluLayer('Name','relu2')
    fullyConnectedLayer(L,'Name','fc3')
    reluLayer('Name','relu3')
    fullyConnectedLayer(2,'Name','fc4')
    tanhLayer('Name','tanh1')
    scalingLayer('Name','ActorScaling1','Scale',[2.5;0.2618],'Bias',[-0.5;0])];
actorNetwork = dlnetwork(actorNetwork);
actorOptions = rlOptimizerOptions('LearnRate',1e-4,'GradientThreshold',1,'L2RegularizationFactor',1e-4);
actor = rlContinuousDeterministicActor(actorNetwork,observationInfo,actionInfo);

DDPG エージェントを作成するには、まず、rlDDPGAgentOptions (Reinforcement Learning Toolbox) を使用して DDPG エージェントのオプションを指定します。

agentOptions = rlDDPGAgentOptions(...
    'SampleTime',Ts,...
    'ActorOptimizerOptions',actorOptions,...
    'CriticOptimizerOptions',criticOptions,...
    'ExperienceBufferLength',1e6);
agentOptions.NoiseOptions.Variance = [0.6;0.1];
agentOptions.NoiseOptions.VarianceDecayRate = 1e-5;

次に、指定したアクター表現、クリティック表現、およびエージェントのオプションを使用して DDPG エージェントを作成します。詳細については、rlDDPGAgent (Reinforcement Learning Toolbox)を参照してください。

agent = rlDDPGAgent(actor,critic,agentOptions);

エージェントの学習

エージェントに学習させるには、まず、学習オプションを指定します。この例では、次のオプションを使用します。

  • 最大 10000 個のエピソードについて、各エピソードの学習を実行 (各エピソードは最大 maxsteps タイム ステップ持続)。

  • Episode Manager のダイアログ ボックスに学習の進行状況を表示 (Verbose オプションと Plots オプションを設定)。

  • 1700 を超える累積エピソード報酬をエージェントが受け取ったときに学習を停止。

詳細については、rlTrainingOptions (Reinforcement Learning Toolbox)を参照してください。

maxepisodes = 1e4;
maxsteps = ceil(Tf/Ts);
trainingOpts = rlTrainingOptions(...
    'MaxEpisodes',maxepisodes,...
    'MaxStepsPerEpisode',maxsteps,...
    'Verbose',false,...
    'Plots','training-progress',...
    'StopTrainingCriteria','EpisodeReward',...
    'StopTrainingValue',1700);

関数 train (Reinforcement Learning Toolbox) を使用して、エージェントに学習させます。学習は計算量が多いプロセスのため、完了するのに数分かかります。この例の実行時間を節約するために、doTrainingfalse に設定して事前学習済みのエージェントを読み込みます。エージェントに学習させるには、doTrainingtrue に設定します。

doTraining = false;

if doTraining    
    % Train the agent.
    trainingStats = train(agent,env,trainingOpts);
else
    % Load a pretrained agent for the example.
    load('SimulinkPFCDDPG.mat','agent')       
end

DDPG エージェントのシミュレーション

学習済みエージェントの性能を検証するには、以下のコマンドのコメントを解除して Simulink 環境内でこのエージェントをシミュレートします。エージェントのシミュレーションの詳細については、rlSimulationOptions (Reinforcement Learning Toolbox) および sim (Reinforcement Learning Toolbox) を参照してください。

% simOptions = rlSimulationOptions('MaxSteps',maxsteps);
% experience = sim(env,agent,simOptions);

確定的な初期条件を使用して学習済みエージェントのデモを実行するには、このモデルを Simulink でシミュレートします。

e1_initial = -0.4;
e2_initial = 0.1;
x0_lead = 80;
sim(mdl)

以下のプロットは、先行車両が自車の 70 (m) 先にあるときのシミュレーション結果を示します。

  • 最初の 35 秒間は、相対距離が安全距離より大きいため (右下のプロット)、自車は設定速度に追従します (右上のプロット)。加速して設定速度に到達するために、加速度はほとんどが非負です (左上のプロット)。

  • 35 ~ 42 秒では、相対距離が安全距離より概ね小さいため (右下のプロット)、自車は先行車両の速度と設定速度のうち最小値に追従します。先行車両の速度が設定速度より小さいため (右上のプロット)、先行車両の速度に追従するように、加速度はゼロ以外になります (左上のプロット)。

  • 42 ~ 58 秒では、自車は設定速度に追従し (右上のプロット)、加速度は 0 のままです (左上のプロット)。

  • 58 ~ 60 秒では、相対距離が安全距離より小さくなるため (右下のプロット)、自車は減速して先行車両の速度に追従します。

  • 左下のプロットは、横方向の偏差を示します。このプロットに示されているように、1 秒以内に横方向の偏差が大きく減少しています。横方向の偏差は 0.05 m 未満を維持しています。

Simulink モデルを閉じます。

bdclose(mdl)

リセット関数

function in = localResetFcn(in) 
in = setVariable(in,'x0_lead',40+randi(60,1,1));    % random value for initial position of lead car
in = setVariable(in,'e1_initial', 0.5*(-1+2*rand)); % random value for lateral deviation
in = setVariable(in,'e2_initial', 0.1*(-1+2*rand)); % random value for relative yaw angle
end

参考

(Reinforcement Learning Toolbox)

関連するトピック