Skip to content

Commit abd2b34

Browse files
committed
Trying to implement stanley controller lol :(
1 parent 7617174 commit abd2b34

File tree

1 file changed

+74
-76
lines changed

1 file changed

+74
-76
lines changed

main.py

+74-76
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,21 @@
88
# Spawn Optimization
99
# Landing Bug
1010

11-
# Initialize Pygame
12-
pygame.init()
1311

1412
# Setup the clock for a decent frame rate
1513
clock = pygame.time.Clock()
1614

17-
# Background Image
18-
background = pygame.image.load('Flight-Control-Bot/Map.png')
19-
2015
# Creating a Window
2116
screen_width = 1920 / 2
2217
screen_height = 1080 / 2
2318
screen = pygame.display.set_mode((1920 / 2, 1080 / 2))
2419

2520
green_dots = []
21+
background = pygame.image.load('Flight-Control-Bot/map.png')
2622
red_dot = pygame.image.load('Flight-Control-Bot/red_dot.png')
2723
green_dot = pygame.image.load('Flight-Control-Bot/green_dot.png')
2824

2925

30-
def dist(x, y):
31-
distance = (((x[0] - y[0]) ** 2) + ((x[1] - y[1]) ** 2)) ** 0.5
32-
return distance
33-
34-
3526
def orientation(p1, p2, p3):
3627
# to find the orientation of
3728
# an ordered triplet (p1,p2,p3)
@@ -47,7 +38,7 @@ def orientation(p1, p2, p3):
4738

4839
if val == 0:
4940
# Clockwise orientation
50-
if dist(p1, p3) < dist(p2, p3):
41+
if math.dist(p1, p3) < math.dist(p2, p3):
5142
result = 0
5243
else:
5344
result = 100
@@ -73,15 +64,15 @@ def __init__(self, spawn_at=[750, 100], offset_angle=-2):
7364
# self.img_gpy = pygame.transform.rotate(self.img_og, offset_angle)
7465

7566
# Speed
76-
self.Speed = 0.4
67+
self.speed = 0.4
7768
self.flying = True
7869

7970
# Position
8071
self.position = spawn_at # [random.randint(0, 1920/2), random.randint(0, 540)]
8172

8273
# Angle In Degrees
83-
self.Angle = self.angle_to_center() # random.randint(0, 180)
84-
print(f"{self.Angle}")
74+
self.angle = self.angle_to_center() # random.randint(0, 180)
75+
print(f"{self.angle}")
8576

8677
self.OffsetAngle = offset_angle
8778

@@ -90,44 +81,38 @@ def __init__(self, spawn_at=[750, 100], offset_angle=-2):
9081
# self.Tow = False
9182
self.shrinkage = [j for j in range(80, 10, -3)]
9283

93-
self.Path = []
84+
self.way_points = []
9485

95-
self.Tow = False
86+
self.towing_status = False
9687

9788
self.alpha = 255
9889

9990
self.size = -1
10091
self.tick = 0
10192

10293
self.red_dots = []
103-
for i in self.Path:
104-
self.red_dots.append(i)
94+
for dot in self.way_points:
95+
self.red_dots.append(dot)
10596
self.turn(0)
10697

10798
# # Turns the plane by a certain bank angle
10899
def turn(self, bank):
109-
self.Angle += bank
110-
self.image = pygame.transform.rotate(self.image_aligned, self.OffsetAngle + self.Angle)
100+
self.angle += bank
101+
self.image = pygame.transform.rotate(self.image_aligned, self.OffsetAngle + self.angle)
111102
self.rect = self.image.get_rect()
112103

113104
# Turns the plane to a Certain Angle
114105
def turn_to(self, angle):
115-
self.Angle = angle
116-
self.image = pygame.transform.rotate(self.image_aligned, self.OffsetAngle + self.Angle)
106+
self.angle = angle
107+
self.image = pygame.transform.rotate(self.image_aligned, self.OffsetAngle + self.angle)
117108
self.rect = self.image.get_rect()
118109

119110
# Starts to fade the sprite on approaching landing
120111

121-
def update(self):
122-
# for i in self.planes:
123-
# i.draw()
124-
# i.fly()
125-
# i.Towing(mouse_position, mouse_press_status)
126-
# if i.alpha < 100:
127-
# self.planes.pop(self.planes.index(i))
128-
self.draw()
129-
self.fly()
130-
self.Towing(pygame.mouse.get_pos(), pygame.mouse.get_pressed())
112+
def update(self, click_pos, click_status):
113+
self.fly() # FLYs The Plane to NEW Location
114+
self.draw() # DRAWs the Game Sprite to NEW Location
115+
self.Towing(click_pos, click_status)
131116

132117
def fade(self):
133118
self.img_og.fill((255, 255, 255, int(self.alpha)), special_flags=pygame.BLEND_RGBA_MULT)
@@ -140,6 +125,31 @@ def fade(self):
140125
# self.img_og = pygame.transform.scale(self.img_og, (size, size))
141126
# self.size = size
142127

128+
def Stanley_Control(self):
129+
k = 100
130+
131+
distances_to_waypoints = list(map(math.dist, [self.position] * len(self.way_points), self.way_points))
132+
# print(distances_to_waypoints)
133+
smallest_distance = min(distances_to_waypoints)
134+
closest_point_index = distances_to_waypoints.index(smallest_distance)
135+
136+
prev_wp = self.way_points[closest_point_index - 1]
137+
next_wp = self.way_points[closest_point_index]
138+
139+
# cross track error
140+
cte_num = (next_wp[0] - prev_wp[0]) * (prev_wp[1] - self.position[1]) - (prev_wp[0] - self.position[0]) * (next_wp[1] - prev_wp[1])
141+
142+
cte_den = math.dist(prev_wp, next_wp)
143+
cross_track_error = cte_num / (cte_den + 1)
144+
145+
theta_track = math.atan2(next_wp[1] - prev_wp[1], next_wp[0] - prev_wp[0])
146+
147+
heading_error = theta_track - self.angle
148+
149+
delta = heading_error + math.atan2(self.speed, k * cross_track_error)
150+
151+
return delta
152+
143153
def fly(self):
144154
self.tick += 1
145155

@@ -150,32 +160,32 @@ def fly(self):
150160
if self.tick % 40 == 0:
151161
# print("Tick")
152162
# print("landing: ",self.landing_strip)
153-
if self.Path[0] in self.landing_strip:
163+
if self.way_points[0] in self.landing_strip:
154164
self.fade()
155165

156-
if len(self.Path) != 0:
166+
if len(self.way_points) != 0:
157167
# if (self.Path[0] not in red_dots):
158168
# red_dots.append(self.Path[0])
159-
dest = self.Path[0]
169+
goal = self.way_points[0]
160170
head = self.head_pose()
161171
tail = self.tail_pose()
162172
mid = (head + tail) / 2
163173

164-
turn_direction = orientation(head, tail, dest) * fine_bank
174+
turn_direction = orientation(head, tail, goal) * fine_bank
165175
# print("Ore", orientation(head, tail, dest))
166176
# print("turnDir", turnDir)
167-
self.turn(turn_direction)
177+
self.turn(self.Stanley_Control())
168178

169-
if dist(mid, self.Path[0]) < 15:
170-
reached = self.Path.pop(0)
179+
if math.dist(mid, self.way_points[0]) < 2:
180+
reached = self.way_points.pop(0)
171181
self.red_dots.pop(0)
172182
# green_dots.append(reached)
173183
# print("Reached", reached)
174184

175185
self.restrict_fly_zone()
176186

177-
self.position = [self.position[0] + self.Speed * math.cos(math.radians(self.Angle)),
178-
self.position[1] - self.Speed * math.sin(math.radians(self.Angle))]
187+
self.position = [self.position[0] + self.speed * math.cos(math.radians(self.angle)),
188+
self.position[1] - self.speed * math.sin(math.radians(self.angle))]
179189

180190
# Keeps the plane bound to the screen
181191
def restrict_fly_zone(self):
@@ -195,40 +205,34 @@ def land(self):
195205
self.flying = False
196206

197207
def draw(self):
198-
# print( self.position)
199208
self.rect.center = self.position
200-
# screen.blit(self.img_gpy, self.position)
201-
# Path Visualization
202-
# Comment to disable Path Visualization
203209
self.path_vis()
204210

205211
def Towing(self, mouse_position, click_status):
206212
# When Clicked Start towing plane with mouse
207-
if click_status[0]:
213+
if click_status[0] and ~self.towing_status:
208214
if self.rect.collidepoint(mouse_position):
209-
if len(self.Path) > 0:
210-
self.Path.clear()
215+
if len(self.way_points) > 0:
216+
self.way_points.clear()
211217
self.red_dots.clear()
212-
self.Tow = True
218+
self.towing_status = True
213219
# print("Towing")
214220

215-
if self.Tow:
221+
if self.towing_status:
216222
if not click_status[0]:
217-
self.Tow = False
223+
self.towing_status = False
218224
# print("UnTOWED")
219-
elif dist(mouse_position, self.landing_strip[0]) < 15:
225+
elif math.dist(mouse_position, self.landing_strip[0]) < 15:
220226
self.flying = False
221227
for i in self.landing_strip:
222-
self.Path.append(i)
228+
self.way_points.append(i)
223229
self.red_dots.append(i)
224230
# print("Locked")
225-
self.Tow = False
231+
self.towing_status = False
226232

227233
else:
228-
# print(mouse_position)
229234
self.red_dots.append(mouse_position)
230-
self.Path.append(mouse_position)
231-
# print(self.Path)
235+
self.way_points.append(mouse_position)
232236

233237
# Give angle to center from current position
234238
def angle_to_center(self):
@@ -238,29 +242,25 @@ def angle_to_center(self):
238242
@staticmethod
239243
def angle(coord1, coord2):
240244

241-
numerator = coord1[1] - coord2[1]
245+
numerator = coord1[1] - coord2[1]
242246
denominator = coord2[0] - coord1[0]
243247
degrees = math.degrees(math.atan2(numerator, denominator))
244248

245249
return degrees
246250

247251
def head_pose(self):
248-
# green_dots.append(self.Pos)
249-
theta = 90
250-
angle = self.Angle + theta
251-
head_loc = (self.position[0] + 30 + (27 * math.cos(math.radians(self.Angle))
252-
- 2 * math.sin(math.radians(self.Angle))),
253-
self.position[1] + 30 + (-27 * math.sin(math.radians(self.Angle))
254-
- 2 * math.cos(math.radians(self.Angle))))
252+
253+
head_loc = (self.position[0] + 30 + (27 * math.cos(math.radians(self.angle))
254+
- 2 * math.sin(math.radians(self.angle))),
255+
self.position[1] + 30 + (-27 * math.sin(math.radians(self.angle))
256+
- 2 * math.cos(math.radians(self.angle))))
255257

256258
# red_dots.append(head_loc)
257259
return np.array(head_loc)
258260

259261
def tail_pose(self):
260-
theta = 90
261-
angle = self.Angle + theta
262-
tail_loc = (self.position[0] + 30 + (-29 * math.cos(math.radians(self.Angle))),
263-
self.position[1] + 30 + (29 * math.sin(math.radians(self.Angle))))
262+
tail_loc = (self.position[0] + 30 + (-29 * math.cos(math.radians(self.angle))),
263+
self.position[1] + 30 + (29 * math.sin(math.radians(self.angle))))
264264

265265
# red_dots.append(tail_loc)
266266
return np.array(tail_loc)
@@ -270,21 +270,20 @@ def tail_pose(self):
270270
# self.img_gpy = pygame.transform.rotate(self.img_og, self.OffsetAngle + self.Angle)
271271

272272
def path_vis(self):
273-
for i in self.red_dots:
274-
screen.blit(red_dot, (i[0] - 4, i[1] - 4))
273+
for dot in self.red_dots:
274+
screen.blit(red_dot, (dot[0] - 4, dot[1] - 4))
275275

276276

277277
class Fleet:
278278

279279
def __init__(self):
280+
self.planes_group = pygame.sprite.Group()
281+
# print(dir(self.planes_group))
280282

281-
self.planes_group = pygame.sprite.Group()
282-
print(dir(self.planes_group))
283283
def Manage(self):
284284
# if (time.time() == 1000)
285285
self.planes_group.draw(screen)
286-
self.planes_group.update()
287-
286+
self.planes_group.update(pygame.mouse.get_pos(), pygame.mouse.get_pressed())
288287

289288
def specialPlane(self, plane):
290289
self.planes.append(plane)
@@ -313,7 +312,6 @@ def spawn(self):
313312
# test_fleet = Fleet()
314313
test_fleet = Fleet()
315314

316-
317315
# Special Plane Instance
318316
# Plane1 h = 37.5685 w = 37.56
319317
# plane1 = Plane( Angle = 90, Pos = (20, 170))

0 commit comments

Comments
 (0)