-
Notifications
You must be signed in to change notification settings - Fork 1
/
driving_directions.py
408 lines (334 loc) · 16 KB
/
driving_directions.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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
from dqn_model import DQNModel
from state_representation import StateRepresentation
from rl_environment import RLEnvironment
import mlflow
import random
import numpy as np
import random
import matplotlib.pyplot as plt
import mlflow
from dqn_model import DQNModel
from rl_environment import RLEnvironment
from google_maps_api import get_coordinates, get_random_nearby_place, get_directions
import googlemaps
import matplotlib.pyplot as plt
from datetime import datetime
import random
from google_maps_api import get_coordinates, get_random_nearby_place, get_directions
def plot_map(latitudes, longitudes, starting_coords):
"""
Plot the car's movement on a map using matplotlib.
Parameters:
- latitudes (list): List of latitude values representing the car's movement.
- longitudes (list): List of longitude values representing the car's movement.
- starting_coords (tuple): Tuple containing latitude and longitude of the starting point.
Returns:
None
"""
# Plot the car's movement on a map using matplotlib
plt.figure(figsize=(10, 8))
plt.plot(longitudes, latitudes, 'bo-', markersize=8, label='Car Movement')
plt.plot(starting_coords[1], starting_coords[0], 'ro', markersize=10, label='Starting Point')
plt.xlabel('Longitude')
plt.ylabel('Latitude')
plt.title('Driving Simulation')
plt.legend()
plt.grid(True)
plt.show()
def turn_right(instruction):
"""
Modify the instruction to simulate turning right at an intersection.
Parameters:
- instruction (str): Original instruction containing directions.
Returns:
str: Modified instruction indicating turning right.
"""
# Function to modify the instruction to simulate turning right at an intersection
if 'right' in instruction.lower():
return instruction
else:
return f"Turn right to {instruction.split('on')[1]}"
def turn_left(instruction):
"""
Modify the instruction to simulate turning left at an intersection.
Parameters:
- instruction (str): Original instruction containing directions.
Returns:
str: Modified instruction indicating turning left.
"""
# Function to modify the instruction to simulate turning left at an intersection
if 'left' in instruction.lower():
return instruction
else:
return f"Turn left to {instruction.split('on')[1]}"
def go_straight(instruction):
"""
Modify the instruction to simulate going straight at an intersection.
Parameters:
- instruction (str): Original instruction containing directions.
Returns:
str: Modified instruction indicating going straight.
"""
# Function to modify the instruction to simulate going straight at an intersection
if 'straight' in instruction.lower():
return instruction
else:
return f"Go straight on {instruction.split('on')[1]}"
def turn_back(instruction):
"""
Modify the instruction to simulate turning back at an intersection.
Parameters:
- instruction (str): Original instruction containing directions.
Returns:
str: Modified instruction indicating turning back.
"""
# Function to modify the instruction to simulate turning back at an intersection
if 'turn around' in instruction.lower():
return instruction
else:
return f"Turn around on {instruction.split('on')[1]}"
def encode_instruction(instruction):
"""
Encode an instruction into a numerical representation.
Parameters:
- instruction (str): The instruction to be encoded.
Returns:
- encoded_instruction (np.ndarray): The encoded instruction as a NumPy array.
"""
# Define a dictionary that maps instruction types to numerical values
instruction_mapping = {
'turn_left': 0,
'turn_right': 1,
'go_straight': 2,
'turn_back': 3
}
# Convert the instruction to lowercase and get its numerical value from the mapping
encoded_value = instruction_mapping.get(instruction.lower(), -1) # -1 for unknown instructions
# Create a one-hot encoded array based on the numerical value
encoded_instruction = np.zeros(len(instruction_mapping))
if encoded_value >= 0:
encoded_instruction[encoded_value] = 1
return encoded_instruction
def prepare_state_for_model(current_address, next_address, instruction):
"""
Prepare the current state for the machine learning model.
Parameters:
- current_address (str): The current address.
- next_address (str): The next address.
- instruction (str): The instruction for the next step.
Returns:
- state (np.ndarray): The prepared state as a NumPy array.
"""
# Convert addresses to coordinates
current_coords = get_coordinates(current_address)
next_coords = get_coordinates(next_address)
# Encode instruction (e.g., one-hot encoding)
encoded_instruction = encode_instruction(instruction)
# Combine all components into the state vector
state = np.concatenate((current_coords, next_coords, encoded_instruction))
return state
def simulate_driving_right(starting_address, max_intersections=100, model=None):
"""
Simulate driving with the right-turning rule.
Parameters:
- starting_address (str): Starting address for the driving simulation.
- max_intersections (int): Maximum number of intersections to simulate (default: 100).
Returns:
None
"""
# Simulate driving with the right-turning rule
intersection_count = 0
car_positions = []
current_address = starting_address
while intersection_count < max_intersections:
# Get the nearby places or streets from the current address
next_address = get_random_nearby_place(current_address)
if next_address:
# Get driving directions between the current address and the next address
driving_steps = get_directions(current_address, next_address)
if driving_steps:
# Retrieve step instructions and duration for the first step
instruction = driving_steps[0]['html_instructions']
duration = driving_steps[0]['duration']['text']
# Call the machine learning model to get an action
if model:
current_state = prepare_state_for_model(current_address, next_address, instruction)
action = model.predict(current_state)
# Decide based on the model's prediction
if action == 'right':
print(f"Model predicts: Turn right at intersection.")
elif action == 'go_straight':
updated_instruction = go_straight(instruction)
print(f"Model predicts: {updated_instruction}")
elif action == 'turn_back':
updated_instruction = turn_back(instruction)
print(f"Model predicts: {updated_instruction}")
# Check if the instruction contains the word 'right' to detect an intersection
if 'right' in instruction.lower():
intersection_count += 1
print(f"Intersection {intersection_count}: {instruction} ({duration})")
else:
updated_instruction = turn_right(instruction)
print(f"Step: {updated_instruction} ({duration})")
# Get latitude and longitude of the next address for plotting
next_address_coords = get_coordinates(next_address)
if next_address_coords:
car_positions.append(next_address_coords)
# Update the current address for the next iteration
current_address = next_address
else:
print(f"Failed to get driving directions from {current_address} to {next_address}.")
break
else:
print("No nearby places found. Ending simulation.")
break
# Plot the car's movement on a map
latitudes, longitudes = zip(*car_positions)
plot_map(latitudes, longitudes, get_coordinates(starting_address))
def simulate_driving_left(starting_address, max_intersections=100, model=None):
"""
Simulate driving with the left-turning rule.
Parameters:
- starting_address (str): Starting address for the driving simulation.
- max_intersections (int): Maximum number of intersections to simulate (default: 100).
Returns:
None
"""
# Simulate driving with the left-turning rule
intersection_count = 0
car_positions = []
current_address = starting_address
while intersection_count < max_intersections:
# Get the nearby places or streets from the current address
next_address = get_random_nearby_place(current_address)
if next_address:
# Get driving directions between the current address and the next address
driving_steps = get_directions(current_address, next_address)
if driving_steps:
# Retrieve step instructions and duration for the first step
instruction = driving_steps[0]['html_instructions']
duration = driving_steps[0]['duration']['text']
# Call the machine learning model to get an action
if model:
current_state = prepare_state_for_model(current_address, next_address, instruction)
action = model.predict(current_state)
# Decide based on the model's prediction
if action == 'left':
print(f"Model predicts: Turn left at intersection.")
elif action == 'go_straight':
updated_instruction = go_straight(instruction)
print(f"Model predicts: {updated_instruction}")
elif action == 'turn_back':
updated_instruction = turn_back(instruction)
print(f"Model predicts: {updated_instruction}")
# Check if the instruction contains the word 'left' to detect an intersection
if 'left' in instruction.lower():
intersection_count += 1
print(f"Intersection {intersection_count}: {instruction} ({duration})")
else:
updated_instruction = turn_left(instruction)
print(f"Step: {updated_instruction} ({duration})")
# Get latitude and longitude of the next address for plotting
next_address_coords = get_coordinates(next_address)
if next_address_coords:
car_positions.append(next_address_coords)
# Update the current address for the next iteration
current_address = next_address
else:
print(f"Failed to get driving directions from {current_address} to {next_address}.")
break
else:
print("No nearby places found. Ending simulation.")
break
# Plot the car's movement on a map
latitudes, longitudes = zip(*car_positions)
plot_map(latitudes, longitudes, get_coordinates(starting_address))
def simulate_driving_alternate(starting_address, max_intersections=100, model=None):
"""
Simulate driving with the alternate turning rule (turn right twice, then turn left once, repeat).
Parameters:
- starting_address (str): Starting address for the driving simulation.
- max_intersections (int): Maximum number of intersections to simulate (default: 100).
Returns:
None
"""
# Simulate driving with the alternate turning rule (turn right twice, then turn left once, repeat)
intersection_count = 0
car_positions = []
current_address = starting_address
while intersection_count < max_intersections:
# Get the nearby places or streets from the current address
next_address = get_random_nearby_place(current_address)
if next_address:
# Get driving directions between the current address and the next address
driving_steps = get_directions(current_address, next_address)
if driving_steps:
# Retrieve step instructions and duration for the first step
instruction = driving_steps[0]['html_instructions']
duration = driving_steps[0]['duration']['text']
# Call the machine learning model to get an action
if model:
current_state = prepare_state_for_model(current_address, next_address, instruction)
action = model.predict(current_state)
# Decide based on the model's prediction
if action == 'right':
print(f"Model predicts: Turn right at intersection.")
elif action == 'left':
print(f"Model predicts: Turn left at intersection.")
elif action == 'go_straight':
updated_instruction = go_straight(instruction)
print(f"Model predicts: {updated_instruction}")
elif action == 'turn_back':
updated_instruction = turn_back(instruction)
print(f"Model predicts: {updated_instruction}")
# Define the turn sequence: right, right, left
turn_sequence = ['right', 'right', 'left']
# Check if the instruction contains the word from the turn sequence
if any(turn in instruction.lower() for turn in turn_sequence):
intersection_count += 1
if turn_sequence[turn_count % 3] in instruction.lower():
print(f"Intersection {intersection_count}: {instruction} ({duration})")
turn_count += 1
else:
updated_instruction = f"Turn {turn_sequence[turn_count % 3]} to {instruction.split('on')[1]}"
print(f"Step: {updated_instruction} ({duration})")
turn_count += 1
else:
updated_instruction = turn_right(instruction)
print(f"Step: {updated_instruction} ({duration})")
# Get latitude and longitude of the next address for plotting
next_address_coords = get_coordinates(next_address)
if next_address_coords:
car_positions.append(next_address_coords)
# Update the current address for the next iteration
current_address = next_address
else:
print(f"Failed to get driving directions from {current_address} to {next_address}.")
break
else:
print("No nearby places found. Ending simulation.")
break
# Plot the car's movement on a map
latitudes, longitudes = zip(*car_positions)
plot_map(latitudes, longitudes, get_coordinates(starting_address))
def parse_rule_choice():
"""
Parser function to get the user's choice of rules.
Returns:
str: Choice of rules ('right', 'left', or 'alternate').
"""
# Parser function to get the user's choice of rules
while True:
print("Choose a set of rules:")
print("1. Right-turning at intersections (Default)")
print("2. Left-turning at intersections")
print("3. Turn right twice, then turn left once, repeat")
choice = input("Enter the number of your choice (1, 2, or 3): ")
if choice == '1':
return 'right'
elif choice == '2':
return 'left'
elif choice == '3':
return 'alternate'
else:
print("Invalid choice. Please enter '1', '2', or '3'.")