1 package org.opentrafficsim.road.gtu.tactical.following;
2
3 import org.djunits.unit.SpeedUnit;
4 import org.djunits.value.vdouble.scalar.Acceleration;
5 import org.djunits.value.vdouble.scalar.Length;
6 import org.djunits.value.vdouble.scalar.Speed;
7 import org.opentrafficsim.base.parameters.ParameterException;
8 import org.opentrafficsim.base.parameters.ParameterTypeAcceleration;
9 import org.opentrafficsim.base.parameters.ParameterTypeDouble;
10 import org.opentrafficsim.base.parameters.ParameterTypeDuration;
11 import org.opentrafficsim.base.parameters.ParameterTypeLength;
12 import org.opentrafficsim.base.parameters.ParameterTypes;
13 import org.opentrafficsim.base.parameters.Parameters;
14 import org.opentrafficsim.base.parameters.constraint.ConstraintInterface;
15 import org.opentrafficsim.core.gtu.Stateless;
16 import org.opentrafficsim.road.gtu.perception.PerceptionIterable;
17 import org.opentrafficsim.road.gtu.perception.object.PerceivedObject;
18 import org.opentrafficsim.road.network.speed.SpeedLimits;
19
20
21
22
23
24
25
26
27
28
29
30
31
32 public abstract class AbstractIdm extends AbstractCarFollowingModel
33 {
34
35
36
37 protected static final ParameterTypeAcceleration A = ParameterTypes.A;
38
39
40 protected static final ParameterTypeAcceleration B = ParameterTypes.B;
41
42
43 protected static final ParameterTypeDuration T = ParameterTypes.T;
44
45
46 protected static final ParameterTypeLength S0 = ParameterTypes.S0;
47
48
49 protected static final ParameterTypeAcceleration B0 = ParameterTypes.B0;
50
51
52 protected static final ParameterTypeDouble FSPEED = ParameterTypes.FSPEED;
53
54
55 protected static final ParameterTypeDouble FSPEED_GTU = ParameterTypes.FSPEED_GTU;
56
57
58 private static final Speed NO_SPEED_LIMIT_SPEED = new Speed(130.0, SpeedUnit.KM_PER_HOUR);
59
60
61
62 public static final ParameterTypeDouble DELTA = new ParameterTypeDouble("delta",
63 "Acceleration flattening exponent towards desired speed", 4.0, ConstraintInterface.POSITIVE);
64
65
66 public static final IdmDesiredHeadwayModel HEADWAY = IdmDesiredHeadwayModel.SINGLETON;
67
68
69 public static final IdmDesiredSpeedModel DESIRED_SPEED = IdmDesiredSpeedModel.SINGLETON;
70
71
72
73
74
75
76 public AbstractIdm(final DesiredHeadwayModel desiredHeadwayModel, final DesiredSpeedModel desiredSpeedModel)
77 {
78 super(desiredHeadwayModel, desiredSpeedModel);
79 }
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95 @Override
96 @SuppressWarnings("checkstyle:designforextension")
97 protected Acceleration followingAcceleration(final Parameters parameters, final Speed speed, final Speed desiredSpeed,
98 final Length desiredHeadway, final PerceptionIterable<? extends PerceivedObject> leaders) throws ParameterException
99 {
100 Acceleration a = parameters.getParameter(A);
101 Acceleration b0 = parameters.getParameter(B0);
102 double delta = parameters.getParameter(DELTA);
103 double aFree = a.si * (1 - Math.pow(speed.si / desiredSpeed.si, delta));
104
105 aFree = aFree > -b0.si ? aFree : -b0.si;
106
107 if (leaders.isEmpty())
108 {
109 return Acceleration.ofSI(aFree);
110 }
111
112 return combineInteractionTerm(Acceleration.ofSI(aFree), parameters, speed, desiredSpeed, desiredHeadway, leaders);
113 }
114
115
116
117
118
119
120
121
122
123
124
125
126 protected abstract Acceleration combineInteractionTerm(Acceleration aFree, Parameters parameters, Speed speed,
127 Speed desiredSpeed, Length desiredHeadway, PerceptionIterable<? extends PerceivedObject> leaders)
128 throws ParameterException;
129
130
131
132
133
134
135
136
137
138
139 protected final Length dynamicDesiredHeadway(final Parameters parameters, final Speed speed, final Length desiredHeadway,
140 final Speed leaderSpeed) throws ParameterException
141 {
142 double sStar = desiredHeadway.si + dynamicHeadwayTerm(parameters, speed, leaderSpeed).si;
143
144
145
146
147
148
149
150 Length s0 = parameters.getParameter(S0);
151
152
153
154
155 return Length.ofSI(sStar >= s0.si ? sStar : s0.si);
156 }
157
158
159
160
161
162
163
164
165
166 protected final Length dynamicHeadwayTerm(final Parameters parameters, final Speed speed, final Speed leaderSpeed)
167 throws ParameterException
168 {
169 Acceleration a = parameters.getParameter(A);
170 Acceleration b = parameters.getParameter(B);
171 return Length.ofSI(speed.si * (speed.si - leaderSpeed.si) / (2 * Math.sqrt(a.si * b.si)));
172 }
173
174
175
176
177 public static class IdmDesiredHeadwayModel implements DesiredHeadwayModel, Stateless<IdmDesiredHeadwayModel>
178 {
179
180 public static final IdmDesiredHeadwayModel SINGLETON = new IdmDesiredHeadwayModel();
181
182
183
184
185 public IdmDesiredHeadwayModel()
186 {
187
188 }
189
190 @Override
191 public IdmDesiredHeadwayModel get()
192 {
193 return SINGLETON;
194 }
195
196 @Override
197 public Length desiredHeadway(final Parameters parameters, final Speed speed) throws ParameterException
198 {
199 return Length.ofSI(parameters.getParameter(S0).si + speed.si * parameters.getParameter(T).si);
200 }
201 }
202
203
204
205
206
207
208 public static class IdmDesiredSpeedModel implements DesiredSpeedModel, Stateless<IdmDesiredSpeedModel>
209 {
210
211 public static final IdmDesiredSpeedModel SINGLETON = new IdmDesiredSpeedModel();
212
213
214
215
216 public IdmDesiredSpeedModel()
217 {
218
219 }
220
221 @Override
222 public IdmDesiredSpeedModel get()
223 {
224 return SINGLETON;
225 }
226
227 @Override
228 public Speed desiredSpeed(final Parameters parameters, final SpeedLimits speedLimits, final Speed maxVehicleSpeed)
229 throws ParameterException
230 {
231 Speed speed = null;
232 if (speedLimits.laneSpeedLimit() != null)
233 {
234 double laneFactor = parameters.getParameter(FSPEED);
235 if (speedLimits.laneSpeedLimit().enforced() && laneFactor > 1.0)
236 {
237 laneFactor = 1.0;
238 }
239 speed = speedLimits.laneSpeedLimit().speed().times(laneFactor);
240 }
241 if (speedLimits.gtuTypeSpeedLimit() != null)
242 {
243 double gtuTypeFactor = parameters.getParameter(FSPEED_GTU);
244 if (speedLimits.gtuTypeSpeedLimit().enforced() && gtuTypeFactor > 1.0)
245 {
246 gtuTypeFactor = 1.0;
247 }
248 if (speed == null)
249 {
250 speed = speedLimits.gtuTypeSpeedLimit().speed().times(gtuTypeFactor);
251 }
252 else
253 {
254 speed = Speed.min(speed, speedLimits.gtuTypeSpeedLimit().speed().times(gtuTypeFactor));
255 }
256 }
257 else if (speed != null)
258 {
259 return Speed.min(maxVehicleSpeed, speed);
260 }
261 return Speed.min(maxVehicleSpeed, NO_SPEED_LIMIT_SPEED.times(parameters.getParameter(FSPEED)));
262 }
263 }
264
265 }