Difference between revisions of "Traffic Accident Risk Analysis"

From Simulace.info
Jump to: navigation, search
(Method)
 
(One intermediate revision by the same user not shown)
Line 14: Line 14:
  
 
== Method ==
 
== Method ==
A systematic approach to traffic safety integrates engineering, enforcement, and education — often referred to as the “Triple E” (Sadauskas, 2011):
+
We adopt a multi-pronged, systematic approach to traffic safety, integrating **engineering**, **enforcement**, and **education**—commonly referred to as the “Triple E.(Sadauskas, 2011)
  
Engineering: Vehicle and road design improvements (e.g., signage, intersections, lighting).
+
== Engineering ==
 +
Vehicle and road design improvements include:
  
Education: Public awareness, driver training programs targeting risk perception and behavior.
+
* **''Intersection geometry optimization:''** Represented in the code by the procedure <code>setup-intersections</code>, which identifies and marks intersection patches. Traffic lights are not working as intended, but are in the code base and interface for user to try.
  
Enforcement: Legal measures (speed limits, penalties) ensuring compliance with traffic rules.
 
  
Human Reliability Analysis (HRA) has also been adapted to driving tasks to quantify driver error probabilities at intersections (Gstalter & Fastenmeier, 2010). By defining “correct” driver actions and measuring deviations, one can estimate how road geometry, age, and psycho-social factors alter driver reliability.
+
Additionally, **Human Reliability Analysis (HRA)** was used to determine driver error probabilities, particularly at urban intersections.(Gstalter & Fastenmeier, 2010). By defining “correct” task execution and measuring deviations, HRA quantifies how factors such as road geometry, driver age, and psychosocial influences affect driver reliability.  
 +
 
 +
In the code, this is reflected in the procedure <code>calculate-accident-probability</code>, which scales a base driver-error rate by factors such as:
 +
 
 +
* Road conditions 
 +
* Speed ratio 
 +
* Local congestion 
 +
* Intersection complexity
  
 
== Model ==
 
== Model ==

Latest revision as of 20:42, 10 January 2025

Introduction

This page introduces a NetLogo-based simulation that models traffic accident risk. The goal is to understand how road conditions, traffic density, and driver behavior intertwine to create or mitigate accidents. Various research sources underscore the need for a systematic approach to traffic safety, illustrating how driver reliability, infrastructure, and cultural factors shape accident outcomes (Sadauskas, 2011; Gstalter & Fastenmeier, 2010; TSK Praha, 2020; Nordfjærn et al., 2011).

Definition of the Problem

Road traffic accidents remain a pressing public health challenge, especially with the steady growth in vehicle numbers worldwide (Sadauskas, 2011). This proliferation escalates the likelihood of collisions, injuries, and fatalities. A robust traffic safety strategy thus necessitates examining:

Road conditions (from good to very bad).

Driver behavior and risk homeostasis (adjusting behavior based on perceived safety).

Environmental and societal factors that influence compliance with safety rules (Nordfjærn et al., 2011).

Moreover, the complexity of urban intersections can amplify error rates, as drivers face higher cognitive loads and multiple conflict points (Gstalter & Fastenmeier, 2010). In city contexts, baseline accident rates still vary considerably depending on infrastructure, as seen in real-world data (TSK Praha, 2020).

Method

We adopt a multi-pronged, systematic approach to traffic safety, integrating **engineering**, **enforcement**, and **education**—commonly referred to as the “Triple E.(Sadauskas, 2011)

Engineering

Vehicle and road design improvements include:

  • **Intersection geometry optimization:** Represented in the code by the procedure setup-intersections, which identifies and marks intersection patches. Traffic lights are not working as intended, but are in the code base and interface for user to try.


Additionally, **Human Reliability Analysis (HRA)** was used to determine driver error probabilities, particularly at urban intersections.(Gstalter & Fastenmeier, 2010). By defining “correct” task execution and measuring deviations, HRA quantifies how factors such as road geometry, driver age, and psychosocial influences affect driver reliability.

