주요 콘텐츠

강화 학습을 통한 이동 로봇의 장애물 회피

이 예제에서는 DDPG(심층 결정적 정책 경사) 기반 강화 학습을 사용하여 이동 로봇이 장애물을 회피하는 전략을 개발합니다. DDPG 알고리즘에 대한 간단한 요약은 DDPG(심층 결정적 정책 경사) 에이전트 (Reinforcement Learning Toolbox) 항목을 참조하십시오.

이 예제 시나리오에서는 맵에 있는 장애물을 검출하는 거리 센서 측정값이 주어진 상태에서 이동 로봇이 장애물을 회피하도록 훈련시킵니다. 강화 학습 알고리즘의 목적은 로봇이 장애물에 충돌하는 것을 회피하기 위해 사용해야 하는 제어(선속도 및 각속도)를 학습하는 것입니다. 이 예제는 알려진 환경의 점유 맵을 사용하여 거리 센서 측정값을 생성하고, 장애물을 검출하고, 로봇이 일으킬 수 있는 충돌을 확인합니다. 거리 센서 측정값은 DDPG 에이전트에 대한 관측값이고, 선속도 제어값과 각속도 제어값은 행동입니다.

맵 불러오기

로봇의 환경을 나타내는 맵 행렬 simpleMap을 불러옵니다.

load exampleMaps simpleMap 
load exampleHelperOfficeAreaMap office_area_map
mapMatrix = simpleMap;
mapScale = 1;

거리 센서 파라미터

다음으로, 잡음이 있는 거리 센서를 시뮬레이션하는 rangeSensor 객체를 설정합니다. 거리 센서 측정값은 에이전트에 의한 관측값으로 간주됩니다. 거리 측정값의 각위치, 최대 거리, 잡음 파라미터를 정의합니다.

scanAngles = -3*pi/8:pi/8:3*pi/8;
maxRange = 12;
lidarNoiseVariance = 0.1^2;
lidarNoiseSeeds = randi(intmax,size(scanAngles));

로봇 파라미터

에이전트의 행동은 2차원 벡터 a=[v,ω]이며, 여기서 vω는 로봇의 선속도와 각속도입니다. DDPG 에이전트는 각속도와 선속도 모두에 정규화된 입력값을 사용합니다. 즉, 에이전트의 행동은 -1과 1 사이의 스칼라이며, 이 값에 maxLinSpeed 파라미터와 maxAngSpeed 파라미터를 곱하여 실제 제어값을 얻습니다. 이 최대 선속도와 최대 각속도를 지정합니다.

또한 로봇의 초기 위치를 [x y theta]로 지정합니다.

% Max speed parameters
maxLinSpeed = 0.3;
maxAngSpeed = 0.3;

% Initial pose of the robot
initX = 17;
initY = 15;
initTheta = pi/2;

맵과 로봇 위치 표시하기

로봇의 행동을 시각화하기 위해 Figure를 만듭니다. 먼저 점유 맵을 표시한 다음 로봇의 초기 위치를 플로팅합니다.

fig = figure("Name","simpleMap");
set(fig, "Visible","on");
ax = axes(fig);

show(binaryOccupancyMap(mapMatrix),"Parent",ax);
hold on
plotTransforms([initX,initY,0],eul2quat([initTheta,0,0]),"MeshFilePath","groundvehicle.stl","View","2D");
light;
hold off

Figure simpleMap contains an axes object. The axes object with title Binary Occupancy Grid, xlabel X [meters], ylabel Y [meters] contains 5 objects of type patch, line, image.

환경 인터페이스

행동을 받아 관측값과 보상 신호를 출력하는 환경 모델을 만듭니다. 제공된 예제 모델 이름, exampleHelperAvoidObstaclesMobileRobot, 시뮬레이션 시간 파라미터, 에이전트 블록 이름을 지정합니다.

mdl = "exampleHelperAvoidObstaclesMobileRobot";
Tfinal = 100;
sampleTime = 0.1;

agentBlk = mdl + "/Agent";

모델을 엽니다.

open_system(mdl)

모델에는 Environment 블록과 Agent 블록이 포함되어 있습니다. Agent 블록은 아직 정의되지 않았습니다.

