はじめに
AWS DeepRacerを始めるにあたり、Reward関数をどのように変更すればいいのか考えてみました。
理論先行型であるため、動作は保証しておりません。
waypointとyaw
deepracer_env.py内の報酬関数の入力パラメータにwaypoints、closest_waypoints、car_orientationがあります。
waypointsはトラックの中心点の座標であり、closest_waypointsは車両に一番近いwaypointsとなっています。
car_orientationは車両のヨーイングとなっています。
そこで、次に向かうwaypointと車両のヨーイングがわかれば最短距離でコースを走れるのではないかと考えました。
車両がどのwaypointsを目指すか
closest_waypointsは車両に対する直線の距離で一番近いwaypointsとなっています。
そのため、車両の後方にclosest_waypointsが存在する可能性があります。
そこで、closest_waypointsとその前後のwaypointsの線分の間に車両が存在するかどうかを判定し、closest_waypointsを更新する必要があります。
closest_waypointsとその前後のwaypointsの線分の間に車両が存在するかどうかの判定は、点と線分との距離の公式から判定することができます。
公式についてはこちらを参考にさせていただきました。
簡単にいうと、2点間を通る直線に対して離れた点Pから垂線を下ろし、交点(内分点)が存在すれば、2点間の間に点Pが存在するというものです。
closest_waypointsをBと置き、その前後のwaypointsをそれぞれA,Cと置きます。
線分AB、線分BCとの間に上記の公式を使い、車両から垂線を下ろした交点が存在するかどうかを判定します。
- 線分ABとの間に交点が存在し、線分BCにはない場合は線分ABの間に車両は存在するため、closest_waypointsをBとする。
- 線分ABとの間に交点が存在せず、線分BCに交点が存在する場合は、線分BC間に車両が存在するため、closest_waypointsをCとする。
- 線分AB、線分BCそれぞれに交点が存在する場合にはclosest_waypointsをCとする。
これにより、車両が目指すべきclosest_waypointsを指定することができます。
車両のヨーイングとx軸に対する線分との角度の差から報酬を決定
diff_yaw = waypoint_yaw - car_orientation
if diff_yaw == math.radians(0):
reward += 10.0
elif (abs(diff_yaw) < math.radians(5) and diff_yaw * steering > 0):
reward += 8.0
elif (abs(diff_yaw) < math.radians(10) and diff_yaw * steering > 0):
reward += 5.0
elif (abs(diff_yaw) < math.radians(15) and diff_yaw * steering > 0):
reward += 3.0
elif (abs(diff_yaw) < math.radians(20) and diff_yaw * steering > 0):
reward += 1.0
else:
reward = 1.0e-3
目指すべきwaypointを求めることができたので、次は車両のヨーイングと交点が存在する線分のヨーイングとの角度の差を求めます。
その差が小さいほどReward値を高く設定しました。
まとめ
defaultの5時間の学習をした結果1周38秒という結果でした。
waypointと車両のヨーイングから報酬を決定し理論的に考えてみましたが、そこまで速くなっている感じは見受けられませんでした。
また、closest_waypointにしても車両と全waypointに対して直線の距離を求めているため、車両の前後ではなく、想定していない箇所のwaypointを参照することがあります。
そこは注意が必要です。