-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsimulation.py
141 lines (106 loc) · 4.58 KB
/
simulation.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
from printer import Printer
from pedestrian import Pedestrian
# Note: we will be developing a custom random number generator for the final
# simulation.
import random
import matplotlib
import matplotlib.pyplot as plt
import time
class Simulation:
"""
Performs a cellular automata simulation using an input Grid object.
"""
def __init__(self, grid, params = {}):
self.grid = grid
self.num_pedestrians = params.get('num_pedestrians', 500)
self.visualization = params.get('visualization', False)
self.seed_pedestrians()
def seed_pedestrians(self):
num_entrance_nodes = len(self.grid.entrance_nodes)
num_destination_nodes = len(self.grid.destination_nodes)
self.ped_queue = [self.generate_pedestrian(num_entrance_nodes, num_destination_nodes)
for i in range(self.num_pedestrians)]
def generate_pedestrian(self, num_entrance_nodes, num_destination_nodes):
# TODO: add random number generator.
entrance_node = self.grid.entrance_nodes[random.randrange(0, num_entrance_nodes-1)]
destination_node = self.grid.destination_nodes[random.randrange(0, num_destination_nodes-1)]
# TODO: set speed (third argument) dynamically by drawing from a distribution.
new_ped = Pedestrian(entrance_node, destination_node, 1, self.grid.node_dict)
return new_ped
# Initialize the Visualization plot.
def init_viz(self):
# Set interactive plot on and create figure.
plt.ion()
fig = plt.figure()
self.ax = fig.add_subplot(1, 1, 1)
self.scat = self.ax.scatter([], [], zorder=1)
# Set background image.
img = plt.imread('playMat.png')
plt.imshow(img, extent=(0, 140, 70, 0), zorder=0)
plt.show()
def update_viz(self, x_vals, y_vals):
# Clear existing points.
self.scat.remove()
# Update points to be plotted.
self.scat = self.ax.scatter(x_vals, y_vals, zorder=1)
# plt.scatter(random.randrange(0, 20), random.randrange(0, 15))
# Draw.
plt.draw()
# A short pause so Mac OS X 10.11.3 doesn't break.
plt.pause(0.0001)
def run(self):
Printer.pp('Initializing simulation.')
self.run_simulation()
def run_simulation(self):
active_peds = []
if self.visualization:
self.init_viz()
while True:
# Initialize for viz.
if self.visualization:
x_vals = []
y_vals = []
target_next_dict = {node: [] for node in self.grid.nodes}
if len(self.ped_queue) == 0 and len(active_peds) == 0:
print('Finished!')
break
if len(self.ped_queue) > 0:
next_ped = self.ped_queue[0]
if next_ped.current.available:
active_peds.append(self.ped_queue.pop(0))
active_peds_remaining = len(active_peds)
if active_peds_remaining % 10 == 0:
print('%d active peds remaining to evacuate.' % active_peds_remaining)
for indx, ped in enumerate(active_peds):
# If the ped is finished,
if ped.egress_complete:
# Remove her.
del active_peds[indx]
continue
# Grab the ped's target next node according to the shortest path algo.
target_next = ped.target_next
# Add an entry in the node => peds dictionary, telling us that the ped
# wants to go to that node.
target_next_dict[target_next].append(ped)
# Get x,y values for viz
if self.visualization:
x_vals.append(ped.current.x)
y_vals.append(ped.current.y)
for node, peds in target_next_dict.iteritems():
ped_len = len(peds)
if ped_len == 0:
# No pedestrian wants the node, so go to the next iteration.
continue
elif ped_len == 1:
# We're done; only one ped wants the node.
ped = peds[0]
else:
# Select a ped at random to get the node.
ped = peds[random.randrange(0, ped_len-1)]
# Move the ped.
ped.move(node, self.grid.node_dict, self.grid.type_map)
# Update viz.
if self.visualization:
self.update_viz(x_vals, y_vals)
print('Simulation completed.')
plt.close()