View Javadoc
1   package org.opentrafficsim.road.gtu.lane.perception.mental.channel;
2   
3   import java.util.Iterator;
4   import java.util.Set;
5   import java.util.function.Function;
6   
7   import org.djunits.value.vdouble.scalar.Length;
8   import org.djutils.exceptions.Try;
9   import org.opentrafficsim.base.parameters.ParameterException;
10  import org.opentrafficsim.base.parameters.ParameterTypeDouble;
11  import org.opentrafficsim.base.parameters.ParameterTypeLength;
12  import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;
13  import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
14  import org.opentrafficsim.road.gtu.lane.perception.PerceptionCollectable.UnderlyingDistance;
15  import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
16  import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.NeighborsPerception;
17  import org.opentrafficsim.road.gtu.lane.perception.mental.AbstractTask;
18  import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
19  
20  /**
21   * Task demand for potential cut-in or cooperation. This is defined as the maximum value of {@code d*(1-s/x0)} where {@code d}
22   * is lane change desire towards the ego lane of any leader in either the left or right adjacent lane, {@code s} is the distance
23   * to the leader with lane change desire and {@code x0} is the look-ahead distance.
24   * <p>
25   * Copyright (c) 2024-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
26   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
27   * </p>
28   * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
29   */
30  public final class ChannelTaskCooperation extends AbstractTask implements ChannelTask
31  {
32  
33      /** Distance discount range. */
34      public static final ParameterTypeLength X0_D = ChannelMental.X0_D;
35  
36      /** Standard set of left and right cooperation task. */
37      private static final Set<ChannelTask> SET = Set.of(new ChannelTaskCooperation(true), new ChannelTaskCooperation(false));
38  
39      /** Standard supplier that supplies instances for left and right cooperation task. */
40      public static final Function<LanePerception, Set<ChannelTask>> SUPPLIER = (p) -> SET;
41  
42      /** Whether this task instance regards the left side. */
43      private final boolean left;
44  
45      /**
46       * Constructor.
47       * @param left whether this task instance regards the left side.
48       */
49      private ChannelTaskCooperation(final boolean left)
50      {
51          super("cooperation");
52          this.left = left;
53      }
54  
55      @Override
56      public String getId()
57      {
58          return this.left ? "cooperation (left)" : "cooperation (right)";
59      }
60  
61      @Override
62      public Object getChannel()
63      {
64          return this.left ? LEFT : RIGHT;
65      }
66  
67      @Override
68      public double calculateTaskDemand(final LanePerception perception)
69      {
70          NeighborsPerception neighbors = Try.assign(() -> perception.getPerceptionCategory(NeighborsPerception.class),
71                  "NeighborsPerception not present.");
72          Iterator<UnderlyingDistance<LaneBasedGtu>> leaders =
73                  neighbors.getLeaders(this.left ? RelativeLane.LEFT : RelativeLane.RIGHT).underlyingWithDistance();
74          ParameterTypeDouble param = this.left ? LmrsParameters.DRIGHT : LmrsParameters.DLEFT;
75          Length x0 = Try.assign(() -> perception.getGtu().getParameters().getParameter(X0_D), "Parameter x0_d not present.");
76          double dMax = 0.0;
77          while (leaders.hasNext())
78          {
79              UnderlyingDistance<LaneBasedGtu> leader = leaders.next();
80              if (leader.distance().gt(x0))
81              {
82                  break;
83              }
84              double d;
85              try
86              {
87                  d = leader.object().getParameters().getParameter(param) * (1.0 - leader.distance().si / x0.si);
88                  dMax = Math.max(dMax, d);
89              }
90              catch (ParameterException ex)
91              {
92                  // leader does not provide lane change desire, ignore
93              }
94          }
95          return Math.min(0.999, dMax);
96      }
97  
98  }