1 package org.opentrafficsim.road.network.lane.conflict;
2
3 import java.util.HashMap;
4 import java.util.Map;
5
6 import org.djunits.value.vdouble.scalar.Length;
7 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
8 import org.opentrafficsim.core.geometry.OTSGeometryException;
9 import org.opentrafficsim.road.network.lane.CrossSectionLink.Priority;
10 import org.opentrafficsim.road.network.lane.Lane;
11
12 import nl.tudelft.simulation.language.Throw;
13 import nl.tudelft.simulation.language.d3.DirectedPoint;
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 public class DefaultConflictRule implements ConflictRule
29 {
30
31
32 private Map<Conflict, ConflictPriority> map = null;
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
69
70
71 @Override
72 public ConflictPriority determinePriority(final Conflict conflict)
73 {
74 if (this.map == null)
75 {
76 ConflictPriority[] conflictPriorities = getConflictRules(conflict.getLane(), conflict.getLongitudinalPosition(),
77 conflict.getOtherConflict().getLane(), conflict.getOtherConflict().getLongitudinalPosition(),
78 conflict.getConflictType());
79 this.map = new HashMap<>();
80 this.map.put(conflict, conflictPriorities[0]);
81 this.map.put(conflict.getOtherConflict(), conflictPriorities[1]);
82 }
83 Throw.when(!this.map.containsKey(conflict), IllegalArgumentException.class,
84 "Conflict %s is not related to a conflict that was used before in the same conflict rule.", conflict);
85 return this.map.get(conflict);
86 }
87
88
89
90
91
92
93
94
95
96
97 private static ConflictPriority[] getConflictRules(final Lane lane1, final Length longitudinalPosition1, final Lane lane2,
98 final Length longitudinalPosition2, final ConflictType conflictType)
99 {
100 Throw.when(conflictType.equals(ConflictType.SPLIT), UnsupportedOperationException.class,
101 "DefaultConflictRule is not for use on a split conflict. Use SplitConflictRule instead.");
102 ConflictPriority[] conflictRules = new ConflictPriority[2];
103 Priority priority1 = lane1.getParentLink().getPriority();
104 Priority priority2 = lane2.getParentLink().getPriority();
105 if (priority1.isAllStop() && priority2.isAllStop())
106 {
107 conflictRules[0] = ConflictPriority.ALL_STOP;
108 conflictRules[1] = ConflictPriority.ALL_STOP;
109 }
110 else if (priority1.equals(priority2))
111 {
112
113 DirectedPoint p1;
114 DirectedPoint p2;
115 try
116 {
117 p1 = lane1.getCenterLine().getLocation(longitudinalPosition1);
118 p2 = lane2.getCenterLine().getLocation(longitudinalPosition2);
119 }
120 catch (OTSGeometryException exception)
121 {
122 throw new RuntimeException("Conflict position is not on its lane.", exception);
123 }
124 double diff = p2.getRotZ() - p1.getRotZ();
125 while (diff > Math.PI)
126 {
127 diff -= 2 * Math.PI;
128 }
129 while (diff < -Math.PI)
130 {
131 diff += 2 * Math.PI;
132 }
133 if (diff > 0.0)
134 {
135
136 conflictRules[0] = priority1.isStop() ? ConflictPriority.STOP : ConflictPriority.GIVE_WAY;
137 conflictRules[1] = ConflictPriority.PRIORITY;
138 }
139 else
140 {
141
142 conflictRules[0] = ConflictPriority.PRIORITY;
143 conflictRules[1] = priority2.isStop() ? ConflictPriority.STOP : ConflictPriority.GIVE_WAY;
144 }
145 }
146 else if (priority1.isPriority() && (priority2.isNone() || priority2.isStop()))
147 {
148 conflictRules[0] = ConflictPriority.PRIORITY;
149 conflictRules[1] = priority2.isStop() ? ConflictPriority.STOP : ConflictPriority.GIVE_WAY;
150 }
151 else if (priority2.isPriority() && (priority1.isNone() || priority1.isStop()))
152 {
153 conflictRules[0] = priority1.isStop() ? ConflictPriority.STOP : ConflictPriority.GIVE_WAY;
154 conflictRules[1] = ConflictPriority.PRIORITY;
155 }
156 else if (priority1.isNone() && priority2.isStop())
157 {
158 conflictRules[0] = ConflictPriority.PRIORITY;
159 conflictRules[1] = ConflictPriority.STOP;
160 }
161 else if (priority2.isNone() && priority1.isStop())
162 {
163 conflictRules[0] = ConflictPriority.STOP;
164 conflictRules[1] = ConflictPriority.PRIORITY;
165 }
166 else
167 {
168 throw new RuntimeException(
169 "Could not sort out conflict priority from link priorities " + priority1 + " and " + priority2);
170 }
171 return conflictRules;
172 }
173
174
175 @Override
176 public ConflictRule clone(final OTSSimulatorInterface newSimulator)
177 {
178 return new DefaultConflictRule();
179 }
180
181
182 @Override
183 public String toString()
184 {
185 return "DefaultConflictRule";
186 }
187
188 }