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.road.gtu.lane.perception.PerceptionIterable;
15 import org.opentrafficsim.road.gtu.lane.perception.headway.Headway;
16 import org.opentrafficsim.road.gtu.lane.tactical.util.SpeedLimitUtil;
17 import org.opentrafficsim.road.network.speed.SpeedLimitInfo;
18
19 /**
20 * Implementation of the IDM. See <a
21 * href=https://en.wikipedia.org/wiki/Intelligent_driver_model>https://en.wikipedia.org/wiki/Intelligent_driver_model</a>
22 * <p>
23 * Copyright (c) 2013-2018 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
24 * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
25 * <p>
26 * @version $Revision$, $LastChangedDate$, by $Author$, initial version Apr 22, 2016 <br>
27 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
28 * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
29 * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
30 */
31 public abstract class AbstractIDM extends AbstractCarFollowingModel
32 {
33
34 /** Acceleration parameter type. */
35 protected static final ParameterTypeAcceleration A = ParameterTypes.A;
36
37 /** Comfortable deceleration parameter type. */
38 protected static final ParameterTypeAcceleration B = ParameterTypes.B;
39
40 /** Desired headway parameter type. */
41 protected static final ParameterTypeDuration T = ParameterTypes.T;
42
43 /** Stopping distance parameter type. */
44 protected static final ParameterTypeLength S0 = ParameterTypes.S0;
45
46 /** Adjustment deceleration parameter type. */
47 protected static final ParameterTypeAcceleration B0 = ParameterTypes.B0;
48
49 /** Speed limit adherence factor parameter type. */
50 protected static final ParameterTypeDouble FSPEED = ParameterTypes.FSPEED;
51
52 /** Acceleration flattening. */
53 public static final ParameterTypeDouble DELTA = new ParameterTypeDouble("delta",
54 "Acceleration flattening exponent towards desired speed.", 4.0, ConstraintInterface.POSITIVE);
55
56 /** Default IDM desired headway model. */
57 public static final DesiredHeadwayModel HEADWAY = new DesiredHeadwayModel()
58 {
59 @Override
60 public Length desiredHeadway(final Parameters parameters, final Speed speed) throws ParameterException
61 {
62 return Length.createSI(parameters.getParameter(S0).si + speed.si * parameters.getParameter(T).si);
63 }
64 };
65
66 /** Default IDM desired speed model. */
67 public static final DesiredSpeedModel DESIRED_SPEED = new DesiredSpeedModel()
68 {
69 @Override
70 public Speed desiredSpeed(final Parameters parameters, final SpeedLimitInfo speedInfo) throws ParameterException
71 {
72 Speed consideredSpeed = SpeedLimitUtil.getLegalSpeedLimit(speedInfo).multiplyBy(parameters.getParameter(FSPEED));
73 Speed maxVehicleSpeed = SpeedLimitUtil.getMaximumVehicleSpeed(speedInfo);
74 return consideredSpeed.le(maxVehicleSpeed) ? consideredSpeed : maxVehicleSpeed;
75 }
76 };
77
78 /**
79 * Constructor with modular models for desired headway and desired speed.
80 * @param desiredHeadwayModel desired headway model
81 * @param desiredSpeedModel desired speed model
82 */
83 public AbstractIDM(final DesiredHeadwayModel desiredHeadwayModel, final DesiredSpeedModel desiredSpeedModel)
84 {
85 super(desiredHeadwayModel, desiredSpeedModel);
86 }
87
88 /**
89 * Determination of car-following acceleration, possibly based on multiple leaders. This implementation calculates the IDM
90 * free term, which is returned if there are no leaders. If there are leaders <tt>combineInteractionTerm()</tt> is invoked
91 * to combine the free term with some implementation specific interaction term. The IDM free term is limited by a
92 * deceleration of <tt>B0</tt> for cases where the current speed is above the desired speed. This method can be overridden
93 * if the free term needs to be redefined.
94 * @param parameters Parameters.
95 * @param speed Current speed.
96 * @param desiredSpeed Desired speed.
97 * @param desiredHeadway Desired headway.
98 * @param leaders Set of leader headways (guaranteed positive) and speeds, ordered by headway (closest first).
99 * @throws ParameterException If parameter exception occurs.
100 * @return Car-following acceleration.
101 */
102 @Override
103 @SuppressWarnings("checkstyle:designforextension")
104 protected Acceleration followingAcceleration(final Parameters parameters, final Speed speed, final Speed desiredSpeed,
105 final Length desiredHeadway, final PerceptionIterable<? extends Headway> leaders) throws ParameterException
106 {
107 Acceleration a = parameters.getParameter(A);
108 Acceleration b0 = parameters.getParameter(B0);
109 double delta = parameters.getParameter(DELTA);
110 double aFree = a.si * (1 - Math.pow(speed.si / desiredSpeed.si, delta));
111 // limit deceleration in free term (occurs if speed > desired speed)
112 aFree = aFree > -b0.si ? aFree : -b0.si;
113 // return free term if there are no leaders
114 if (!leaders.iterator().hasNext())
115 {
116 return Acceleration.createSI(aFree);
117 }
118 // return combined acceleration
119 return combineInteractionTerm(Acceleration.createSI(aFree), parameters, speed, desiredSpeed, desiredHeadway, leaders);
120 }
121
122 /**
123 * Combines an interaction term with the free term. There should be at least 1 leader for this method.
124 * @param aFree Free term of acceleration.
125 * @param parameters Parameters.
126 * @param speed Current speed.
127 * @param desiredSpeed Desired speed.
128 * @param desiredHeadway Desired headway.
129 * @param leaders Set of leader headways (guaranteed positive) and speeds, ordered by headway (closest first).
130 * @return Combination of terms into a single acceleration.
131 * @throws ParameterException In case of parameter exception.
132 */
133 protected abstract Acceleration combineInteractionTerm(Acceleration aFree, Parameters parameters, Speed speed,
134 Speed desiredSpeed, Length desiredHeadway, PerceptionIterable<? extends Headway> leaders) throws ParameterException;
135
136 /**
137 * Determines the dynamic desired headway, which is non-negative.
138 * @param parameters Parameters.
139 * @param speed Current speed.
140 * @param desiredHeadway Desired headway.
141 * @param leaderSpeed Speed of the leading vehicle.
142 * @return Dynamic desired headway.
143 * @throws ParameterException In case of parameter exception.
144 */
145 protected final Length dynamicDesiredHeadway(final Parameters parameters, final Speed speed, final Length desiredHeadway,
146 final Speed leaderSpeed) throws ParameterException
147 {
148 double sStar = desiredHeadway.si + dynamicHeadwayTerm(parameters, speed, leaderSpeed).si;
149 /*
150 * Due to a power of 2 in the IDM, negative values of sStar are not allowed. A negative sStar means that the leader is
151 * faster to such an extent, that the equilibrium headway (s0+vT) is completely compensated by the dynamic part in
152 * sStar. This might occur if a much faster leader changes lane closely in front. The compensation is limited to the
153 * equilibrium headway minus the stopping distance (i.e. sStar > s0), which means the driver wants to follow with
154 * acceleration. Note that usually the free term determines acceleration in such cases.
155 */
156 Length s0 = parameters.getParameter(S0);
157 /*
158 * Limit used to be 0, but the IDM is very sensitive there. With a decelerating leader, an ok acceleration in one time
159 * step, may results in acceleration < -10 in the next.
160 */
161 return Length.createSI(sStar >= s0.si ? sStar : s0.si);
162 }
163
164 /**
165 * Determines the dynamic headway term. May be used on individual leaders for multi-anticipative following.
166 * @param parameters Parameters.
167 * @param speed Current speed.
168 * @param leaderSpeed Speed of the leading vehicle.
169 * @return Dynamic headway term.
170 * @throws ParameterException In case of parameter exception.
171 */
172 protected final Length dynamicHeadwayTerm(final Parameters parameters, final Speed speed, final Speed leaderSpeed)
173 throws ParameterException
174 {
175 Acceleration a = parameters.getParameter(A);
176 Acceleration b = parameters.getParameter(B);
177 return Length.createSI(speed.si * (speed.si - leaderSpeed.si) / (2 * Math.sqrt(a.si * b.si)));
178 }
179
180 }