-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSimpleTrackEnv.py
160 lines (134 loc) · 4.42 KB
/
SimpleTrackEnv.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
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
"""
SimpleTrack Car Race Env
@Author: Yuanda Wang
@Date: Mar. 30, 2024
"""
import numpy as np
import random
import matplotlib.pyplot as plt
from CarModel_Kinematic import CarModelClass
from SimpleTrack import SimpleTrackClass
class SimpleTrackEnvClass():
def __init__(self):
self.track = SimpleTrackClass()
def reset(self):
# reset car at random state
pose = self.track.random_car_pose()
spd = np.random.uniform(10, 20)
self.car = CarModelClass(pose, spd)
self.reset_flags()
ob = self.observe()
return ob
def test_reset(self):
# reset car at start point
posx, posy = 0, 0
psi = np.pi / 2
spd = 10
self.car = CarModelClass([posx, posy, psi], spd)
self.reset_flags()
ob = self.observe()
return ob
def step(self, action):
# move the car by action
self.car.step(action)
# observe car and track states
ob = self.observe()
# check fails
self.check_fails()
done = self.FAIL
# give reward
r = self.reward()
return ob, r, done
def observe(self):
# observe car state
pose = self.car.pose
self.spd = spd = self.car.spd
psi_dot = self.car.psi_dot
steer = self.car.steer
# observe car-in-track states
if self.track.findcar(pose):
# off-centerline distance
self.dist = dist = self.track.centerlinedist
# car-track angle
self.angle00 = angle00 = self.track.find_cartrack_angle(pose)
# looking forward track edge
centerpoints = []
# point of 5m
addtrip = 5
# print('addtrip:', addtrip)
pt = self.track.find_relative_centerpoint(pose, addtrip)
ptlist = [pt[0]/100, pt[1]/100]
centerpoints += ptlist
# points of [10, 20, 30, 40]
for i in range(1,5):
addtrip = i*10
# print('addtrip', addtrip)
pt = self.track.find_relative_centerpoint(pose, addtrip)
ptlist = [pt[0]/100, pt[1]/100]
centerpoints += ptlist
for i in range(3,11):
addtrip = i*20
# print('addtrip', addtrip)
pt = self.track.find_relative_centerpoint(pose, addtrip)
ptlist = [pt[0]/100, pt[1]/100]
centerpoints += ptlist
else:
raise RuntimeError('Car out of track, unable to get states!')
# normalize observations
spd /= 30.0 # 30m/s is about the max speed
dist /= self.track.width/2
psi_dot /= 1.57 # np.pi/2 rad/s is max rotation speed
steer /= np.pi/4 # np.pi/4 rad is max steer angle
angle00 /= np.pi
ob = [spd, psi_dot, steer, dist, angle00] + centerpoints
return ob
def reward(self):
if not self.FAIL:
r = self.spd * np.cos(self.angle00) / 10.0
else:
r = -100
return r
def reset_flags(self):
self.OUT_TRACK = False
self.WRONG_DIR = False
self.MAX_ACC = False
self.STOP = False
self.FAIL = False
def check_fails(self):
# check wrong way direction
if abs(self.angle00) > np.pi / 2:
self.WRONG_DIR = True
self.FAIL = True
# check out of track
if abs(self.dist) > self.track.width / 2 * 0.95:
self.OUT_TRACK = True
self.FAIL = True
# check max acc
if self.car.check_acc():
self.MAX_ACC = True
self.FAIL = True
if self.car.spd < 6.0: # below 6 is too slow, for most of the time, should start from 10
self.STOP = True
self.FAIL = True
def query_fail_reason(self):
if self.OUT_TRACK:
reason = 'OUT TRACK!'
elif self.MAX_ACC:
reason = 'MAX_ACC'
elif self.WRONG_DIR:
reason = 'WRONG DIRECTION'
elif self.STOP:
reason = 'STOP'
else:
reason = 'FINISH'
return reason
if __name__ == '__main__':
env = SimpleTrackEnvClass()
ob = env.reset()
for step in range(10):
# generate action
action = [0,0]
ob, r, done = env.step(action)
print('ob', ob)
print('obsize', np.shape(ob))
print('r', r)