1 package org.opentrafficsim.road.network.lane.conflict;
2
3 import java.util.LinkedHashMap;
4 import java.util.Map;
5
6 import org.djunits.value.vdouble.scalar.Length;
7 import org.djutils.draw.point.OrientedPoint2d;
8 import org.djutils.exceptions.Throw;
9 import org.opentrafficsim.core.geometry.OtsGeometryException;
10 import org.opentrafficsim.road.network.lane.CrossSectionLink.Priority;
11 import org.opentrafficsim.road.network.lane.Lane;
12
13
14
15
16
17
18
19
20
21
22
23
24
25 public class DefaultConflictRule implements ConflictRule
26 {
27
28
29 private Map<String, ConflictPriority> map = null;
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 @Override
69 public ConflictPriority determinePriority(final Conflict conflict)
70 {
71 if (this.map == null)
72 {
73 ConflictPriority[] conflictPriorities = getConflictRules(conflict.getLane(), conflict.getLongitudinalPosition(),
74 conflict.getOtherConflict().getLane(), conflict.getOtherConflict().getLongitudinalPosition(),
75 conflict.getConflictType());
76 this.map = new LinkedHashMap<>();
77 this.map.put(conflict.getId(), conflictPriorities[0]);
78 this.map.put(conflict.getOtherConflict().getId(), conflictPriorities[1]);
79 }
80 ConflictPriority out = this.map.get(conflict.getId());
81 Throw.when(out == null, IllegalArgumentException.class,
82 "Conflict %s is not related to a conflict that was used before in the same conflict rule.", conflict);
83 return out;
84 }
85
86
87
88
89
90
91
92
93
94
95 private static ConflictPriority[] getConflictRules(final Lane lane1, final Length longitudinalPosition1, final Lane lane2,
96 final Length longitudinalPosition2, final ConflictType conflictType)
97 {
98 Throw.when(conflictType.equals(ConflictType.SPLIT), UnsupportedOperationException.class,
99 "DefaultConflictRule is not for use on a split conflict. Use SplitConflictRule instead.");
100 ConflictPriority[] conflictRules = new ConflictPriority[2];
101 Priority priority1 = lane1.getLink().getPriority();
102 Priority priority2 = lane2.getLink().getPriority();
103 if (priority1.isAllStop() && priority2.isAllStop())
104 {
105 conflictRules[0] = ConflictPriority.ALL_STOP;
106 conflictRules[1] = ConflictPriority.ALL_STOP;
107 }
108 else if (priority1.equals(priority2) || (priority1.isYield() && priority2.isStop())
109 || (priority2.isYield() && priority1.isStop()))
110 {
111 Throw.when(priority1.isBusStop(), IllegalArgumentException.class,
112 "Both priorities are 'bus stop', which is not allowed. Use BusStopConflictRule for bus stops.");
113
114 OrientedPoint2d p1;
115 OrientedPoint2d p2;
116 try
117 {
118 p1 = lane1.getCenterLine().getLocation(longitudinalPosition1);
119 p2 = lane2.getCenterLine().getLocation(longitudinalPosition2);
120 }
121 catch (OtsGeometryException exception)
122 {
123 throw new RuntimeException("Conflict position is not on its lane.", exception);
124 }
125 double diff = p2.getDirZ() - p1.getDirZ();
126 while (diff > Math.PI)
127 {
128 diff -= 2 * Math.PI;
129 }
130 while (diff < -Math.PI)
131 {
132 diff += 2 * Math.PI;
133 }
134 if (diff > 0.0)
135 {
136
137 conflictRules[0] = priority1.isStop() ? ConflictPriority.STOP : ConflictPriority.YIELD;
138 conflictRules[1] = ConflictPriority.PRIORITY;
139 }
140 else
141 {
142
143 conflictRules[0] = ConflictPriority.PRIORITY;
144 conflictRules[1] = priority2.isStop() ? ConflictPriority.STOP : ConflictPriority.YIELD;
145 }
146 }
147 else if ((priority1.isPriority() || priority1.isNone())
148 && (priority2.isNone() || priority2.isYield() || priority2.isStop()))
149 {
150 conflictRules[0] = ConflictPriority.PRIORITY;
151 conflictRules[1] = priority2.isStop() ? ConflictPriority.STOP : ConflictPriority.YIELD;
152 }
153 else if ((priority2.isPriority() || priority2.isNone())
154 && (priority1.isNone() || priority1.isYield() || priority1.isStop()))
155 {
156 conflictRules[0] = priority1.isStop() ? ConflictPriority.STOP : ConflictPriority.YIELD;
157 conflictRules[1] = ConflictPriority.PRIORITY;
158 }
159 else
160 {
161 throw new IllegalArgumentException(
162 "Could not sort out conflict priority from link priorities " + priority1 + " and " + priority2);
163 }
164 return conflictRules;
165 }
166
167
168 @Override
169 public final String toString()
170 {
171 return "DefaultConflictRule";
172 }
173
174 }