In the code, this is reflected in the procedure calculate-accident-probability, which scales a base driver-error rate by factors such as:

  • Road conditions
  • Speed ratio
  • Local congestion
  • Intersection complexity

Model

This simulation uses NetLogo to create a grid of patches representing:

Road segments: Assigned good, bad, or very bad condition.

Intersections: Potentially with traffic lights.

Cars (turtles): Move according to lane rules and can trigger accidents based on speed, congestion, and driver-error-rate.

Key points:

Accident Probability: Derived from a base driver-error-rate, amplified by intersection complexity, road condition, and local traffic density (Gstalter & Fastenmeier, 2010; Nordfjærn et al., 2011).

Baseline Rates: Inspired by real accident data (e.g., TSK Praha’s ročenka dopravy or Accident risks of different weather conditions) (TSK Praha, 2020) (Malin 2017).

Systematic Approach: Reflects suggestions for engineering (road condition logic), education (driver-error slider), and enforcement (speed constraints) in modeling different scenarios (Sadauskas, 2011).

Interface

Interface timm03.png


High Density, Poor Roads

LowDensity timm03.png

Because there are 100 cars with a fairly high driver-error-rate (0.05), multiple accidents occurred (10 total). However, they tended to happen later in the simulation (average time until accident over 300 ticks). Most cars (90 out of 100) still reached their destination—likely because accident-duration is very short (1 tick), so blocked patches quickly returned to normal. The relatively high base speed (0.8) also increased mobility, helping more cars finish faster, but also contributed to a moderate accident rate.

Low Density, Strict Limits

HighDensity timm03.png

Fewer cars (50), but also a much lower base speed (0.3), so cars move more slowly—leading to a higher average travel time (over 200 ticks). Because driver-error-rate is only 0.01 (lower chance of human error) and 70% roads are good, only 3 accidents occurred. Even with slow speed, many cars still took a long time to finish, as shown by the high travel time. Almost all cars managed to complete or crash within the time frame, with 47 successful arrivals.


Moderate Density, Extended Accident Duration

ModerateDensity timm03.png

Compared to the second screenshot, the big difference is accident-duration = 90 (very long). Even though speed is still 0.3 and the road condition/distribution is the same, the accident count has climbed to 13, and 16% of the cars ended up in accidents. Because accidents last 90 ticks on a patch, any collision severely disrupts traffic, likely forcing more cars to queue or collide. Despite that, 67 cars did manage to exit, though the blocked patches would have contributed to higher accident numbers and more emergent congestion.


Conclusion

This NetLogo simulation allows users to vary key parameters—such as base speed, number of cars (density), road condition (good to very bad), driver-error rate, and accident duration—then observe metrics like average travel time, distance/time until accident, and accident hotspots. Results show that poor roads and high driver-error rates sharply increase collisions, while long accident durations intensify congestion. Conversely, safer infrastructure, lower driver-error rates, and faster incident clearance foster smoother traffic flow and fewer crashes, underlining the value of integrated traffic safety strategies.

Code

Below is the NetLogo code implementing the simulation structure (patch definitions, accident logic, congestion metrics, etc.). Users can copy and paste it into a NetLogo environment to run their own experiments. For a complete listing, see the setup, go, and supporting procedures:


<syntaxhighlight lang="netlogo">

globals [

 ;; Sliders / Switch in Interface:
 ;;   - number-of-cars      (int)
 ;;   - road-spacing        (int)
 ;;   - base-speed          (float)
 ;;   - driver-error-rate   (float)
 ;;   - accident-duration   (int)
 ;;   - traffic-lights?     (boolean switch)
 ;; Statistics
 total-cars-reached-destination
 total-cars-accident         ;; how many cars died in accidents (cumulative)
 accident-count              ;; how many total accidents have started
 average-speed
 average-congestion
 accident-percentage
 sum-travel-time           ;; sum of time in system for all cars that exit
 count-completed-cars      ;; how many cars reached destination
 average-travel-time       ;; output metric
 accident-count-good
 accident-count-bad
 accident-count-very-bad
  sum-time-until-accident
 sum-distance-until-accident
 average-time-until-accident
 average-distance-until-accident

]

