300x250

졸업 논문을 쓰기 위해 AirSim 자율주행 시뮬레이션을 강화학습을 사용하여 어떻게 구현하였는지 알아보고자 한다.

상세한 내용은 아래 링크를 참고하자.

https://microsoft.github.io/AirSim/reinforcement_learning/

 

Reinforcement Learning - AirSim

Reinforcement Learning in AirSim We below describe how we can implement DQN in AirSim using an OpenAI gym wrapper around AirSim API, and using stable baselines implementations of standard RL algorithms. We recommend installing stable-baselines3 in order to

microsoft.github.io

 

 

목차

     

     

     

     

    1. Introduction

     

    아래 내용은 AirSim API와 OpenAI gym, 그리고 RL 알고리즘의 baseline을 활용하여 DQN을 어떻게 구현하였는지에 대한 내용이다.

     

    우선 아래 링크에서 stable-baseline3를 다운받아두자.

    https://github.com/DLR-RM/stable-baselines3

     

    GitHub - DLR-RM/stable-baselines3: PyTorch version of Stable Baselines, reliable implementations of reinforcement learning algor

    PyTorch version of Stable Baselines, reliable implementations of reinforcement learning algorithms. - GitHub - DLR-RM/stable-baselines3: PyTorch version of Stable Baselines, reliable implementatio...

    github.com

     

    stable-baseline3 download

     

    참고로, 해당 개발 내용은 현재에도 진행중인 개발이다. 아래에 소개된 framework는 확장되고, 발전시킬 수 있는 내용이다.

     

     

     

     

    1) Gym wrapper

     

    AirSim을 gym 환경으로 사용하려면, AirSim에 맞게 'step', '_get_obs', '_compute_reward', 'reset' 등의 base 메소드들을 확장하거나 재구현해야 한다.

    차와 드론에 관한 예제에 쓰인 샘플 environment는 다음 경로에 있다.

     

    PythonClient/reinforcement_learning/airgym/envs/*_env.py

     

    이 예제는 아래 링크의 release와 같은 AirSimNeighborhood 환경에서 동작한다.

    https://github.com/Microsoft/AirSim/releases

     

    Releases · microsoft/AirSim

    Open source simulator for autonomous vehicles built on Unreal Engine / Unity, from Microsoft AI & Research - microsoft/AirSim

    github.com

     

     

     

     

     

     

    2. RL with Car

     

    Source Code들은 아래 깃허브를 참조하자.

    https://github.com/Microsoft/AirSim/tree/master/PythonClient/reinforcement_learning

     

    GitHub - microsoft/AirSim: Open source simulator for autonomous vehicles built on Unreal Engine / Unity, from Microsoft AI & Res

    Open source simulator for autonomous vehicles built on Unreal Engine / Unity, from Microsoft AI & Research - GitHub - microsoft/AirSim: Open source simulator for autonomous vehicles built on Un...

    github.com

     

     

     

     

    1) 이미지 변환

     

    먼저, 시뮬레이션으로부터 얻은 이미지를 적절한 형태로 transform 해야한다.

    Ego camera로부터 depth image를 어떻게 얻고, 네트워크에 84 × 84 input으로 어떻게 변환하는지 알아보자.

    (해당 코드는 다른 센서 modality나 센서 input으로 바꿀 수 있고, 당연히 그에 따라 적절히 코드를 수정해야 할 것이다.)

     

    responses = client.simGetImages([ImageRequest(0, AirSimImageType.DepthPerspective, True, False)])
    current_state = transform_input(responses)

     

     

     

     

    2) Agent가 행할 수 있는 Action 정의

     

    'interpret_action' 함수를 통해 Agent가 할 수 있는 Action을 정의해준다. 그 Action은 다음과 같이 6가지이다.

    • Brake
    • Straight with throttle
    • Full-left with throttle
    • Full-right with throttle
    • Half-left with throttle
    • Half-right with throttle

     

    def interpret_action(action):
        car_controls.brake = 0
        car_controls.throttle = 1
        
        if action == 0:
            car_controls.throttle = 0
            car_controls.brake = 1
        elif action == 1:
            car_controls.steering = 0
        elif action == 2:
            car_controls.steering = 0.5
        elif action == 3:
            car_controls.steering = -0.5
        elif action == 4:
            car_controls.steering = 0.25
        else:
            car_controls.steering = -0.25
        return car_controls

     

     

     

     

    3) Reward Function 정의

     

    다음으로 '_compute_reward' 함수로 reward function을 정의한다. 이는 차가 얼마나 빠른지, center line으로부터 얼마나 떨어져 있는지에 대한 convex combination으로 정의된다.

    이에 따라 Agent는 빠르면서 차선의 중앙에 있으면 높은 reward를 받게 된다.

     

    def _compute_reward(car_state):
        MAX_SPEED = 300
        MIN_SPEED = 10
        thresh_dist = 3.5
        beta = 3
        
        z = 0
        pts = [np.array([0, -1, z]), np.array([130, -1, z]), np.array([130, 125, z]),
                np.array([0, 125, z]), np.array([0, -1, z]), np.array([130, -1, z]),
                np.array([130, -128, z]), np.array([0, -128, z]), np.array([0, -1, z])]
        pd = car_state.position
        car_pt = np.array(list(pd.values()))
        
        dist = 10000000
        for i in range(0, len(pts) - 1):
            dist = min(dist, np.linalg.norm(np.cross((car_pt - pts[i]), (car_pt - 
                    pts[i + 1]))) / np.linalg.norm(pts[i] - pts[i + 1]))
        # print(dist)
        if dist > thresh_dist:
            reward = -3
        else:
            reward_dist = (math.exp(-beta * dist) - 0.5)
            reward_speed = (((car_state.speed - MIN_SPEED) / (MAX_SPEED - MIN_SPEED)) - 0.5)
            reward = reward_dist + reward_speed
        
        return reward

     

    이후에 reward 계산 함수는 충돌 등에 의해 에피소드가 끝나는지 또한 결정한다.

    차의 속도를 계속 관찰하고, threshold보다 작게 되면 에피소드는 끝나게 된다.

     

    done = 0
    if reward < -1:
        done = 1
    if car_controls.brake == 0:
        if car_state.speed <= 5:
            done = 1
    return done

     

     

     

     

    4) Main Loop

     

    이제 main loop에서 이미지를 얻고, 현재 Policy에 따라 취할 Action을 계산하고, Reward를 받는 등의 과정을 진행한다.

    에피소드가 끝나게 되면 'reset()'함수로 차량을 처음 state로 되돌린다.

     

    client.reset()
    client.enableApiControl(True)
    client.armDisarm(True)
    car_control = intercept_action(1) // Reset position and drive straight for one second
    client.setCarControls(car_control)
    time.sleep(1)

     

     

     

     

    5) DQN Training Loop

     

    gym wrapper가 'car_env.py' 파일 내에서 정의되면 DQN 학습 loop를 실행하기 위해 stable-baselines3를 사용하게 된다.

    DQN training은 'dqn_car.py' 파일에서 보이는 바와 같이 다음과 같다.

     

    model = DQN(
        "CnnPolicy",
        env,
        learning_rate=0.00025,
        verbose=1,
        batch_size=32,
        train_freq=4,
        target_update_interval=10000,
        learning_starts=200000,
        buffer_size=500000,
        max_grad_norm=10,
        exploration_fraction=0.1,
        exploration_final_eps=0.01,
        device="cuda",
        tensorboard_log="./tb_logs/",
    )

     

    Training 환경과 Evaluation 환경('dqn_car.py'파일의 'EvalCallback')을 정의할 수 있다.

    Evaluation 환경은 training 환경과는 다른 termination 조건과 scene 설정을 가질 수 있다.

    결론적으로 'model.learn()'함수는 DQN training loop를 시작하도록 하며, 이는 stable-baselines3로부터 사용 가능한 PPO, A3C 등의 실행과 비슷하다.

     

    'dqn_car.py'파일을 실행시키기 전에 시뮬레이션을 실행시켜야 한다. 아래 video는 DQN training 처음 몇몇 에피소드를 보여준다.

    https://www.youtube.com/watch?v=fv-oFPAqSZ4 

     

     

    728x90
    • 네이버 블러그 공유하기
    • 네이버 밴드에 공유하기
    • 페이스북 공유하기
    • 카카오스토리 공유하기