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
16
17
18
19
20
21
22
23
24 public class BusStopConflictRule implements ConflictRule
25 {
26
27
28 private final OtsSimulatorInterface simulator;
29
30
31 private final GtuType busType;
32
33
34
35
36
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
49 boolean requestingFromBusStop;
50 Conflict busConflict;
51
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
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
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
98
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 }