patches-own [

 is-road?           ;; boolean: is this patch part of a road?
 is-intersection?   ;; boolean: is this patch an intersection?
 lane-direction     ;; forced heading: 0, 90, 180, 270, or -1 if intersection
 traffic-light?     ;; does this patch have a traffic light?
 light-state        ;; true=green, false=red
 has-accident?      ;; boolean: accident currently on this patch?
 accident-lifetime  ;; integer: how many ticks remain for this accident?
 road-condition     ;; 0=good, 1=bad, 2=very bad (affects accident prob)

]

breed [ cars car ] cars-own [

 speed
 max-speed
 stopped-ticks
 destination        ;; patch or nobody
 birth-tick                 ;; store the tick when the car is created
 distance-traveled          ;; accumulates how far the car has moved

]

1. SETUP  ;;;

to setup

 clear-all
 ;; Initialize stats
 set total-cars-reached-destination 0
 set total-cars-accident 0
 set accident-count 0
 set average-speed 0
 set average-congestion 0
 
 set sum-travel-time 0
 set count-completed-cars 0
 set average-travel-time 0
 
 set accident-count-good 0
 set accident-count-bad 0
 set accident-count-very-bad 0
 
 set sum-time-until-accident 0
 set sum-distance-until-accident 0
 set average-time-until-accident 0
 set average-distance-until-accident 0
 setup-roads
 setup-intersections
 setup-traffic-lights
 setup-road-conditions
 
 reset-ticks
 
 create-initial-cars

end

2. CREATE ROADS (TWO LANE, ONE-WAY)  ;;;

to setup-roads

 ask patches [
   set is-road? false
   set is-intersection? false
   set traffic-light? false
   set light-state false
   set has-accident? false
   set accident-lifetime 0
   set lane-direction 0
   set road-condition 0
   set pcolor green
 ]
 ;; 2-lane roads in x or y dimension
 let road-patches patches with [
   (abs pxcor mod road-spacing <= 1) or
   (abs pycor mod road-spacing <= 1)
 ]
 ask road-patches [
   set is-road? true
   set pcolor grey
 ]
 ;; Assign forced lane headings for non-intersection road patches
 ask road-patches [
   let x-road? (abs pxcor mod road-spacing <= 1)
   let y-road? (abs pycor mod road-spacing <= 1)
   ;; purely vertical lane: pick 0 or 180
   if (x-road? and not y-road?) [
     ifelse (pxcor mod 2 = 0)
       [ set lane-direction 0   ]   ;; "northbound"
       [ set lane-direction 180 ]   ;; "southbound"
   ]
   ;; purely horizontal lane: pick 90 or 270
   if (y-road? and not x-road?) [
     ifelse (pycor mod 2 = 0)
       [ set lane-direction 90  ]   ;; "eastbound"
       [ set lane-direction 270 ]   ;; "westbound"
   ]
 ]

end

3. INTERSECTIONS  ;;;

to setup-intersections

 ask patches with [is-road?] [
   let x-road? (abs pxcor mod road-spacing <= 1)
   let y-road? (abs pycor mod road-spacing <= 1)
   ;; Intersection = patch that is both x-road & y-road
   if (x-road? and y-road?) [
     set is-intersection? true
     set pcolor yellow
     set lane-direction -1   ;; means "all directions possible here"
   ]
 ]

end

4. TRAFFIC LIGHTS  ;;;

to setup-traffic-lights

 if traffic-lights? [
   ;; Turn on lights at each intersection
   ask patches with [is-intersection?] [
     set traffic-light? true
     set light-state true
   ]
 ]

end

5. ROAD CONDITIONS  ;;;

to setup-road-conditions

 let sum-prob (good-road-probability + bad-road-probability)
 
 ask patches with [is-road?] [
   let r random-float 1
   
   ifelse (r < good-road-probability) [
     ;; (1) "Good" road
     set road-condition 0
     set pcolor grey
     
   ] [
     ifelse (r < sum-prob) [
       ;; (2) "Bad" road
       set road-condition 1
       set pcolor (grey - 2)
       
       ;; 5% chance to become "Very Bad" instead:
       if random-float 1 < 0.05 [
         set road-condition 2
         set pcolor orange
       ]
       
     ] [
       
       set road-condition 0
       set pcolor grey
     ]
   ]
 ]

