2020-09-24 21:23:19 +03:00
|
|
|
#!/usr/bin/python3
|
|
|
|
# This example runs a scenario, finds roads with high driver throughput, then
|
|
|
|
# establishes a per-hour cap.
|
|
|
|
#
|
|
|
|
# Before running this script, start the API server:
|
|
|
|
#
|
|
|
|
# > cargo run --release --bin headless -- --port=1234 --alerts=silence
|
|
|
|
#
|
|
|
|
# You may need to install https://requests.readthedocs.io
|
|
|
|
# Keep this script formatted with autopep8 -i
|
|
|
|
|
|
|
|
import abst_helpers
|
2020-09-25 03:26:46 +03:00
|
|
|
from abst_helpers import get
|
|
|
|
from abst_helpers import post
|
2020-09-24 21:23:19 +03:00
|
|
|
import argparse
|
|
|
|
import sys
|
|
|
|
import time
|
|
|
|
|
|
|
|
|
|
|
|
def main():
|
|
|
|
parser = argparse.ArgumentParser()
|
|
|
|
parser.add_argument('--api', default='http://localhost:1234')
|
2020-11-06 01:05:48 +03:00
|
|
|
parser.add_argument('--city_name', default='seattle')
|
2020-09-24 21:23:19 +03:00
|
|
|
parser.add_argument('--map_name', default='montlake')
|
|
|
|
parser.add_argument('--hours', type=int, default=24)
|
2020-09-24 22:08:46 +03:00
|
|
|
parser.add_argument('--cap_pct', type=int, default=80)
|
2020-09-24 23:24:31 +03:00
|
|
|
parser.add_argument('--rounds', type=int, default=10)
|
2020-10-02 01:13:18 +03:00
|
|
|
parser.add_argument('--cap_all_roads', type=bool, default=True)
|
2020-09-24 21:23:19 +03:00
|
|
|
args = parser.parse_args()
|
2020-11-06 01:05:48 +03:00
|
|
|
print('Simulating {} hours of data/system/{}/scenarios/{}/weekday.bin'.format(
|
|
|
|
args.hours, args.city_name, args.map_name))
|
2020-09-24 21:23:19 +03:00
|
|
|
|
|
|
|
baseline = abst_helpers.run_sim(args)
|
2020-09-25 03:26:46 +03:00
|
|
|
edits = get(args, '/map/get-edits').json()
|
2020-09-24 22:08:46 +03:00
|
|
|
|
2020-09-24 23:24:31 +03:00
|
|
|
for _ in range(args.rounds):
|
|
|
|
print('')
|
2020-10-02 01:13:18 +03:00
|
|
|
print('{} roads have a cap'.format(len(edits['commands'])))
|
2020-09-24 23:24:31 +03:00
|
|
|
experiment = abst_helpers.run_sim(args, edits=edits)
|
|
|
|
baseline.compare(experiment)
|
2020-09-25 04:08:05 +03:00
|
|
|
print('{:,} trips changed due to the caps'.format(
|
|
|
|
len(experiment.capped_trips)))
|
2020-09-24 23:24:31 +03:00
|
|
|
|
2020-10-02 01:13:18 +03:00
|
|
|
if args.cap_all_roads:
|
|
|
|
edits['commands'] = cap_all_roads(args)
|
2020-10-07 00:17:55 +03:00
|
|
|
# Individual cap per road; don't merge adjacent roads that happen to have the same cap.
|
|
|
|
edits['merge_zones'] = False
|
2020-10-02 01:13:18 +03:00
|
|
|
else:
|
|
|
|
# Cap the busiest road
|
|
|
|
busiest_road, thruput = find_busiest_road(args)
|
|
|
|
cmd = get(args, '/map/get-edit-road-command',
|
|
|
|
params={'id': busiest_road}).json()
|
|
|
|
cmd['ChangeRoad']['new']['access_restrictions']['cap_vehicles_per_hour'] = int(
|
|
|
|
(args.cap_pct / 100.0) * thruput)
|
|
|
|
edits['commands'].append(cmd)
|
|
|
|
|
|
|
|
# Write the final edits
|
|
|
|
f = open('cap_edits.json', 'w')
|
|
|
|
f.write(get(args, '/map/get-edits').text)
|
|
|
|
f.close()
|
2020-09-24 22:08:46 +03:00
|
|
|
|
|
|
|
|
|
|
|
# Find the road with the most car traffic in any one hour period
|
|
|
|
def find_busiest_road(args):
|
2020-09-25 03:26:46 +03:00
|
|
|
thruput = get(
|
|
|
|
args, '/data/get-road-thruput').json()['counts']
|
2020-09-24 21:23:19 +03:00
|
|
|
max_key = None
|
|
|
|
max_value = 0
|
|
|
|
for r, agent, hr, count in thruput:
|
|
|
|
if agent == 'Car':
|
|
|
|
if count > max_value:
|
|
|
|
max_key = (r, hr)
|
|
|
|
max_value = count
|
|
|
|
print('Busiest road is #{}, with {} cars crossing during hour {}'.format(
|
|
|
|
max_key[0], max_value, max_key[1]))
|
2020-09-24 22:08:46 +03:00
|
|
|
return (max_key[0], max_value)
|
2020-09-24 21:23:19 +03:00
|
|
|
|
|
|
|
|
2020-10-02 01:13:18 +03:00
|
|
|
# Cap all roads to some percent of their max throughput over any one hour period
|
|
|
|
def cap_all_roads(args):
|
|
|
|
thruput = get(
|
|
|
|
args, '/data/get-road-thruput').json()['counts']
|
|
|
|
max_per_road = {}
|
|
|
|
for r, agent, hr, count in thruput:
|
|
|
|
if agent == 'Car':
|
|
|
|
if r not in max_per_road or count > max_per_road[r]:
|
|
|
|
max_per_road[r] = count
|
|
|
|
commands = []
|
|
|
|
for r, count in max_per_road.items():
|
|
|
|
cap = int((args.cap_pct / 100.0) * count)
|
|
|
|
# Don't go too low
|
|
|
|
if cap > 10:
|
|
|
|
cmd = get(args, '/map/get-edit-road-command',
|
|
|
|
params={'id': r}).json()
|
|
|
|
cmd['ChangeRoad']['new']['access_restrictions']['cap_vehicles_per_hour'] = cap
|
|
|
|
commands.append(cmd)
|
|
|
|
return commands
|
|
|
|
|
|
|
|
|
2020-09-24 21:23:19 +03:00
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|