재형이의 성장통 일지
  • 딥레이서(DeepRacer) 대회
    2023년 06월 13일 12시 28분 25초에 업로드 된 글입니다.
    작성자: 재형이
    반응형

    딥레이서 대회 포스터

    AWS DeepRacer 는 강화 학습 모델을 사용하여 물리적 트랙에서 스스로 주행할 수 있도록 RC 차량을 학습시키는 서비스입니다.

    https://docs.aws.amazon.com/ko_kr/deepracer/latest/developerguide/what-is-deepracer.html

     

    AWS란 DeepRacer 무엇입니까? - AWS DeepRacer

    이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

    docs.aws.amazon.com

    AWS 클라우드를 공부하기 위해 솔데스크에서 국비지원 교육을 수강하고 있는데, 마침 해당 학원에서 AWS 관련 대회를 주최하길래 좋은 경험이 될 것 같아 참가를 하게 되었습니다.


    📢 추후에 솔데스크 국비지원 교육 관련해서도 포스팅해볼 생각입니다 :)

    1. RC 차량

    RC 차량

    AWS 딥레이서 대회에 사용할 RC 차량입니다. 차량은 학원 측에서 제공을 받아서 사용했습니다. 실제 가격은 

    399$ 로 현재 환율로 환산하면

    50만원이 넘어가네요

    훈련시키다가 실수로 고장이라도 낸다면...ㅎ (하지만 그 일이 실제로 일어났습니다...)

    2. AWS Deepracer 학습시키기

    학습 모델을 생성해서 훈련을 시킨 후 실제 RC 차량에 넣어준 후 실제 트랙에서 주행 테스트를 해보면 됩니다.

     

    모델 생성 시 사용할 트랙을 선택해주셔야 하는데

    대회에서 사용할 트랙이 re:Invent 2018 이라서 이 트랙을 선택해주었습니다.

     

     

     

     

     

     

     

     

     

     

     

     

     

    그리고 해당 학습 모델에 사용할 보상 함수를 넣어주어야 합니다.

    AWS에서 기본으로 제공해주는 보상함수도 충분히 훌륭합니다.

    하지만 저는 clone 기능을 활용하여 여러 보상 함수들을 적용해서 학습시킬 생각입니다.

     

    📢 한번 학습한 모델을 Action 탭에서 clone할 수 있는데, 이렇게 하면 직전의 학습 결과물을 유지한상태에서 추가 학습시킬 수 있습니다.

     

    첫번째 훈련

    일단 웨이포인트를 통해 경로를 학습시켜주었습니다

    def reward_function(params):
         
        center_variance = params["distance_from_center"] / params["track_width"]
         
        track_width = params['track_width']
        distance_from_center = params['distance_from_center']
        all_wheels_on_track = params['all_wheels_on_track']
        closest_waypoints = params["closest_waypoints"]
        waypoints = params['waypoints']
        heading = params['heading']
        speed = params['speed']
        abs_steering = abs(params['steering_angle'])
        MAX_SPEED = 3
     
        marker_1 = 0.12 * track_width
        marker_2 = 0.24 * track_width
        marker_3 = 0.36 * track_width
        marker_4 = 0.48 * track_width
         
        left_lane = [25,26,27,28,29,30,31,57,58,59,60,61,62,63,72,73,74,75,76,77,78,79,80,81,82,83,84,
                     101,102,103,104,105,106,127,128,129,130,131,159,160,161,162,163,164]
        right_lane = [38,39,40,41,42,43,44,45,46,85,86,87,88,89,90,91,91,93,94,95]
        center_lane = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,
                        32,33,34,35,36,37,46,47,48,49,50,51,52,53,54,55,56,64,65,66,67,68,69,70,71,
                        96,97,98,99,100,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,
                        132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158]
        straight_lane = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,113,114,115,116,117,118,119,120,121,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155]
        left_end_lane = [31,32,33,63,64,65,110,111,112,133,134,135,136,137,138]
        right_end_lane = [45,46,47,48]
      
         
        # RC 차량의 바퀴가 트랙을 최대한 벗어나지 않도록 설정
        reward = 2.1
         
        if all_wheels_on_track:
            reward += 1
        else:
            reward -= 1
         
        # 설정해준 주행 경로를 잘 따라서 갈 수 있도록 설정, 인코스를 돌아야할 때는 인코스를 탈 수 있게!
         
        if closest_waypoints[1] in left_lane and params['is_left_of_center']:
            reward += 1
        elif closest_waypoints[1] in right_lane and not params['is_left_of_center']:
            reward += 1
        elif closest_waypoints[1] in center_lane and center_variance <0.4:
            reward += 1
        else:
            reward -= 1
    
    
        # 직진 코스는 최대한 빠르게 주행할 수 있도록 설정
        if closest_waypoints[1] in straight_lane and abs_steering < 5:
            speed = MAX_SPEED
             
        # RC 차량이 트랙 중앙을 너무 벗어나지 않도록 설정
         
        reward_distance=1
         
        if distance_from_center <= marker_1:
            reward_distance = 1.0
        elif distance_from_center <= marker_2:
            reward_distance = 0.7
        elif distance_from_center <= marker_3:
            reward_distance = 0.4
        elif distance_from_center <= marker_4:
            reward_distance = 0.1
        else:
            reward_distance = 1e-3 
         
         
        reward_all  = reward + reward_distance
         
        ABS_STEERING_THRESHOLD = 15
         
        # RC 차량가 너무 빠르게 주행 각도를 꺾지 않도록 설정, 그렇지 않으면 속도가 높아질 경우 혼자 빙빙 도는 경우가 생김
        if closest_waypoints[1] in straight_lane and abs_steering > 5:
            reward_all *=0.8
        elif closest_waypoints[1] in left_end_lane and abs_steering >10 and params['is_left_of_center']:
            reward_all *= 0.8
        elif closest_waypoints[1] in right_end_lane and abs_steering >10 and not params['is_left_of_center']:
            reward_all *= 0.8
        elif closest_waypoints[1] in center_lane and abs_steering > ABS_STEERING_THRESHOLD:
            reward_all *= 0.8
        else:
            reward_all = reward_all
     
        return float(reward_all)

    보상 함수 그래프

    모델을 학습시키면 training 구간과 evaluating 구간이 있습니다.

    빨간선은 evaluating 구간 동안 트랙을 얼마나 완수하였는가를 의미하고,

    초록선과 파란선은 training 구간 동안 트랙을 돌면서 얼마나 보상을 받았는지를 의미합니다.

    그래프가 우상향으로 갈 수록 좋은 그래프입니다.

    두번째 훈련

    웨이포인트는 학습시켜주었으니 여러가지 보상함수를 학습!

    import math
    
     
    
    def reward_function(params):  
    
        waypoints = params['waypoints']
    
        closest_waypoints = params['closest_waypoints']
    
        heading = params['heading']
    
    
        reward = 1.0
    
        next_point = waypoints[closest_waypoints[1]]
    
        prev_point = waypoints[closest_waypoints[0]]
    
        track_direction = math.atan2(next_point[1] - prev_point[1], next_point[0] - prev_point[0])
    
        track_direction = math.degrees(track_direction)
    
        direction_diff = abs(track_direction - heading)
    
        if direction_diff > 180:
    
            direction_diff = 360 - direction_diff
    
        DIRECTION_THRESHOLD = 10.0
    
        if direction_diff > DIRECTION_THRESHOLD:
    
            reward *= 0.5
    
        return float(reward)

    세번째 훈련

    import math
    	
    def steering_reward(reward, steering, is_left_of_center, speed):
        if steering < -25 and is_left_of_center == False and speed < 3 or steering > 25 and is_left_of_center == True and speed < 3:
            reward *= 1.2
        else:
            reward *= 0.8
    
        if abs(steering) < 15 and speed < 4:
            reward *= 1.1
        else:
            reward *= 0.9
    
        if abs(steering) < 0.1 and speed > 4:
            reward *= 1.4
    
        return reward
        
    def direction_reward(reward, waypoints, closest_waypoints, heading):
        next_point = waypoints[closest_waypoints[1]]
        prev_point = waypoints[closest_waypoints[0]]
    
        direction = math.degrees(math.atan2(next_point[1] - prev_point[1], next_point[0] - prev_point[0]))
    
        direction_diff = abs(direction - heading)
    
        if direction_diff > 30:
            reward *= 0.5
    
        return reward
    
    def reward_function1(params):
    
        if params['all_wheels_on_track']:
            reward = params['progress']/100
        else:
            reward = 0.001
    
        return float(reward)
        
    def straight_line_reward(current_reward, steering, speed):
        if abs(steering) < 0.1 and speed > 6:
            current_reward *= 1.5
        elif abs(steering) < 0.2 and speed > 5:
            current_reward *= 1.2
        return current_reward
    
    def reward_function(params):
        reward = 1e-3
        
        track_width = params['track_width']
        distance_from_center = params['distance_from_center']
    	
        all_wheels_on_track = params['all_wheels_on_track']
        
        steer = abs(params['steering_angle'])
        steer_thres = 12
        if all_wheels_on_track and (0.5*track_width - distance_from_center) >= 0.07:
            if steer > steer_thres:
                reward *= 0.8
            else:
                
                reward = 1.0
            reward = direction_reward(reward,params['waypoints'],params['closest_waypoints'],params['heading']) + reward
            reward = steering_reward(reward,steer,params['is_left_of_center'] , params['speed']) + reward
            reward += reward_function1(params)
            reward += straight_line_reward(reward, steer, params['speed'])
        else:
            reward = 1e-3
        
        return float(reward)

    모의 주행

    잘 간다~

    3. 실제 주행

    실제 주행 테스트를 하려면 wifi로 RC 차량을 연결해서 내부 콘솔에서 차량 속도와 핸들 각도 설정을 해주어야 합니다.

    https://docs.aws.amazon.com/ko_kr/deepracer/latest/developerguide/deepracer-set-up-vehicle.html

     

    AWS DeepRacer 차량용 Wi-Fi 네트워크 선택 - AWS DeepRacer

    이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

    docs.aws.amazon.com

    https://docs.aws.amazon.com/ko_kr/deepracer/latest/developerguide/deepracer-calibrate-vehicle.html

     

    AWS DeepRacer 차량 캘리브레이션 - AWS DeepRacer

    챠량의 속도가 너무 높게 설정되어 있으면 보정 과정에서 너무 빠르게 작동하여 자칫 환경, 차량 또는 기타 주변 물체가 손상될 수 있습니다. 여기에서 설명하는 대로 차량을 들어 올려야 하지

    docs.aws.amazon.com

    아무래도 처음이다 보니 차량 속도 설정을 너무 빠르게 해버려서 차량이 벽에 박아서 바퀴 연결 와이어(?) 부분이 부러져버렸다...

    내 50만원...

     

    다행히 학원 측에서 다른 차량을 무상으로 제공해주었다... 휴우~ 죄송합니다!

    4. 대회 출전

    실제 환경이랑 가상 환경이 아무래도 차이가 많다보니 실제 주행에서는 잘 동작하지 못했어요...ㅜㅜ

    핑크로켓이 저희 팀명입니다ㅎ;

    tmi: Potential IN the K-ROCKET해서 핑크로켓... 사실 팀명을 왜 이렇게 지었는지 설명해야 해서 억지로 가져다 붙였습니다... 사실 아무 의미 없음ㅋ

     

    여튼 대회는 잘 마무리하고 비록 우승은 못했지만

    짜잔~!
    잘 쓸게요~

     

    반응형

    '클라우드 > AWS' 카테고리의 다른 글

    EKS 란  (0) 2023.08.11
    AWS 네이티브 환경에서 OTT 서비스 배포하기  (6) 2023.08.06
    Route 53 서비스 란  (0) 2023.05.22
    Elastic Load Balancer 란  (2) 2023.05.22
    Transit Gateway 란  (2) 2023.05.22
    댓글