end

6. CREATE INITIAL CARS  ;;;

to create-initial-cars

 ask cars [ die ]  ;; remove any old cars
 let valid-starts patches with [
   is-road? and
   not has-accident? and
   not any? cars-here
 ]
 if not any? valid-starts [
   user-message "No valid road patches for car creation!"
   stop
 ]
 create-cars min list number-of-cars (count valid-starts) [
   set shape "car"
   set color blue
   set size 0.8
   ;; pick a random road patch
   let start-patch one-of valid-starts
   move-to start-patch
   set valid-starts valid-starts with [self != start-patch]
   ;; If this patch is an intersection => pick a direction
   ifelse ([lane-direction] of patch-here = -1)
     [ set heading one-of [0 90 180 270] ]
     [ set heading [lane-direction] of patch-here ]
   set speed 0
   set max-speed base-speed
   set stopped-ticks 0
   set destination nobody
   set distance-traveled 0
   set birth-tick ticks
 ]

end

7. GO (MAIN LOOP)  ;;;

to go

 if not any? cars [ stop ]
 update-traffic-lights
 move-cars
 check-accidents
 clear-old-accidents
 update-statistics
 tick

end

8. UPDATE TRAFFIC LIGHTS  ;;;

to update-traffic-lights

 if traffic-lights? [
   ask patches with [is-intersection? and traffic-light?] [
     ;; simple toggle every 30 ticks
     if (ticks mod 30 = 0) [
       set light-state not light-state
       set pcolor ifelse-value light-state [green] [red]
     ]
   ]
 ]

end

9. MOVE CARS  ;;;

to move-cars

 ask cars [
   ;; Force lane direction
   let patch-lane [lane-direction] of patch-here
   ifelse patch-lane = -1 [
     ;; intersection => pick a new direction each tick or once
     set heading one-of [0 90 180 270]
   ] 
   [
     ;; normal lane => enforce that heading
     set heading patch-lane
   ]
   ;; Decide if it's safe to move
   let safe-to-move? true
   ;; Check traffic light
   if [traffic-light?] of patch-here [
     if not ([light-state] of patch-here) [
       set safe-to-move? false
     ]
   ]
   ;; Check for cars ahead in same lane
   if any? cars-on patch-ahead 1 [
     set safe-to-move? false
   ]
   ;;  Move or slow
   ifelse safe-to-move? [
     set speed min (list (speed + 0.1) max-speed)
     forward speed
     set distance-traveled distance-traveled + speed
     set stopped-ticks 0
   ] [
     set speed max (list (speed - 0.2) 0)
     set stopped-ticks (stopped-ticks + 1)
   ]
;; if the car leaves the grid:
   if not is-patch? patch-here [
     
     set count-completed-cars (count-completed-cars + 1)
     
     ;;  Add to sum-travel-time:
     set sum-travel-time (sum-travel-time + (ticks - birth-tick))
     ;; Then die
     die
   ]
   if (max-pxcor - abs xcor) < 1 or (max-pycor - abs ycor) < 1 [
     set total-cars-reached-destination (total-cars-reached-destination + 1)
     set count-completed-cars (count-completed-cars + 1)
     set sum-travel-time (sum-travel-time + (ticks - birth-tick))
     
     die
   ]
 ]

end

10. ACCIDENT LOGIC (EXPANDED)  ;;;

to check-accidents

 ;; For each car, compute probability of an accident
 ask cars [
   if random-float 1 < calculate-accident-probability self [
     create-accident self
   ]
 ]

end

