

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 보상 함수 사용자 지정하기
<a name="reward-function"></a>

보상 함수를 생성하는 것은 인센티브 플랜을 설계하는 것과 같습니다. 파라미터는 인센티브 플랜을 개발하는 데 사용할 수 있는 값입니다.

인센티브 전략이 다르면 차량의 동작도 달라질 수 있습니다. 차량이 더 빨리 주행하도록 장려하려면 차량이 한 바퀴를 완주하는 데 너무 오래 걸리거나 트랙을 벗어날 경우 음수 값을 부여해 보세요. 지그재그 주행 패턴을 피하려면 조향 각도 범위 제한을 정의하고 트랙의 직선 구간에서 덜 공격적으로 조향하면 차량에 보상을 제공하세요.

트랙의 중앙선과 안쪽, 바깥쪽 가장자리를 따라 배치된 번호가 매겨진 마커인 웨이포인트를 사용하여 특정 주행 동작을 직선 도로, 커브 같은 트랙의 특성과 연관시킬 수 있습니다.

효과적인 보상 함수를 만드는 것은 창의적이고 반복적인 프로세스입니다. 다양한 전략을 시도하고 파라미터를 여러 가지로 조합해보세요. 가장 중요한 건 즐기는 것입니다\$1

**Topics**
+ [Python 코드를 편집하여 보상 함수를 사용자 지정하세요](#edit-reward-function)
+ [AWS DeepRacer 보상 함수의 입력 파라미터](#deepracer-reward-function-input)

## Python 코드를 편집하여 보상 함수를 사용자 지정하세요
<a name="edit-reward-function"></a>

In AWS DeepRacer Student에서는 샘플 보상 함수를 편집하여 모델에 맞는 사용자 지정 레이싱 전략을 만들 수 있습니다.

**보상 함수를 사용자 지정하려면**

1.  AWS DeepRacer Student **모델 경험 생성**의 **5단계: 보상 함수 사용자 지정** 페이지에서 샘플 보상 함수를 선택합니다.

1. 샘플 보상 함수 선택기 아래의 코드 편집기를 사용하여 Python 코드로 보상 함수의 입력 파라미터를 사용자 지정합니다.

1. **유효성 검사**를 선택하여 코드가 작동하는지 여부를 확인합니다. 또는 **재설정**을 선택하여 다시 시작할 수도 있습니다.

1. 변경을 완료했으면 **다음**을 선택합니다.

[AWS DeepRacer 보상 함수의 입력 파라미터](#deepracer-reward-function-input)을 사용해 각 파라미터에 관해 알아볼 수 있습니다. 보상 함수 예제에서 다양한 파라미터가 어떻게 쓰이는지 살펴보세요.

## AWS DeepRacer 보상 함수의 입력 파라미터
<a name="deepracer-reward-function-input"></a>

 AWS DeepRacer 보상 함수는 변수인 로 전달된 사전 객체를 입력`params`으로 사용합니다.

```
def reward_function(params) :

    reward = ...

    return float(reward)
```

`params` 딕셔너리 객체에는 다음과 같은 키-값 페어가 저장됩니다.

```
{
    "all_wheels_on_track": Boolean,        # flag to indicate if the agent is on the track
    "x": float,                            # agent's x-coordinate in meters
    "y": float,                            # agent's y-coordinate in meters
    "closest_objects": [int, int],         # zero-based indices of the two closest objects to the agent's current position of (x, y).
    "closest_waypoints": [int, int],       # indices of the two nearest waypoints.
    "distance_from_center": float,         # distance in meters from the track center
    "is_crashed": Boolean,                 # Boolean flag to indicate whether the agent has crashed.
    "is_left_of_center": Boolean,          # Flag to indicate if the agent is on the left side to the track center or not.
    "is_offtrack": Boolean,                # Boolean flag to indicate whether the agent has gone off track.
    "is_reversed": Boolean,                # flag to indicate if the agent is driving clockwise (True) or counter clockwise (False).
    "heading": float,                      # agent's yaw in degrees
    "objects_distance": [float, ],         # list of the objects' distances in meters between 0 and track_length in relation to the starting line.
    "objects_heading": [float, ],          # list of the objects' headings in degrees between -180 and 180.
    "objects_left_of_center": [Boolean, ], # list of Boolean flags indicating whether elements' objects are left of the center (True) or not (False).
    "objects_location": [(float, float),], # list of object locations [(x,y), ...].
    "objects_speed": [float, ],            # list of the objects' speeds in meters per second.
    "progress": float,                     # percentage of track completed
    "speed": float,                        # agent's speed in meters per second (m/s)
    "steering_angle": float,               # agent's steering angle in degrees
    "steps": int,                          # number steps completed
    "track_length": float,                 # track length in meters.
    "track_width": float,                  # width of the track
    "waypoints": [(float, float), ]        # list of (x,y) as milestones along the track center

}
```

다음 참조를 사용하여 AWS DeepRacer 입력 파라미터를 더 잘 이해할 수 있습니다.

### all\$1wheels\$1on\$1track
<a name="reward-function-input-all_wheels_on_track"></a>

**유형: ** `Boolean`

**범위:** `(True:False)`

에이전트의 트랙 주행 또는 트랙 이탈을 나타내는 `Boolean` 플래그입니다. 바퀴 하나라도 트랙 경계를 벗어나면 트랙 이탈(`False`)입니다. 네 바퀴가 안쪽과 바깥쪽 트랙 경계 안에 있으면 트랙 주행(`True`)입니다. 다음 그림은 에이전트가 트랙을 따라 주행하는 것을 나타냅니다.

![\[\]](http://docs.aws.amazon.com/ko_kr/deepracer/latest/student-userguide/images/reward-function/deepracer-reward-function-input-all_wheels_on_track-true.png)


다음 그림은 두 바퀴가 트랙 경계 밖에 있어서 트랙 이탈인 에이전트를 보여줍니다.

![\[\]](http://docs.aws.amazon.com/ko_kr/deepracer/latest/student-userguide/images/reward-function/deepracer-reward-function-input-all_wheels_on_track-false.png)


**예제: ** *`all_wheels_on_track` 파라미터를 사용하는 보상 함수*

```
def reward_function(params):
    #############################################################################
    '''
    Example of using all_wheels_on_track and speed
    '''

    # Read input variables
    all_wheels_on_track = params['all_wheels_on_track']
    speed = params['speed']

    # Set the speed threshold based your action space
    SPEED_THRESHOLD = 1.0

    if not all_wheels_on_track:
        # Penalize if the car goes off track
        reward = 1e-3
    elif speed < SPEED_THRESHOLD:
        # Penalize if the car goes too slow
        reward = 0.5
    else:
        # High reward if the car stays on track and goes fast
        reward = 1.0

    return float(reward)
```

### closest\$1waypoints
<a name="reward-function-input-closest_waypoints"></a>

**유형**: `[int, int]`

**범위**: `[(0:Max-1),(1:Max-1)]`

에이전트의 현재 위치인 `(x, y)`에 가장 가깝게 인접한 두 `waypoint`의 제로 기반 인덱스입니다. 거리는 에이전트 중앙에서 유클리트(Eudlidean) 거리로 측정됩니다. 첫 번째 요소는 에이전트 뒤에서 가장 가까운 중간 지점을 나타내고, 두 번째 요소는 에이전트 앞에서 가장 가까운 중간 지점을 나타냅니다. `Max`는 중간 지점 목록의 길이입니다. [중간 지점](#reward-function-input-waypoints)의 그림에서 `closest_waypoints`는 `[16, 17]`이게 됩니다.

다음 보상 함수 예제는 `waypoints`, `closest_waypoints` 및 `heading`을 사용해 즉각적인 보상을 계산하는 방법을 나타낸 것입니다.

AWS DeepRacer는 `math`, , `random`, `numpy` `scipy`및 Python 라이브러리를 지원합니다`shapely`. 하나를 사용하려면 함수 정의 `def reward_function(params)` 앞에 가져오기`import supported library`를 추가합니다.

**예:** *`closest_waypoints` 파라미터를 사용하는 보상 함수*.

```
# Place import statement outside of function (supported libraries: math, random, numpy, scipy, and shapely)
# Example imports of available libraries
#
# import math
# import random
# import numpy
# import scipy
# import shapely

import math

def reward_function(params):
    ###############################################################################
    '''
    Example of using waypoints and heading to make the car point in the right direction
    '''

    # Read input variables
    waypoints = params['waypoints']
    closest_waypoints = params['closest_waypoints']
    heading = params['heading']

    # Initialize the reward with typical value
    reward = 1.0

    # Calculate the direction of the centerline based on the closest waypoints
    next_point = waypoints[closest_waypoints[1]]
    prev_point = waypoints[closest_waypoints[0]]

    # Calculate the direction in radius, arctan2(dy, dx), the result is (-pi, pi) in radians
    track_direction = math.atan2(next_point[1] - prev_point[1], next_point[0] - prev_point[0])
    # Convert to degree
    track_direction = math.degrees(track_direction)

    # Calculate the difference between the track direction and the heading direction of the car
    direction_diff = abs(track_direction - heading)
    if direction_diff > 180:
        direction_diff = 360 - direction_diff

    # Penalize the reward if the difference is too large
    DIRECTION_THRESHOLD = 10.0
    if direction_diff > DIRECTION_THRESHOLD:
        reward *= 0.5

    return float(reward)
​
```

### closest\$1objects
<a name="reward-function-input-closest_objects"></a>

**유형**: `[int, int]`

**범위**: `[(0:len(object_locations)-1), (0:len(object_locations)-1]`

에이전트의 현재 위치(x, y)에 가장 가까운 두 객체의 인덱스(0부터 시작)입니다. 첫 번째 인덱스는 에이전트 뒤에서 가장 가까운 객체를 참조하고 두 번째 인덱스는 에이전트 앞에서 가장 가까운 객체를 참조합니다. 객체가 하나만 있는 경우 두 인덱스는 모두 0이 됩니다.

### distance\$1from\$1center
<a name="reward-function-input-distance_from_center"></a>

**유형**: `float`

**범위**: `0:~track_width/2`

에이전트의 중앙과 트랙의 중앙 사이의 변위(미터)입니다. 에이전트의 바퀴 중 하나라도 트랙 경계를 벗어났을 때 최대 변위가 관측될 수 있으며, 이때 최대 변위는 트랙 경계의 너비에 따라 다르지만 `track_width`의 절반보다 약간 작거나 클 수 있습니다.

![\[\]](http://docs.aws.amazon.com/ko_kr/deepracer/latest/student-userguide/images/reward-function/deepracer-reward-function-input-distance_from_center.png)


**예:** *`distance_from_center` 파라미터를 사용하는 보상 함수*

```
def reward_function(params):
    #################################################################################
    '''
    Example of using distance from the center
    '''

    # Read input variable
    track_width = params['track_width']
    distance_from_center = params['distance_from_center']

    # Penalize if the car is too far away from the center
    marker_1 = 0.1 * track_width
    marker_2 = 0.5 * track_width

    if distance_from_center <= marker_1:
        reward = 1.0
    elif distance_from_center <= marker_2:
        reward = 0.5
    else:
        reward = 1e-3  # likely crashed/ close to off track

    return float(reward)
```

### heading
<a name="reward-function-input-heading"></a>

**유형**: `float`

**범위**: `-180:+180`

좌표계의 x축에 대한 에이전트 진행 방향(각도)입니다.

![\[\]](http://docs.aws.amazon.com/ko_kr/deepracer/latest/student-userguide/images/reward-function/deepracer-reward-function-input-heading.png)


**예:** *`heading` 파라미터를 사용하는 보상 함수*

자세한 내용은 [`closest_waypoints`](#reward-function-input-closest_waypoints) 단원을 참조하십시오.

### is\$1crashed
<a name="reward-function-input-crashed"></a>

**유형**: `Boolean`

**범위**: `(True:False)`

에이전트가 다른 객체와 충돌했는지(`True`) 또는 충돌하지 않았는지(`False`)를 종료 상태로 나타내는 `Boolean` 플래그입니다.

### is\$1left\$1of\$1center
<a name="reward-function-input-is_left_of_center"></a>

**유형**: `Boolean`

**범위**: `[True : False]`

에이전트가 트랙 중앙선의 왼쪽에 있는지(`True`) 트랙 중앙선의 왼쪽에 있지 않은지(`False`)를 나타내는 `Boolean` 플래그입니다.

### is\$1offtrack
<a name="reward-function-input-offtrack"></a>

**유형**: `Boolean`

**범위**: `(True:False)`

에이전트의 바퀴 4개가 모두 트랙의 안쪽 또는 바깥쪽 경계선 밖으로 주행했는지(`True`) 또는 그렇지 않은지(`False`)를 나타내는 `Boolean` 플래그입니다.

### is\$1reversed
<a name="reward-function-input-is_reversed"></a>

**유형**: `Boolean`

**범위**: `[True:False]`

에이전트가 시계 방향으로 주행(`True`)하는지 시계 반대 방향으로 주행(`False`)하는지를 나타내는 `Boolean` 플래그입니다.

각 에피소드에 대한 방향 변경을 활성화할 때 사용됩니다.

### objects\$1distance
<a name="reward-function-input-objects_distance"></a>

**유형**: `[float, … ]`

**범위**: `[(0:track_length), … ]`

시작선을 기준으로 환경 내 객체 간 거리 목록입니다. i번째 요소는 트랙 중앙선을 따라 i번째 객체와 시작선 사이의 거리(미터)를 측정합니다.

**참고**  
abs \$1 (var1) - (var2)\$1 = how close the car is to an object, WHEN var1 = ["objects\$1distance"][index] and var2 = params["progress"]\$1params["track\$1length"]  
차량 앞에서 가장 가까운 객체와 차량 뒤에서 가장 가까운 객체의 인덱스를 가져오려면 `closest_objects` 파라미터를 사용합니다.

### objects\$1heading
<a name="reward-function-input-objects_heading"></a>

**유형**: `[float, … ]`

**범위**: `[(-180:180), … ]`

객체의 방향(도)의 목록입니다. i번째 요소는 i번째 객체의 방향을 측정합니다. 고정된 객체의 방향은 0입니다. 봇 차량의 경우 해당 요소의 값은 그 봇 차량의 방향 각도입니다.

### objects\$1left\$1of\$1center
<a name="reward-function-input-objects_left_of_center"></a>

**유형**: `[Boolean, … ]`

**범위**: `[True|False, … ]`

`Boolean` 플래그 목록. i번째 요소 값은 그 i번째 객체가 트랙 중앙선의 왼쪽에 있는지(`True`) 오른쪽에 있는지(`False`)를 나타냅니다.

### objects\$1location
<a name="reward-function-input-objects_location"></a>

**유형**: `[(x,y), ...]`

**범위**: `[(0:N,0:N), ...]`

이 파라미터는 모든 객체 위치를 저장합니다. 각 위치는 ([x, y](#reward-function-input-x_y))의 튜플입니다.

목록 크기는 트랙 위 객체의 수와 같습니다. 나열된 객체에는 고정된 장애물과 움직이는 봇 차량이 모두 포함됩니다.

### objects\$1speed
<a name="reward-function-input-objects_speed"></a>

**유형**: `[float, … ]`

**범위**: `[(0:12.0), … ]`

트랙 위 객체의 속도(m/s) 목록입니다. 정지 객체의 경우 속도는 0입니다. 로봇 차량의 경우 이 값은 훈련 시 설정한 속도입니다.

### progress
<a name="reward-function-input-progress"></a>

**유형**: `float`

**범위**: `0:100`

주행한 트랙의 비율입니다.

**예:** *`progress` 파라미터를 사용하는 보상 함수*

자세한 내용은 [단계](#reward-function-input-steps) 항목을 참조하십시오.

### 속도
<a name="reward-function-input-speed"></a>

**유형**: `float`

**범위**: `0.0:5.0`

관측된 에이전트 속도(m/s)입니다.

![\[\]](http://docs.aws.amazon.com/ko_kr/deepracer/latest/student-userguide/images/reward-function/deepracer-reward-function-input-speed.png)


**예:** *`speed` 파라미터를 사용하는 보상 함수*

자세한 내용은 [all\$1wheels\$1on\$1track](#reward-function-input-all_wheels_on_track) 항목을 참조하십시오.

### steering\$1angle
<a name="reward-function-input-steering_angle"></a>

**유형**: `float`

**범위**: `-30:30`

에이전트 중앙선에 대한 전륜 조향 각도입니다. 음의 기호(-)는 오른쪽 조향을, 그리고 양의 기호(\$1)는 왼쪽 조향을 의미합니다. 다음 그림에 표시된 것처럼 에이전트의 중앙선이 트랙 중앙선과 반드시 ​​평행을 이루지는 않습니다.

![\[\]](http://docs.aws.amazon.com/ko_kr/deepracer/latest/student-userguide/images/reward-function/deepracer-reward-function-steering.png)


**예:** *`steering_angle` 파라미터를 사용하는 보상 함수*

```
def reward_function(params):
    '''
    Example of using steering angle
    '''

    # Read input variable
    abs_steering = abs(params['steering_angle']) # We don't care whether it is left or right steering

    # Initialize the reward with typical value
    reward = 1.0

    # Penalize if car steer too much to prevent zigzag
    ABS_STEERING_THRESHOLD = 20.0
    if abs_steering > ABS_STEERING_THRESHOLD:
        reward *= 0.8

    return float(reward)
```

### steps
<a name="reward-function-input-steps"></a>

**유형**: `int`

**범위**: `0:Nstep`

완료한 단계 수입니다. 한 단계는 에이전트가 현재 정책을 사용하여 완료한 하나의 관찰-조치 시퀀스에 해당합니다.

**예:** *`steps` 파라미터를 사용하는 보상 함수*

```
def reward_function(params):
    #############################################################################
    '''
    Example of using steps and progress
    '''

    # Read input variable
    steps = params['steps']
    progress = params['progress']

    # Total num of steps we want the car to finish the lap, it will vary depends on the track length
    TOTAL_NUM_STEPS = 300

    # Initialize the reward with typical value
    reward = 1.0

    # Give additional reward if the car pass every 100 steps faster than expected
    if (steps % 100) == 0 and progress > (steps / TOTAL_NUM_STEPS) * 100 :
        reward += 10.0

    return float(reward)
```

### track\$1length
<a name="reward-function-input-track_len"></a>

**유형**: `float`

**범위**: `[0:Lmax]`

트랙 길이(미터)입니다. `Lmax is track-dependent.` 

### track\$1width
<a name="reward-function-input-track_width"></a>

**유형**: `float`

**범위**: `0:Dtrack`

트랙 너비(미터)입니다.

![\[\]](http://docs.aws.amazon.com/ko_kr/deepracer/latest/student-userguide/images/reward-function/deepracer-reward-function-input-track_width.png)


**예:** *`track_width` 파라미터를 사용하는 보상 함수*

```
def reward_function(params):
    #############################################################################
    '''
    Example of using track width
    '''

    # Read input variable
    track_width = params['track_width']
    distance_from_center = params['distance_from_center']

    # Calculate the distance from each border
    distance_from_border = 0.5 * track_width - distance_from_center

    # Reward higher if the car stays inside the track borders
    if distance_from_border >= 0.05:
        reward = 1.0
    else:
        reward = 1e-3 # Low reward if too close to the border or goes off the track

    return float(reward)
```

### x, y
<a name="reward-function-input-x_y"></a>

**유형**: `float`

**범위**: `0:N`

트랙이 포함된 시뮬레이션 환경에서 x축과 y축에 따른 에이전트 중앙의 위치(미터)입니다. 원점은 시뮬레이션 환경에서 왼쪽 하단 모퉁이입니다.

![\[\]](http://docs.aws.amazon.com/ko_kr/deepracer/latest/student-userguide/images/reward-function/deepracer-reward-function-input-x-y.png)


### 중간 지점
<a name="reward-function-input-waypoints"></a>

**유형**: `[float, float]` `list`

**범위**: `[[xw,0,yw,0] … [xw,Max-1, yw,Max-1]]`

트랙 중앙을 따라 순서대로 나열된 트랙에 의존하는 `Max` 이정표 목록입니다. 각 이정표는 (xw,i, yw,i) 좌표로 알 수 있습니다. 순환 트랙의 경우, 첫 번째와 마지막 중간 지점은 동일합니다. 직선 또는 다른 비순환 트랙의 경우, 첫 번째와 마지막 중간 지점은 다릅니다.

![\[\]](http://docs.aws.amazon.com/ko_kr/deepracer/latest/student-userguide/images/reward-function/deepracer-reward-function-input-waypoints.png)


**예:** *`waypoints` 파라미터를 사용하는 보상 함수*

자세한 내용은 [`closest_waypoints`](#reward-function-input-closest_waypoints) 단원을 참조하십시오.