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.Length;
6   import org.djunits.value.vdouble.scalar.Speed;
7   import org.opentrafficsim.base.parameters.ParameterException;
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.core.gtu.perception.EgoPerception;
13  import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
14  import org.opentrafficsim.core.network.LateralDirectionality;
15  import org.opentrafficsim.road.gtu.lane.perception.InfrastructureLaneChangeInfo;
16  import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
17  import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
18  import org.opentrafficsim.road.gtu.lane.perception.categories.InfrastructurePerception;
19  import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
20  import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Desire;
21  import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.MandatoryIncentive;
22  
23  /**
24   * Determines desire by assessing the number of required lane change to be performed and the distance within which these have to
25   * be performed. Desire starts to increase from 0 linearly over a distance of x0 per required lane change, or per v*t0 per
26   * required lane change. For v>x0/t0 this gives that remaining time is critical, while for v<x0/t0 remaining space is
27   * critical. The desire is set towards the adjacent lane with a better situation. Negative desire towards the other lane, the
28   * extent of which pertains to the other adjacent lane, is also set.
29   * <p>
30   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
31   * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
32   * <p>
33   * @version $Revision$, $LastChangedDate$, by $Author$, initial version Apr 13, 2016 <br>
34   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
35   */
36  public class IncentiveRoute implements MandatoryIncentive
37  {
38  
39      /** Look ahead parameter type. */
40      protected static final ParameterTypeLength LOOKAHEAD = ParameterTypes.LOOKAHEAD;
41  
42      /** Look-ahead time for mandatory lane changes parameter type. */
43      public static final ParameterTypeDuration T0 = ParameterTypes.T0;
44  
45      /** {@inheritDoc} */
46      @Override
47      public final Desire determineDesire(final Parameters parameters, final LanePerception perception,
48              final CarFollowingModel carFollowingModel, final Desire mandatoryDesire)
49              throws ParameterException, OperationalPlanException
50      {
51          Speed speed = perception.getPerceptionCategory(EgoPerception.class).getSpeed();
52          InfrastructurePerception infra = perception.getPerceptionCategory(InfrastructurePerception.class);
53  
54          // desire to leave current lane
55          SortedSet<InfrastructureLaneChangeInfo> currentInfo = infra.getInfrastructureLaneChangeInfo(RelativeLane.CURRENT);
56          Length currentFirst = currentInfo.isEmpty() || currentInfo.first().getRequiredNumberOfLaneChanges() == 0
57                  ? Length.POSITIVE_INFINITY : currentInfo.first().getRemainingDistance();
58          double dCurr = getDesireToLeave(parameters, infra, RelativeLane.CURRENT, speed);
59          double dLeft = 0;
60          if (perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.LEFT)
61                  && infra.getLegalLaneChangePossibility(RelativeLane.CURRENT, LateralDirectionality.LEFT).neg().lt(currentFirst))
62          {
63              // desire to leave left lane
64              dLeft = getDesireToLeave(parameters, infra, RelativeLane.LEFT, speed);
65              // desire to leave from current to left lane
66              dLeft = dLeft < dCurr ? dCurr : dLeft > dCurr ? -dLeft : 0;
67          }
68          double dRigh = 0;
69          if (perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.RIGHT) && infra
70                  .getLegalLaneChangePossibility(RelativeLane.CURRENT, LateralDirectionality.RIGHT).neg().lt(currentFirst))
71          {
72              // desire to leave right lane
73              dRigh = getDesireToLeave(parameters, infra, RelativeLane.RIGHT, speed);
74              // desire to leave from current to right lane
75              dRigh = dRigh < dCurr ? dCurr : dRigh > dCurr ? -dRigh : 0;
76          }
77          return new Desire(dLeft, dRigh);
78      }
79  
80      /**
81       * Calculates desire to leave a lane.
82       * @param params Parameters; parameters
83       * @param infra InfrastructurePerception; infrastructure perception
84       * @param lane RelativeLane; relative lane to evaluate
85       * @param speed Speed; speed
86       * @return desire to leave a lane
87       * @throws ParameterException in case of a parameter exception
88       * @throws OperationalPlanException in case of perception exceptions
89       */
90      private static double getDesireToLeave(final Parameters params, final InfrastructurePerception infra,
91              final RelativeLane lane, final Speed speed) throws ParameterException, OperationalPlanException
92      {
93          double dOut = 0.0;
94          if (infra.getCrossSection().contains(lane))
95          {
96              for (InfrastructureLaneChangeInfo info : infra.getInfrastructureLaneChangeInfo(lane))
97              {
98                  double d = getDesireToLeave(params, info.getRemainingDistance(), info.getRequiredNumberOfLaneChanges(), speed);
99                  dOut = d > dOut ? d : dOut;
100             }
101         }
102         return dOut;
103     }
104 
105     /**
106      * Calculates desire to leave a lane for a single infrastructure info.
107      * @param params Parameters; parameters
108      * @param x Length; remaining distance for lane changes
109      * @param n int; number of required lane changes
110      * @param v Speed; current speed
111      * @return desire to leave a lane for a single infrastructure info
112      * @throws ParameterException in case of a parameter exception
113      */
114     public static double getDesireToLeave(final Parameters params, final Length x, final int n, final Speed v)
115             throws ParameterException
116     {
117         double d1 = 1 - x.si / (n * params.getParameter(LOOKAHEAD).si);
118         double d2 = 1 - (x.si / v.si) / (n * params.getParameter(T0).si);
119         d1 = d2 > d1 ? d2 : d1;
120         return d1 < 0 ? 0 : d1;
121     }
122 
123     /** {@inheritDoc} */
124     @Override
125     public final String toString()
126     {
127         return "IncentiveRoute";
128     }
129 
130 }