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