1 package org.opentrafficsim.road.gtu.lane.tactical.following;
2
3 import org.djunits.value.vdouble.scalar.Acceleration;
4 import org.djunits.value.vdouble.scalar.Length;
5 import org.djunits.value.vdouble.scalar.Speed;
6 import org.opentrafficsim.base.parameters.ParameterException;
7 import org.opentrafficsim.base.parameters.ParameterTypeAcceleration;
8 import org.opentrafficsim.base.parameters.ParameterTypeDouble;
9 import org.opentrafficsim.base.parameters.ParameterTypeDuration;
10 import org.opentrafficsim.base.parameters.ParameterTypeLength;
11 import org.opentrafficsim.base.parameters.ParameterTypes;
12 import org.opentrafficsim.base.parameters.Parameters;
13 import org.opentrafficsim.base.parameters.constraint.ConstraintInterface;
14 import org.opentrafficsim.core.gtu.Stateless;
15 import org.opentrafficsim.road.gtu.lane.perception.PerceptionIterable;
16 import org.opentrafficsim.road.gtu.lane.perception.object.PerceivedObject;
17 import org.opentrafficsim.road.gtu.lane.tactical.util.SpeedLimitUtil;
18 import org.opentrafficsim.road.network.speed.SpeedLimitInfo;
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
56 public static final ParameterTypeDouble DELTA = new ParameterTypeDouble("delta",
57 "Acceleration flattening exponent towards desired speed", 4.0, ConstraintInterface.POSITIVE);
58
59
60 public static final IdmDesiredHeadwayModel HEADWAY = IdmDesiredHeadwayModel.SINGLETON;
61
62
63 public static final IdmDesiredSpeedModel DESIRED_SPEED = IdmDesiredSpeedModel.SINGLETON;
64
65
66
67
68
69
70 public AbstractIdm(final DesiredHeadwayModel desiredHeadwayModel, final DesiredSpeedModel desiredSpeedModel)
71 {
72 super(desiredHeadwayModel, desiredSpeedModel);
73 }
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89 @Override
90 @SuppressWarnings("checkstyle:designforextension")
91 protected Acceleration followingAcceleration(final Parameters parameters, final Speed speed, final Speed desiredSpeed,
92 final Length desiredHeadway, final PerceptionIterable<? extends PerceivedObject> leaders) throws ParameterException
93 {
94 Acceleration a = parameters.getParameter(A);
95 Acceleration b0 = parameters.getParameter(B0);
96 double delta = parameters.getParameter(DELTA);
97 double aFree = a.si * (1 - Math.pow(speed.si / desiredSpeed.si, delta));
98
99 aFree = aFree > -b0.si ? aFree : -b0.si;
100
101 if (leaders.isEmpty())
102 {
103 return Acceleration.ofSI(aFree);
104 }
105
106 return combineInteractionTerm(Acceleration.ofSI(aFree), parameters, speed, desiredSpeed, desiredHeadway, leaders);
107 }
108
109
110
111
112
113
114
115
116
117
118
119
120 protected abstract Acceleration combineInteractionTerm(Acceleration aFree, Parameters parameters, Speed speed,
121 Speed desiredSpeed, Length desiredHeadway, PerceptionIterable<? extends PerceivedObject> leaders)
122 throws ParameterException;
123
124
125
126
127
128
129
130
131
132
133 protected final Length dynamicDesiredHeadway(final Parameters parameters, final Speed speed, final Length desiredHeadway,
134 final Speed leaderSpeed) throws ParameterException
135 {
136 double sStar = desiredHeadway.si + dynamicHeadwayTerm(parameters, speed, leaderSpeed).si;
137
138
139
140
141
142
143
144 Length s0 = parameters.getParameter(S0);
145
146
147
148
149 return Length.ofSI(sStar >= s0.si ? sStar : s0.si);
150 }
151
152
153
154
155
156
157
158
159
160 protected final Length dynamicHeadwayTerm(final Parameters parameters, final Speed speed, final Speed leaderSpeed)
161 throws ParameterException
162 {
163 Acceleration a = parameters.getParameter(A);
164 Acceleration b = parameters.getParameter(B);
165 return Length.ofSI(speed.si * (speed.si - leaderSpeed.si) / (2 * Math.sqrt(a.si * b.si)));
166 }
167
168
169
170
171 public static class IdmDesiredHeadwayModel implements DesiredHeadwayModel, Stateless<IdmDesiredHeadwayModel>
172 {
173
174 public static final IdmDesiredHeadwayModel SINGLETON = new IdmDesiredHeadwayModel();
175
176
177
178
179 public IdmDesiredHeadwayModel()
180 {
181
182 }
183
184 @Override
185 public IdmDesiredHeadwayModel get()
186 {
187 return SINGLETON;
188 }
189
190 @Override
191 public Length desiredHeadway(final Parameters parameters, final Speed speed) throws ParameterException
192 {
193 return Length.ofSI(parameters.getParameter(S0).si + speed.si * parameters.getParameter(T).si);
194 }
195 }
196
197
198
199
200 public static class IdmDesiredSpeedModel implements DesiredSpeedModel, Stateless<IdmDesiredSpeedModel>
201 {
202
203 public static final IdmDesiredSpeedModel SINGLETON = new IdmDesiredSpeedModel();
204
205
206
207
208 public IdmDesiredSpeedModel()
209 {
210
211 }
212
213 @Override
214 public IdmDesiredSpeedModel get()
215 {
216 return SINGLETON;
217 }
218
219 @Override
220 public Speed desiredSpeed(final Parameters parameters, final SpeedLimitInfo speedInfo) throws ParameterException
221 {
222 Speed consideredSpeed = SpeedLimitUtil.getLegalSpeedLimit(speedInfo).times(parameters.getParameter(FSPEED));
223 Speed maxVehicleSpeed = SpeedLimitUtil.getMaximumVehicleSpeed(speedInfo);
224 return consideredSpeed.le(maxVehicleSpeed) ? consideredSpeed : maxVehicleSpeed;
225 }
226 }
227
228 }