Smart Traffic Lights Supercomputing Challenge Final Report April 6, 2016 Team #81 Mountain Elementary Team Members: Titus de Jong Kyle Kenamond Marek Jablonski Team Mentors Mack Kenamond Bernard de Jong David Jablonski
Executive Summary: There is a problem with our current traffic lights. They force people to stop at traffic lights when they don t need to. This wastes fuel, time, and increases pollution. We believe that this problem can easily be solved using Smart traffic lights. We first created a simple single intersection simulation on a simple programming website called Scratch with two car going from top to bottom or left to right and vise versa and a traffic light at the intersection. We programmed two types of traffic lights to simulate the time wasted at the traffic light while the car was sitting at the light stationary. One was based on a timer and one was human controlled. This showed that a smart traffic light could be better. We decided that scratch was too limited so we decided to start using Python for our simulation. Our Python program consisted of towns defined by lines and points where lines are roads and points are intersections. Each road has an assigned speed limit. Cars/Vehicles know where they are going or what roads they are supposed to follow. Several towns were tested and the car would successfully drive through the town. Unfortunately, we ran out of time and had to stop. Both the Scratch and Python programs were tested. The Scratch program was verified, but we did not think that it was very valid for actual traffic simulation. The Python program was verified but without traffic lights, it can not be validated. Problem Statement: Standard traffic lights are based on a timer which forces vehicles to stop when they do not need to; stopping wastes time and fuel and increases pollution. It also increases risks of accident because stopping for no reason may lead to people running red lights and having a car crash. Methodology: To solve this we could create Smart traffic lights that used modern technology to detect oncoming vehicles and would know which light to change from green to red and vice versa. This should decrease fuel consumption along with pollution. It should also decrease accidents and other law related problems.
Scratch: We started with a simple programming website named Scratch. It is an agents based programming language where the agents are called sprites. Sprites are characters or things that the programmer can implement into his/her program giving the viewer a visual representation of the program. The programmer is able to control each sprite using the commands provided. In our program we used two car sprites and a traffic light sprite. Scratch also provides a background or stage. We made our stage look like an intersection. Our intersection is shown below. Car Sprites: When programming our car sprites we needed the cars to move and stop. They also needed to know when to stop (at red light) and when they could move (away from traffic light or when the light is green). To simulate a person getting angry while waiting at red light we implemented a variable called Anger and when Anger was large enough the car sprite would complain. We also added a variable called Stop_Time which measured the amount of time that all car sprites were waiting at the traffic light. This allowed us to compare how long the cars waited at each traffic light type. The flowchart for this program is shown below.
. Traffic Light Sprite: We have two types of traffic lights: one is based on a timer, the other is human controlled or smart (depending on the human). Smart traffic light: When the spacebar is pressed, the light switches. The flowchart for this program is shown below.
Standard Traffic Light: The standard traffic light is based on a timer, so all it needs to do is switch the light whenever the timer reaches a set amount. The flowchart for this program is shown below.
The Scratch program worked but was too simple to be realistic. We decided to move on to a more realistic program in Python. Python: We used a Python module called Turtle which we used to draw our town and to represent the cars. Town: The town consists of lines and endpoints where the lines are roads and the endpoints are intersections. Points are defined using a list of (x.y) coordinates. Roads are defined using lists of start and endpoints. Also, each road is assigned a speed limit. After the town was defined we created a turtle object called Builder to build (draw) our town. The Builder followed each road from start to end point therefore drawing the town. Each car (Turtle object) had a certain Route which is the list of roads that the Car must follow. A list of route directions was also required. This defines each direction of all roads in the cars route (either forward or backward). The car's position is defined by its current road R and its parametric coordinate u along road R. The parametric coordinate varies between 0 at the beginning of the road and 1 at the end of the road. Therefore u indicates how far along the road the car is. Because we wanted to figure out how traffic changes over time our simulator relies on a time loop. Within a cycle of our time loop the state of the simulation must be updated, evolving from its state at the start of the cycle, at time t, to its state at the end of the cycle, at time t + Δt, where Δ t is the time step size for the cycle. For example: cars must update their locations and traffic lights must determine if they have to change their light or not. Before the time loop begins, the simulation must be initialized. This included: defining the town, drawing the town, and defining cars route information. In addition, the cars starting road in its route must be specified. Finally the simulation time was set to t = 0. With the simulation initialized, the time loop could begin. The car's location at the beginning of the cycle is defined by R 0 and u 0.The code must update the car s location at the end of the cycle ( R 1 and u 1 must be computed). If the car stays on the same road the following equation can be used to compute u 1 : u 1 = u 0 + s 0 Δt/L 0
Where s 0 is the speed limit of road R 0 and L 0 is the length of road R 0. Road lengths are calculated using: L = (x 2 x ) 2 1 + ( y ) 2 2 y 1 Where ( x 1, y 1 ) and ( x 2, y 2 ) are the coordinates of the road s end points. If u 1 < 1 then the car is still on the same road at the end of the cycle. Therefore, R 1 = R 0. In this case, the new car location ( R 1 and u 1 ) is now known.. If u 1 > 1 then the car is off of the current road and on next road in its Route. The car s Route list provides R 1. Because the car is no longer on the same road, the previous u 1 equation is not valid, instead u 1 is calculated using a different equation: u 1 = s 1 (Δt [ L 0 (1 u 0 )]/s 0 )/L 1 Where s 1 is the speed limit of the new road ( R 1 ) and L 1 is its length. Using the logic above, the location of the car at the end of the cycle is now known whether it stays on the same road or moves to the next road in its Route. In order for the car to move its turtle, the car s and R 1 data: ( x, y) coordinates have to be calculated from its u 1 x = u 1 x 2 + ( 1 u 1 )x 1 y = u 1 y 2 + ( 1 u 1 )y 1 Where ( x 1, y 1 ) and ( x 2, y 2 ) are the coordinates of the end points of R 1. After updating the turtle position, the update of all car data for the cycle is complete. In order to prepare for the next cycle all end values values ( u 0 R 0 ) in preparation for the next cycle: ( u 1 R 1 ) must be changed back to original R 0 = R 1 u 0 = u 1 Also, the simulation time must be increased by desired total simulation time, the time loop is terminated. Δ t. If the simulation time is larger than the Unfortunately, we did not have enough time to do more with this program. :(
Verification and Validation : To test if our Scratch program was working we ran it. It did what it was supposed to do. Thus when a car stopped, anger started to increase until hitting a critical level where it would complain. The cars stopped when and where they were supposed to stop and moved when they were supposed to move. The smart traffic light switched color when the space bar was pressed. The standard traffic light switched color at regular intervals. To test our Python program we picked a problem which we knew the answer to. Then we tested the program to see if it got the same answer. We built a rectangular town with the first road with a length of 160 ft long with a speed limit of 10 ft per second. The second road 100ft long with a speed limit of 5. The third road 160 ft long with a speed limit of 10. The last and fourth 100ft long with a speed limit of 20. The formula Time = distance/speed was used to calculate the time to get around the town. For this test case our answer should be 57 seconds. We ran this test case in our program and we got the expected answer. We varied the timestep size and still got the same answer. Results: For our Scratch project we tested the two different types of traffic lights, smart (human controlled) and standard (timer based). In both cases we ran the experiment for one minute and measured how long the cars had to wait. The following table shows the results. We then compared how long each car had to wait at the traffic light with a standard traffic light as compared to a human controlled traffic lights. Two of our team members took a turn controlling the traffic light. We then compared the amount of time that the cars were waiting between the smart and standard tests. Table 1: Scratch Results for Standard and Smart traffic lights, indicating that the smart traffic light reduces the travel time by at least halve. Total time vehicle stopped Test # Standard Smart operator 1 Smart operator 2 1 1492 266 624 2 1538 205 647 3 1464 183 568
Our Python Results for two different towns, are shown in the figures below. The lines are roads the black dot is the car. Both cars started at (0,0) which is at the left bottom corner. The cars would follow their Routes correctly. Because we only got car motion in our program, we weren t able to compare anything with traffic lights. The cars would follow their routes around the town and different towns could be defined. Conclusions: We didn t finish our Python objective of constructing a town with running cars and traffic lights. We did make a manually operated smart traffic light using scratch. Comparing the timed difference between a smart traffic light and a regular one shows the substantial promise in fuel consumption of smart traffic lights by halving the waiting times. We did this for two cars only so we expect these results to be modified with increased traffic. We have constructed a town with multiple intersections and a car moving along an assigned trajectory using Python. Moving to more cars and completing the town with inclusion of the traffic lights will be the future step in this project. Software: The Python source code is: import turtle
from math import sqrt def RoadLength(RoadEnds,PointCoords,Road): point1=roadends[road][0] point2=roadends[road][1] x1=pointcoords[point1][0] y1=pointcoords[point1][1] x2=pointcoords[point2][0] y2=pointcoords[point2][1] Length=sqrt((x2 x1)**2+(y2 y1)**2) return Length def CarCoords(RoadEnds,PointCoords,Road,u): point1=roadends[road][0] point2=roadends[road][1] x1=pointcoords[point1][0] y1=pointcoords[point1][1] x2=pointcoords[point2][0] y2=pointcoords[point2][1] x=x1*(1.0 u)+x2*u y=y1*(1.0 u)+y2*u return x,y print "Staring program..." # # Define town. # Intersections are just points. # Roads are line segments between intersections or between points. # PointCoords=[[0.0,0.0],[100.0,0.0],[100.0,150.0],[0.0,100.0],[150.0,50.0]] RoadEnds=[[2,3],[3,0],[0,1],[1,2],[1,4],[4,2],[3,1],[1,3]] RoadSpeed=[10.0,2.5,3.0,5.0,4.0,3.0,7.0,10.0] # # Build (draw) the town. # Create a turtle that will draw the town. # Loop over roads and draw each one. # To draw a road: # Raise the builder turtle's pen # Go to start of road # Lower the build turtle's pen # Go to end of road # print CarCoords(RoadEnds,PointCoords,0,0.5) builder=turtle.turtle() numroads = len(roadspeed) builder.hideturtle() for Road in range(numroads): builder.penup() point1=roadends[road][0]
point2=roadends[road][1] x1=pointcoords[point1][0] y1=pointcoords[point1][1] x2=pointcoords[point2][0] y2=pointcoords[point2][1] builder.goto(x1,y1) builder.pendown() builder.goto(x2,y2) # # Define car. # Need route (list of roads that tells how the car goes around the town). # Need route road directions/orientation (forward vs backward along each road). # Need starting u value (how far the car is along the starting road). # Need to set which route command the car starts with. # Get the number of roads along the car's route # Get the starting (x,y) for the car # Get the first road in the route # Move the car to its starting location # car = turtle.turtle() car.shape("circle") Route=[2,3,0,1,2,4,5,0,6,7,6] RouteDir=[1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0] u_start = 0.5 routecommand = 0 numcommands=len(route) u0=u_start R0=Route[routeCommand] dir0=routedir[routecommand] coords=[0.0,0.0] coords=carcoords(roadends,pointcoords,r0,u0) x=coords[0] y=coords[1] car.penup() car.goto(x,y) # # Initial conditions for time loop. # T=0 # time step size: dt # Number of cycles in time loop. # Termination time. # t=0.0 dt=1.0 maxcycle=1000 stoptime=60.0 # # Initialize car's u0 value to starting value. # coords=carcoords(roadends,pointcoords,0,0.5)
print coords # # Start the time loop (start the simulation) # for n in range(maxcycle): L0=RoadLength(RoadEnds,PointCoords,R0) s0=roadspeed[r0] u1=u0+s0*dt/l0 if u1>1.0: routecommand = routecommand+1 if routecommand > numcommands 1: break R1=Route[routeCommand] dir1=routedir[routecommand] s1=roadspeed[r1] L1=RoadLength(RoadEnds,PointCoords,R1) u1=s1*(dt (L0*(1.0 u0))/s0)/l1 else: R1=R0 s1=s0 L1=L0 dir1=dir0 coords=carcoords(roadends,pointcoords,r1,u1) x=coords[0] y=coords[1] car.goto(x,y) u0=u1 s0=s1 L0=L1 dir0=dir1 R0=R1 t=t+dt print "time=",t," road=",r1," u=",u1 print "Program finished!"
The Scratch source is below (from screen captures):
Achievements: In this project we learned about how to program in Python and how to work efficiently and cooperatively with each other. We also learned how to insert different ideas that were originally in our Python program into our scratch program. We could readily achieve this using our flowcharts which are easily translated due to scratch s simple programming language. Acknowledgements: We would like to thank Mrs. Zeynep Unal for supporting us and providing a meeting room for us to discuss our program and presentations. We would also like to thank her for being so flexible with our team s meeting times.
Our team would also like to thank our wonderful mentors, first and foremost Mack Kenamond who proposed the task and was crucial in its implementation. Bernard de Jong, and David Jablonski helping us reach our goals and taught us new skills that will be important later on in life. Some of these skills include: Programming in Python, working well together, including everyone in activities, and creating presentations. We would also like to thank all of those who helped us, made suggestions, and encouraged us to do more. References: https://www.python.org/ http://dirtbags.net/python/ https://scratch.mit.edu/ https://en.wikipedia.org/wiki/traffic_simulation http://www.latimes.com/business/autos/la fi hy ihs automotive average age car 20140609 story.html https://www.fhwa.dot.gov/ohim/onh00/bar8.htm http://askville.amazon.com/miles average car gallon gas/answerviewer.do?requestid=410121 http://fuelgaugereport.aaa.com/average u s gas prices may remain low this winter/ https://docs.python.org/2/library/turtle.html