├── plots
├── hellooo.txt
├── time_vs_epoch_city1.png
├── time_vs_epoch_city3.png
└── time_vs_epoch_model.png
├── .gitignore
├── requirements.txt
├── documentation
├── project_info.txt
├── PSAR4.pdf
├── patent1.pdf
├── patent2.pdf
├── psar3.pdf
├── psar5.pdf
├── PSAR2(1).pdf
├── test_loop.png
├── samplecity1.PNG
├── train_loop.png
├── Ideation canvas.docx
├── 5_6298785061042914214.PDF
├── AEIOU_Summary_Team_No.docx
├── Business model canvas.PNG
├── Final Project Report.pdf
├── AEIOU_Summary_Team_No(1).docx
├── Final Project Report(1)(1).docx
├── Final Project Report-final.docx
├── Final Project Report-final.pdf
├── Empathy Mapping canvas FINAL.docx
├── product development canvas FINAL.docx
└── patent1.txt
├── models
├── model.bin
├── model_city.bin
├── model_city1.bin
├── model_city2.bin
├── model_city3.bin
├── model_city1_2.bin
└── model_city1_3.bin
├── maps_images
├── city2.JPG
├── city3.JPG
├── Capture.JPG
├── citymap.JPG
└── ezgif.com-gif-maker.gif.mp4
├── arduino_images
├── arduino1.jpg
├── arduino2.jpg
└── arduino3.jpg
├── maps
├── nodes.nod.xml
├── edges.edg.xml
├── tripinfo.xml
├── routes3.rou.xml
├── routes3.rou.alt.xml
├── outputs.out
├── city2.rou.xml
├── network.net.xml
├── city3.rou.xml
├── city2.rou.alt.xml
├── randomTrips.py
└── trips.trips.xml
├── configuration.sumocfg
├── trafficlight_2
└── trafficlight_2.ino
├── README.md
└── train.py
/plots/hellooo.txt:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | documentation/
2 | arduino_images/
3 | maps_images/
4 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | torch
2 | numpy
3 | matplotlib
4 | sumo
5 |
--------------------------------------------------------------------------------
/documentation/project_info.txt:
--------------------------------------------------------------------------------
1 | traffic light management system info.
2 |
--------------------------------------------------------------------------------
/models/model.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/models/model.bin
--------------------------------------------------------------------------------
/maps_images/city2.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/maps_images/city2.JPG
--------------------------------------------------------------------------------
/maps_images/city3.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/maps_images/city3.JPG
--------------------------------------------------------------------------------
/models/model_city.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/models/model_city.bin
--------------------------------------------------------------------------------
/models/model_city1.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/models/model_city1.bin
--------------------------------------------------------------------------------
/models/model_city2.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/models/model_city2.bin
--------------------------------------------------------------------------------
/models/model_city3.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/models/model_city3.bin
--------------------------------------------------------------------------------
/documentation/PSAR4.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/PSAR4.pdf
--------------------------------------------------------------------------------
/documentation/patent1.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/patent1.pdf
--------------------------------------------------------------------------------
/documentation/patent2.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/patent2.pdf
--------------------------------------------------------------------------------
/documentation/psar3.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/psar3.pdf
--------------------------------------------------------------------------------
/documentation/psar5.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/psar5.pdf
--------------------------------------------------------------------------------
/maps_images/Capture.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/maps_images/Capture.JPG
--------------------------------------------------------------------------------
/maps_images/citymap.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/maps_images/citymap.JPG
--------------------------------------------------------------------------------
/models/model_city1_2.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/models/model_city1_2.bin
--------------------------------------------------------------------------------
/models/model_city1_3.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/models/model_city1_3.bin
--------------------------------------------------------------------------------
/arduino_images/arduino1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/arduino_images/arduino1.jpg
--------------------------------------------------------------------------------
/arduino_images/arduino2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/arduino_images/arduino2.jpg
--------------------------------------------------------------------------------
/arduino_images/arduino3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/arduino_images/arduino3.jpg
--------------------------------------------------------------------------------
/documentation/PSAR2(1).pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/PSAR2(1).pdf
--------------------------------------------------------------------------------
/documentation/test_loop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/test_loop.png
--------------------------------------------------------------------------------
/documentation/samplecity1.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/samplecity1.PNG
--------------------------------------------------------------------------------
/documentation/train_loop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/train_loop.png
--------------------------------------------------------------------------------
/plots/time_vs_epoch_city1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/plots/time_vs_epoch_city1.png
--------------------------------------------------------------------------------
/plots/time_vs_epoch_city3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/plots/time_vs_epoch_city3.png
--------------------------------------------------------------------------------
/plots/time_vs_epoch_model.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/plots/time_vs_epoch_model.png
--------------------------------------------------------------------------------
/documentation/Ideation canvas.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/Ideation canvas.docx
--------------------------------------------------------------------------------
/documentation/5_6298785061042914214.PDF:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/5_6298785061042914214.PDF
--------------------------------------------------------------------------------
/documentation/AEIOU_Summary_Team_No.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/AEIOU_Summary_Team_No.docx
--------------------------------------------------------------------------------
/documentation/Business model canvas.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/Business model canvas.PNG
--------------------------------------------------------------------------------
/documentation/Final Project Report.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/Final Project Report.pdf
--------------------------------------------------------------------------------
/maps_images/ezgif.com-gif-maker.gif.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/maps_images/ezgif.com-gif-maker.gif.mp4
--------------------------------------------------------------------------------
/documentation/AEIOU_Summary_Team_No(1).docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/AEIOU_Summary_Team_No(1).docx
--------------------------------------------------------------------------------
/documentation/Final Project Report(1)(1).docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/Final Project Report(1)(1).docx
--------------------------------------------------------------------------------
/documentation/Final Project Report-final.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/Final Project Report-final.docx
--------------------------------------------------------------------------------
/documentation/Final Project Report-final.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/Final Project Report-final.pdf
--------------------------------------------------------------------------------
/documentation/Empathy Mapping canvas FINAL.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/Empathy Mapping canvas FINAL.docx
--------------------------------------------------------------------------------
/documentation/product development canvas FINAL.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Maunish-dave/Dynamic-Traffic-light-management-system/HEAD/documentation/product development canvas FINAL.docx
--------------------------------------------------------------------------------
/maps/nodes.nod.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/maps/edges.edg.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/configuration.sumocfg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/maps/tripinfo.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/trafficlight_2/trafficlight_2.ino:
--------------------------------------------------------------------------------
1 | int pin13 = 13;
2 | int pin12 = 12;
3 | int pin11 = 11;
4 |
5 | int pin10 = 10;
6 | int pin9 = 9;
7 | int pin8 = 8;
8 |
9 | int pin7 = 7;
10 | int pin6 = 6;
11 | int pin5 = 5;
12 |
13 | int pin4 = 4;
14 | int pin3 = 3;
15 | int pin2 = 2;
16 |
17 | int phase;
18 | int x;
19 | void setup() {
20 | pinMode(pin13, OUTPUT);
21 | pinMode(pin12, OUTPUT);
22 | pinMode(pin11, OUTPUT);
23 | pinMode(pin10, OUTPUT);
24 | pinMode(pin9, OUTPUT);
25 | pinMode(pin8, OUTPUT);
26 | pinMode(pin7, OUTPUT);
27 | pinMode(pin6, OUTPUT);
28 | pinMode(pin5, OUTPUT);
29 | pinMode(pin4, OUTPUT);
30 | pinMode(pin3, OUTPUT);
31 | pinMode(pin2, OUTPUT);
32 |
33 | Serial.begin(9600);
34 | Serial.setTimeout(1);
35 |
36 | }
37 |
38 | void loop() {
39 | while (!Serial.available());
40 | phase = Serial.readString().toInt();
41 | Serial.print(phase + 1);
42 |
43 |
44 | if (phase == 0){
45 | digitalWrite(pin13, HIGH);
46 | digitalWrite(pin10, HIGH);
47 | digitalWrite(pin7, HIGH);
48 | digitalWrite(pin2, HIGH);
49 |
50 | digitalWrite(pin11, LOW);
51 | digitalWrite(pin12, LOW);
52 | digitalWrite(pin9, LOW);
53 | digitalWrite(pin8, LOW);
54 | digitalWrite(pin6, LOW);
55 | digitalWrite(pin5, LOW);
56 | digitalWrite(pin3, LOW);
57 | digitalWrite(pin4, LOW);
58 | }
59 |
60 | if (phase == 2){
61 | digitalWrite(pin13, HIGH);
62 | digitalWrite(pin10, HIGH);
63 | digitalWrite(pin5, HIGH);
64 | digitalWrite(pin4, HIGH);
65 |
66 | digitalWrite(pin11, LOW);
67 | digitalWrite(pin12, LOW);
68 | digitalWrite(pin9, LOW);
69 | digitalWrite(pin8, LOW);
70 | digitalWrite(pin6, LOW);
71 | digitalWrite(pin7, LOW);
72 | digitalWrite(pin3, LOW);
73 | digitalWrite(pin2, LOW);
74 | }
75 |
76 | if (phase == 4){
77 | digitalWrite(pin11, HIGH);
78 | digitalWrite(pin10, HIGH);
79 | digitalWrite(pin7, HIGH);
80 | digitalWrite(pin4, HIGH);
81 |
82 | digitalWrite(pin13, LOW);
83 | digitalWrite(pin12, LOW);
84 | digitalWrite(pin9, LOW);
85 | digitalWrite(pin8, LOW);
86 | digitalWrite(pin6, LOW);
87 | digitalWrite(pin5, LOW);
88 | digitalWrite(pin3, LOW);
89 | digitalWrite(pin2, LOW);
90 | }
91 |
92 | if (phase == 6){
93 | digitalWrite(pin13, HIGH);
94 | digitalWrite(pin8, HIGH);
95 | digitalWrite(pin7, HIGH);
96 | digitalWrite(pin4, HIGH);
97 |
98 | digitalWrite(pin11, LOW);
99 | digitalWrite(pin12, LOW);
100 | digitalWrite(pin9, LOW);
101 | digitalWrite(pin10, LOW);
102 | digitalWrite(pin6, LOW);
103 | digitalWrite(pin5, LOW);
104 | digitalWrite(pin3, LOW);
105 | digitalWrite(pin2, LOW);
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/documentation/patent1.txt:
--------------------------------------------------------------------------------
1 | Google Patents
2 |
3 | keywords:
4 | traffic , prediction , system
5 |
6 | search string: traffic lights prediction system
7 |
8 | number of results : 5
9 | ----------------------------
10 | Environmental Science And Engineering
11 |
12 | Controlling traffic signals
13 |
14 | Ipc : G08G1/07
15 |
16 | Title: Traffic light prediction system
17 |
18 | Patent No. US 7,187,301 B2
19 |
20 | App No. 10/894,922
21 |
22 | weblink: https://patents.google.com/patent/US7187301B2/en?oq=traffic+lights#title
23 |
24 | Date of filing: 2004-07-20
25 |
26 | Name of Inventor: Guixian Lu
27 |
28 | Address of Inventor: Melrose Rd Pontiac MI US 48340
29 |
30 | Name of Applicant/Assignee: Guixian Lu
31 |
32 | Name of Applicant/Assignee: Melrose Rd Pontiac MI US 48340
33 |
34 | Application for patent is: individual
35 |
36 | ----------------------------------
37 |
38 | Limitation:The limitation to current technology is it only gives driver of the vehicle the information regarding the future traffic lights.
39 | but the system won't optimize itself and adapt to current traffic situation to reduce the traffic.
40 | Another limitation is to setup various different lights for different moving section which is not cost effective.
41 |
42 |
43 |
44 | Specific Problem solved by invention:primary objective of the present invention is to save fuel.
45 | other objective are to save fuel to maximize the usage of streets,
46 | and to reduce traffic accidents.
47 |
48 |
49 | Brief about invention:A traffic system that helps a driver to save gasoline by avoiding red light or by decelerating before a red light. It predicts the colors of a traffic light and informs about the future traffic light colors that will happen to a driver. The system comprising a sub-control system, three kinds of moving sections representing three future colors: green, yellow, and red. The positions of the moving sections are showed by indicators. The indicators are secured along one side of the street.
50 |
51 |
52 |
53 | Key learning points:The idea here is creative but the cost required to make this is not proportional to the cost it saves.
54 |
55 |
56 | Summary of invention:The primary objective of the present invention is to save fuel for vehicles and travel time. Other objectives are to reduce pollution from vehicles, to maximize the usage of the streets, and to reduce traffic accidents and traffic jams.
57 |
58 | The forgoing objectives are accomplished by defining moving sections on a street, moving towards the traffic light. Usually each kind of moving section represents one future color from the traffic light. Green sections will result in arriving to a green light. Red section will result in arriving to a red light. There are Indicators informing the drivers about the locations and colors of the moving sections. Some small lights, may act as Indicators. The drivers will know how to change the speed in order to shift from a red section to a green section.
59 |
60 |
61 |
62 | Number of claims:10
63 |
64 |
65 | Patent status:expired
66 |
67 |
68 | How much this invention is related with your IDP/UDP?
69 |
70 | Instead of using lights as indicator for the future traffic lights there should be a system which can broadcast signal directly to system in your car or phone. which will make this cost effective. Other than that it would be better if the system adapts to current traffic condition to reduce traffic jams and save waiting time on traffic lights.
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/maps/routes3.rou.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Dynamic-Traffic-light-management-system
2 | This repository contains files for the traffic light management system using Reinforcement Learning.
3 |
4 | ## Basic Idea
5 |
6 | 
7 |
8 | Suppose we have a city grid as shown above with 4 traffic light nodes.
9 | n1, n2, n3, and n4
10 |
11 | So, our model makes 4 decisions (one for each node) for which side to select for the green signal
12 |
13 | we have to select a minimum time (for ex 30s) that our model can not select a green light time below that limit.
14 |
15 | Our task is to minimize the amount of time vehicles have to wait on the traffic signal.
16 | The amount of waiting time for a given traffic signal is equal to the total car present on the signal x number of seconds.
17 | Each traffic signal will have 4 waiting time counter for each side of the road. So based on that our model will
18 | decide which side to select for the green signal.
19 |
20 | 
21 |
22 | ## Basic training process.
23 |
24 | We have trained our model on a number of events.
25 | Event is defined as a fixed motion where vehicles will pass through nodes in a fixed (pseudo-random manner).
26 | The reason for keeping the event fixed is that using a random event every time will give a random result.
27 | we will use many such fixed events to train our model so our model can handle different situations.
28 |
29 | The only input our model will receive is the number of vehicles present on 4 sides of each traffic node.
30 | and our model will output 4 sides one for each node.
31 |
32 | The number of nodes depends on the size of the grid.
33 |
34 | ## SUMO for siumlation
35 |
36 | We used SUMO open-source software to make maps and generate simulations to train our model.
37 |
38 | Here are examples of some of the maps used to train the model.
39 |
40 | ### Map1
41 | 
42 |
43 | ### Map2
44 | 
45 |
46 | ### Map 3
47 | 
48 |
49 | ### Epoch Vs Time for Map1
50 |
51 | 
52 |
53 | ### Epoch Vs Time for Map2
54 | 
55 |
56 | ### Epoch Vs Time for Map3
57 | 
58 |
59 | ## Simulation of Trained Model.
60 |
61 |
62 |
63 | https://user-images.githubusercontent.com/44360315/113673665-e8edd300-96d6-11eb-8fbe-d09e078fbfbe.mp4
64 |
65 |
66 |
67 | ## Arduino connection.
68 |
69 | We have connected our simulation with Arduino.
70 |
71 | ### Arduino1
72 |
73 |
74 | ### Arduino2
75 |
76 |
77 | ### Arduino3
78 |
79 |
80 | ## How to train new Networks.
81 |
82 | First Download or clone the repository.
83 | Then pip install requirements.txt using
84 |
85 | `pip install -r requirements.txt`
86 |
87 | you need to download SUMO GUI for running simulations.
88 |
89 | download sumo gui from [here](https://sumo.dlr.de/docs/Downloads.php)
90 |
91 | ### Step1: create network and route file
92 |
93 | Use SUMO netedit tool to create a network
94 | for example 'network.net.xml' and save it in the maps folder.
95 |
96 | cd into maps folder and run the following command
97 |
98 | `python randomTrips.py -n network.net.xml -r routes.rou.xml -e 500`
99 |
100 | This will create a routes.rou.xml file for 500 simulation steps for the network "network.net.xml"
101 |
102 | ### Step2: Set Configuration file.
103 |
104 | You need to provide network and route files to the Configuration file.
105 | change net-file and route-files in input.
106 |
107 | ``
108 | ``
109 | ``
110 | ``
111 |
112 | ### Step3: Train the model.
113 |
114 | Now use the train.py file to train a model for this network.
115 |
116 | `python train.py --train -e 50 -m model_name -s 500`
117 |
118 | This code will train the model for 50 epochs.
119 | -e is to set the epochs.
120 | -m for model_name which will be saved in the model folder.
121 | -s tells simulation to run for 500 steps.
122 | --train tells the train.py to train the model if not specified it will load model_name from the model's folder.
123 |
124 | At the end of the simulation, it will show time_vs_epoch graphs and save them to plots folder with name time_vs_epoch_{model_name}.png
125 |
126 | ### Step4: Running trained model.
127 |
128 | You can use train.py to run a pre-trained model on GUI.
129 |
130 | `python train.py -m model_name -s 500`
131 |
132 | This will open GUI which you can run to see how your model performs.
133 | To get accurate results set a value of -s the same for testing and training.
134 |
135 | ### Extra: Running Ardunio
136 | Currently, Arduino works only for a single crossroad.
137 | More than one cross road will return an error.
138 |
139 | For running Arduino for testing use --ard.
140 |
141 | `python train.py -m model_name -s 500 --ard`
142 |
--------------------------------------------------------------------------------
/maps/routes3.rou.alt.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 |
--------------------------------------------------------------------------------
/maps/outputs.out:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 |
--------------------------------------------------------------------------------
/train.py:
--------------------------------------------------------------------------------
1 | from __future__ import absolute_import
2 | from __future__ import print_function
3 |
4 | import os
5 | import sys
6 | import time
7 | import optparse
8 | import random
9 | import serial
10 | import numpy as np
11 | import torch
12 | import torch.optim as optim
13 | import torch.nn.functional as F
14 | import torch.nn as nn
15 | import matplotlib.pyplot as plt
16 |
17 | # we need to import python modules from the $SUMO_HOME/tools directory
18 | if "SUMO_HOME" in os.environ:
19 | tools = os.path.join(os.environ["SUMO_HOME"], "tools")
20 | sys.path.append(tools)
21 | else:
22 | sys.exit("please declare environment variable 'SUMO_HOME'")
23 |
24 | from sumolib import checkBinary # noqa
25 | import traci # noqa
26 |
27 | def get_vehicle_numbers(lanes):
28 | vehicle_per_lane = dict()
29 | for l in lanes:
30 | vehicle_per_lane[l] = 0
31 | for k in traci.lane.getLastStepVehicleIDs(l):
32 | if traci.vehicle.getLanePosition(k) > 10:
33 | vehicle_per_lane[l] += 1
34 | return vehicle_per_lane
35 |
36 |
37 | def get_waiting_time(lanes):
38 | waiting_time = 0
39 | for lane in lanes:
40 | waiting_time += traci.lane.getWaitingTime(lane)
41 | return waiting_time
42 |
43 |
44 | def phaseDuration(junction, phase_time, phase_state):
45 | traci.trafficlight.setRedYellowGreenState(junction, phase_state)
46 | traci.trafficlight.setPhaseDuration(junction, phase_time)
47 |
48 |
49 |
50 | class Model(nn.Module):
51 | def __init__(self, lr, input_dims, fc1_dims, fc2_dims, n_actions):
52 | super(Model, self).__init__()
53 | self.lr = lr
54 | self.input_dims = input_dims
55 | self.fc1_dims = fc1_dims
56 | self.fc2_dims = fc2_dims
57 | self.n_actions = n_actions
58 |
59 | self.linear1 = nn.Linear(self.input_dims, self.fc1_dims)
60 | self.linear2 = nn.Linear(self.fc1_dims, self.fc2_dims)
61 | self.linear3 = nn.Linear(self.fc2_dims, self.n_actions)
62 |
63 | self.optimizer = optim.Adam(self.parameters(), lr=self.lr)
64 | self.loss = nn.MSELoss()
65 | self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
66 | self.to(self.device)
67 |
68 | def forward(self, state):
69 | x = F.relu(self.linear1(state))
70 | x = F.relu(self.linear2(x))
71 | actions = self.linear3(x)
72 | return actions
73 |
74 |
75 | class Agent:
76 | def __init__(
77 | self,
78 | gamma,
79 | epsilon,
80 | lr,
81 | input_dims,
82 | fc1_dims,
83 | fc2_dims,
84 | batch_size,
85 | n_actions,
86 | junctions,
87 | max_memory_size=100000,
88 | epsilon_dec=5e-4,
89 | epsilon_end=0.05,
90 | ):
91 | self.gamma = gamma
92 | self.epsilon = epsilon
93 | self.lr = lr
94 | self.batch_size = batch_size
95 | self.input_dims = input_dims
96 | self.fc1_dims = fc1_dims
97 | self.fc2_dims = fc2_dims
98 | self.n_actions = n_actions
99 | self.action_space = [i for i in range(n_actions)]
100 | self.junctions = junctions
101 | self.max_mem = max_memory_size
102 | self.epsilon_dec = epsilon_dec
103 | self.epsilon_end = epsilon_end
104 | self.mem_cntr = 0
105 | self.iter_cntr = 0
106 | self.replace_target = 100
107 |
108 | self.Q_eval = Model(
109 | self.lr, self.input_dims, self.fc1_dims, self.fc2_dims, self.n_actions
110 | )
111 | self.memory = dict()
112 | for junction in junctions:
113 | self.memory[junction] = {
114 | "state_memory": np.zeros(
115 | (self.max_mem, self.input_dims), dtype=np.float32
116 | ),
117 | "new_state_memory": np.zeros(
118 | (self.max_mem, self.input_dims), dtype=np.float32
119 | ),
120 | "reward_memory":np.zeros(self.max_mem, dtype=np.float32),
121 | "action_memory": np.zeros(self.max_mem, dtype=np.int32),
122 | "terminal_memory": np.zeros(self.max_mem, dtype=np.bool),
123 | "mem_cntr": 0,
124 | "iter_cntr": 0,
125 | }
126 |
127 |
128 | def store_transition(self, state, state_, action,reward, done,junction):
129 | index = self.memory[junction]["mem_cntr"] % self.max_mem
130 | self.memory[junction]["state_memory"][index] = state
131 | self.memory[junction]["new_state_memory"][index] = state_
132 | self.memory[junction]['reward_memory'][index] = reward
133 | self.memory[junction]['terminal_memory'][index] = done
134 | self.memory[junction]["action_memory"][index] = action
135 | self.memory[junction]["mem_cntr"] += 1
136 |
137 | def choose_action(self, observation):
138 | state = torch.tensor([observation], dtype=torch.float).to(self.Q_eval.device)
139 | if np.random.random() > self.epsilon:
140 | actions = self.Q_eval.forward(state)
141 | action = torch.argmax(actions).item()
142 | else:
143 | action = np.random.choice(self.action_space)
144 | return action
145 |
146 | def reset(self,junction_numbers):
147 | for junction_number in junction_numbers:
148 | self.memory[junction_number]['mem_cntr'] = 0
149 |
150 | def save(self,model_name):
151 | torch.save(self.Q_eval.state_dict(),f'models/{model_name}.bin')
152 |
153 | def learn(self, junction):
154 | self.Q_eval.optimizer.zero_grad()
155 |
156 | batch= np.arange(self.memory[junction]['mem_cntr'], dtype=np.int32)
157 |
158 | state_batch = torch.tensor(self.memory[junction]["state_memory"][batch]).to(
159 | self.Q_eval.device
160 | )
161 | new_state_batch = torch.tensor(
162 | self.memory[junction]["new_state_memory"][batch]
163 | ).to(self.Q_eval.device)
164 | reward_batch = torch.tensor(
165 | self.memory[junction]['reward_memory'][batch]).to(self.Q_eval.device)
166 | terminal_batch = torch.tensor(self.memory[junction]['terminal_memory'][batch]).to(self.Q_eval.device)
167 | action_batch = self.memory[junction]["action_memory"][batch]
168 |
169 | q_eval = self.Q_eval.forward(state_batch)[batch, action_batch]
170 | q_next = self.Q_eval.forward(new_state_batch)
171 | q_next[terminal_batch] = 0.0
172 | q_target = reward_batch + self.gamma * torch.max(q_next, dim=1)[0]
173 | loss = self.Q_eval.loss(q_target, q_eval).to(self.Q_eval.device)
174 |
175 | loss.backward()
176 | self.Q_eval.optimizer.step()
177 |
178 | self.iter_cntr += 1
179 | self.epsilon = (
180 | self.epsilon - self.epsilon_dec
181 | if self.epsilon > self.epsilon_end
182 | else self.epsilon_end
183 | )
184 |
185 |
186 | def run(train=True,model_name="model",epochs=50,steps=500,ard=False):
187 | if ard:
188 | arduino = serial.Serial(port='COM4', baudrate=9600, timeout=.1)
189 | def write_read(x):
190 | arduino.write(bytes(x, 'utf-8'))
191 | time.sleep(0.05)
192 | data = arduino.readline()
193 | return data
194 | """execute the TraCI control loop"""
195 | epochs = epochs
196 | steps = steps
197 | best_time = np.inf
198 | total_time_list = list()
199 | traci.start(
200 | [checkBinary("sumo"), "-c", "configuration.sumocfg", "--tripinfo-output", "maps/tripinfo.xml"]
201 | )
202 | all_junctions = traci.trafficlight.getIDList()
203 | junction_numbers = list(range(len(all_junctions)))
204 |
205 | brain = Agent(
206 | gamma=0.99,
207 | epsilon=0.0,
208 | lr=0.1,
209 | input_dims=4,
210 | # input_dims = len(all_junctions) * 4,
211 | fc1_dims=256,
212 | fc2_dims=256,
213 | batch_size=1024,
214 | n_actions=4,
215 | junctions=junction_numbers,
216 | )
217 |
218 | if not train:
219 | brain.Q_eval.load_state_dict(torch.load(f'models/{model_name}.bin',map_location=brain.Q_eval.device))
220 |
221 | print(brain.Q_eval.device)
222 | traci.close()
223 | for e in range(epochs):
224 | if train:
225 | traci.start(
226 | [checkBinary("sumo"), "-c", "configuration.sumocfg", "--tripinfo-output", "tripinfo.xml"]
227 | )
228 | else:
229 | traci.start(
230 | [checkBinary("sumo-gui"), "-c", "configuration.sumocfg", "--tripinfo-output", "tripinfo.xml"]
231 | )
232 |
233 | print(f"epoch: {e}")
234 | select_lane = [
235 | ["yyyrrrrrrrrr", "GGGrrrrrrrrr"],
236 | ["rrryyyrrrrrr", "rrrGGGrrrrrr"],
237 | ["rrrrrryyyrrr", "rrrrrrGGGrrr"],
238 | ["rrrrrrrrryyy", "rrrrrrrrrGGG"],
239 | ]
240 |
241 | # select_lane = [
242 | # ["yyyyrrrrrrrrrrrr", "GGGGrrrrrrrrrrrr"],
243 | # ["rrrryyyyrrrrrrrr", "rrrrGGGGrrrrrrrr"],
244 | # ["rrrrrrrryyyyrrrr", "rrrrrrrrGGGGrrrr"],
245 | # ["rrrrrrrrrrrryyyy", "rrrrrrrrrrrrGGGG"],
246 | # ]
247 |
248 | step = 0
249 | total_time = 0
250 | min_duration = 5
251 |
252 | traffic_lights_time = dict()
253 | prev_wait_time = dict()
254 | prev_vehicles_per_lane = dict()
255 | prev_action = dict()
256 | all_lanes = list()
257 |
258 | for junction_number, junction in enumerate(all_junctions):
259 | prev_wait_time[junction] = 0
260 | prev_action[junction_number] = 0
261 | traffic_lights_time[junction] = 0
262 | prev_vehicles_per_lane[junction_number] = [0] * 4
263 | # prev_vehicles_per_lane[junction_number] = [0] * (len(all_junctions) * 4)
264 | all_lanes.extend(list(traci.trafficlight.getControlledLanes(junction)))
265 |
266 | while step <= steps:
267 | traci.simulationStep()
268 | for junction_number, junction in enumerate(all_junctions):
269 | controled_lanes = traci.trafficlight.getControlledLanes(junction)
270 | waiting_time = get_waiting_time(controled_lanes)
271 | total_time += waiting_time
272 | if traffic_lights_time[junction] == 0:
273 | vehicles_per_lane = get_vehicle_numbers(controled_lanes)
274 | # vehicles_per_lane = get_vehicle_numbers(all_lanes)
275 |
276 | #storing previous state and current state
277 | reward = -1 * waiting_time
278 | state_ = list(vehicles_per_lane.values())
279 | state = prev_vehicles_per_lane[junction_number]
280 | prev_vehicles_per_lane[junction_number] = state_
281 | brain.store_transition(state, state_, prev_action[junction_number],reward,(step==steps),junction_number)
282 |
283 | #selecting new action based on current state
284 | lane = brain.choose_action(state_)
285 | prev_action[junction_number] = lane
286 | phaseDuration(junction, 6, select_lane[lane][0])
287 | phaseDuration(junction, min_duration + 10, select_lane[lane][1])
288 |
289 | if ard:
290 | ph = str(traci.trafficlight.getPhase("0"))
291 | value = write_read(ph)
292 |
293 | traffic_lights_time[junction] = min_duration + 10
294 | if train:
295 | brain.learn(junction_number)
296 | else:
297 | traffic_lights_time[junction] -= 1
298 | step += 1
299 | print("total_time",total_time)
300 | total_time_list.append(total_time)
301 |
302 | if total_time < best_time:
303 | best_time = total_time
304 | if train:
305 | brain.save(model_name)
306 |
307 | traci.close()
308 | sys.stdout.flush()
309 | if not train:
310 | break
311 | if train:
312 | plt.plot(list(range(len(total_time_list))),total_time_list)
313 | plt.xlabel("epochs")
314 | plt.ylabel("total time")
315 | plt.savefig(f'plots/time_vs_epoch_{model_name}.png')
316 | plt.show()
317 |
318 | def get_options():
319 | optParser = optparse.OptionParser()
320 | optParser.add_option(
321 | "-m",
322 | dest='model_name',
323 | type='string',
324 | default="model",
325 | help="name of model",
326 | )
327 | optParser.add_option(
328 | "--train",
329 | action = 'store_true',
330 | default=False,
331 | help="training or testing",
332 | )
333 | optParser.add_option(
334 | "-e",
335 | dest='epochs',
336 | type='int',
337 | default=50,
338 | help="Number of epochs",
339 | )
340 | optParser.add_option(
341 | "-s",
342 | dest='steps',
343 | type='int',
344 | default=500,
345 | help="Number of steps",
346 | )
347 | optParser.add_option(
348 | "--ard",
349 | action='store_true',
350 | default=False,
351 | help="Connect Arduino",
352 | )
353 | options, args = optParser.parse_args()
354 | return options
355 |
356 |
357 | # this is the main entry point of this script
358 | if __name__ == "__main__":
359 | options = get_options()
360 | model_name = options.model_name
361 | train = options.train
362 | epochs = options.epochs
363 | steps = options.steps
364 | ard = options.ard
365 | run(train=train,model_name=model_name,epochs=epochs,steps=steps,ard=ard)
366 |
--------------------------------------------------------------------------------
/maps/city2.rou.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 |
--------------------------------------------------------------------------------
/maps/network.net.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 |
--------------------------------------------------------------------------------
/maps/city3.rou.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
578 |
579 |
580 |
581 |
--------------------------------------------------------------------------------
/maps/city2.rou.alt.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
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 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
508 |
509 |
510 |
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 |
531 |
532 |
533 |
534 |
535 |
536 |
537 |
538 |
539 |
540 |
541 |
542 |
543 |
544 |
545 |
546 |
547 |
548 |
549 |
550 |
551 |
552 |
553 |
554 |
555 |
556 |
557 |
558 |
559 |
560 |
561 |
562 |
563 |
564 |
565 |
566 |
567 |
568 |
569 |
570 |
571 |
572 |
573 |
574 |
575 |
576 |
577 |
--------------------------------------------------------------------------------
/maps/randomTrips.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 | # Copyright (C) 2010-2020 German Aerospace Center (DLR) and others.
4 | # This program and the accompanying materials are made available under the
5 | # terms of the Eclipse Public License 2.0 which is available at
6 | # https://www.eclipse.org/legal/epl-2.0/
7 | # This Source Code may also be made available under the following Secondary
8 | # Licenses when the conditions for such availability set forth in the Eclipse
9 | # Public License 2.0 are satisfied: GNU General Public License, version 2
10 | # or later which is available at
11 | # https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 | # SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 |
14 | # @file randomTrips.py
15 | # @author Daniel Krajzewicz
16 | # @author Jakob Erdmann
17 | # @author Michael Behrisch
18 | # @date 2010-03-06
19 |
20 |
21 | from __future__ import print_function
22 | from __future__ import absolute_import
23 | import os
24 | import sys
25 | import random
26 | import bisect
27 | import subprocess
28 | from collections import defaultdict
29 | import math
30 | import optparse
31 |
32 | if 'SUMO_HOME' in os.environ:
33 | sys.path.append(os.path.join(os.environ['SUMO_HOME'], 'tools'))
34 | import sumolib # noqa
35 | from sumolib.miscutils import euclidean # noqa
36 | from sumolib.geomhelper import naviDegree, minAngleDegreeDiff # noqa
37 |
38 | DUAROUTER = sumolib.checkBinary('duarouter')
39 |
40 | SOURCE_SUFFIX = ".src.xml"
41 | SINK_SUFFIX = ".dst.xml"
42 | VIA_SUFFIX = ".via.xml"
43 |
44 |
45 | def get_options(args=None):
46 | optParser = optparse.OptionParser()
47 | optParser.add_option("-n", "--net-file", dest="netfile",
48 | help="define the net file (mandatory)")
49 | optParser.add_option("-a", "--additional-files", dest="additional",
50 | help="define additional files to be loaded by the router")
51 | optParser.add_option("-o", "--output-trip-file", dest="tripfile",
52 | default="trips.trips.xml", help="define the output trip filename")
53 | optParser.add_option("-r", "--route-file", dest="routefile",
54 | help="generates route file with duarouter")
55 | optParser.add_option("--vtype-output", dest="vtypeout",
56 | help="Store generated vehicle types in a separate file")
57 | optParser.add_option("--weights-prefix", dest="weightsprefix",
58 | help="loads probabilities for being source, destination and via-edge from the files named " +
59 | ".src.xml, .sink.xml and .via.xml")
60 | optParser.add_option("--weights-output-prefix", dest="weights_outprefix",
61 | help="generates weights files for visualisation")
62 | optParser.add_option("--pedestrians", action="store_true",
63 | default=False, help="create a person file with pedestrian trips instead of vehicle trips")
64 | optParser.add_option("--persontrips", action="store_true",
65 | default=False, help="create a person file with person trips instead of vehicle trips")
66 | optParser.add_option("--personrides", help="create a person file with rides using STR as lines attribute")
67 | optParser.add_option("--persontrip.transfer.car-walk", dest="carWalkMode",
68 | help="Where are mode changes from car to walking allowed " +
69 | "(possible values: 'ptStops', 'allJunctions' and combinations)")
70 | optParser.add_option("--persontrip.walkfactor", dest="walkfactor",
71 | help="Use FLOAT as a factor on pedestrian maximum speed during intermodal routing")
72 | optParser.add_option("--prefix", dest="tripprefix",
73 | default="", help="prefix for the trip ids")
74 | optParser.add_option("-t", "--trip-attributes", dest="tripattrs",
75 | default="", help="additional trip attributes. When generating pedestrians, attributes for " +
76 | " and are supported.")
77 | optParser.add_option("--fringe-start-attributes", dest="fringeattrs",
78 | default="", help="additional trip attributes when starting on a fringe.")
79 | optParser.add_option("-b", "--begin", default=0, help="begin time")
80 | optParser.add_option("-e", "--end", default=3600, help="end time (default 3600)")
81 | optParser.add_option(
82 | "-p", "--period", type="float", default=1, help="Generate vehicles with equidistant departure times and " +
83 | "period=FLOAT (default 1.0). If option --binomial is used, the expected arrival rate is set to 1/period.")
84 | optParser.add_option("-s", "--seed", type="int", default=42, help="random seed")
85 | optParser.add_option("--random", action="store_true",
86 | default=False, help="use a random seed to initialize the random number generator")
87 | optParser.add_option("-l", "--length", action="store_true",
88 | default=False, help="weight edge probability by length")
89 | optParser.add_option("-L", "--lanes", action="store_true",
90 | default=False, help="weight edge probability by number of lanes")
91 | optParser.add_option("--edge-param", dest="edgeParam",
92 | help="use the given edge parameter as factor for edge")
93 | optParser.add_option("--speed-exponent", type="float", dest="speed_exponent",
94 | default=0.0, help="weight edge probability by speed^ (default 0)")
95 | optParser.add_option("--angle", type="float", dest="angle",
96 | default=90.0, help="weight edge probability by angle [0-360] relative to the network center")
97 | optParser.add_option("--angle-factor", type="float", dest="angle_weight",
98 | default=1.0, help="maximum weight factor for angle")
99 | optParser.add_option("--fringe-factor", type="float", dest="fringe_factor",
100 | default=1.0, help="multiply weight of fringe edges by (default 1")
101 | optParser.add_option("--fringe-threshold", type="float", dest="fringe_threshold",
102 | default=0.0, help="only consider edges with speed above as fringe edges (default 0)")
103 | optParser.add_option("--allow-fringe", dest="allow_fringe", action="store_true",
104 | default=False, help="Allow departing on edges that leave the network and arriving on edges " +
105 | "that enter the network (via turnarounds or as 1-edge trips")
106 | optParser.add_option("--allow-fringe.min-length", type="float", dest="allow_fringe_min_length",
107 | help="Allow departing on edges that leave the network and arriving on edges " +
108 | "that enter the network, if they have at least the given length")
109 | optParser.add_option("--min-distance", type="float", dest="min_distance",
110 | default=0.0, help="require start and end edges for each trip to be at least m apart")
111 | optParser.add_option("--max-distance", type="float", dest="max_distance",
112 | default=None, help="require start and end edges for each trip to be at most m " +
113 | "apart (default 0 which disables any checks)")
114 | optParser.add_option("-i", "--intermediate", type="int",
115 | default=0, help="generates the given number of intermediate way points")
116 | optParser.add_option("--flows", type="int",
117 | default=0, help="generates INT flows that together output vehicles with the specified period")
118 | optParser.add_option("--jtrrouter", action="store_true",
119 | default=False, help="Create flows without destination as input for jtrrouter")
120 | optParser.add_option("--maxtries", type="int",
121 | default=100, help="number of attemps for finding a trip which meets the distance constraints")
122 | optParser.add_option("--binomial", type="int", metavar="N",
123 | help="If this is set, the number of departures per seconds will be drawn from a binomial " +
124 | "distribution with n=N and p=PERIOD/N where PERIOD is the argument given to " +
125 | "option --period. Tnumber of attemps for finding a trip which meets the distance constraints")
126 | optParser.add_option(
127 | "-c", "--vclass", "--edge-permission", default="passenger",
128 | help="only from and to edges which permit the given vehicle class")
129 | optParser.add_option(
130 | "--vehicle-class", help="The vehicle class assigned to the generated trips (adds a standard vType definition " +
131 | "to the output file).")
132 | optParser.add_option("--remove-loops", dest="remove_loops", action="store_true",
133 | default=False, help="Remove loops at route start and end")
134 | optParser.add_option("--junction-taz", dest="junctionTaz", action="store_true",
135 | default=False, help="Write trips with fromJunction and toJunction")
136 | optParser.add_option("--via-edge-types", dest="viaEdgeTypes",
137 | help="Set list of edge types that cannot be used for departure or arrival " +
138 | "(unless being on the fringe)")
139 | optParser.add_option("--validate", default=False, action="store_true",
140 | help="Whether to produce trip output that is already checked for connectivity")
141 | optParser.add_option("-v", "--verbose", action="store_true",
142 | default=False, help="tell me what you are doing")
143 | (options, args) = optParser.parse_args(args=args)
144 | if not options.netfile:
145 | optParser.print_help()
146 | sys.exit(1)
147 |
148 | if options.persontrips or options.personrides:
149 | options.pedestrians = True
150 |
151 | if options.pedestrians:
152 | options.vclass = 'pedestrian'
153 | if options.flows > 0:
154 | print("Error: Person flows are not supported yet", file=sys.stderr)
155 | sys.exit(1)
156 |
157 | if options.validate and options.routefile is None:
158 | options.routefile = "routes.rou.xml"
159 |
160 | if options.period <= 0:
161 | print("Error: Period must be positive", file=sys.stderr)
162 | sys.exit(1)
163 |
164 | if options.jtrrouter and options.flows <= 0:
165 | print("Error: Option --jtrrouter must be used with option --flows", file=sys.stderr)
166 | sys.exit(1)
167 |
168 | if options.vehicle_class:
169 | if options.tripprefix:
170 | options.vtypeID = "%s_%s" % (options.tripprefix, options.vehicle_class)
171 | else:
172 | options.vtypeID = options.vehicle_class
173 |
174 | if 'type=' in options.tripattrs:
175 | print("Error: trip-attribute 'type' cannot be used together with option --vehicle-class", file=sys.stderr)
176 | sys.exit(1)
177 |
178 | if options.viaEdgeTypes:
179 | options.viaEdgeTypes = options.viaEdgeTypes.split(',')
180 |
181 | return options
182 |
183 |
184 | class InvalidGenerator(Exception):
185 | pass
186 |
187 | # assigns a weight to each edge using weight_fun and then draws from a discrete
188 | # distribution with these weights
189 |
190 |
191 | class RandomEdgeGenerator:
192 |
193 | def __init__(self, net, weight_fun):
194 | self.net = net
195 | self.weight_fun = weight_fun
196 | self.cumulative_weights = []
197 | self.total_weight = 0
198 | for edge in self.net._edges:
199 | # print edge.getID(), weight_fun(edge)
200 | self.total_weight += weight_fun(edge)
201 | self.cumulative_weights.append(self.total_weight)
202 | if self.total_weight == 0:
203 | raise InvalidGenerator()
204 |
205 | def get(self):
206 | r = random.random() * self.total_weight
207 | index = bisect.bisect(self.cumulative_weights, r)
208 | return self.net._edges[index]
209 |
210 | def write_weights(self, fname, interval_id, begin, end):
211 | # normalize to [0,100]
212 | normalizer = 100.0 / max(1, max(map(self.weight_fun, self.net._edges)))
213 | weights = [(self.weight_fun(e) * normalizer, e.getID()) for e in self.net.getEdges()]
214 | weights.sort(reverse=True)
215 | with open(fname, 'w+') as f:
216 | f.write('\n')
217 | f.write(' \n' % (
218 | interval_id, begin, end))
219 | for weight, edgeID in weights:
220 | f.write(' \n' %
221 | (edgeID, weight))
222 | f.write(' \n')
223 | f.write('\n')
224 |
225 |
226 | class RandomTripGenerator:
227 |
228 | def __init__(self, source_generator, sink_generator, via_generator, intermediate, pedestrians):
229 | self.source_generator = source_generator
230 | self.sink_generator = sink_generator
231 | self.via_generator = via_generator
232 | self.intermediate = intermediate
233 | self.pedestrians = pedestrians
234 |
235 | def get_trip(self, min_distance, max_distance, maxtries=100, junctionTaz=False):
236 | for _ in range(maxtries):
237 | source_edge = self.source_generator.get()
238 | intermediate = [self.via_generator.get()
239 | for i in range(self.intermediate)]
240 | sink_edge = self.sink_generator.get()
241 | if self.pedestrians:
242 | destCoord = sink_edge.getFromNode().getCoord()
243 | else:
244 | destCoord = sink_edge.getToNode().getCoord()
245 |
246 | coords = ([source_edge.getFromNode().getCoord()] +
247 | [e.getFromNode().getCoord() for e in intermediate] +
248 | [destCoord])
249 | distance = sum([euclidean(p, q)
250 | for p, q in zip(coords[:-1], coords[1:])])
251 | if (distance >= min_distance
252 | and (not junctionTaz or source_edge.getFromNode() != sink_edge.getToNode())
253 | and (max_distance is None or distance < max_distance)):
254 | return source_edge, sink_edge, intermediate
255 | raise Exception("no trip found after %s tries" % maxtries)
256 |
257 |
258 | def get_prob_fun(options, fringe_bonus, fringe_forbidden, max_length):
259 | # fringe_bonus None generates intermediate way points
260 | def edge_probability(edge):
261 | if options.vclass and not edge.allows(options.vclass):
262 | return 0 # not allowed
263 | if fringe_bonus is None and edge.is_fringe() and not options.pedestrians:
264 | return 0 # not suitable as intermediate way point
265 | if (fringe_forbidden is not None and edge.is_fringe(getattr(edge, fringe_forbidden)) and
266 | not options.pedestrians and
267 | (options.allow_fringe_min_length is None or edge.getLength() < options.allow_fringe_min_length)):
268 | return 0 # the wrong kind of fringe
269 | if (fringe_bonus is not None and options.viaEdgeTypes is not None and not edge.is_fringe() and
270 | edge.getType() in options.viaEdgeTypes):
271 | return 0 # the wrong type of edge (only allows depart and arrival on the fringe)
272 | prob = 1
273 | if options.length:
274 | if options.fringe_factor != 1.0 and fringe_bonus is not None and edge.is_fringe():
275 | # short fringe edges should not suffer a penalty
276 | prob *= max_length
277 | else:
278 | prob *= edge.getLength()
279 | if options.lanes:
280 | prob *= edge.getLaneNumber()
281 | prob *= (edge.getSpeed() ** options.speed_exponent)
282 | if (options.fringe_factor != 1.0 and
283 | not options.pedestrians and
284 | fringe_bonus is not None and
285 | edge.getSpeed() > options.fringe_threshold and
286 | edge.is_fringe(getattr(edge, fringe_bonus))):
287 | prob *= options.fringe_factor
288 | if options.edgeParam is not None:
289 | prob *= float(edge.getParam(options.edgeParam, 1.0))
290 | if options.angle_weight != 1.0 and fringe_bonus is not None:
291 | xmin, ymin, xmax, ymax = edge.getBoundingBox()
292 | ex, ey = ((xmin + xmax) / 2, (ymin + ymax) / 2)
293 | nx, ny = options.angle_center
294 | edgeAngle = naviDegree(math.atan2(ey - ny, ex - nx))
295 | angleDiff = minAngleDegreeDiff(options.angle, edgeAngle)
296 | # print("e=%s nc=%s ec=%s ea=%s a=%s ad=%s" % (
297 | # edge.getID(), options.angle_center, (ex,ey), edgeAngle,
298 | # options.angle, angleDiff))
299 | # relDist = 2 * euclidean((ex, ey), options.angle_center) / max(xmax - xmin, ymax - ymin)
300 | # prob *= (relDist * (options.angle_weight - 1) + 1)
301 | if fringe_bonus == "_incoming":
302 | # source edge
303 | prob *= (angleDiff * (options.angle_weight - 1) + 1)
304 | else:
305 | prob *= ((180 - angleDiff) * (options.angle_weight - 1) + 1)
306 |
307 | return prob
308 | return edge_probability
309 |
310 |
311 | class LoadedProps:
312 |
313 | def __init__(self, fname):
314 | self.weights = defaultdict(lambda: 0)
315 | for edge in sumolib.output.parse_fast(fname, 'edge', ['id', 'value']):
316 | self.weights[edge.id] = float(edge.value)
317 |
318 | def __call__(self, edge):
319 | return self.weights[edge.getID()]
320 |
321 |
322 | def buildTripGenerator(net, options):
323 | try:
324 | max_length = 0
325 | for edge in net.getEdges():
326 | if not edge.is_fringe():
327 | max_length = max(max_length, edge.getLength())
328 | forbidden_source_fringe = None if options.allow_fringe else "_outgoing"
329 | forbidden_sink_fringe = None if options.allow_fringe else "_incoming"
330 | source_generator = RandomEdgeGenerator(
331 | net, get_prob_fun(options, "_incoming", forbidden_source_fringe, max_length))
332 | sink_generator = RandomEdgeGenerator(
333 | net, get_prob_fun(options, "_outgoing", forbidden_sink_fringe, max_length))
334 | if options.weightsprefix:
335 | if os.path.isfile(options.weightsprefix + SOURCE_SUFFIX):
336 | source_generator = RandomEdgeGenerator(
337 | net, LoadedProps(options.weightsprefix + SOURCE_SUFFIX))
338 | if os.path.isfile(options.weightsprefix + SINK_SUFFIX):
339 | sink_generator = RandomEdgeGenerator(
340 | net, LoadedProps(options.weightsprefix + SINK_SUFFIX))
341 | except InvalidGenerator:
342 | print("Error: no valid edges for generating source or destination. Try using option --allow-fringe",
343 | file=sys.stderr)
344 | return None
345 |
346 | try:
347 | via_generator = RandomEdgeGenerator(
348 | net, get_prob_fun(options, None, None, 1))
349 | if options.weightsprefix and os.path.isfile(options.weightsprefix + VIA_SUFFIX):
350 | via_generator = RandomEdgeGenerator(
351 | net, LoadedProps(options.weightsprefix + VIA_SUFFIX))
352 | except InvalidGenerator:
353 | if options.intermediate > 0:
354 | print(
355 | "Error: no valid edges for generating intermediate points", file=sys.stderr)
356 | return None
357 | else:
358 | via_generator = None
359 |
360 | return RandomTripGenerator(
361 | source_generator, sink_generator, via_generator, options.intermediate, options.pedestrians)
362 |
363 |
364 | def is_walk_attribute(attr):
365 | for cand in ['arrivalPos', 'speed=', 'duration=', 'busStop=']:
366 | if cand in attr:
367 | return True
368 | return False
369 |
370 |
371 | def is_persontrip_attribute(attr):
372 | for cand in ['vTypes', 'modes']:
373 | if cand in attr:
374 | return True
375 | return False
376 |
377 |
378 | def is_person_attribute(attr):
379 | for cand in ['departPos', 'type']:
380 | if cand in attr:
381 | return True
382 | return False
383 |
384 |
385 | def is_vehicle_attribute(attr):
386 | for cand in ['depart', 'arrival', 'line', 'Number', 'type']:
387 | if cand in attr:
388 | return True
389 | return False
390 |
391 |
392 | def split_trip_attributes(tripattrs, pedestrians, hasType):
393 | # handle attribute values with a space
394 | # assume that no attribute value includes an '=' sign
395 | allattrs = []
396 | for a in tripattrs.split():
397 | if "=" in a:
398 | allattrs.append(a)
399 | else:
400 | if len(allattrs) == 0:
401 | print("Warning: invalid trip-attribute '%s'" % a)
402 | else:
403 | allattrs[-1] += ' ' + a
404 |
405 | # figure out which of the tripattrs belong to the or ,
406 | # which belong to the and which belong to the or
407 | vehicleattrs = []
408 | personattrs = []
409 | vtypeattrs = []
410 | otherattrs = []
411 | for a in allattrs:
412 | if pedestrians:
413 | if is_walk_attribute(a) or is_persontrip_attribute(a):
414 | otherattrs.append(a)
415 | elif is_person_attribute(a):
416 | personattrs.append(a)
417 | else:
418 | vtypeattrs.append(a)
419 | else:
420 | if is_vehicle_attribute(a):
421 | vehicleattrs.append(a)
422 | else:
423 | vtypeattrs.append(a)
424 |
425 | if not hasType:
426 | if pedestrians:
427 | personattrs += vtypeattrs
428 | else:
429 | vehicleattrs += vtypeattrs
430 | vtypeattrs = []
431 |
432 | return (prependSpace(' '.join(vtypeattrs)),
433 | prependSpace(' '.join(vehicleattrs)),
434 | prependSpace(' '.join(personattrs)),
435 | prependSpace(' '.join(otherattrs)))
436 |
437 |
438 | def prependSpace(s):
439 | if len(s) == 0 or s[0] == " ":
440 | return s
441 | else:
442 | return " " + s
443 |
444 |
445 | def main(options):
446 | if not options.random:
447 | random.seed(options.seed)
448 |
449 | net = sumolib.net.readNet(options.netfile)
450 | if options.min_distance > net.getBBoxDiameter() * (options.intermediate + 1):
451 | options.intermediate = int(
452 | math.ceil(options.min_distance / net.getBBoxDiameter())) - 1
453 | print(("Warning: setting number of intermediate waypoints to %s to achieve a minimum trip length of " +
454 | "%s in a network with diameter %.2f.") % (
455 | options.intermediate, options.min_distance, net.getBBoxDiameter()))
456 |
457 | if options.angle_weight != 1:
458 | xmin, ymin, xmax, ymax = net.getBoundary()
459 | options.angle_center = (xmin + xmax) / 2, (ymin + ymax) / 2
460 |
461 | trip_generator = buildTripGenerator(net, options)
462 | idx = 0
463 |
464 | vtypeattrs, options.tripattrs, personattrs, otherattrs = split_trip_attributes(
465 | options.tripattrs, options.pedestrians, options.vehicle_class)
466 |
467 | vias = {}
468 |
469 | def generate_one(idx):
470 | label = "%s%s" % (options.tripprefix, idx)
471 | try:
472 | source_edge, sink_edge, intermediate = trip_generator.get_trip(
473 | options.min_distance, options.max_distance, options.maxtries,
474 | options.junctionTaz)
475 | combined_attrs = options.tripattrs
476 | if options.fringeattrs and source_edge.is_fringe(source_edge._incoming):
477 | combined_attrs += " " + options.fringeattrs
478 | if options.junctionTaz:
479 | attrFrom = ' fromJunction="%s"' % source_edge.getFromNode().getID()
480 | attrTo = ' toJunction="%s"' % sink_edge.getToNode().getID()
481 | else:
482 | attrFrom = ' from="%s"' % source_edge.getID()
483 | attrTo = ' to="%s"' % sink_edge.getID()
484 | via = ""
485 | if len(intermediate) > 0:
486 | via = ' via="%s" ' % ' '.join(
487 | [e.getID() for e in intermediate])
488 | if options.validate:
489 | vias[label] = via
490 | if options.pedestrians:
491 | fouttrips.write(
492 | ' \n' % (label, depart, personattrs))
493 | if options.persontrips:
494 | fouttrips.write(
495 | ' \n' % (attrFrom, attrTo, otherattrs))
496 | elif options.personrides:
497 | fouttrips.write(
498 | ' \n' % (
499 | source_edge.getID(), sink_edge.getID(), options.personrides, otherattrs))
500 | else:
501 | fouttrips.write(
502 | ' \n' % (attrFrom, attrTo, otherattrs))
503 | fouttrips.write(' \n')
504 | else:
505 | if options.jtrrouter:
506 | attrTo = ''
507 | combined_attrs = attrFrom + attrTo + via + combined_attrs
508 | if options.flows > 0:
509 | if options.binomial:
510 | for j in range(options.binomial):
511 | fouttrips.write((' \n') % (
512 | label, j, options.begin, options.end, 1.0 / options.period / options.binomial,
513 | combined_attrs))
514 | else:
515 | fouttrips.write((' \n') % (
516 | label, options.begin, options.end, options.period * options.flows, combined_attrs))
517 | else:
518 | fouttrips.write(' \n' % (
519 | label, depart, combined_attrs))
520 | except Exception as exc:
521 | print(exc, file=sys.stderr)
522 | return idx + 1
523 |
524 | with open(options.tripfile, 'w') as fouttrips:
525 | sumolib.writeXMLHeader(fouttrips, "$Id$", "routes") # noqa
526 | if options.vehicle_class:
527 | vTypeDef = ' \n' % (
528 | options.vtypeID, options.vehicle_class, vtypeattrs)
529 | if options.vtypeout:
530 | # ensure that trip output does not contain types, file may be
531 | # overwritten by later call to duarouter
532 | if options.additional is None:
533 | options.additional = options.vtypeout
534 | else:
535 | options.additional += ",options.vtypeout"
536 | with open(options.vtypeout, 'w') as fouttype:
537 | sumolib.writeXMLHeader(fouttype, "$Id$", "additional") # noqa
538 | fouttype.write(vTypeDef)
539 | fouttype.write("\n")
540 | else:
541 | fouttrips.write(vTypeDef)
542 | options.tripattrs += ' type="%s"' % options.vtypeID
543 | personattrs += ' type="%s"' % options.vtypeID
544 | depart = sumolib.miscutils.parseTime(options.begin)
545 | maxTime = sumolib.miscutils.parseTime(options.end)
546 | if trip_generator:
547 | if options.flows == 0:
548 | while depart < maxTime:
549 | if options.binomial is None:
550 | # generate with constant spacing
551 | idx = generate_one(idx)
552 | depart += options.period
553 | else:
554 | # draw n times from a Bernoulli distribution
555 | # for an average arrival rate of 1 / period
556 | prob = 1.0 / options.period / options.binomial
557 | for _ in range(options.binomial):
558 | if random.random() < prob:
559 | idx = generate_one(idx)
560 | depart += 1
561 | else:
562 | for _ in range(options.flows):
563 | idx = generate_one(idx)
564 |
565 | fouttrips.write("\n")
566 |
567 | # call duarouter for routes or validated trips
568 | args = [DUAROUTER, '-n', options.netfile, '-r', options.tripfile, '--ignore-errors',
569 | '--begin', str(options.begin), '--end', str(options.end), '--no-step-log']
570 | if options.additional is not None:
571 | args += ['--additional-files', options.additional]
572 | if options.carWalkMode is not None:
573 | args += ['--persontrip.transfer.car-walk', options.carWalkMode]
574 | if options.walkfactor is not None:
575 | args += ['--persontrip.walkfactor', options.walkfactor]
576 | if options.remove_loops:
577 | args += ['--remove-loops']
578 | if options.vtypeout is not None:
579 | args += ['--vtype-output', options.vtypeout]
580 | if options.junctionTaz:
581 | args += ['--junction-taz']
582 | if not options.verbose:
583 | args += ['--no-warnings']
584 | else:
585 | args += ['-v']
586 |
587 | if options.routefile:
588 | args2 = args + ['-o', options.routefile]
589 | print("calling", " ".join(args2))
590 | sys.stdout.flush()
591 | subprocess.call(args2)
592 | sys.stdout.flush()
593 |
594 | if options.validate:
595 | # write to temporary file because the input is read incrementally
596 | tmpTrips = options.tripfile + ".tmp"
597 | args2 = args + ['-o', tmpTrips, '--write-trips']
598 | if options.junctionTaz:
599 | args2 += ['--write-trips.junctions']
600 | print("calling", " ".join(args2))
601 | sys.stdout.flush()
602 | subprocess.call(args2)
603 | sys.stdout.flush()
604 | os.remove(options.tripfile) # on windows, rename does not overwrite
605 | os.rename(tmpTrips, options.tripfile)
606 |
607 | if options.weights_outprefix:
608 | idPrefix = ""
609 | if options.tripprefix:
610 | idPrefix = options.tripprefix + "."
611 | trip_generator.source_generator.write_weights(
612 | options.weights_outprefix + SOURCE_SUFFIX,
613 | idPrefix + "src", options.begin, options.end)
614 | trip_generator.sink_generator.write_weights(
615 | options.weights_outprefix + SINK_SUFFIX,
616 | idPrefix + "dst", options.begin, options.end)
617 | if trip_generator.via_generator:
618 | trip_generator.via_generator.write_weights(
619 | options.weights_outprefix + VIA_SUFFIX,
620 | idPrefix + "via", options.begin, options.end)
621 |
622 | # return wether trips could be generated as requested
623 | return trip_generator is not None
624 |
625 |
626 | if __name__ == "__main__":
627 | if not main(get_options()):
628 | sys.exit(1)
629 |
--------------------------------------------------------------------------------
/maps/trips.trips.xml:
--------------------------------------------------------------------------------
1 |
2 |
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 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
441 |
442 |
443 |
444 |
445 |
446 |
447 |
448 |
449 |
450 |
451 |
452 |
453 |
454 |
455 |
456 |
457 |
458 |
459 |
460 |
461 |
462 |
463 |
464 |
465 |
466 |
467 |
468 |
469 |
470 |
471 |
472 |
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 |
481 |
482 |
483 |
484 |
485 |
486 |
487 |
488 |
489 |
490 |
491 |
492 |
493 |
494 |
495 |
496 |
497 |
498 |
499 |
500 |
501 |
502 |
503 |
504 |
505 |
506 |
507 |
--------------------------------------------------------------------------------