Traffic Scheduler
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
WHAT IS IT?
This section could give a general understanding of what the model is trying to show or explain.
HOW IT WORKS
This section could explain what rules the agents use to create the overall behavior of the model.
HOW TO USE IT
This section could explain how to use the model, including a description of each of the items in the interface tab.
THINGS TO NOTICE
This section could give some ideas of things for the user to notice while running the model.
THINGS TO TRY
This section could give some ideas of things for the user to try to do (move sliders, switches, etc.) with the model.
EXTENDING THE MODEL
This section could give some ideas of things to add or change in the procedures tab to make the model more complicated, detailed, accurate, etc.
NETLOGO FEATURES
This section could point out any especially interesting or unusual features of NetLogo that the model makes use of, particularly in the Procedures tab. It might also point out places where workarounds were needed because of missing features.
RELATED MODELS
This section could give the names of models in the NetLogo Models Library or elsewhere which are of related interest.
CREDITS AND REFERENCES
This section could contain a reference to the model's URL on the web if it has one, as well as any other necessary credits or references.
Comments and Questions
breed [cars car] breed [trains train] breed [walkers walker] breed [traffic-lights traffic-light] ;; direction is one of 0, 90, 180, 270 cars-own [speed acceleration direction turning-left? turning-right? truck? emergency-vehicle? start-time] trains-own [speed direction] walkers-own [orig-speed speed direction student? start-time] patches-own [ intersection? sidewalk? crosswalk? track? sensor1? sensor2? sensor3? sensor4? from change-marker ] globals [ log-id gen-freq max-speed car-length truck-length road-color sidewalk-color lane-divider-color crosswalk-color track-underlay-color rail-color tie-color round-robin-state round-robin-last tick-count-last num-accidents-cars num-accidents-pedestrians max-wait-time-cars max-wait-time-pedestrians min-wait-time-cars min-wait-time-pedestrians total-wait-time-cars total-wait-time-pedestrians total-cars total-pedestrians ] to setup clear-all setup-globals setup-patches setup-agents setup-traffic-lights plot-data end to setup-globals set log-id 0 set gen-freq 10 set max-speed 2 set car-length 10 set truck-length 20 set road-color 3 ;; dark gray set lane-divider-color 46 ;; light yellow set sidewalk-color 8 ;; light gray set crosswalk-color 9.5 ;; off-white set track-underlay-color 38 ;; light-brown set rail-color 2 ;; steel gray set tie-color 33 ;; brown set round-robin-state 2 set round-robin-last "EW" set tick-count-last 0 set num-accidents-cars 0 set num-accidents-pedestrians 0 set max-wait-time-cars 0 set max-wait-time-pedestrians 0 set min-wait-time-cars 0 set min-wait-time-pedestrians 0 set total-wait-time-cars 0 set total-wait-time-pedestrians 0 set total-cars 0 set total-pedestrians 0 end to setup-patches ask patches [ set pcolor green set intersection? false set track? false set sensor1? false set sensor2? false set sensor3? false set sensor4? false set change-marker 0 ;; road if (pycor >= -10 and pycor <= 10) or (pxcor >= -10 and pxcor <= 10) [ set pcolor road-color ] ;; interesection if (pycor >= -10 and pycor <= 10) and (pxcor >= -10 and pxcor <= 10) [ set intersection? true set pcolor road-color ] ;; sidewalk if ((pxcor > 10 and pxcor <= 15) and (pycor < -10 or pycor > 10)) or ((pxcor < -10 and pxcor >= -15) and (pycor < -10 or pycor > 10)) or ((pycor > 10 and pycor <= 15) and (pxcor < -10 or pxcor > 10)) or ((pycor < -10 and pycor >= -15) and (pxcor < -10 or pxcor > 10)) [ set sidewalk? true set pcolor sidewalk-color ] ;; crosswalk if ((pxcor > 10 and pxcor <= 15) and (pycor >= -10 and pycor <= 10)) or ((pxcor < -10 and pxcor >= -15) and (pycor >= -10 and pycor <= 10)) or ((pycor > 10 and pycor <= 15) and (pxcor >= -10 and pxcor <= 10)) or ((pycor < -10 and pycor >= -15) and (pxcor >= -10 and pxcor <= 10)) [ set crosswalk? true ] ;; crosswalk lines if ((pxcor = 11 or pxcor = 15) and (pycor >= -10 and pycor <= 10)) or ((pxcor = -11 or pxcor = -15) and (pycor >= -10 and pycor <= 10)) or ((pycor = 11 or pycor = 15) and (pxcor >= -10 and pxcor <= 10)) or ((pycor = -11 or pycor = -15) and (pxcor >= -10 and pxcor <= 10)) [ set pcolor crosswalk-color ] ;; sensors if (pxcor < -15 and pxcor >= -20) and (pycor < 0 and pycor >= -10) [set sensor1? true set from 90 if show-sensors? [set pcolor 135]] ;;pink if (pxcor < 0 and pxcor >= -10) and (pycor > 15 and pycor <= 20) [set sensor1? true set from 180 if show-sensors? [set pcolor 135]] ;;pink if (pxcor > 15 and pxcor <= 20) and (pycor > 0 and pycor <= 10) [set sensor1? true set from 270 if show-sensors? [set pcolor 135]] ;;pink if (pxcor > 0 and pxcor <= 10) and (pycor < -15 and pycor >= -20) [set sensor1? true set from 0 if show-sensors? [set pcolor 135]] ;;pink if (pxcor < -10 and pxcor >= -15) and (pycor > 10 and pycor <= 15) [set sensor2? true set from 180 if show-sensors? [set pcolor 49]] ;; yellow if (pxcor < -10 and pxcor >= -15) and (pycor < -10 and pycor >= -15) [set sensor2? true set from 90 if show-sensors? [set pcolor 49]] ;; yellow if (pxcor > 10 and pxcor <= 15) and (pycor < -10 and pycor >= -15) [set sensor2? true set from 0 if show-sensors? [set pcolor 49]] ;; yellow if (pxcor > 10 and pxcor <= 15) and (pycor > 10 and pycor <= 15) [set sensor2? true set from 270 if show-sensors? [set pcolor 49]] ;; yellow if (pxcor < -55 and pxcor >= -60) and (pycor < 0 and pycor >= -10) [set sensor3? true set from 90 if show-sensors? [set pcolor 117]] ;;purple if (pxcor < 0 and pxcor >= -10) and (pycor > 55 and pycor <= 60) [set sensor3? true set from 180 if show-sensors? [set pcolor 117]] ;;purple if (pxcor > 55 and pxcor <= 60) and (pycor > 0 and pycor <= 10) [set sensor3? true set from 270 if show-sensors? [set pcolor 117]] ;;purple if (pxcor > 0 and pxcor <= 10) and (pycor < -55 and pycor >= -60) [set sensor3? true set from 0 if show-sensors? [set pcolor 117]] ;;purple if (pxcor > 0 and pxcor <= 15) and (pycor < 60 and pycor >= 55) [set sensor4? true if show-sensors? [set pcolor 68]] ;;green if (pxcor < 0 and pxcor >= -15) and (pycor > 70 and pycor <= 75) [set sensor4? true if show-sensors? [set pcolor 68]] ;;green ;; train tracks if (pycor > 60 and pycor <= 70) [ set track? true set pcolor track-underlay-color ] ;; train rails if (pycor >= 60 and pycor <= 61) or (pycor <= 70 and pycor >= 69) [ set pcolor rail-color ] ] ;; lane-dividers (do this for the entire patch set, not each patch) paint-stripes 15 0 1 0 max-pxcor 1 lane-divider-color 5 paint-stripes -15 0 -1 0 min-pxcor 1 lane-divider-color 5 paint-stripes 0 15 0 1 1 max-pycor lane-divider-color 5 paint-stripes 0 -15 0 -1 1 min-pycor lane-divider-color 5 ;; ties (do this for the entire patch set, not each patch) let index min-pxcor let width 2 let len 9 let step 5 while [index <= max-pxcor] [ let w 0 while [w < width] [ let l 0 while [l < len and (index + w <= max-pxcor)] [ ask patch (index + w) (61 + l) [set pcolor tie-color] set l (l + 1) ] set w (w + 1) ] set index (index + step) ] end to paint-stripes [x-start y-start x-incr y-incr x-max y-max col len] let on? true let patch-count 0 let x x-start let y y-start while [abs x <= abs x-max and abs y <= abs y-max] [ if patch-count mod len = 0 [set on? (not on?)] ask patch x y [ if on? [set pcolor col] ] set x (x + x-incr) set y (y + y-incr) set patch-count (patch-count + 1) ] end to setup-agents ;; cars set-default-shape cars "car" ;; walkers set-default-shape walkers "person" ;; train set-default-shape trains "train" end to setup-traffic-lights foreach [0 180] [set-car-light ? red] ;; "NS" foreach [90 270] [set-car-light ? green] ;; "EW" foreach [0 90 180 270] [set-walker-light ? red] ;; "ped" end to set-car-light [dir col] ask patches with [sensor1? = true and from = dir] [set pcolor col set change-marker ticks] end to set-walker-light [dir col] ask patches with [sensor2? = true and from = dir] [set pcolor col set change-marker ticks] end ;; runtime to go manage-traffic-light move-cars move-walkers move-trains gen-cars gen-walkers gen-trains tick plot-data end to manage-traffic-light if scheduling-algorithm = "round-robin" [manage-traffic-light-round-robin] ;;if scheduling-algorithm = "simple-priority" [manage-traffic-light-simple-priority] end to manage-traffic-light-round-robin ;; simple round robin if (round-robin-state = 2 and ticks - tick-count-last = green-light-duration) [ ;; change to orange if (round-robin-last = "NS") [ foreach [0 180] [set-car-light ? orange] ] if (round-robin-last = "EW") [ foreach [90 270] [set-car-light ? orange] ] if (round-robin-last = "ped") [ foreach [0 90 180 270] [set-walker-light ? orange] ] set round-robin-state 0 ;;type "(" type round-robin-state type ") " type "set tick-count-last " print ticks set tick-count-last ticks ] if (round-robin-state = 0 and ticks - tick-count-last = orange-light-duration) [ ;; change orange to red if (round-robin-last = "NS") [ foreach [0 180] [set-car-light ? red] ] if (round-robin-last = "EW") [ foreach [90 270] [set-car-light ? red] ] if (round-robin-last = "ped") [ foreach [0 90 180 270] [set-walker-light ? red] ] set round-robin-state 1 ;;type "(" type round-robin-state type ") " type "set tick-count-last " print ticks set tick-count-last ticks ] if (round-robin-state = 1 and ticks - tick-count-last = all-red-duration) [ let next-dir round-robin-last ;; new green lights if (round-robin-last = "NS") [ foreach [90 270] [set-car-light ? green] set next-dir "EW" ] if (round-robin-last = "EW") [ foreach [0 90 180 270] [set-walker-light ? green] set next-dir "ped" ] if (round-robin-last = "ped") [ foreach [0 180] [set-car-light ? green] set next-dir "NS" ] set round-robin-state 2 ;;type "(" type round-robin-state type ") " type "set tick-count-last " print ticks set tick-count-last ticks set round-robin-last next-dir ] end to gen-trains if (ticks mod gen-freq = 0) [ if ((random 100) < train-frequency) and (not any? trains) [ ask patch min-pxcor 65 [ sprout-trains 1 [init-train] ] ] ] end to init-train set heading 90 set size 20 set speed ((random 10) + 10) / 10 ;; visualize the train sensor ask patches with [sensor4? = true] [if show-sensors? [set pcolor red]] end to move-trains ask trains [ ifelse can-move? speed [ fd speed] [ ask patches with [sensor4? = true] [if show-sensors? [set pcolor 68]] die ] ] end to gen-walkers if (ticks mod gen-freq = 0) [ ;;show ticks foreach [0 90 180 270] [ let x 0 let y 0 let create? false if ? = 0 and (random 100) < S-pedestrian-density [ set x 13 set y min-pycor set create? true ] if ? = 90 and (random 100) < W-pedestrian-density [ set x min-pxcor set y -13 set create? true ] if ? = 180 and (random 100) < N-pedestrian-density [ set x -13 set y max-pycor set create? true ] if ? = 270 and (random 100) < E-pedestrian-density [ set x max-pxcor set y 13 set create? true ] if create? = true [ ask patch x y [ sprout-walkers 1 [ ;; pass in the current direction of the foreach loop init-walker ? ] ] ] ] ] end to init-walker [dir] if dir = 0 [set color violet] if dir = 90 [set color orange] if dir = 180 [set color 76] if dir = 270 [set color 96] set heading dir set direction dir set size 5 set speed ((random 5) + 5) / 30 set orig-speed speed set student? random 100 < 90 ; slider? if student? [set shape "person-student"] set start-time ticks end to move-walkers ask walkers [ ifelse can-move? speed [ ;; stop if at train sensor and train is passing let on-sensor4? false ask patch-here [if sensor4? [set on-sensor4? true] ] ifelse on-sensor4? and any? trains [ set speed 0 ] [ if speed = 0 [set speed orig-speed] ] ;; stop if at a traffic light and the color is red let on-sensor2? false let patch-from -1 ask patch-here [ if sensor2? [ set on-sensor2? true set patch-from from ] ] if on-sensor2? [ ifelse pcolor != green and direction = patch-from [ set speed 0 ] [ if speed = 0 [set speed orig-speed] ] ] fd speed ] [ let wait-time (ticks - start-time) if wait-time > max-wait-time-pedestrians [set max-wait-time-pedestrians wait-time] if (min-wait-time-pedestrians = 0) or (wait-time < min-wait-time-pedestrians) [set min-wait-time-pedestrians wait-time] set total-wait-time-pedestrians (total-wait-time-pedestrians + wait-time) set total-pedestrians (total-pedestrians + 1) die ] ] end to-report free-space [x y dir] ;;set log-id (log-id + 1) let dist 0 let max-dist (truck-length + 1) let x-delta 0 let y-delta 0 if dir = 0 [ set y-delta 1 ] if dir = 90 [ set x-delta 1 ] if dir = 180 [ set y-delta -1 ] if dir = 270 [ set x-delta -1 ] while [dist <= max-dist] [ let next-patch patch x y if next-patch != nobody [ let car-ahead one-of turtles-on next-patch if car-ahead != nobody and is-car? car-ahead [ ;;type log-id print "false" report false ] ] set x (x + x-delta) set y (y + y-delta) set dist (dist + 1) ] ;;type log-id print "true" report true end to gen-cars if (ticks mod gen-freq = 0) [ ;;show ticks foreach [0 90 180 270] [ let free-space? false; let x 0 let y 0 if ? = 0 and (random 100 < S-car-density) [ set x 5 set y min-pycor set free-space? (free-space x y ?) ] if ? = 90 and (random 100 < W-car-density) [ set x min-pxcor set y -5 set free-space? (free-space x y ?) ] if ? = 180 and (random 100 < N-car-density) [ set x -5 set y max-pycor set free-space? (free-space x y ?) ] if ? = 270 and (random 100 < E-car-density) [ set x max-pxcor set y 5 set free-space? (free-space x y ?) ] ;; TODO: decision here, or make it configurable? : only generate a car if there's room, ;; or let them stack up ;; if (x != 0) prevents the generation of cars when the randomization ;; above does not yield one :) if (x != 0) ;; and free-space? [ ask patch x y [ sprout-cars 1 [ ;; pass in the current direction of the foreach loop init-car ? ] ] ] ] ] end to init-car [dir] if dir = 0 [set color 37] ;; brown if dir = 90 [set color 47] ;; yellow if dir = 180 [set color 97] ;; blue if dir = 270 [set color 127] ;; magenta set heading dir set direction dir set turning-left? (random 100) < percent-turning-left set turning-right? (not turning-left?) and ((random 100) < percent-turning-right) set truck? random 100 < percent-trucks set emergency-vehicle? random 100 < percent-emergency-vehicles ifelse truck? [ set shape "truck-rotate" set size truck-length set speed ((random 5) + 5) / 10 set acceleration ((random-float .5) + .5) / 10 if dir = 270 [set shape "truck-rotate-inverted"] ] [ ifelse emergency-vehicle? [ set shape "ambulance" set size 15 set color red set speed ((random 10) + 10) / 10 set acceleration ((random-float 1.5) + .5) / 10 if dir = 270 [set shape "ambulance-inverted"] ] [ set size car-length set speed ((random 8) + 8) / 10 set acceleration ((random-float 1) + 1) / 10 if dir = 270 [set shape "car-inverted"] ] ] set start-time ticks end to check-ahead-and-react let current-speed speed ;;type current-speed type "__" ;; adjust if there's a car in front of you let found-car? false let dist 0 let max-dist (size / 2) + (truck-length / 2) + 1 while [dist <= max-dist and found-car? = false ] [ let next-patch patch-ahead dist if next-patch != nobody [ let car-ahead one-of turtles-on next-patch if car-ahead != nobody and is-car? car-ahead and car-ahead != self [ set found-car? true set speed (([speed] of car-ahead) - acceleration) ;; type dist type " [" type size type "] " type "[" type [size] of car-ahead type "]" ;; slow the car down even more if it is overlapping another car if dist < size or dist < [size] of car-ahead [set speed 0] ] ] set dist (dist + 1) ] ;; if no car, accelerate if found-car? = false [set speed speed + acceleration] if speed < 0 [set speed 0 ] if speed > max-speed [set speed max-speed] ;;type "__" print speed end to-report clear-on-other-side [max-dist] let found-car? false let dist 0 while [dist <= max-dist and found-car? = false ] [ let next-patch patch-ahead dist if next-patch != nobody [ let car-ahead one-of turtles-on next-patch if car-ahead != nobody and is-car? car-ahead and car-ahead != self [ set found-car? true ] ] set dist (dist + 1) ] report not found-car? end to move-cars ask cars [ ifelse can-move? speed [ check-ahead-and-react ;; stop if at train sensor and train is passing let on-sensor4? false ask patch-here [if sensor4? [set on-sensor4? true] ] if on-sensor4? [ ifelse any? trains or not clear-on-other-side (15 + size) [set speed 0] [if speed = 0 [ set speed .1]] ] ;; approaching intersection / traffic light let on-sensor1? false ask patch-here [if sensor1? [set on-sensor1? true]] if on-sensor1? [ ;; stop if at a traffic light and the color is red ;; stop at intersection if there is no room on the other side ;; TODO also handle turns (this will stop a car from turning even if there is room!) ifelse pcolor = red or (any? trains and not clear-on-other-side (20 + size)) [set speed 0] [if speed = 0 [set speed .1]] ] let in-intersection? false ask patch-here [if intersection? [set in-intersection? true]] if in-intersection? [ if turning-left? [ if direction = 0 [ ifelse ycor > 0 and ycor < 5 [set heading (heading - (15 * speed) / 2)] [if ycor >= 5 [set heading 270 ifelse truck? [set shape "truck-rotate-inverted"] [set shape "car-inverted"]]] ] if direction = 90 [ ifelse xcor > 0 and xcor < 5 [set heading (heading - (15 * speed) / 2)] [if xcor >= 5 [set heading 0]] ] if direction = 180 [ ifelse ycor < 0 and ycor > -5 [set heading (heading - (15 * speed) / 2)] [if ycor <= -5 [set heading 90]] ] if direction = 270 [ ifelse xcor < 0 and xcor > -5 [set heading (heading - (15 * speed) / 2)] [if xcor <= -5 [set heading 180 ifelse truck? [set shape "truck-rotate"] [set shape "car"]]] ] ] if turning-right? [ if direction = 0 [ ifelse ycor > -10 and ycor < -6 [set heading (heading + (15 * speed) / 2)] [if ycor >= -6 [set heading 90]] ] if direction = 90 [ ifelse xcor > -10 and xcor < -6 [set heading (heading + (15 * speed) / 2)] [if xcor >= -6 [set heading 180]] ] if direction = 180 [ ifelse ycor < 10 and ycor > 6 [set heading (heading + (15 * speed) / 2)] [if ycor <= 6 [set heading 270 ifelse truck? [set shape "truck-rotate-inverted"] [set shape "car-inverted"]]] ] if direction = 270 [ ifelse xcor < 10 and xcor > 6 [set heading (heading + (15 * speed) / 2)] [if xcor <= 6 [set heading 0 ifelse truck? [set shape "truck-rotate"] [set shape "car"]]] ] ] ] fd speed ] [ let wait-time (ticks - start-time) if wait-time > max-wait-time-cars [set max-wait-time-cars wait-time] if (min-wait-time-cars = 0) or (wait-time < min-wait-time-cars) [set min-wait-time-cars wait-time] set total-wait-time-cars (total-wait-time-cars + wait-time) set total-cars (total-cars + 1) die ] ] end to plot-data ;; write "m:" write count-make write " d:" print count-die set-current-plot "Car Wait Time" set-current-plot-pen "max-wait-time" plot max-wait-time-cars set-current-plot-pen "min-wait-time" plot min-wait-time-cars set-current-plot-pen "avg-wait-time" ifelse total-cars != 0 [plot total-wait-time-cars / total-cars] [plot 0] set-current-plot "Pedestrian Wait Time" set-current-plot-pen "max-wait-time" plot max-wait-time-pedestrians set-current-plot-pen "min-wait-time" plot min-wait-time-pedestrians set-current-plot-pen "avg-wait-time" ifelse total-pedestrians != 0 [plot total-wait-time-pedestrians / total-pedestrians] [plot 0] ; set-current-plot "Accidents" ; set-current-plot-pen "car-car" ; plot count d ; set-current-plot-pen "car-pedestrian" ; plot count e end
There is only one version of this model, created almost 15 years ago by Coram Bryant.
Attached files
No files
This model does not have any ancestors.
This model does not have any descendants.