This repository has been archived by the owner on Aug 19, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmugen
executable file
·223 lines (170 loc) · 5.79 KB
/
mugen
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
#!/usr/bin/env python
VERSION = 0.4
import sys
import random
import os.path
from optparse import OptionParser
from lib import *
def main():
parser = OptionParser(usage='Usage: %prog [OPTION] FILE',
version='%prog ' + '%.1f' % VERSION)
parser.add_option('-t', '--time', type='float', help='simulation time (default: 60 seconds)')
parser.add_option('-s', '--speed', type='float', help='mean vehicle speed (default: 30 m/s)')
parser.add_option('-d', '--density', type='float', help='vehicle density (default: 2600 vehicles/hour)')
parser.add_option('--speed-stdev', type='float', help='standard deviation of vehicle speed (default: 4 m/s)')
parser.add_option('--arrival-stdev', type='float', help='standard deviation of intra-arrival time (default: 0.8s)')
parser.set_defaults(time=60.0,
speed=30.0,
speed_stdev=4.0,
density=2600.0,
arrival_stdev=0.8)
options, args = parser.parse_args()
if len(args) < 1:
parser.print_help()
sys.exit(2)
setattr(parser.values, 'arrival', 3600.0 / options.density)
if os.path.exists(args[0]):
mugen(args[0], options)
else:
print 'mugen: error: no such file: %s' % args[0]
def mugen(file, options):
with open(file) as f:
vehicles = generate(f, options)
with open(file + '.gpi', 'w') as f:
plot_vehicle_count(f, vehicles, options.time)
with open(file + '.tcl', 'w') as f:
generate_ns2_scene(f, vehicles, options)
display_stats(vehicles, options)
def generate(f, options):
points, roads, regions = parse(f)
paths = find_all_paths(points, roads)
trim = calculate_trim(paths, options.speed)
vehicles = generate_movement(paths, options.time + trim,
options.speed, options.speed_stdev,
options.arrival, options.arrival_stdev)
trimmed = trim_vehicles(vehicles, options.time, trim)
add_collisions(trimmed, regions, options.time)
return trimmed
def find_all_paths(points, roads):
paths = []
tpaths = []
entrances = points[:]
exits = points[:]
for road in roads:
if road[1] in entrances:
entrances.remove(road[1])
if road[0] in exits:
exits.remove(road[0])
for road in roads:
if road[0] in entrances:
tpaths.append(list(road))
while len(tpaths):
t2paths = []
for path in tpaths:
if len(path) > 1 and path[0] in entrances and path[-1] in exits:
paths.append(path)
elif not is_cyclic(path):
for road in roads:
if road[0] == path[-1]:
t2paths.append(path + [road[1]])
tpaths = t2paths
return paths
def calculate_trim(paths, mean_speed):
longest_dist = 0.0
for path in paths:
dist = total_distance(path)
if dist > longest_dist:
longest_dist = dist
return longest_dist / mean_speed
def generate_movement(paths, duration, speed_mean, speed_stdev, arrival_mean, arrival_stdev):
vehicles = []
t = 0.0
while t < duration:
v = Vehicle()
while True:
v.speed = random.gauss(speed_mean, speed_stdev)
if v.speed > 0:
break
while True:
q = random.gauss(arrival_mean, arrival_stdev)
if q > 0:
v.arrival = t + q
break
v.path = random.choice(paths)
vehicles.append(v)
t = v.arrival
return vehicles
def trim_vehicles(vehicles, time, trim):
trimmed = []
for v in vehicles:
v.arrival -= trim
v.calculate_movements()
if v.arrival < time and v.leave >= 0:
v.movements = [m for m in v.movements if m.time < time]
trimmed.append(v)
return trimmed
def add_collisions(vehicles, regions, time):
for v in vehicles:
v.calculate_collisions(regions)
v.collisions = [c for c in v.collisions if c['time'] < time]
def plot_vehicle_count(f, vehicles, time):
v_count = {}
for v in vehicles:
v_count[v.arrival] = v_count.get(v.arrival, 0) + 1
v_count[v.leave] = v_count.get(v.leave, 0) - 1
times = sorted(v_count.keys())
real_count = 0
f.write("set style data lines\n")
f.write("set xlabel 'Time (s)'\n")
f.write("set ylabel 'Vehicles'\n")
f.write("set xrange [0:%d]\n" % time)
f.write("set yrange [0:]\n")
f.write("set nokey\n")
f.write("plot '-'\n")
for t in times:
if t > time:
break
real_count += v_count[t]
f.write("%f %d\n" % (t, real_count))
def generate_ns2_scene(f, vehicles, options):
f.write('#\n')
f.write('# Generated using MUGEN %.1f\n' % VERSION)
f.write('#\n')
for line in get_stats(vehicles, options):
f.write('# ')
f.write(line)
f.write('\n')
f.write('#\n')
for i, v in enumerate(vehicles):
f.write('$node_(%d) set X_ %f\n' % (i, v.movements[0].start[0]))
f.write('$node_(%d) set Y_ %f\n' % (i, v.movements[0].start[1]))
f.write('$node_(%d) set Z_ %f\n' % (i, 0))
f.write('$ns_ at %f "$beacon_(%d) PeriodicBroadcast ON"\n' % (v.arrival, i))
for m in v.movements:
f.write('$ns_ at %f "$node_(%d) setdest %f %f %f"\n' % (m.time, i, m.end[0], m.end[1], m.speed))
for c in v.collisions:
f.write('$ns_ at %f "$agent_(%d) enter"\n' % (c['time'], i))
if v.leave < options.time:
params = (v.leave, i, i)
f.write('$ns_ at %f "$ns_ detach-agent $node_(%d) $agent_(%d)"\n' % params)
f.write('$ns_ at %f "$ns_ detach-agent $node_(%d) $beacon_(%d)"\n' % params)
f.write('\n')
def display_stats(vehicles, options):
for line in get_stats(vehicles, options):
print line
def get_stats(vehicles, options):
stats = []
stats.append("Simulation Time: %.2fs" % options.time)
stats.append("")
stats.append("Mean Speed: %.2f m/s" % options.speed)
stats.append("Speed Std. Dev.: %.2f m/s" % options.speed_stdev)
stats.append("")
stats.append("Vehicle Density: %d veh/h" % options.density)
stats.append("")
stats.append("Mean Inter-Arrival Time: %.2fs" % options.arrival)
stats.append("Inter-Arrival Time Std. Dev.: %.2fs" % options.arrival_stdev)
stats.append("")
stats.append("Number of Vehicles: %d" % len(vehicles))
return stats
if __name__ == '__main__':
main()