-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDriverModel.py
114 lines (93 loc) · 3.53 KB
/
DriverModel.py
1
2
3
4
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
import math
import Consts
class DriverModel(object):
@staticmethod
def calc_acceleration(vehicle):
raise NotImplementedError()
@staticmethod
def calc_velocity(vehicle):
raise NotImplementedError()
@staticmethod
def calc_position(vehicle):
raise NotImplementedError()
@staticmethod
def calc_gap(vehicle):
raise NotImplementedError()
class IDM(DriverModel):
@staticmethod
def calc_acceleration(vehicle):
"""
dv(t)/dt = [1 - (v(t)/v0)^4 - (s*(t)/s(t))^2]
"""
acceleration = math.pow(
(vehicle.velocity / vehicle.get_desired_velocity()), 4)
deceleration = math.pow(IDM.calc_desired_gap(vehicle) / vehicle.gap, 2)
return float(vehicle.max_acceleration * (1 - acceleration - deceleration))
@staticmethod
def calc_desired_gap(vehicle):
pv = vehicle.velocity
if vehicle.lead_vehicle:
lpv = vehicle.lead_vehicle.velocity
else:
lpv = pv
c = ((vehicle.get_safetime_headway() * pv) +
((pv * (pv - lpv)) / (2 * math.sqrt(
vehicle.max_acceleration * vehicle.max_deceleration))))
ret = float(vehicle.minimum_distance + max(0, c))
return ret
@staticmethod
def calc_velocity(vehicle):
new_velocity = IDM.calc_raw_velocity(vehicle)
return float(max(0, new_velocity))
@staticmethod
def calc_raw_velocity(vehicle):
return float(vehicle.velocity + (IDM.calc_acceleration(vehicle) *
Consts.TIME_STEP))
@staticmethod
def calc_position(vehicle):
if IDM.calc_raw_velocity(vehicle) < 0:
new_position = (vehicle.position -
(0.5 * (math.pow(vehicle.velocity, 2) /
IDM.calc_acceleration(vehicle))))
else:
new_position = (vehicle.position +
(vehicle.velocity * Consts.TIME_STEP) +
(0.5 * IDM.calc_acceleration(vehicle) *
math.pow(Consts.TIME_STEP, 2)))
return float(new_position)
@staticmethod
def calc_gap(vehicle):
if vehicle.lead_vehicle:
return float(vehicle.lead_vehicle.position -
IDM.calc_position(vehicle) -
vehicle.lead_vehicle.length)
else:
return float(Consts.ROAD_LENGTH + 100)
class TruckPlatoon(DriverModel):
@staticmethod
def calc_acceleration(vehicle):
if vehicle.is_leader:
return float(IDM.calc_acceleration(vehicle))
else:
return float(TruckPlatoon.calc_acceleration(vehicle.lead_vehicle))
@staticmethod
def calc_velocity(vehicle):
if vehicle.is_leader:
return float(IDM.calc_velocity(vehicle))
else:
return float(TruckPlatoon.calc_velocity(vehicle.lead_vehicle))
@staticmethod
def calc_position(vehicle):
if vehicle.is_leader:
return float(IDM.calc_position(vehicle))
else:
return float(TruckPlatoon.calc_position(vehicle.lead_vehicle) -
vehicle.lead_vehicle.length - vehicle.follow_distance)
@staticmethod
def calc_gap(vehicle):
if vehicle.lead_vehicle:
return float(vehicle.lead_vehicle.position -
TruckPlatoon.calc_position(vehicle) -
vehicle.lead_vehicle.length)
else:
return float(Consts.ROAD_LENGTH + 100)