Lesson 10: Traffic Simulation. Mandatory Assignment 5.1 och 5.2.
Part: | Object-oriented design and implementation. Simulation. Programming with multiple classes. |
Estimated workload: | 10 hours |
Examination: | Oral examination for a teacher/assistant in two steps according to the information on this page. |
Preparation
Create a folder dedicated to this lesson with the name lesson10
.
Download the following files into the created folder:
Files to download | |
---|---|
simulation.py |
Contains a main -function with a time step-loop that drives the simulation.
|
wallclock.py |
Contains a globally accessible clock that keeps track of the simulation time. |
vehicleGenerator.py |
Creates vehicles with varying intensity. This class is complete as given and shall not be modified. |
vehicle.py |
Code skeleton for the Vehicle class. To be filled with code. |
light.py |
Code skeleton for the Light class. To be filled with code. |
lane.py |
Code skeleton for the Lane clsas. To be filled with code. |
trafficSystem.py |
Code skeleton for the class representing a traffic system with lanes and lights. To be filled with code. |
Simulations
A major use-case for computers are simulations, i.e. the creation of a computer model of some process of interest. This can be a weather model, climate model, related to how heaps of snow form around different buildings, how the traffic flows through a street network, or a world of turtles that are born, eat, live and die.
The idea of the model is that you should be able to make predictions about what would happen if one makes a change to various parameters (releasing more carbon-dioxide into the atmosphere, changing the shape of the building, build a round-about or supply more food to the turtles ...)
It tends to be considerably cheaper to experiment with a computer model than to make changes in the real world (build one or more different round-abouts) or to do it with physical models (build model houses and blow potato flour on them through a wind tunnel).
When you build models, you must typically simplify and ignore many details that you don't beleve will have any (or at least very small) effect.
One way to do simulations is to subdivide time in a number of discrete time steps. You start from an initial state and step one step at the time and make note of what happes at each time step:
Sometimes you can know exactly what happens at every time step, but most often you have to resort to approximations. In addition there may also be an element of randomness that you need to approximate with some probability distribution. As an example, you rarely know exactly at which times a vehicle will arrive at a round-about but you may have measured an intensity so that you have a probability of a vehicle arriving at a given time step.
Problem Description
The program should simulate the traffic flow of several different types of traffic systems.
Example 1
A street with one street light:
Example 2
A street with one turning lane and two lights:
Example 3
Crossroads:
The crossroads are controlled by the four traffic lights s1, s2, s3 och s4.
A problem with these types of crossroads are that vehicles that arrive from E
and wants to turn left towards S
in the crossroads are blocked by vehicles that arrive from W
which in turn block vehicles that want to drive straight ahead.
Example 4
To solve the problem, the municipality are considering the construction of turning lanes for vehicles that arrive from E
and W
respectively, and who are taking a left turn in the crossroads, i.e. they want the following design:

This crossroads has turning lanes controlled by the signals s2 and s5.
Computer model
You will construct a traffic system model from two generic components: traffic lights (the class Light
) and lanes (the class Lane
). It will also contain a varying number of vehicle objects (the class Vehicle
). In addition, the class Simulation
is used to run the simulation and the class VehicleGenerator
is used to generate new vehicles in the system.
The class Vehicle
See for a discussion and specification.
The class Light
Ett trafikljus kan ha två lägen: "grönt" som tillåter passage och "rött" som förbjuder passage. Se diskussion och specifikation av klassen.
The class Lane
A lane is a structure that contains a number of vehicles and a number of empty spaces. The vehicles can only enter at the beginning of the lane, and leave at the end of the lane. It acts like a pipe:

The class TrafficSystem
The class TrafficSystem
defines a specific traffic system, i.e. it keeps track of which lanes and traffic lights that are included and how the vehicles move through the system.
To represent the system in example 1, you need two lanes and one light:


