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