Environment Subsystem 블록 내부에는 로봇과 센서 데이터를 시뮬레이션하기 위한 모델이 보입니다. 서브시스템은 행동을 받고, 거리 센서 측정값을 기반으로 관측 신호를 생성하고, 장애물과의 거리와 행동 명령에 드는 노력을 기반으로 보상을 계산합니다.

open_system(mdl + "/Environment")

거리 센서의 각 각위치에 대해 충분한 수의 요소를 갖도록 거리 측정값의 하한과 상한을 지정하고 rlNumericSpec 객체를 사용하여 관측값 파라미터 obsInfo를 정의합니다.

obsInfo = rlNumericSpec([numel(scanAngles) 1],...
    "LowerLimit",zeros(numel(scanAngles),1),...
    "UpperLimit",ones(numel(scanAngles),1)*maxRange);
numObservations = obsInfo.Dimension(1);

행동 파라미터 actInfo를 정의합니다. 행동은 제어 명령 벡터 a=[v,ω]로, [-1,1] 범위로 정규화됩니다.

numActions = 2;
actInfo = rlNumericSpec([numActions 1],...
    "LowerLimit",-1,...
    "UpperLimit",1);

rlSimulinkEnv (Reinforcement Learning Toolbox)를 사용하여 환경 인터페이스 객체를 작성합니다. 모델, 에이전트 블록 이름, 관측값 파라미터, 행동 파라미터를 지정합니다. exampleHelperRLAvoidObstaclesResetFcn을 사용하여 시뮬레이션에 대한 재설정 함수를 설정합니다. 이 함수는 장애물 회피를 시작하기 위한 새로운 위치에 로봇을 무작위로 배치하여 시뮬레이션을 재시작합니다.

env = rlSimulinkEnv(mdl,agentBlk,obsInfo,actInfo);
env.ResetFcn = @(in)exampleHelperRLAvoidObstaclesResetFcn(in,scanAngles,maxRange,mapMatrix);
env.UseFastRestart = "Off";

훈련용 Simulink® 환경을 설정하는 다른 예제는 DDPG 에이전트를 사용하여 탱크의 수위 제어하기 (Reinforcement Learning Toolbox) 항목을 참조하십시오.

DDPG 에이전트

DDPG 에이전트는 관측값과 행동이 주어지면 크리틱 가치 함수 표현을 사용하여 장기 보상을 근사합니다. 크리틱을 만들려면 먼저 두 개의 입력값(관측값과 행동)과 하나의 출력값으로 심층 신경망을 생성합니다. 심층 신경망 가치 함수 표현을 생성하는 방법에 대한 자세한 내용은 Create Policies and Value Functions (Reinforcement Learning Toolbox) 항목을 참조하십시오.

statePath = [
    featureInputLayer(numObservations, "Normalization","none","Name","State")
    fullyConnectedLayer(50,"Name","CriticStateFC1")
    reluLayer("Name","CriticRelu1")
    fullyConnectedLayer(25,"Name","CriticStateFC2")];
actionPath = [
    featureInputLayer(numActions,"Normalization","none","Name","Action")
    fullyConnectedLayer(25,"Name","CriticActionFC1")];
commonPath = [
    additionLayer(2,"Name","add")
    reluLayer("Name","CriticCommonRelu")
    fullyConnectedLayer(1,"Name","CriticOutput")];

criticNetwork = layerGraph();
criticNetwork = addLayers(criticNetwork,statePath);
criticNetwork = addLayers(criticNetwork,actionPath);
criticNetwork = addLayers(criticNetwork,commonPath);
criticNetwork = connectLayers(criticNetwork,"CriticStateFC2","add/in1");
criticNetwork = connectLayers(criticNetwork,"CriticActionFC1","add/in2");
criticNetwork = dlnetwork(criticNetwork);

다음으로 rlOptimizerOptions를 사용하여 크리틱 최적화 함수의 옵션을 지정합니다.

마지막으로, 지정된 심층 신경망과 옵션을 사용하여 크리틱 표현을 생성합니다. 또한 크리틱에 대한 행동 사양과 관측값 사양도 지정해야 합니다. 이 값은 환경 인터페이스로부터 얻을 수 있습니다. 자세한 내용은 rlQValueFunction (Reinforcement Learning Toolbox) 항목을 참조하십시오.