See a discription of the class !
The module simulation
The module simulation
only contains a main
-function that handles the time stepping which was described in the introduction:
create the components
time = 0
while True
time = time + 1
update all components
present the state
|
tf = TrafficSystem()
time = 0
while True
time = time + 1
tf.step()
tf.print()
|
Relevant functionality of the |
The class also provides a globally accessible clock through the class method getTime()
. It may be used by the constructor for the Vehicle
class and by the method isGreen()
in the class Light
.
Klassen VehicleGenerator
This class is used to generate new vehicles with varying intensity and destination. The class is given and does not require any modification.
Each call to the method step()
returns either a vehicle or None
.
The first system
You will simulate the system in example 1:
i.e. a system with two lanes and a traffic light.
Suitable workflow
-
Download the Python-files if you have not already done so.
The program (
simulation
) can be run immediately even if does not produce anything interesting as is. -
The class
Vehicle
can, until further notice, be used as provided but remember that it must be modified later on. -
Implement the methods in the class
Lane
. Write amain
function in the file that shows that the methods work. See the description! -
Update the class
TrafficSystem
:- Add instance variables for a lane and and a vehicle generator.
-
Create the lane and the vehicle generator. You can directly select the length of the lane (e.g. 10) and use the parameter-free constructor for the vehicle generator.
(Du don't need to use the predefined instance variables for lane lengths and light parameters - these are meant for the second system.) -
Write the
print
method. It only needs to print what the lane's__str__
method returns. -
Write the step-method so that it starts by extracting the first vehicle from the lane, followed by stepping the lane with its
step
method and finally call the vehicle generator'sstep
method. If the generator gives a new vehicle, it should be inserted into the lane. - Test your code! Now you should see vehicles gliding through the lane.
-
Implement the class
Light
according to the description. Read the specification so that you see exactly what its__str__
method is supposed to return. -
Update
TrafficSystem
with a traffic light and one additional lane, i.e. add these as instance variables and update the constructor and theprint
method.The sequence in the
step
method now becomes:- Step the new lane
- If the signal is green and there is a vehicle at the forward end of the old lane, it should be moved from the old to the new lane.
- Step the old lane
-
If the vehicle generator's
step
method gives a vehicle, it should be inserted into the old lane.
Note that the order of this sequence is important. It may be more elegant if you starts with stepping the light since you see that it is green before any vehicle is allowed to pass.
Now a problem has been introduced: The entry point of the old lane may not be free when we want to insert a vehicle there. Since we are not allowed to lose vehicles, we organize a queue with the help of one more instance variable
queue
. The queue should also be printed by theprint
method. The simplest way is th use the list's__str__
method.Hint: The code becomes simple if you always place incoming vehicles in the queue, and then pop the first vehicle in the queue when the queue is non-empty and the last position in the lane is free. Make sure that you don't store
None
in the queue. -
Even if it is not required for the first part, it is suitable to review the class
Vehicle
. You need to update the construct andget
, as well as__str__
. You also need to make sure that__str__
method inLane
uses theVehicle
class's__str__
method orgetDestination
method. This will be required to solve part 2 of this assignment. - Present your work!
The second system
You will now implement the system in example 2:
The traffic system should consist of three lanes (lane
, lane_west
och
lane_south
) and the lights light_west
och light_south
(earlier called s1 and s2):

It can be elegant to have short lanes after the lights so that you can see how the vehicles pass the lights.
At the position E
, there is a queue (not drawn).
Instance variables for lane lengths and light periods are predfined in the code skeleton. Use these!
At a time step may one or more of the following things happen:
- a vehicle passes a light (if it is green),
- a vehicle advances a step in a lane (if the position in front is free),
-
a vehicle immediately ahead
X
(i.e. in position0
of the lanelane
) moves tolane_west
orlane_south
depending on its destination (W
orS
), -
a vehicle arrives to the system at the position
E
and is placed in the queue, -
if the last position in
lane
is free and there is one ore more vehicles in the queue, the one at the front of the queue is removed from the queue and is inserted at the back-end oflane
, - one or both of the lights change color.
A simulation consists of a time step where the above-mentioned events happen. It is good that these events, just as in reality, are done in the order in which they are listed above.
Note that the classes Lane
and Light
will not need to change further - only TrafficSystem
needs to be modified.
Input to a simulation
The program is controlled by the following input
-
arrival intensity, i.e. the probability that a vehicle arrives at
E
at a given time step, -
the probability that a created vehicle will turn, i.e. it has
S
as destination, - the lengths of the lanes and
- the characteristics of the lights (period and green period).
The first two values varies with time. This is managed by the class VehicleGenerator
.
This class is given and you only need to understand how it is used, not how it works internally.
For the last two items, lengths of the lanes and characteristics of the lights, there are predefined and initialized variables in TrafficSystem
:
Lane
and Light
objects!
The result of a program execution
-
Initial printout of the simulation parameters through
printSetup
. Example:Simulation parameters: lane_length : 11 lanews_length : 8 light_period : 14 south_green : 4 west_green : 6 -
Statistics containing:
-
Average, minimal och maximal time (number of time steps) for vehicles to pass the lights
light_west
andlight_south
respectively. -
The number of time steps that the splitting-point
X
has been blocked. Blocked, means that it is impossible to move a vehicle fromlane
because the last position in the destination lane is occupied. -
The number of time steps that there have been vehicles in the queue at the entry point
E
.
Gather the times for vehicles leaving the system in two lists, one for each exit, and use these to obtain the statistics. Use either your own module with statistics functions or the standard-module
statistics
The statistics should be printed out by the method
print_statistics
inTrafficSystem
. The method should be callable at any time during the simulation. Example output:Statistics after 100 timesteps Created vehicles: 48 In system : 7 At exit West South Vehicles out: 22 19 Minimal time: 19 20 Maximal time: 37 52 Mean time : 26.3 38.3 Median time : 26.0 42.0 Blocked : 17.0% Queue : 10.0% -
Average, minimal och maximal time (number of time steps) for vehicles to pass the lights
-
A simple snapshot of the system at a given time step. Example:
(G) [..W...W.] [S..WS.W.S.S] <> (R) [...S..S.]Both lights are green, there are vehicles distributed over the lanes, and there is no queue.
This output should be produced by
print
that is called every time step bySimulation
.Example snapshots of the system for a number of time steps:
(G) [.....W..] [SWWSWSSSWSW] <> (R) [SSSSS.SS] (R) [....W...] [WWSWSSSWSWW] <> (R) [SSSSSSSS] (R) [...W...W] [WSWSSSWSWWS] <> (R) [SSSSSSSS] (R) [..W...WW] [SWSSSWSWWSW] <> (R) [SSSSSSSS] (R) [.W...WW.]*[SWSSSWSWWSW] < ('W', 23)> (R) [SSSSSSSS] (R) [W...WW..]*[SWSSSWSWWSW] < ('W', 23)> (R) [SSSSSSSS] (R) [W..WW...]*[SWSSSWSWWSW] < ('W', 23) ('S', 25)> (R) [SSSSSSSS]The last three time steps, the division point is blocked (*
character) and in addition there is at first one and then two vehicles in the queue.
Before you present!
- Make sure that the code follows the style rules!
- Make sure that all requested statistics are included and that the results are correct!
-
Make sure that the method
print
produces outputs according to the example above.