View Javadoc
1   package org.opentrafficsim.road.gtu.lane.tactical.following;
2   
3   import java.util.SortedMap;
4   
5   import org.djunits.unit.AccelerationUnit;
6   import org.djunits.unit.LengthUnit;
7   import org.djunits.value.vdouble.scalar.Acceleration;
8   import org.djunits.value.vdouble.scalar.Length;
9   import org.djunits.value.vdouble.scalar.Length.Rel;
10  import org.djunits.value.vdouble.scalar.Speed;
11  import org.opentrafficsim.core.gtu.drivercharacteristics.ParameterException;
12  import org.opentrafficsim.core.gtu.drivercharacteristics.ParameterTypeDouble;
13  import org.opentrafficsim.core.gtu.drivercharacteristics.ParameterTypes;
14  import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
15  
16  /**
17   * Implementation of the IDM.
18   * See <a href=https://en.wikipedia.org/wiki/Intelligent_driver_model>https://en.wikipedia.org/wiki/Intelligent_driver_model</a>
19   * @author Wouter Schakel
20   */
21  public class IDM extends AbstractCarFollowingModel {
22  
23  	/** Speed limit adherence factor. */
24      public static final ParameterTypeDouble DELTA = new ParameterTypeDouble("delta", 
25      		"Acceleration flattening exponent towards desired speed.", 4.0) {
26      	public void check(double value) throws ParameterException {
27      		ParameterException.failIf(value<=0, "Parameter of type delta may not have a negative or zero value.");
28      	}
29      };
30  	
31  	/** {@inheritDoc} */
32  	public Speed desiredSpeed(LaneBasedGTU gtu, Speed speedLimit, boolean enforcement, Speed maximumVehicleSpeed) 
33  			throws ParameterException {
34  		if (!enforcement) {
35  			speedLimit = speedLimit.multiplyBy(gtu.getBehavioralCharacteristics().getParameter(ParameterTypes.FSPEED));
36  		}
37  		return speedLimit.le(maximumVehicleSpeed) ? speedLimit : maximumVehicleSpeed;
38  	}
39  
40  	/** {@inheritDoc} */
41  	public Rel desiredHeadway(LaneBasedGTU gtu, Speed speed) throws ParameterException {
42  		return gtu.getBehavioralCharacteristics().getLengthParameter(ParameterTypes.S0).plus(
43  				speed.multiplyBy(gtu.getBehavioralCharacteristics().getTimeParameter(ParameterTypes.T)));
44  	}
45  
46  	/** {@inheritDoc} */
47  	public String getName() {
48  		return "IDM";
49  	}
50  
51  	/** {@inheritDoc} */
52  	public String getLongName() {
53  		return "Intelligent Driver Model";
54  	}
55  
56  	/** {@inheritDoc} */
57  	protected Acceleration followingAcceleration(LaneBasedGTU gtu, Speed speed, Speed desiredSpeed, Rel desiredHeadway,
58  			SortedMap<Rel, Speed> leaders) throws ParameterException {
59  		Acceleration a = gtu.getBehavioralCharacteristics().getAccelerationParameter(ParameterTypes.A);
60  		double delta = gtu.getBehavioralCharacteristics().getParameter(DELTA);
61  		double sStar = dynamicDesiredHeadway(gtu, speed, desiredHeadway, leaders.get(leaders.firstKey())).si;
62  		return new Acceleration(a.si * (1-Math.pow(speed.si/desiredSpeed.si, delta)-
63  				(sStar/leaders.firstKey().si)*(sStar/leaders.firstKey().si)), AccelerationUnit.SI);
64  	}
65  	
66  	/**
67  	 * Determines the dynamic desired headway, which is non-negative.
68  	 * @param gtu GTU for which the dynamic desired headway is calculated.
69  	 * @param speed Current speed.
70  	 * @param desiredHeadway Desired speed.
71  	 * @param leaderSpeed Speed of the leading vehicle.
72  	 * @return Dynamic desired headway.
73  	 * @throws ParameterException x
74  	 */
75  	protected Length.Rel dynamicDesiredHeadway(LaneBasedGTU gtu, Speed speed, Rel desiredHeadway, Speed leaderSpeed) 
76  			throws ParameterException {
77  		double sStar = desiredHeadway.si + dynamicHeadwayTerm(gtu, speed, leaderSpeed).si;
78  		/*
79  		 * Due to a power of 2 in the IDM, negative values of sStar are not allowed. A negative sStar means that the 
80  		 * leader is faster to such an extent, that the equilibrium headway (s0+vT) is completely compensated by the 
81  		 * dynamic part in sStar. This might occur if a much faster leader changes lane closely in front. The 
82  		 * compensation is limited to the equilibrium headway (i.e. sStar = 0), which means the driver wants to follow 
83  		 * with acceleration. Note that usually the free term determines acceleration in such cases.
84  		 */
85  		return new Length.Rel(sStar>=0 ? sStar : 0, LengthUnit.SI);
86  	}
87  	
88  	/**
89  	 * Determines the dynamic headway term. May be used on individual leaders for multi-anticipative following.
90  	 * @param gtu GTU for which the dynamic desired headway term is calculated.
91  	 * @param speed Current speed.
92  	 * @param leaderSpeed Speed of the leading vehicle.
93  	 * @return Dynamic headway term.
94  	 * @throws ParameterException  x
95  	 */
96  	protected Length.Rel dynamicHeadwayTerm(LaneBasedGTU gtu, Speed speed, Speed leaderSpeed) throws ParameterException {
97  		Acceleration a = gtu.getBehavioralCharacteristics().getAccelerationParameter(ParameterTypes.A);
98  		Acceleration b = gtu.getBehavioralCharacteristics().getAccelerationParameter(ParameterTypes.B);
99  		return new Length.Rel(speed.si*(speed.si-leaderSpeed.si) / (2*Math.sqrt(a.si + b.si)), LengthUnit.SI);
100 	}
101 
102 }