View Javadoc
1   package org.opentrafficsim.road.gtu.lane.tactical.lmrs;
2   
3   import java.util.SortedSet;
4   
5   import org.djunits.value.vdouble.scalar.Speed;
6   import org.opentrafficsim.base.parameters.ParameterException;
7   import org.opentrafficsim.base.parameters.ParameterTypeDouble;
8   import org.opentrafficsim.base.parameters.ParameterTypeSpeed;
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.road.gtu.lane.perception.InfrastructureLaneChangeInfo;
13  import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
14  import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
15  import org.opentrafficsim.road.gtu.lane.perception.categories.InfrastructurePerception;
16  import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.NeighborsPerception;
17  import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGTU;
18  import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
19  import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Desire;
20  import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
21  import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.MandatoryIncentive;
22  
23  /**
24   * Incentive that lets drivers queue in an adjacent lane as soon as the speed is low in the adjacent lane, and stopping in the
25   * current lane might block traffic towards other directions.
26   * <p>
27   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
28   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
29   * <p>
30   * @version $Revision$, $LastChangedDate$, by $Author$, initial version 28 mrt. 2017 <br>
31   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
32   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
33   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
34   */
35  public class IncentiveGetInLane implements MandatoryIncentive
36  {
37  
38      /** Congestion speed threshold parameter type. */
39      protected static final ParameterTypeSpeed VCONG = ParameterTypes.VCONG;
40  
41      /** Hierarchy parameter. */
42      protected static final ParameterTypeDouble SOCIO = LmrsParameters.SOCIO;
43  
44      /** {@inheritDoc} */
45      @Override
46      public Desire determineDesire(final Parameters parameters, final LanePerception perception,
47              final CarFollowingModel carFollowingModel, final Desire mandatoryDesire)
48              throws ParameterException, OperationalPlanException
49      {
50  
51          Speed vCong = parameters.getParameter(VCONG);
52          double socio = parameters.getParameter(SOCIO);
53          InfrastructurePerception infra = perception.getPerceptionCategory(InfrastructurePerception.class);
54          NeighborsPerception neighbors = perception.getPerceptionCategory(NeighborsPerception.class);
55          SortedSet<InfrastructureLaneChangeInfo> info = infra.getInfrastructureLaneChangeInfo(RelativeLane.CURRENT);
56          double dCur = info.isEmpty() ? Double.POSITIVE_INFINITY
57                  : info.first().getRemainingDistance().si / info.first().getRequiredNumberOfLaneChanges();
58          double left = 0;
59          double right = 0;
60          double vCur = Double.POSITIVE_INFINITY;
61  
62          for (RelativeLane lane : new RelativeLane[] {RelativeLane.LEFT, RelativeLane.RIGHT})
63          {
64              if (infra.getCrossSection().contains(lane))
65              {
66                  SortedSet<InfrastructureLaneChangeInfo> adjInfo = infra.getInfrastructureLaneChangeInfo(lane);
67                  double dAdj = adjInfo.isEmpty() ? Double.POSITIVE_INFINITY
68                          : adjInfo.first().getRemainingDistance().si / adjInfo.first().getRequiredNumberOfLaneChanges();
69                  if (!info.isEmpty() && !info.first().isDeadEnd() && dCur < dAdj)
70                  {
71                      double v = Double.POSITIVE_INFINITY;
72                      for (HeadwayGTU neighbor : neighbors.getLeaders(lane))
73                      {
74                          v = Math.min(v, neighbor.getSpeed().si);
75                      }
76                      if (lane.isLeft())
77                      {
78                          double d = Math.max(0.0, 1.0 - v / vCong.si);
79                          left += d;
80                          // right -= d;
81                      }
82                      else
83                      {
84                          double d = Math.max(0.0, 1.0 - v / vCong.si);
85                          right += d;
86                          // left -= d;
87                      }
88                  }
89                  if (!adjInfo.isEmpty() && !adjInfo.first().isDeadEnd()
90                          && (info.isEmpty() || (!info.isEmpty() && !info.first().isDeadEnd())) && dCur > dAdj)
91                  {
92                      if (Double.isInfinite(vCur))
93                      {
94                          for (HeadwayGTU neighbor : neighbors.getLeaders(RelativeLane.CURRENT))
95                          {
96                              vCur = Math.min(vCur, neighbor.getSpeed().si);
97                          }
98                      }
99                      if (lane.isLeft())
100                     {
101                         left -= Math.max(0.0, 1.0 - vCur / vCong.si);
102                     }
103                     else
104                     {
105                         right -= Math.max(0.0, 1.0 - vCur / vCong.si);
106                     }
107                 }
108             }
109         }
110         return new Desire(left * socio, right * socio);
111     }
112 
113     /** {@inheritDoc} */
114     @Override
115     public final String toString()
116     {
117         return "IncentiveGetInLane";
118     }
119 
120 }