8
8
# Spawn Optimization
9
9
# Landing Bug
10
10
11
- # Initialize Pygame
12
- pygame .init ()
13
11
14
12
# Setup the clock for a decent frame rate
15
13
clock = pygame .time .Clock ()
16
14
17
- # Background Image
18
- background = pygame .image .load ('Flight-Control-Bot/Map.png' )
19
-
20
15
# Creating a Window
21
16
screen_width = 1920 / 2
22
17
screen_height = 1080 / 2
23
18
screen = pygame .display .set_mode ((1920 / 2 , 1080 / 2 ))
24
19
25
20
green_dots = []
21
+ background = pygame .image .load ('Flight-Control-Bot/map.png' )
26
22
red_dot = pygame .image .load ('Flight-Control-Bot/red_dot.png' )
27
23
green_dot = pygame .image .load ('Flight-Control-Bot/green_dot.png' )
28
24
29
25
30
- def dist (x , y ):
31
- distance = (((x [0 ] - y [0 ]) ** 2 ) + ((x [1 ] - y [1 ]) ** 2 )) ** 0.5
32
- return distance
33
-
34
-
35
26
def orientation (p1 , p2 , p3 ):
36
27
# to find the orientation of
37
28
# an ordered triplet (p1,p2,p3)
@@ -47,7 +38,7 @@ def orientation(p1, p2, p3):
47
38
48
39
if val == 0 :
49
40
# Clockwise orientation
50
- if dist (p1 , p3 ) < dist (p2 , p3 ):
41
+ if math . dist (p1 , p3 ) < math . dist (p2 , p3 ):
51
42
result = 0
52
43
else :
53
44
result = 100
@@ -73,15 +64,15 @@ def __init__(self, spawn_at=[750, 100], offset_angle=-2):
73
64
# self.img_gpy = pygame.transform.rotate(self.img_og, offset_angle)
74
65
75
66
# Speed
76
- self .Speed = 0.4
67
+ self .speed = 0.4
77
68
self .flying = True
78
69
79
70
# Position
80
71
self .position = spawn_at # [random.randint(0, 1920/2), random.randint(0, 540)]
81
72
82
73
# 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 } " )
85
76
86
77
self .OffsetAngle = offset_angle
87
78
@@ -90,44 +81,38 @@ def __init__(self, spawn_at=[750, 100], offset_angle=-2):
90
81
# self.Tow = False
91
82
self .shrinkage = [j for j in range (80 , 10 , - 3 )]
92
83
93
- self .Path = []
84
+ self .way_points = []
94
85
95
- self .Tow = False
86
+ self .towing_status = False
96
87
97
88
self .alpha = 255
98
89
99
90
self .size = - 1
100
91
self .tick = 0
101
92
102
93
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 )
105
96
self .turn (0 )
106
97
107
98
# # Turns the plane by a certain bank angle
108
99
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 )
111
102
self .rect = self .image .get_rect ()
112
103
113
104
# Turns the plane to a Certain Angle
114
105
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 )
117
108
self .rect = self .image .get_rect ()
118
109
119
110
# Starts to fade the sprite on approaching landing
120
111
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 )
131
116
132
117
def fade (self ):
133
118
self .img_og .fill ((255 , 255 , 255 , int (self .alpha )), special_flags = pygame .BLEND_RGBA_MULT )
@@ -140,6 +125,31 @@ def fade(self):
140
125
# self.img_og = pygame.transform.scale(self.img_og, (size, size))
141
126
# self.size = size
142
127
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
+
143
153
def fly (self ):
144
154
self .tick += 1
145
155
@@ -150,32 +160,32 @@ def fly(self):
150
160
if self .tick % 40 == 0 :
151
161
# print("Tick")
152
162
# print("landing: ",self.landing_strip)
153
- if self .Path [0 ] in self .landing_strip :
163
+ if self .way_points [0 ] in self .landing_strip :
154
164
self .fade ()
155
165
156
- if len (self .Path ) != 0 :
166
+ if len (self .way_points ) != 0 :
157
167
# if (self.Path[0] not in red_dots):
158
168
# red_dots.append(self.Path[0])
159
- dest = self .Path [0 ]
169
+ goal = self .way_points [0 ]
160
170
head = self .head_pose ()
161
171
tail = self .tail_pose ()
162
172
mid = (head + tail ) / 2
163
173
164
- turn_direction = orientation (head , tail , dest ) * fine_bank
174
+ turn_direction = orientation (head , tail , goal ) * fine_bank
165
175
# print("Ore", orientation(head, tail, dest))
166
176
# print("turnDir", turnDir)
167
- self .turn (turn_direction )
177
+ self .turn (self . Stanley_Control () )
168
178
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 )
171
181
self .red_dots .pop (0 )
172
182
# green_dots.append(reached)
173
183
# print("Reached", reached)
174
184
175
185
self .restrict_fly_zone ()
176
186
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 ))]
179
189
180
190
# Keeps the plane bound to the screen
181
191
def restrict_fly_zone (self ):
@@ -195,40 +205,34 @@ def land(self):
195
205
self .flying = False
196
206
197
207
def draw (self ):
198
- # print( self.position)
199
208
self .rect .center = self .position
200
- # screen.blit(self.img_gpy, self.position)
201
- # Path Visualization
202
- # Comment to disable Path Visualization
203
209
self .path_vis ()
204
210
205
211
def Towing (self , mouse_position , click_status ):
206
212
# When Clicked Start towing plane with mouse
207
- if click_status [0 ]:
213
+ if click_status [0 ] and ~ self . towing_status :
208
214
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 ()
211
217
self .red_dots .clear ()
212
- self .Tow = True
218
+ self .towing_status = True
213
219
# print("Towing")
214
220
215
- if self .Tow :
221
+ if self .towing_status :
216
222
if not click_status [0 ]:
217
- self .Tow = False
223
+ self .towing_status = False
218
224
# print("UnTOWED")
219
- elif dist (mouse_position , self .landing_strip [0 ]) < 15 :
225
+ elif math . dist (mouse_position , self .landing_strip [0 ]) < 15 :
220
226
self .flying = False
221
227
for i in self .landing_strip :
222
- self .Path .append (i )
228
+ self .way_points .append (i )
223
229
self .red_dots .append (i )
224
230
# print("Locked")
225
- self .Tow = False
231
+ self .towing_status = False
226
232
227
233
else :
228
- # print(mouse_position)
229
234
self .red_dots .append (mouse_position )
230
- self .Path .append (mouse_position )
231
- # print(self.Path)
235
+ self .way_points .append (mouse_position )
232
236
233
237
# Give angle to center from current position
234
238
def angle_to_center (self ):
@@ -238,29 +242,25 @@ def angle_to_center(self):
238
242
@staticmethod
239
243
def angle (coord1 , coord2 ):
240
244
241
- numerator = coord1 [1 ] - coord2 [1 ]
245
+ numerator = coord1 [1 ] - coord2 [1 ]
242
246
denominator = coord2 [0 ] - coord1 [0 ]
243
247
degrees = math .degrees (math .atan2 (numerator , denominator ))
244
248
245
249
return degrees
246
250
247
251
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 ))))
255
257
256
258
# red_dots.append(head_loc)
257
259
return np .array (head_loc )
258
260
259
261
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 ))))
264
264
265
265
# red_dots.append(tail_loc)
266
266
return np .array (tail_loc )
@@ -270,21 +270,20 @@ def tail_pose(self):
270
270
# self.img_gpy = pygame.transform.rotate(self.img_og, self.OffsetAngle + self.Angle)
271
271
272
272
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 ))
275
275
276
276
277
277
class Fleet :
278
278
279
279
def __init__ (self ):
280
+ self .planes_group = pygame .sprite .Group ()
281
+ # print(dir(self.planes_group))
280
282
281
- self .planes_group = pygame .sprite .Group ()
282
- print (dir (self .planes_group ))
283
283
def Manage (self ):
284
284
# if (time.time() == 1000)
285
285
self .planes_group .draw (screen )
286
- self .planes_group .update ()
287
-
286
+ self .planes_group .update (pygame .mouse .get_pos (), pygame .mouse .get_pressed ())
288
287
289
288
def specialPlane (self , plane ):
290
289
self .planes .append (plane )
@@ -313,7 +312,6 @@ def spawn(self):
313
312
# test_fleet = Fleet()
314
313
test_fleet = Fleet ()
315
314
316
-
317
315
# Special Plane Instance
318
316
# Plane1 h = 37.5685 w = 37.56
319
317
# plane1 = Plane( Angle = 90, Pos = (20, 170))
0 commit comments