View Javadoc
1   package org.opentrafficsim.road.gtu.lane.tactical.util.lmrs;
2   
3   import static org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.GapAcceptance.egoAcceleration;
4   
5   import org.djunits.unit.AccelerationUnit;
6   import org.djunits.value.vdouble.scalar.Acceleration;
7   import org.djunits.value.vdouble.scalar.Speed;
8   import org.opentrafficsim.base.parameters.ParameterException;
9   import org.opentrafficsim.base.parameters.ParameterTypes;
10  import org.opentrafficsim.base.parameters.Parameters;
11  import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
12  import org.opentrafficsim.core.network.LateralDirectionality;
13  import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
14  import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.NeighborsPerception;
15  import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGTU;
16  import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
17  import org.opentrafficsim.road.network.speed.SpeedLimitInfo;
18  
19  /**
20   * Interface for LMRS gap-acceptance models.
21   * <p>
22   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
23   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
24   * <p>
25   * @version $Revision$, $LastChangedDate$, by $Author$, initial version 9 okt. 2017 <br>
26   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
27   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
28   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
29   */
30  public interface GapAcceptance
31  {
32  
33      /** Being informed of the model and parameters of other drivers (default LMRS). */
34      GapAcceptance INFORMED = new GapAcceptance()
35      {
36  
37          @Override
38          public boolean acceptGap(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
39                  final CarFollowingModel cfm, final double desire, final Speed ownSpeed, final Acceleration ownAcceleration,
40                  final LateralDirectionality lat) throws ParameterException, OperationalPlanException
41          {
42              NeighborsPerception neighbors = perception.getPerceptionCategory(NeighborsPerception.class);
43              if (neighbors.isGtuAlongside(lat))
44              {
45                  // gtu alongside
46                  return false;
47              }
48  
49              // TODO
50              /*-
51               * Followers and are accepted if the acceleration and speed is 0, a leader is accepted if the ego speed is 0. This 
52               * is in place as vehicles that provide courtesy, will decelerate for us and overshoot the stand-still distance. As
53               * a consequence, they will cease cooperation as they are too close. A pattern will arise where followers slow down
54               * to (near) stand-still, and accelerate again, before we could ever accept the gap.
55               * 
56               * By accepting the gap in the moment that they reach stand-still, this vehicle can at least accept the gap at some 
57               * point. All of this is only a problem if the own vehicle is standing still. Otherwise the stand-still distance is 
58               * not important and movement of our own will create an acceptable situation.
59               * 
60               * What needs to be done, is to find a better way to deal with the cooperation and gap-acceptance, such that this  
61               * hack is not required.
62               */
63  
64              Acceleration b = params.getParameter(ParameterTypes.B);
65              Acceleration aFollow = new Acceleration(Double.POSITIVE_INFINITY, AccelerationUnit.SI);
66              for (HeadwayGTU follower : neighbors.getFirstFollowers(lat))
67              {
68                  if (follower.getSpeed().gt0() || follower.getAcceleration().gt0() || follower.getDistance().si < 1.0)
69                  {
70                      Acceleration a = LmrsUtil.singleAcceleration(follower.getDistance(), follower.getSpeed(), ownSpeed, desire,
71                              follower.getParameters(), follower.getSpeedLimitInfo(), follower.getCarFollowingModel());
72                      aFollow = Acceleration.min(aFollow, a);
73                  }
74              }
75  
76              Acceleration aSelf = egoAcceleration(perception, params, sli, cfm, desire, ownSpeed, lat);
77              Acceleration threshold = b.multiplyBy(-desire);
78              return aFollow.ge(threshold) && aSelf.ge(threshold) && ownAcceleration.ge(threshold);
79          }
80  
81          /** {@inheritDoc} */
82          @Override
83          public String toString()
84          {
85              return "INFORMED";
86          }
87  
88      };
89  
90      /** Being informed of the model and parameters of other drivers, but applying own headway value. */
91      GapAcceptance EGO_HEADWAY = new GapAcceptance()
92      {
93  
94          @Override
95          public boolean acceptGap(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
96                  final CarFollowingModel cfm, final double desire, final Speed ownSpeed, final Acceleration ownAcceleration,
97                  final LateralDirectionality lat) throws ParameterException, OperationalPlanException
98          {
99              NeighborsPerception neigbors = perception.getPerceptionCategory(NeighborsPerception.class);
100             if (neigbors.isGtuAlongside(lat))
101             {
102                 // gtu alongside
103                 return false;
104             }
105 
106             Acceleration b = params.getParameter(ParameterTypes.B);
107             Acceleration aFollow = new Acceleration(Double.POSITIVE_INFINITY, AccelerationUnit.SI);
108             for (HeadwayGTU follower : neigbors.getFirstFollowers(lat))
109             {
110                 if (follower.getSpeed().gt0() || follower.getAcceleration().gt0())
111                 {
112                     // Change headway parameter
113                     Parameters folParams = follower.getParameters();
114                     folParams.setParameterResettable(ParameterTypes.TMIN, params.getParameter(ParameterTypes.TMIN));
115                     folParams.setParameterResettable(ParameterTypes.TMAX, params.getParameter(ParameterTypes.TMAX));
116                     Acceleration a = LmrsUtil.singleAcceleration(follower.getDistance(), follower.getSpeed(), ownSpeed, desire,
117                             folParams, follower.getSpeedLimitInfo(), follower.getCarFollowingModel());
118                     aFollow = Acceleration.min(aFollow, a);
119                     folParams.resetParameter(ParameterTypes.TMIN);
120                     folParams.resetParameter(ParameterTypes.TMAX);
121                 }
122             }
123 
124             Acceleration aSelf = egoAcceleration(perception, params, sli, cfm, desire, ownSpeed, lat);
125             Acceleration threshold = b.multiplyBy(-desire);
126             return aFollow.ge(threshold) && aSelf.ge(threshold);
127         }
128 
129         /** {@inheritDoc} */
130         @Override
131         public String toString()
132         {
133             return "EGO_HEADWAY";
134         }
135 
136     };
137 
138     /**
139      * Determine whether a gap is acceptable.
140      * @param perception LanePerception; perception
141      * @param params Parameters; parameters
142      * @param sli SpeedLimitInfo; speed limit info
143      * @param cfm CarFollowingModel; car-following model
144      * @param desire double; level of lane change desire
145      * @param ownSpeed Speed; own speed
146      * @param lat LateralDirectionality; lateral direction for synchronization
147      * @return whether a gap is acceptable
148      * @throws ParameterException if a parameter is not defined
149      * @throws OperationalPlanException perception exception
150      */
151     static Acceleration egoAcceleration(final LanePerception perception, final Parameters params, final SpeedLimitInfo sli,
152             final CarFollowingModel cfm, final double desire, final Speed ownSpeed, final LateralDirectionality lat)
153             throws ParameterException, OperationalPlanException
154     {
155         Acceleration aSelf = new Acceleration(Double.POSITIVE_INFINITY, AccelerationUnit.SI);
156         if (ownSpeed.gt0())
157         {
158             for (
159 
160             HeadwayGTU leader : perception.getPerceptionCategory(NeighborsPerception.class).getFirstLeaders(lat))
161             {
162                 Acceleration a = LmrsUtil.singleAcceleration(leader.getDistance(), ownSpeed, leader.getSpeed(), desire, params,
163                         sli, cfm);
164                 aSelf = Acceleration.min(aSelf, a);
165             }
166         }
167         return aSelf;
168     }
169 
170     /**
171      * Determine whether a gap is acceptable.
172      * @param perception LanePerception; perception
173      * @param params Parameters; parameters
174      * @param sli SpeedLimitInfo; speed limit info
175      * @param cfm CarFollowingModel; car-following model
176      * @param desire double; level of lane change desire
177      * @param ownSpeed Speed; own speed
178      * @param ownAcceleration Acceleration; current car-following acceleration
179      * @param lat LateralDirectionality; lateral direction for synchronization
180      * @return whether a gap is acceptable
181      * @throws ParameterException if a parameter is not defined
182      * @throws OperationalPlanException perception exception
183      */
184     boolean acceptGap(LanePerception perception, Parameters params, SpeedLimitInfo sli, CarFollowingModel cfm, double desire,
185             Speed ownSpeed, Acceleration ownAcceleration, LateralDirectionality lat)
186             throws ParameterException, OperationalPlanException;
187 
188 }