criticOptions = rlOptimizerOptions("LearnRate",1e-3,"L2RegularizationFactor",1e-4,"GradientThreshold",1);
critic = rlQValueFunction(criticNetwork,obsInfo,actInfo,"ObservationInputNames","State","ActionInputNames","Action");

DDPG 에이전트는 액터 표현을 사용하여 주어진 관측값에 따라 수행할 행동을 결정합니다. 액터를 생성하려면 먼저 하나의 입력값(관측값)과 하나의 출력값(행동)으로 심층 신경망을 생성합니다.

마지막으로 크리틱과 유사한 방식으로 액터를 구성합니다. 자세한 내용은 rlContinuousDeterministicActor (Reinforcement Learning Toolbox) 항목을 참조하십시오.

actorNetwork = [
    featureInputLayer(numObservations,"Normalization","none","Name","State")
    fullyConnectedLayer(50,"Name","actorFC1")
    reluLayer("Name","actorReLU1")
    fullyConnectedLayer(50, "Name","actorFC2")
    reluLayer("Name","actorReLU2")
    fullyConnectedLayer(2, "Name","actorFC3")
    tanhLayer("Name","Action")];
actorNetwork = dlnetwork(actorNetwork);

actorOptions = rlOptimizerOptions("LearnRate",1e-4,"L2RegularizationFactor",1e-4,"GradientThreshold",1);
actor = rlContinuousDeterministicActor(actorNetwork,obsInfo,actInfo);

DDPG 에이전트 객체 만들기

에이전트 옵션을 지정합니다.

agentOpts = rlDDPGAgentOptions(...
    "SampleTime",sampleTime,...
    "ActorOptimizerOptions",actorOptions,...
    "CriticOptimizerOptions",criticOptions,...
    "DiscountFactor",0.995, ...
    "MiniBatchSize",128, ...
    "ExperienceBufferLength",1e6); 

agentOpts.NoiseOptions.Variance = 0.1;
agentOpts.NoiseOptions.VarianceDecayRate = 1e-5;

rlDDPGAgent 객체를 만듭니다. obstacleAvoidanceAgent 변수가 모델에서 Agent 블록에 대해 사용됩니다.

obstacleAvoidanceAgent = rlDDPGAgent(actor,critic,agentOpts);
open_system(mdl + "/Agent")

보상

에이전트에 대한 보상 함수는 다음과 같이 모델링됩니다.

에이전트는 가장 가까운 장애물을 회피할 경우 보상을 받으며, 이를 통해 최악의 시나리오를 최소화합니다. 또한 에이전트는 선속도가 높을수록 양의 보상을 받고, 각속도가 높을수록 음의 보상을 받습니다. 이 보상 전략은 에이전트가 원을 그리며 이동하는 행동을 억제합니다. 에이전트를 제대로 훈련시키려면 보상을 조정하는 것이 관건이므로, 응용 사례에 따라 보상이 달라집니다.

에이전트 훈련시키기

에이전트를 훈련시키려면 먼저 훈련 옵션을 지정합니다. 이 예제에서는 다음 옵션을 사용합니다.

  • 최대 10000개의 에피소드에 대해 훈련시키며, 각 에피소드는 최대 maxSteps 시간 스텝으로 지속됩니다.

  • 에피소드 관리자 대화 상자에 훈련 진행 상황을 표시하고(Plots 옵션 설정) 명령줄 표시를 활성화합니다(Verbose 옵션을 true로 설정).

  • 에이전트가 연속으로 50개 넘는 에피소드에 걸쳐 평균 누적 보상을 400 이상 받는 경우 훈련을 중지합니다.

자세한 내용은 rlTrainingOptions (Reinforcement Learning Toolbox) 항목을 참조하십시오.

maxEpisodes = 10000;
maxSteps = ceil(Tfinal/sampleTime);
trainOpts = rlTrainingOptions(...
    "MaxEpisodes",maxEpisodes, ...
    "MaxStepsPerEpisode",maxSteps, ...
    "ScoreAveragingWindowLength",50, ...
    "StopTrainingCriteria","AverageReward", ...
    "StopTrainingValue",400, ...
    "Verbose", true, ...
    "Plots","training-progress");

