View Javadoc
1   package org.opentrafficsim.road.network.conflict;
2   
3   import java.util.Set;
4   
5   import org.djunits.value.vdouble.scalar.Length;
6   import org.djutils.exceptions.Throw;
7   import org.opentrafficsim.core.dsol.OtsSimulatorInterface;
8   import org.opentrafficsim.core.gtu.GtuType;
9   import org.opentrafficsim.core.gtu.RelativePosition;
10  import org.opentrafficsim.road.gtu.LaneBasedGtu;
11  import org.opentrafficsim.road.network.CrossSectionLink.Priority;
12  import org.opentrafficsim.road.network.Lane;
13  
14  /**
15   * Conflict rule for conflicts where busses enter the lane after a stop.
16   * <p>
17   * Copyright (c) 2013-2026 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
18   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
19   * </p>
20   * @author Alexander Verbraeck
21   * @author Peter Knoppers
22   * @author Wouter Schakel
23   */
24  public class BusStopConflictRule implements ConflictRule
25  {
26  
27      /** Simulator. */
28      private final OtsSimulatorInterface simulator;
29  
30      /** GTU type for buses. */
31      private final GtuType busType;
32  
33      /**
34       * Constructor.
35       * @param simulator simulator
36       * @param busType GTU type for buses.
37       */
38      public BusStopConflictRule(final OtsSimulatorInterface simulator, final GtuType busType)
39      {
40          this.simulator = simulator;
41          this.busType = busType;
42      }
43  
44      @Override
45      public ConflictPriority determinePriority(final Conflict conflict)
46      {
47  
48          // determine if we request from bus stop, or not
49          boolean requestingFromBusStop;
50          Conflict busConflict;
51          // conflict builder enforces that only one of the two links has priority BUS_STOP
52          if (conflict.getLane().getLink().getPriority().equals(Priority.BUS_STOP))
53          {
54              Throw.when(conflict.getOtherConflict().getLane().getLink().getPriority().equals(Priority.BUS_STOP),
55                      IllegalArgumentException.class,
56                      "BusStopConflictRule does not support a conflict between two links with priority BUS_STOP.");
57              requestingFromBusStop = true;
58              busConflict = conflict;
59          }
60          else
61          {
62              requestingFromBusStop = false;
63              busConflict = conflict.getOtherConflict();
64          }
65  
66          // find bus and determine if it has priority
67          Lane lane = busConflict.getLane();
68          Length pos = busConflict.getLongitudinalPosition();
69          LaneBasedGtu gtu = null;
70          while (gtu == null && lane != null)
71          {
72              gtu = lane.getGtuBehind(pos, RelativePosition.FRONT, this.simulator.getSimulatorTime()).orElse(null);
73              if (gtu == null)
74              {
75                  Set<Lane> set = lane.prevLanes(this.busType);
76                  if (set.size() == 1)
77                  {
78                      lane = set.iterator().next();
79                      // only on bus stop
80                      if (lane.getLink().getPriority().isBusStop())
81                      {
82                          pos = lane.getLength();
83                      }
84                      else
85                      {
86                          lane = null;
87                      }
88                  }
89                  else
90                  {
91                      lane = null;
92                  }
93              }
94          }
95          boolean busHasPriority = gtu != null && gtu.getType().isOfType(this.busType) && gtu.getTurnIndicatorStatus().isLeft();
96  
97          // if bus has priority and bus is asking, PRIORITY
98          // if bus has no priority and bus is not asking (i.e. car is asking), PRIORITY
99          return busHasPriority == requestingFromBusStop ? ConflictPriority.PRIORITY : ConflictPriority.YIELD;
100 
101     }
102 
103     @Override
104     public final String toString()
105     {
106         return "BusStopConflictRule";
107     }
108 
109 }