to-report calculate-accident-probability [ c ]

 ;; Base accident probability from driver error
 let base (driver-error-rate * 0.00025)
 
 ;;  Find the patch under turtle c (using c's pxcor, pycor)
 let p patch ([pxcor] of c) ([pycor] of c)
 
 ;;  Road condition effect
 if [road-condition] of p = 1 [
   set base (base * 2)
 ]
 if [road-condition] of p = 2 [
   set base (base * 2.6)
 ]
 
 ;; Speed factor
 let speed-ratio ([speed] of c / [max-speed] of c)
 set base (base * (speed-ratio + 0.1))   ;; +0.1 so even slow cars have some chance
 
 ;; Congestion effect: how many other cars are within radius 1.5 of c
 let nearby-cars count cars with [ distance c < 1.5 ]
 set base (base + (nearby-cars * 0.0005))
 
 ;;  Intersection effect
 if [is-intersection?] of p [
   set base (base * 1.5)
 ]
 
 ;; Cap at 1% (0.01) to avoid extreme probabilities
 report min (list base 0.1)
 

end


to create-accident [ c ]

 set accident-count (accident-count + 1)
 set total-cars-accident (total-cars-accident + 1)
 ;; Mark the patch
 let px ([pxcor] of c)
 let py ([pycor] of c)
 ask patch px py [
   set has-accident? true
   set pcolor red
   set accident-lifetime accident-duration
   ;; Accidents by Road Condition:
   if (road-condition = 0) [ set accident-count-good (accident-count-good + 1) ]
   if (road-condition = 1) [ set accident-count-bad (accident-count-bad + 1) ]
   if (road-condition = 2) [ set accident-count-very-bad (accident-count-very-bad + 1) ]
 ]
 ;; Time & Distance to Accident:
 let time-until-accident (ticks - [birth-tick] of c)
 let dist-until-accident ([distance-traveled] of c)
 set sum-time-until-accident (sum-time-until-accident + time-until-accident)
 set sum-distance-until-accident (sum-distance-until-accident + dist-until-accident)
 ;; kill the car
 ask c [ die ]

end

to clear-old-accidents

 ;; Decrement accident-lifetime. When it hits 0, clear the patch.
 ask patches with [has-accident?] [
   set accident-lifetime (accident-lifetime - 1)
   if (accident-lifetime <= 0) [
     set has-accident? false
     ;; restore color based on road-condition
     if (road-condition = 0) [
       set pcolor grey
     ] 
     if (road-condition = 1) [
       set pcolor (grey - 2)
     ]
     if (road-condition = 2) [
       set pcolor orange
     ]
   ]
 ]

end

11. STATISTICS & PLOTS  ;;;

to update-statistics

 let car-count count cars
 let total-speed 0
 if car-count > 0 [
   set total-speed sum [speed] of cars
   set average-speed (total-speed / car-count)
 ] 
 if car-count = 0 [
   set average-speed 0
 ]


 set average-congestion count cars with [
   (stopped-ticks >= 2) and (any? cars-on patch-ahead 1)
 ]
  if number-of-cars > 0 [
   set accident-percentage ((accident-count / number-of-cars) * 100)
 ]
 ;;Average travel time for cars that completed trip
 if count-completed-cars > 0 [
   set average-travel-time (sum-travel-time / count-completed-cars)
 ]
 ;;Averages for time & distance until accident
 if accident-count > 0 [
   set average-time-until-accident (sum-time-until-accident / accident-count)
   set average-distance-until-accident (sum-distance-until-accident / accident-count)
 ]
 ;; Plot them
 carefully [
   set-current-plot "Average Speed"
   plot average-speed
   set-current-plot "Total Accidents"
   plot accident-count
   set-current-plot "Average Congestion"
   plot average-congestion
 ] []

end

</syntaxhighlight>

References

Sadauskas, V. (2011). Traffic safety strategies, Transport, 18(2), 79–83. DOI: 10.1080/16483840.2003.10414070 
Gstalter, H., & Fastenmeier, W. (2010). Reliability of drivers in urban intersections. Accident Analysis & Prevention, 42(1), 225–234. Link 
TSK Praha (2020). Ročenka dopravy – 2020. Link 
Nordfjærn, T., Jørgensen, S., & Rundmo, T. (2011). A cross-cultural comparison of road traffic risk perceptions, attitudes towards traffic safety, and driver behaviour. Journal of Risk Research, 14(6), 657–684. Link 
Fanny Malin (2017). Accident risks in different weather conditions. Link