View Javadoc
1   package org.opentrafficsim.road.gtu.lane.perception.mental;
2   
3   import org.djunits.value.vdouble.scalar.Duration;
4   import org.djutils.exceptions.Try;
5   import org.opentrafficsim.base.parameters.ParameterException;
6   import org.opentrafficsim.base.parameters.Parameters;
7   import org.opentrafficsim.core.gtu.GtuException;
8   import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;
9   import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
10  import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
11  import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.NeighborsPerception;
12  import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.TaskHeadwayCollector;
13  import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
14  
15  /**
16   * Lane changing task based on car-following (as gap-acceptance proxy), and an underlying consideration to include adjacent
17   * lanes.
18   * <p>
19   * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
20   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
21   * </p>
22   * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
23   * @author <a href="https://github.com/peter-knoppers">Peter Knoppers</a>
24   * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
25   */
26  public class TaskLaneChanging extends TaskHeadwayBased
27  {
28  
29      /** Lateral consideration. */
30      private final LateralConsideration lateralConsideration;
31  
32      /**
33       * Constructor.
34       * @param lateralConsideration lateral consideration
35       */
36      public TaskLaneChanging(final LateralConsideration lateralConsideration)
37      {
38          super("lane-changing");
39          this.lateralConsideration = lateralConsideration;
40      }
41  
42      @Override
43      protected Duration getHeadway(final LanePerception perception, final LaneBasedGtu gtu, final Parameters parameters)
44              throws ParameterException
45      {
46          NeighborsPerception neighbors = Try.assign(() -> perception.getPerceptionCategory(NeighborsPerception.class),
47                  "NeighborsPerception not available.");
48          double lat = Try.assign(() -> this.lateralConsideration.getConsideration(perception, gtu, parameters),
49                  "Exception during lateral consideration.");
50          RelativeLane lane;
51          if (Math.abs(lat) < 1e-9)
52          {
53              return null;
54          }
55          if (lat < 0.0)
56          {
57              lane = RelativeLane.LEFT;
58              lat = -lat;
59          }
60          else
61          {
62              lane = RelativeLane.RIGHT;
63          }
64          if (perception.getLaneStructure().exists(lane) && neighbors.isGtuAlongside(lane.getLateralDirectionality()))
65          {
66              return Duration.ZERO;
67          }
68          Duration h1 = neighbors.getLeaders(lane).collect(new TaskHeadwayCollector(getSpeed()));
69          Duration h2 = neighbors.getFollowers(lane).collect(new TaskHeadwayCollector(getSpeed()));
70          if (h1 == null)
71          {
72              return h2 == null ? null : h2.divide(lat);
73          }
74          if (h2 == null)
75          {
76              return h1 == null ? null : h1.divide(lat);
77          }
78          if (h1.eq0() && h2.eq0())
79          {
80              return Duration.ZERO;
81          }
82          return Duration.instantiateSI(h1.si * h2.si / (lat * (h1.si + h2.si)));
83      }
84  
85      /**
86       * Lateral consideration leading to lane change task demand.
87       * <p>
88       * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
89       * <br>
90       * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
91       * </p>
92       * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
93       * @author <a href="https://github.com/peter-knoppers">Peter Knoppers</a>
94       * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
95       */
96      public interface LateralConsideration
97      {
98  
99          /** Desire based lateral consideration. */
100         LateralConsideration DESIRE = new LateralConsideration()
101         {
102             @Override
103             public double getConsideration(final LanePerception perception, final LaneBasedGtu gtu, final Parameters parameters)
104                     throws ParameterException, GtuException
105             {
106                 double dLeft = gtu.getParameters().getParameter(LmrsParameters.DLEFT);
107                 double dRight = gtu.getParameters().getParameter(LmrsParameters.DRIGHT);
108                 if (dLeft > dRight && dLeft > 0.0)
109                 {
110                     return dLeft > 1.0 ? -1.0 : -dLeft;
111                 }
112                 else if (dRight > dLeft && dRight > 0.0)
113                 {
114                     return dRight > 1.0 ? 1.0 : dRight;
115                 }
116                 return 0.0;
117             }
118         };
119 
120         /**
121          * Returns fraction of lateral consideration, &lt;0 for left lane, &gt;0 for right lane. Should be in the range -1 ...
122          * 1.
123          * @param perception perception
124          * @param gtu gtu
125          * @param parameters parameters
126          * @return demand of this task
127          * @throws ParameterException if a parameter is missing or out of bounds
128          * @throws GtuException exceptions pertaining to the GTU
129          */
130         double getConsideration(LanePerception perception, LaneBasedGtu gtu, Parameters parameters)
131                 throws ParameterException, GtuException;
132     }
133 
134 }