GapAcceptance.java

  1. package org.opentrafficsim.road.gtu.lane.tactical.util.lmrs;

  2. import org.djunits.unit.AccelerationUnit;
  3. import org.djunits.value.vdouble.scalar.Acceleration;
  4. import org.djunits.value.vdouble.scalar.Speed;
  5. import org.opentrafficsim.base.parameters.ParameterException;
  6. import org.opentrafficsim.base.parameters.ParameterTypes;
  7. import org.opentrafficsim.base.parameters.Parameters;
  8. import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
  9. import org.opentrafficsim.core.network.LateralDirectionality;
  10. import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
  11. import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.NeighborsPerception;
  12. import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGtu;
  13. import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
  14. import org.opentrafficsim.road.network.speed.SpeedLimitInfo;

  15. /**
  16.  * Interface for LMRS gap-acceptance models.
  17.  * <p>
  18.  * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
  19.  * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
  20.  * </p>
  21.  * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
  22.  * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
  23.  * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
  24.  */
  25. public interface GapAcceptance
  26. {

  27.     /** Being informed of the model and parameters of other drivers (default LMRS). */
  28.     GapAcceptance INFORMED = new GapAcceptance()
  29.     {
  30.         /** {@inheritDoc} */
  31.         @Override
  32.         public boolean acceptGap(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
  33.                 final CarFollowingModel cfm, final double desire, final Speed ownSpeed, final Acceleration ownAcceleration,
  34.                 final LateralDirectionality lat) throws ParameterException, OperationalPlanException
  35.         {
  36.             NeighborsPerception neighbors = perception.getPerceptionCategory(NeighborsPerception.class);
  37.             if (neighbors.isGtuAlongside(lat))
  38.             {
  39.                 // gtu alongside
  40.                 return false;
  41.             }

  42.             // TODO
  43.             /*-
  44.              * Followers and are accepted if the acceleration and speed is 0, a leader is accepted if the ego speed is 0. This
  45.              * is in place as vehicles that provide courtesy, will decelerate for us and overshoot the stand-still distance. As
  46.              * a consequence, they will cease cooperation as they are too close. A pattern will arise where followers slow down
  47.              * to (near) stand-still, and accelerate again, before we could ever accept the gap.
  48.              *
  49.              * By accepting the gap in the moment that they reach stand-still, this vehicle can at least accept the gap at some
  50.              * point. All of this is only a problem if the own vehicle is standing still. Otherwise the stand-still distance is
  51.              * not important and movement of our own will create an acceptable situation.
  52.              *
  53.              * What needs to be done, is to find a better way to deal with the cooperation and gap-acceptance, such that this  
  54.              * hack is not required.
  55.              */

  56.             Acceleration b = params.getParameter(ParameterTypes.B);
  57.             Acceleration aFollow = new Acceleration(Double.POSITIVE_INFINITY, AccelerationUnit.SI);
  58.             for (HeadwayGtu follower : neighbors.getFirstFollowers(lat))
  59.             {
  60.                 if (follower.getSpeed().gt0() || follower.getAcceleration().gt0() || follower.getDistance().si < 1.0)
  61.                 {
  62.                     Acceleration a = LmrsUtil.singleAcceleration(follower.getDistance(), follower.getSpeed(), ownSpeed, desire,
  63.                             follower.getParameters(), follower.getSpeedLimitInfo(), follower.getCarFollowingModel());
  64.                     aFollow = Acceleration.min(aFollow, a);
  65.                 }
  66.             }

  67.             Acceleration aSelf = egoAcceleration(perception, params, sli, cfm, desire, ownSpeed, lat);
  68.             Acceleration threshold = b.times(-desire);
  69.             return aFollow.ge(threshold) && aSelf.ge(threshold) && ownAcceleration.ge(threshold);
  70.         }

  71.         /** {@inheritDoc} */
  72.         @Override
  73.         public String toString()
  74.         {
  75.             return "INFORMED";
  76.         }
  77.     };

  78.     /** Being informed of the model and parameters of other drivers, but applying own headway value. */
  79.     GapAcceptance EGO_HEADWAY = new GapAcceptance()
  80.     {
  81.         /** {@inheritDoc} */
  82.         @Override
  83.         public boolean acceptGap(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
  84.                 final CarFollowingModel cfm, final double desire, final Speed ownSpeed, final Acceleration ownAcceleration,
  85.                 final LateralDirectionality lat) throws ParameterException, OperationalPlanException
  86.         {
  87.             NeighborsPerception neigbors = perception.getPerceptionCategory(NeighborsPerception.class);
  88.             if (neigbors.isGtuAlongside(lat))
  89.             {
  90.                 // gtu alongside
  91.                 return false;
  92.             }

  93.             Acceleration b = params.getParameter(ParameterTypes.B);
  94.             Acceleration aFollow = new Acceleration(Double.POSITIVE_INFINITY, AccelerationUnit.SI);
  95.             for (HeadwayGtu follower : neigbors.getFirstFollowers(lat))
  96.             {
  97.                 if (follower.getSpeed().gt0() || follower.getAcceleration().gt0())
  98.                 {
  99.                     // Change headway parameter
  100.                     Parameters folParams = follower.getParameters();
  101.                     folParams.setParameterResettable(ParameterTypes.TMIN, params.getParameter(ParameterTypes.TMIN));
  102.                     folParams.setParameterResettable(ParameterTypes.TMAX, params.getParameter(ParameterTypes.TMAX));
  103.                     Acceleration a = LmrsUtil.singleAcceleration(follower.getDistance(), follower.getSpeed(), ownSpeed, desire,
  104.                             folParams, follower.getSpeedLimitInfo(), follower.getCarFollowingModel());
  105.                     aFollow = Acceleration.min(aFollow, a);
  106.                     folParams.resetParameter(ParameterTypes.TMIN);
  107.                     folParams.resetParameter(ParameterTypes.TMAX);
  108.                 }
  109.             }

  110.             Acceleration aSelf = egoAcceleration(perception, params, sli, cfm, desire, ownSpeed, lat);
  111.             Acceleration threshold = b.times(-desire);
  112.             return aFollow.ge(threshold) && aSelf.ge(threshold);
  113.         }

  114.         /** {@inheritDoc} */
  115.         @Override
  116.         public String toString()
  117.         {
  118.             return "EGO_HEADWAY";
  119.         }
  120.     };

  121.     /**
  122.      * Determine whether a gap is acceptable.
  123.      * @param perception LanePerception; perception
  124.      * @param params Parameters; parameters
  125.      * @param sli SpeedLimitInfo; speed limit info
  126.      * @param cfm CarFollowingModel; car-following model
  127.      * @param desire double; level of lane change desire
  128.      * @param ownSpeed Speed; own speed
  129.      * @param lat LateralDirectionality; lateral direction for synchronization
  130.      * @return whether a gap is acceptable
  131.      * @throws ParameterException if a parameter is not defined
  132.      * @throws OperationalPlanException perception exception
  133.      */
  134.     static Acceleration egoAcceleration(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
  135.             final CarFollowingModel cfm, final double desire, final Speed ownSpeed, final LateralDirectionality lat)
  136.             throws ParameterException, OperationalPlanException
  137.     {
  138.         Acceleration aSelf = new Acceleration(Double.POSITIVE_INFINITY, AccelerationUnit.SI);
  139.         if (ownSpeed.gt0())
  140.         {
  141.             for (

  142.             HeadwayGtu leader : perception.getPerceptionCategory(NeighborsPerception.class).getFirstLeaders(lat))
  143.             {
  144.                 Acceleration a = LmrsUtil.singleAcceleration(leader.getDistance(), ownSpeed, leader.getSpeed(), desire, params,
  145.                         sli, cfm);
  146.                 aSelf = Acceleration.min(aSelf, a);
  147.             }
  148.         }
  149.         return aSelf;
  150.     }

  151.     /**
  152.      * Determine whether a gap is acceptable.
  153.      * @param perception LanePerception; perception
  154.      * @param params Parameters; parameters
  155.      * @param sli SpeedLimitInfo; speed limit info
  156.      * @param cfm CarFollowingModel; car-following model
  157.      * @param desire double; level of lane change desire
  158.      * @param ownSpeed Speed; own speed
  159.      * @param ownAcceleration Acceleration; current car-following acceleration
  160.      * @param lat LateralDirectionality; lateral direction for synchronization
  161.      * @return whether a gap is acceptable
  162.      * @throws ParameterException if a parameter is not defined
  163.      * @throws OperationalPlanException perception exception
  164.      */
  165.     boolean acceptGap(LanePerception perception, Parameters params, SpeedLimitInfo sli, CarFollowingModel cfm, double desire,
  166.             Speed ownSpeed, Acceleration ownAcceleration, LateralDirectionality lat)
  167.             throws ParameterException, OperationalPlanException;

  168. }