1 package org.opentrafficsim.road.gtu.lane.perception.object;
2
3 import java.util.Optional;
4
5 import org.djunits.value.vdouble.scalar.Length;
6 import org.djunits.value.vdouble.scalar.Speed;
7 import org.djutils.exceptions.Try;
8 import org.opentrafficsim.base.geometry.OtsLine2d;
9 import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;
10 import org.opentrafficsim.road.gtu.lane.perception.PerceptionCollectable;
11 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.PerceivedGtuType;
12 import org.opentrafficsim.road.network.lane.CrossSectionLink;
13 import org.opentrafficsim.road.network.lane.Lane;
14 import org.opentrafficsim.road.network.lane.conflict.Conflict;
15 import org.opentrafficsim.road.network.lane.conflict.ConflictPriority;
16 import org.opentrafficsim.road.network.lane.conflict.ConflictRule;
17 import org.opentrafficsim.road.network.lane.conflict.ConflictType;
18
19
20
21
22
23
24
25
26
27
28
29 public interface PerceivedConflict extends PerceivedLaneBasedObject
30 {
31
32
33
34
35
36 ConflictType getConflictType();
37
38
39
40
41
42 boolean isCrossing();
43
44
45
46
47
48 boolean isMerge();
49
50
51
52
53
54 boolean isSplit();
55
56
57
58
59
60 ConflictPriority getConflictPriority();
61
62
63
64
65
66 Length getConflictingLength();
67
68
69
70
71
72 PerceptionCollectable<PerceivedGtu, LaneBasedGtu> getUpstreamConflictingGTUs();
73
74
75
76
77
78
79
80 PerceptionCollectable<PerceivedGtu, LaneBasedGtu> getDownstreamConflictingGTUs();
81
82
83
84
85
86
87
88 Length getConflictingVisibility();
89
90
91
92
93
94 Speed getConflictingSpeedLimit();
95
96
97
98
99
100 CrossSectionLink getConflictingLink();
101
102
103
104
105
106 PerceivedObject getStopLine();
107
108
109
110
111
112 PerceivedObject getConflictingStopLine();
113
114
115
116
117
118 Class<? extends ConflictRule> getConflictRuleType();
119
120
121
122
123
124 Optional<Length> getConflictingTrafficLightDistance();
125
126
127
128
129
130 boolean isPermitted();
131
132
133
134
135
136
137 Length getWidthAtFraction(double fraction);
138
139
140
141
142
143
144
145
146
147
148
149 @SuppressWarnings("methodlength")
150 static PerceivedConflict of(final LaneBasedGtu perceivingGtu, final Conflict conflict,
151 final PerceivedGtuType perceivedGtuType, final Length distance, final Length conflictingVisibility)
152 {
153 final Kinematics kinematics = Kinematics.staticAhead(distance);
154
155 final PerceivedObject stopLine =
156 new PerceivedObjectBase("stopLineId", ObjectType.STOPLINE, Length.ZERO, Kinematics.staticAhead(Length.ZERO));
157 final PerceivedObject conflictingStopLine = new PerceivedObjectBase("conflictingStopLineId", ObjectType.STOPLINE,
158 Length.ZERO, Kinematics.staticAhead(Length.ZERO));
159 final Speed conflictingSpeedLimit = Try.assign(() -> conflict.getOtherConflict().getLane().getHighestSpeedLimit(),
160 "Unable to obtain higest speed limit on conflicting lane.");
161 final Length conflictingTrafficLightDistance =
162 conflict.getOtherConflict().getTrafficLightDistance(conflictingVisibility);
163
164 final PerceptionCollectable<PerceivedGtu, LaneBasedGtu> upstreamConflictingGTUs =
165 conflict.getOtherConflict().getUpstreamGtus(perceivingGtu, perceivedGtuType, conflictingVisibility);
166 final PerceptionCollectable<PerceivedGtu, LaneBasedGtu> downstreamConflictingGTUs =
167 conflict.getOtherConflict().getDownstreamGtus(perceivingGtu, perceivedGtuType, conflictingVisibility);
168
169 Length pos1a = conflict.getLongitudinalPosition();
170 Length pos2a = conflict.getOtherConflict().getLongitudinalPosition();
171 Length pos1b = Length.min(pos1a.plus(conflict.getLength()), conflict.getLane().getLength());
172 Length pos2b = Length.min(pos2a.plus(conflict.getOtherConflict().getLength()),
173 conflict.getOtherConflict().getLane().getLength());
174 OtsLine2d line1 = conflict.getLane().getCenterLine();
175 OtsLine2d line2 = conflict.getOtherConflict().getLane().getCenterLine();
176 double dStart = line1.getLocation(pos1a).distance(line2.getLocation(pos2a));
177 double dEnd = line1.getLocation(pos1b).distance(line2.getLocation(pos2b));
178 double startWidth = dStart + .5 * conflict.getLane().getWidth(pos1a).si
179 + .5 * conflict.getOtherConflict().getLane().getWidth(pos2a).si;
180 double endWidth = dEnd + .5 * conflict.getLane().getWidth(pos1b).si
181 + .5 * conflict.getOtherConflict().getLane().getWidth(pos2b).si;
182
183 return new PerceivedConflict()
184 {
185 @Override
186 public Lane getLane()
187 {
188 return conflict.getLane();
189 }
190
191 @Override
192 public ObjectType getObjectType()
193 {
194 return ObjectType.CONFLICT;
195 }
196
197 @Override
198 public Length getLength()
199 {
200 return conflict.getLength();
201 }
202
203 @Override
204 public Kinematics getKinematics()
205 {
206 return kinematics;
207 }
208
209 @Override
210 public String getId()
211 {
212 return conflict.getId();
213 }
214
215 @Override
216 public ConflictType getConflictType()
217 {
218 return conflict.getConflictType();
219 }
220
221 @Override
222 public boolean isCrossing()
223 {
224 return conflict.getConflictType().isCrossing();
225 }
226
227 @Override
228 public boolean isMerge()
229 {
230 return conflict.getConflictType().isMerge();
231 }
232
233 @Override
234 public boolean isSplit()
235 {
236 return conflict.getConflictType().isSplit();
237 }
238
239 @Override
240 public ConflictPriority getConflictPriority()
241 {
242 return conflict.conflictPriority();
243 }
244
245 @Override
246 public Length getConflictingLength()
247 {
248 return conflict.getOtherConflict().getLength();
249 }
250
251 @Override
252 public PerceptionCollectable<PerceivedGtu, LaneBasedGtu> getUpstreamConflictingGTUs()
253 {
254 return upstreamConflictingGTUs;
255 }
256
257 @Override
258 public PerceptionCollectable<PerceivedGtu, LaneBasedGtu> getDownstreamConflictingGTUs()
259 {
260 return downstreamConflictingGTUs;
261 }
262
263 @Override
264 public Length getConflictingVisibility()
265 {
266 return conflictingVisibility;
267 }
268
269 @Override
270 public Speed getConflictingSpeedLimit()
271 {
272 return conflictingSpeedLimit;
273 }
274
275 @Override
276 public CrossSectionLink getConflictingLink()
277 {
278 return conflict.getOtherConflict().getLane().getLink();
279 }
280
281 @Override
282 public PerceivedObject getStopLine()
283 {
284 return stopLine;
285 }
286
287 @Override
288 public PerceivedObject getConflictingStopLine()
289 {
290 return conflictingStopLine;
291 }
292
293 @Override
294 public Class<? extends ConflictRule> getConflictRuleType()
295 {
296 return conflict.getConflictRule().getClass();
297 }
298
299 @Override
300 public Optional<Length> getConflictingTrafficLightDistance()
301 {
302 return Optional.of(conflictingTrafficLightDistance);
303 }
304
305 @Override
306 public boolean isPermitted()
307 {
308 return conflict.isPermitted();
309 }
310
311 @Override
312 public Length getWidthAtFraction(final double fraction)
313 {
314 return Length.ofSI((1.0 - fraction) * startWidth + fraction * endWidth);
315 }
316 };
317 }
318
319 }