AbstractIDM.java

  1. package org.opentrafficsim.road.gtu.lane.tactical.following;

  2. import org.djunits.value.vdouble.scalar.Acceleration;
  3. import org.djunits.value.vdouble.scalar.Length;
  4. import org.djunits.value.vdouble.scalar.Speed;
  5. import org.opentrafficsim.base.parameters.ParameterException;
  6. import org.opentrafficsim.base.parameters.ParameterTypeAcceleration;
  7. import org.opentrafficsim.base.parameters.ParameterTypeDouble;
  8. import org.opentrafficsim.base.parameters.ParameterTypeDuration;
  9. import org.opentrafficsim.base.parameters.ParameterTypeLength;
  10. import org.opentrafficsim.base.parameters.ParameterTypes;
  11. import org.opentrafficsim.base.parameters.Parameters;
  12. import org.opentrafficsim.base.parameters.constraint.ConstraintInterface;
  13. import org.opentrafficsim.road.gtu.lane.perception.PerceptionIterable;
  14. import org.opentrafficsim.road.gtu.lane.perception.headway.Headway;
  15. import org.opentrafficsim.road.gtu.lane.tactical.util.SpeedLimitUtil;
  16. import org.opentrafficsim.road.network.speed.SpeedLimitInfo;

  17. /**
  18.  * Implementation of the IDM. See <a
  19.  * href=https://en.wikipedia.org/wiki/Intelligent_driver_model>https://en.wikipedia.org/wiki/Intelligent_driver_model</a>
  20.  * <p>
  21.  * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  22.  * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
  23.  * <p>
  24.  * @version $Revision$, $LastChangedDate$, by $Author$, initial version Apr 22, 2016 <br>
  25.  * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
  26.  * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
  27.  * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
  28.  */
  29. public abstract class AbstractIDM extends AbstractCarFollowingModel
  30. {

  31.     /** Acceleration parameter type. */
  32.     protected static final ParameterTypeAcceleration A = ParameterTypes.A;

  33.     /** Comfortable deceleration parameter type. */
  34.     protected static final ParameterTypeAcceleration B = ParameterTypes.B;

  35.     /** Desired headway parameter type. */
  36.     protected static final ParameterTypeDuration T = ParameterTypes.T;

  37.     /** Stopping distance parameter type. */
  38.     protected static final ParameterTypeLength S0 = ParameterTypes.S0;

  39.     /** Adjustment deceleration parameter type. */
  40.     protected static final ParameterTypeAcceleration B0 = ParameterTypes.B0;

  41.     /** Speed limit adherence factor parameter type. */
  42.     protected static final ParameterTypeDouble FSPEED = ParameterTypes.FSPEED;

  43.     /** Acceleration flattening. */
  44.     public static final ParameterTypeDouble DELTA = new ParameterTypeDouble("delta",
  45.             "Acceleration flattening exponent towards desired speed", 4.0, ConstraintInterface.POSITIVE);

  46.     /** Default IDM desired headway model. */
  47.     public static final DesiredHeadwayModel HEADWAY = new DesiredHeadwayModel()
  48.     {
  49.         @Override
  50.         public Length desiredHeadway(final Parameters parameters, final Speed speed) throws ParameterException
  51.         {
  52.             return Length.instantiateSI(parameters.getParameter(S0).si + speed.si * parameters.getParameter(T).si);
  53.         }
  54.     };

  55.     /** Default IDM desired speed model. */
  56.     public static final DesiredSpeedModel DESIRED_SPEED = new DesiredSpeedModel()
  57.     {
  58.         @Override
  59.         public Speed desiredSpeed(final Parameters parameters, final SpeedLimitInfo speedInfo) throws ParameterException
  60.         {
  61.             Speed consideredSpeed = SpeedLimitUtil.getLegalSpeedLimit(speedInfo).times(parameters.getParameter(FSPEED));
  62.             Speed maxVehicleSpeed = SpeedLimitUtil.getMaximumVehicleSpeed(speedInfo);
  63.             return consideredSpeed.le(maxVehicleSpeed) ? consideredSpeed : maxVehicleSpeed;
  64.         }
  65.     };

  66.     /**
  67.      * Constructor with modular models for desired headway and desired speed.
  68.      * @param desiredHeadwayModel DesiredHeadwayModel; desired headway model
  69.      * @param desiredSpeedModel DesiredSpeedModel; desired speed model
  70.      */
  71.     public AbstractIDM(final DesiredHeadwayModel desiredHeadwayModel, final DesiredSpeedModel desiredSpeedModel)
  72.     {
  73.         super(desiredHeadwayModel, desiredSpeedModel);
  74.     }

  75.     /**
  76.      * Determination of car-following acceleration, possibly based on multiple leaders. This implementation calculates the IDM
  77.      * free term, which is returned if there are no leaders. If there are leaders <code>combineInteractionTerm()</code> is invoked
  78.      * to combine the free term with some implementation specific interaction term. The IDM free term is limited by a
  79.      * deceleration of <code>B0</code> for cases where the current speed is above the desired speed. This method can be overridden
  80.      * if the free term needs to be redefined.
  81.      * @param parameters Parameters; Parameters.
  82.      * @param speed Speed; Current speed.
  83.      * @param desiredSpeed Speed; Desired speed.
  84.      * @param desiredHeadway Length; Desired headway.
  85.      * @param leaders PerceptionIterable&lt;? extends Headway&gt;; Set of leader headways (guaranteed positive) and speeds,
  86.      *            ordered by headway (closest first).
  87.      * @throws ParameterException If parameter exception occurs.
  88.      * @return Car-following acceleration.
  89.      */
  90.     @Override
  91.     @SuppressWarnings("checkstyle:designforextension")
  92.     protected Acceleration followingAcceleration(final Parameters parameters, final Speed speed, final Speed desiredSpeed,
  93.             final Length desiredHeadway, final PerceptionIterable<? extends Headway> leaders) throws ParameterException
  94.     {
  95.         Acceleration a = parameters.getParameter(A);
  96.         Acceleration b0 = parameters.getParameter(B0);
  97.         double delta = parameters.getParameter(DELTA);
  98.         double aFree = a.si * (1 - Math.pow(speed.si / desiredSpeed.si, delta));
  99.         // limit deceleration in free term (occurs if speed > desired speed)
  100.         aFree = aFree > -b0.si ? aFree : -b0.si;
  101.         // return free term if there are no leaders
  102.         if (leaders.isEmpty())
  103.         {
  104.             return Acceleration.instantiateSI(aFree);
  105.         }
  106.         // return combined acceleration
  107.         return combineInteractionTerm(Acceleration.instantiateSI(aFree), parameters, speed, desiredSpeed, desiredHeadway, leaders);
  108.     }

  109.     /**
  110.      * Combines an interaction term with the free term. There should be at least 1 leader for this method.
  111.      * @param aFree Acceleration; Free term of acceleration.
  112.      * @param parameters Parameters; Parameters.
  113.      * @param speed Speed; Current speed.
  114.      * @param desiredSpeed Speed; Desired speed.
  115.      * @param desiredHeadway Length; Desired headway.
  116.      * @param leaders PerceptionIterable&lt;? extends Headway&gt;; Set of leader headways (guaranteed positive) and speeds,
  117.      *            ordered by headway (closest first).
  118.      * @return Combination of terms into a single acceleration.
  119.      * @throws ParameterException In case of parameter exception.
  120.      */
  121.     protected abstract Acceleration combineInteractionTerm(Acceleration aFree, Parameters parameters, Speed speed,
  122.             Speed desiredSpeed, Length desiredHeadway, PerceptionIterable<? extends Headway> leaders) throws ParameterException;

  123.     /**
  124.      * Determines the dynamic desired headway, which is non-negative.
  125.      * @param parameters Parameters; Parameters.
  126.      * @param speed Speed; Current speed.
  127.      * @param desiredHeadway Length; Desired headway.
  128.      * @param leaderSpeed Speed; Speed of the leading vehicle.
  129.      * @return Dynamic desired headway.
  130.      * @throws ParameterException In case of parameter exception.
  131.      */
  132.     protected final Length dynamicDesiredHeadway(final Parameters parameters, final Speed speed, final Length desiredHeadway,
  133.             final Speed leaderSpeed) throws ParameterException
  134.     {
  135.         double sStar = desiredHeadway.si + dynamicHeadwayTerm(parameters, speed, leaderSpeed).si;
  136.         /*
  137.          * Due to a power of 2 in the IDM, negative values of sStar are not allowed. A negative sStar means that the leader is
  138.          * faster to such an extent, that the equilibrium headway (s0+vT) is completely compensated by the dynamic part in
  139.          * sStar. This might occur if a much faster leader changes lane closely in front. The compensation is limited to the
  140.          * equilibrium headway minus the stopping distance (i.e. sStar > s0), which means the driver wants to follow with
  141.          * acceleration. Note that usually the free term determines acceleration in such cases.
  142.          */
  143.         Length s0 = parameters.getParameter(S0);
  144.         /*
  145.          * Limit used to be 0, but the IDM is very sensitive there. With a decelerating leader, an ok acceleration in one time
  146.          * step, may results in acceleration < -10 in the next.
  147.          */
  148.         return Length.instantiateSI(sStar >= s0.si ? sStar : s0.si);
  149.     }

  150.     /**
  151.      * Determines the dynamic headway term. May be used on individual leaders for multi-anticipative following.
  152.      * @param parameters Parameters; Parameters.
  153.      * @param speed Speed; Current speed.
  154.      * @param leaderSpeed Speed; Speed of the leading vehicle.
  155.      * @return Dynamic headway term.
  156.      * @throws ParameterException In case of parameter exception.
  157.      */
  158.     protected final Length dynamicHeadwayTerm(final Parameters parameters, final Speed speed, final Speed leaderSpeed)
  159.             throws ParameterException
  160.     {
  161.         Acceleration a = parameters.getParameter(A);
  162.         Acceleration b = parameters.getParameter(B);
  163.         return Length.instantiateSI(speed.si * (speed.si - leaderSpeed.si) / (2 * Math.sqrt(a.si * b.si)));
  164.     }

  165. }