train (Reinforcement Learning Toolbox) 함수를 사용하여 에이전트를 훈련시킵니다. 훈련은 완료하는 데 몇 분 정도 소요되는 계산 집약적인 절차입니다. 이 예제를 실행하는 동안 시간을 절약하기 위해 doTrainingfalse로 설정하여 사전 훈련된 에이전트를 불러옵니다. 에이전트를 직접 훈련시키려면 doTrainingtrue로 설정하십시오.

doTraining = false; % Toggle this to true for training. 

if doTraining
    % Train the agent.
    trainingStats = train(obstacleAvoidanceAgent,env,trainOpts);
else
    % Load pretrained agent for the example.
    load exampleHelperAvoidObstaclesAgent obstacleAvoidanceAgent
end

강화 학습 에피소드 관리자를 사용하여 에피소드별 훈련 진행 상황을 추적할 수 있습니다. 에피소드 번호가 늘어날수록 보상 값도 증가하는 것이 바람직합니다.

시뮬레이션

훈련된 에이전트를 사용하여 200초 동안 맵에서의 로봇 주행과 장애물 회피를 시뮬레이션합니다.

set_param("exampleHelperAvoidObstaclesMobileRobot","StopTime","200");
out = sim("exampleHelperAvoidObstaclesMobileRobot.slx");

시각화

로봇이 거리 센서 측정값을 바탕으로 환경을 주행하는 시뮬레이션을 시각화하려면 헬퍼 exampleHelperAvoidObstaclesPosePlot을 사용합니다.

for i = 1:5:size(out.range,3)
    u = out.pose(i,:);
    r = out.range(:,:,i);
    exampleHelperAvoidObstaclesPosePlot(u,mapMatrix,mapScale,r,scanAngles,ax);
end

Figure simpleMap contains an axes object. The axes object with title Binary Occupancy Grid, xlabel X [meters], ylabel Y [meters] contains 6 objects of type patch, line, image. One or more of the lines displays its values using only markers

확장성

이제 이 에이전트를 사용하여 다른 맵에서의 주행을 시뮬레이션할 수 있습니다. 사무실 환경의 라이더 스캔으로부터 생성된 다른 맵을 동일한 훈련된 모델과 함께 사용할 수 있습니다. 이 맵은 훈련 후에 훈련된 모델을 적용하기 위한 보다 현실적인 시나리오를 나타냅니다.

맵 변경하기

mapMatrix = office_area_map.occupancyMatrix > 0.5;
mapScale = 10;
initX = 20;
initY = 30;
initTheta = 0;
fig = figure("Name","office_area_map");
set(fig,"Visible","on");
ax = axes(fig);
show(binaryOccupancyMap(mapMatrix,mapScale),"Parent",ax);
hold on
plotTransforms([initX,initY,0],eul2quat([initTheta, 0, 0]),"MeshFilePath","groundvehicle.stl","View","2D");
light;
hold off

Figure office_area_map contains an axes object. The axes object with title Binary Occupancy Grid, xlabel X [meters], ylabel Y [meters] contains 5 objects of type patch, line, image.

시뮬레이션

새 맵 전반에 걸쳐 로봇 궤적을 시뮬레이션합니다. 나중에 에이전트를 다시 훈련시키고 다시 조정해야 할 경우를 대비하여 시뮬레이션 시간을 재설정합니다.

out = sim("exampleHelperAvoidObstaclesMobileRobot.slx");
set_param("exampleHelperAvoidObstaclesMobileRobot","StopTime","inf");

시각화

for i = 1:5:size(out.range,3)
    u = out.pose(i,:);
    r = out.range(:,:,i);
    exampleHelperAvoidObstaclesPosePlot(u,mapMatrix,mapScale,r,scanAngles,ax);
end

Figure office_area_map contains an axes object. The axes object with title Binary Occupancy Grid, xlabel X [meters], ylabel Y [meters] contains 6 objects of type patch, line, image. One or more of the lines displays its values using only markers