1 package org.opentrafficsim.road.network.lane.conflict;
2
3 import java.util.ArrayList;
4 import java.util.Iterator;
5 import java.util.LinkedHashMap;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Set;
9 import java.util.SortedSet;
10 import java.util.TreeSet;
11 import java.util.concurrent.Executors;
12 import java.util.concurrent.ThreadPoolExecutor;
13 import java.util.concurrent.atomic.AtomicInteger;
14
15 import org.djunits.value.vdouble.scalar.Length;
16 import org.djutils.exceptions.Throw;
17 import org.djutils.immutablecollections.ImmutableIterator;
18 import org.djutils.immutablecollections.ImmutableMap;
19 import org.djutils.immutablecollections.ImmutableMap.ImmutableEntry;
20 import org.opentrafficsim.core.geometry.OTSGeometryException;
21 import org.opentrafficsim.core.geometry.OTSLine3D;
22 import org.opentrafficsim.core.geometry.OTSPoint3D;
23 import org.opentrafficsim.core.gtu.GTUDirectionality;
24 import org.opentrafficsim.core.gtu.GTUType;
25 import org.opentrafficsim.core.network.Link;
26 import org.opentrafficsim.core.network.NetworkException;
27 import org.opentrafficsim.road.network.OTSRoadNetwork;
28 import org.opentrafficsim.road.network.lane.CrossSectionElement;
29 import org.opentrafficsim.road.network.lane.CrossSectionLink;
30 import org.opentrafficsim.road.network.lane.Lane;
31 import org.pmw.tinylog.Level;
32
33 import nl.tudelft.simulation.dsol.logger.SimLogger;
34 import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
35
36
37
38
39
40
41
42
43
44
45
46
47 public final class ConflictBuilder
48 {
49
50 private static AtomicInteger numberMergeConflicts = new AtomicInteger(0);
51
52
53 private static AtomicInteger numberSplitConflicts = new AtomicInteger(0);
54
55
56 private static AtomicInteger numberCrossConflicts = new AtomicInteger(0);
57
58
59 public static final WidthGenerator DEFAULT_WIDTH_GENERATOR = new RelativeWidthGenerator(0.8);
60
61
62
63
64 private ConflictBuilder()
65 {
66
67 }
68
69
70
71
72
73
74
75
76
77 public static void buildConflicts(final OTSRoadNetwork network, final GTUType gtuType,
78 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator)
79 throws OTSGeometryException
80 {
81 buildConflicts(network, gtuType, simulator, widthGenerator, new LaneCombinationListrk/lane/conflict/LaneCombinationList.html#LaneCombinationList">LaneCombinationList(), new LaneCombinationList());
82 }
83
84
85
86
87
88
89
90
91
92
93
94 public static void buildConflicts(final OTSRoadNetwork network, final GTUType gtuType,
95 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator,
96 final LaneCombinationListflict/LaneCombinationList.html#LaneCombinationList">LaneCombinationList ignoreList, final LaneCombinationList permittedList) throws OTSGeometryException
97 {
98
99 ImmutableMap<String, Link> links = network.getLinkMap();
100 List<Lane> lanes = new ArrayList<>();
101 for (String linkId : links.keySet())
102 {
103 Link link = links.get(linkId);
104 if (link instanceof CrossSectionLink)
105 {
106 for (CrossSectionElement element : ((CrossSectionLink) link).getCrossSectionElementList())
107 {
108 if (element instanceof Lane)
109 {
110 lanes.add((Lane) element);
111 }
112 }
113 }
114 }
115 buildConflicts(lanes, gtuType, simulator, widthGenerator, ignoreList, permittedList);
116 }
117
118
119
120
121
122
123
124
125
126 public static void buildConflicts(final List<Lane> lanes, final GTUType gtuType,
127 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator)
128 throws OTSGeometryException
129 {
130 buildConflicts(lanes, gtuType, simulator, widthGenerator, new LaneCombinationListrk/lane/conflict/LaneCombinationList.html#LaneCombinationList">LaneCombinationList(), new LaneCombinationList());
131 }
132
133
134
135
136
137
138
139
140
141
142
143 public static void buildConflicts(final List<Lane> lanes, final GTUType gtuType,
144 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator,
145 final LaneCombinationListflict/LaneCombinationList.html#LaneCombinationList">LaneCombinationList ignoreList, final LaneCombinationList permittedList) throws OTSGeometryException
146 {
147
148 long totalCombinations = ((long) lanes.size()) * ((long) lanes.size() - 1) / 2;
149 SimLogger.always().debug("GENERATING CONFLICTS (NON-PARALLEL MODE). {} COMBINATIONS", totalCombinations);
150 long lastReported = 0;
151 Map<Lane, OTSLine3D> leftEdges = new LinkedHashMap<>();
152 Map<Lane, OTSLine3D> rightEdges = new LinkedHashMap<>();
153
154 for (int i = 0; i < lanes.size(); i++)
155 {
156 long combinationsDone = totalCombinations - ((long) (lanes.size() - i)) * ((long) (lanes.size() - i)) / 2;
157 if (combinationsDone / 100000000 > lastReported)
158 {
159 SimLogger.always()
160 .debug(String.format(
161 "generating conflicts at %.0f%% (generated %d merge conflicts, %d split "
162 + "conflicts, %d crossing conflicts)",
163 100.0 * combinationsDone / totalCombinations, numberMergeConflicts.get(),
164 numberSplitConflicts.get(), numberCrossConflicts.get()));
165 lastReported = combinationsDone / 100000000;
166 }
167 Lane lane1 = lanes.get(i);
168 for (GTUDirectionality dir1 : lane1.getLaneType().getDirectionality(gtuType).getDirectionalities())
169 {
170 ImmutableMap<Lane, GTUDirectionality> down1 = lane1.downstreamLanes(dir1, gtuType);
171 ImmutableMap<Lane, GTUDirectionality> up1 = lane1.upstreamLanes(dir1, gtuType);
172
173 for (int j = i + 1; j < lanes.size(); j++)
174 {
175 Lane lane2 = lanes.get(j);
176 if (ignoreList.contains(lane1, lane2))
177 {
178 continue;
179 }
180 boolean permitted = permittedList.contains(lane1, lane2);
181
182 for (GTUDirectionality dir2 : lane2.getLaneType().getDirectionality(gtuType).getDirectionalities())
183 {
184 ImmutableMap<Lane, GTUDirectionality> down2 = lane2.downstreamLanes(dir2, gtuType);
185 ImmutableMap<Lane, GTUDirectionality> up2 = lane2.upstreamLanes(dir2, gtuType);
186
187 try
188 {
189 buildConflicts(lane1, dir1, down1, up1, lane2, dir2, down2, up2, gtuType, permitted, simulator,
190 widthGenerator, leftEdges, rightEdges, true);
191 }
192 catch (NetworkException ne)
193 {
194 throw new RuntimeException("Conflict build with bad combination of types / rules.", ne);
195 }
196 }
197 }
198 }
199 }
200 SimLogger.always()
201 .debug(String.format(
202 "generating conflicts complete (generated %d merge conflicts, %d split "
203 + "conflicts, %d crossing conflicts)",
204 numberMergeConflicts.get(), numberSplitConflicts.get(), numberCrossConflicts.get()));
205 }
206
207
208
209
210
211
212
213
214
215
216
217
218 @SuppressWarnings("checkstyle:parameternumber")
219 public static void buildConflicts(final Lane lane1, Lane_keyword">final GTUDirectionality dir1, final Lane lane2,
220 final GTUDirectionality dir2, final GTUType gtuType, final DEVSSimulatorInterface.TimeDoubleUnit simulator,
221 final WidthGenerator widthGenerator) throws OTSGeometryException
222 {
223 buildConflicts(lane1, dir1, lane2, dir2, gtuType, simulator, widthGenerator, false);
224 }
225
226
227
228
229
230
231
232
233
234
235
236
237
238 @SuppressWarnings("checkstyle:parameternumber")
239 public static void buildConflicts(final Lane lane1, Lane_keyword">final GTUDirectionality dir1, final Lane lane2,
240 final GTUDirectionality dir2, final GTUType gtuType, final DEVSSimulatorInterface.TimeDoubleUnit simulator,
241 final WidthGenerator widthGenerator, final boolean permitted) throws OTSGeometryException
242 {
243 ImmutableMap<Lane, GTUDirectionality> down1 = lane1.downstreamLanes(dir1, gtuType);
244 ImmutableMap<Lane, GTUDirectionality> up1 = lane1.upstreamLanes(dir1, gtuType);
245 ImmutableMap<Lane, GTUDirectionality> down2 = lane2.downstreamLanes(dir2, gtuType);
246 ImmutableMap<Lane, GTUDirectionality> up2 = lane2.upstreamLanes(dir2, gtuType);
247 try
248 {
249 buildConflicts(lane1, dir1, down1, up1, lane2, dir2, down2, up2, gtuType, permitted, simulator, widthGenerator,
250 new LinkedHashMap<>(), new LinkedHashMap<>(), true);
251 }
252 catch (NetworkException ne)
253 {
254 throw new RuntimeException("Conflict build with bad combination of types / rules.", ne);
255 }
256 }
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278 @SuppressWarnings({"checkstyle:parameternumber", "checkstyle:methodlength"})
279 static void buildConflicts(final Lane lane1, final GTUDirectionality dir1,
280 final ImmutableMap<Lane, GTUDirectionality> down1, final ImmutableMap<Lane, GTUDirectionality> up1,
281 final Lane lane2, final GTUDirectionality dir2, final ImmutableMap<Lane, GTUDirectionality> down2,
282 final ImmutableMap<Lane, GTUDirectionality> up2, final GTUType gtuType, final boolean permitted,
283 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator,
284 final Map<Lane, OTSLine3D> leftEdges, final Map<Lane, OTSLine3D> rightEdges, final boolean intersectionCheck)
285 throws OTSGeometryException, NetworkException
286 {
287
288 if (intersectionCheck)
289 {
290 if (!lane1.getContour().intersects(lane2.getContour()))
291 {
292 return;
293 }
294 }
295
296
297
298
299 OTSLine3D left1;
300 OTSLine3D right1;
301 synchronized (lane1)
302 {
303 left1 = leftEdges.get(lane1);
304 right1 = rightEdges.get(lane1);
305 OTSLine3D line1 = lane1.getCenterLine();
306 if (null == left1)
307 {
308 left1 = line1.offsetLine(widthGenerator.getWidth(lane1, 0.0) / 2, widthGenerator.getWidth(lane1, 1.0) / 2);
309 leftEdges.put(lane1, left1);
310 }
311 if (null == right1)
312 {
313 right1 = line1.offsetLine(-widthGenerator.getWidth(lane1, 0.0) / 2, -widthGenerator.getWidth(lane1, 1.0) / 2);
314 rightEdges.put(lane1, right1);
315 }
316 }
317
318 OTSLine3D left2;
319 OTSLine3D right2;
320 synchronized (lane2)
321 {
322 left2 = leftEdges.get(lane2);
323 right2 = rightEdges.get(lane2);
324 OTSLine3D line2 = lane2.getCenterLine();
325 if (null == left2)
326 {
327 left2 = line2.offsetLine(widthGenerator.getWidth(lane2, 0.0) / 2, widthGenerator.getWidth(lane2, 1.0) / 2);
328 leftEdges.put(lane2, left2);
329 }
330 if (null == right2)
331 {
332 right2 = line2.offsetLine(-widthGenerator.getWidth(lane2, 0.0) / 2, -widthGenerator.getWidth(lane2, 1.0) / 2);
333 rightEdges.put(lane2, right2);
334 }
335 }
336
337
338 SortedSet<Intersection> intersections = Intersection.getIntersectionList(left1, left2, 0);
339 intersections.addAll(Intersection.getIntersectionList(left1, right2, 1));
340 intersections.addAll(Intersection.getIntersectionList(right1, left2, 2));
341 intersections.addAll(Intersection.getIntersectionList(right1, right2, 3));
342
343
344 ImmutableIterator<ImmutableEntry<Lane, GTUDirectionality>> iterator1 = down1.entrySet().iterator();
345 ImmutableIterator<ImmutableEntry<Lane, GTUDirectionality>> iterator2 = down2.entrySet().iterator();
346 boolean merge = false;
347 while (iterator1.hasNext() && !merge)
348 {
349 ImmutableEntry<Lane, GTUDirectionality> next1 = iterator1.next();
350 while (iterator2.hasNext() && !merge)
351 {
352 ImmutableEntry<Lane, GTUDirectionality> next2 = iterator2.next();
353 if (next1.equals(next2))
354 {
355
356 double fraction1 = Double.NaN;
357 double fraction2 = Double.NaN;
358 for (Intersection intersection : intersections)
359 {
360
361 if (intersection.getCombo() == 1 || intersection.getCombo() == 2)
362 {
363 fraction1 = intersection.getFraction1();
364 fraction2 = intersection.getFraction2();
365 }
366 }
367
368 Iterator<Intersection> iterator = intersections.iterator();
369 while (iterator.hasNext())
370 {
371 if (iterator.next().getFraction1() >= fraction1)
372 {
373 iterator.remove();
374 }
375 }
376 if (Double.isNaN(fraction1))
377 {
378 SimLogger.always().warn("Fixing fractions of merge conflict");
379 fraction1 = 0;
380 fraction2 = 0;
381 }
382
383 buildMergeConflict(lane1, dir1, fraction1, lane2, dir2, fraction2, gtuType, simulator, widthGenerator,
384 permitted);
385
386 merge = true;
387 }
388 }
389 }
390
391
392 iterator1 = up1.entrySet().iterator();
393 iterator2 = up2.entrySet().iterator();
394 boolean split = false;
395 while (iterator1.hasNext() && !split)
396 {
397 ImmutableEntry<Lane, GTUDirectionality> prev1 = iterator1.next();
398 while (iterator2.hasNext() && !split)
399 {
400 ImmutableEntry<Lane, GTUDirectionality> prev2 = iterator2.next();
401 if (prev1.equals(prev2))
402 {
403
404 double fraction1 = Double.NaN;
405 double fraction2 = Double.NaN;
406 for (Intersection intersection : intersections)
407 {
408
409 if (intersection.getCombo() == 1 || intersection.getCombo() == 2)
410 {
411 fraction1 = intersection.getFraction1();
412 fraction2 = intersection.getFraction2();
413 break;
414 }
415 }
416
417 Iterator<Intersection> iterator = intersections.iterator();
418 while (iterator.hasNext())
419 {
420 if (iterator.next().getFraction1() <= fraction1)
421 {
422 iterator.remove();
423 }
424 else
425 {
426
427 break;
428 }
429 }
430 if (Double.isNaN(fraction1))
431 {
432 SimLogger.always().warn("Fixing fractions of split conflict");
433 fraction1 = 1;
434 fraction2 = 1;
435 }
436
437 buildSplitConflict(lane1, dir1, fraction1, lane2, dir2, fraction2, gtuType, simulator, widthGenerator);
438
439 split = true;
440 }
441 }
442 }
443
444
445 if (!lane1.getParentLink().equals(lane2.getParentLink()))
446 {
447 boolean[] crossed = new boolean[4];
448 Iterator<Intersection> iterator = intersections.iterator();
449 double f1Start = Double.NaN;
450 double f2Start = Double.NaN;
451 double f2End = Double.NaN;
452 while (iterator.hasNext())
453 {
454 Intersection intersection = iterator.next();
455
456 if (Double.isNaN(f1Start))
457 {
458 f1Start = intersection.getFraction1();
459 }
460 f2Start = Double.isNaN(f2Start) ? intersection.getFraction2() : Math.min(f2Start, intersection.getFraction2());
461 f2End = Double.isNaN(f2End) ? intersection.getFraction2() : Math.max(f2End, intersection.getFraction2());
462
463 crossed[intersection.getCombo()] = !crossed[intersection.getCombo()];
464
465 if ((crossed[0] && crossed[1] && crossed[2] && crossed[3])
466 || (!crossed[0] && !crossed[1] && !crossed[2] && !crossed[3]))
467 {
468 if (dir2.isMinus())
469 {
470 double f2Temp = f2Start;
471 f2Start = f2End;
472 f2End = f2Temp;
473 }
474 if (Double.isNaN(f1Start) || Double.isNaN(f2Start) || Double.isNaN(f2End))
475 {
476 SimLogger.always().warn("NOT YET Fixing fractions of crossing conflict");
477 }
478 buildCrossingConflict(lane1, dir1, f1Start, intersection.getFraction1(), lane2, dir2, f2Start, f2End,
479 gtuType, simulator, widthGenerator, permitted);
480 f1Start = Double.NaN;
481 f2Start = Double.NaN;
482 f2End = Double.NaN;
483 }
484 }
485 }
486
487 }
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504 @SuppressWarnings("checkstyle:parameternumber")
505 private static void buildMergeConflict(final Lane lane1, final GTUDirectionality dir1, final double f1start,
506 final Lane lane2, final GTUDirectionality dir2, final double f2start, final GTUType gtuType,
507 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator, final boolean permitted)
508 throws NetworkException, OTSGeometryException
509 {
510
511
512 double f1end = dir1.isPlus() ? 1.0 : 0.0;
513 double f2end = dir2.isPlus() ? 1.0 : 0.0;
514
515
516 Length longitudinalPosition1 = lane1.getLength().times(f1start);
517 Length longitudinalPosition2 = lane2.getLength().times(f2start);
518 Length length1 = lane1.getLength().times(Math.abs(f1end - f1start));
519 Length length2 = lane2.getLength().times(Math.abs(f2end - f2start));
520
521
522 OTSLine3D geometry1 = getGeometry(lane1, f1start, f1end, widthGenerator);
523 OTSLine3D geometry2 = getGeometry(lane2, f2start, f2end, widthGenerator);
524
525
526 ConflictRule conflictRule;
527 if (lane1.getParentLink().getPriority().isBusStop() || lane2.getParentLink().getPriority().isBusStop())
528 {
529 Throw.when(lane1.getParentLink().getPriority().isBusStop() && lane2.getParentLink().getPriority().isBusStop(),
530 IllegalArgumentException.class, "Merge conflict between two links with bus stop priority not supported.");
531 conflictRule = new BusStopConflictRule(simulator);
532 }
533 else
534 {
535 conflictRule = new DefaultConflictRule();
536 }
537
538
539 Conflict.generateConflictPair(ConflictType.MERGE, conflictRule, permitted, lane1, longitudinalPosition1, length1, dir1,
540 geometry1, gtuType, lane2, longitudinalPosition2, length2, dir2, geometry2, gtuType, simulator);
541
542 numberMergeConflicts.incrementAndGet();
543 }
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559 @SuppressWarnings("checkstyle:parameternumber")
560 private static void buildSplitConflict(final Lane lane1, final GTUDirectionality dir1, finalLanetrong class="jxr_keyword">double f1end, final Lane lane2,
561 final GTUDirectionality dir2, final double f2end, final GTUType gtuType,
562 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator)
563 throws NetworkException, OTSGeometryException
564 {
565
566
567 double f1start = dir1.isPlus() ? 0.0 : 1.0;
568 double f2start = dir2.isPlus() ? 0.0 : 1.0;
569
570
571 Length longitudinalPosition1 = lane1.getLength().times(f1start);
572 Length longitudinalPosition2 = lane2.getLength().times(f2start);
573 Length length1 = lane1.getLength().times(Math.abs(f1end - f1start));
574 Length length2 = lane2.getLength().times(Math.abs(f2end - f2start));
575
576
577 OTSLine3D geometry1 = getGeometry(lane1, f1start, f1end, widthGenerator);
578 OTSLine3D geometry2 = getGeometry(lane2, f2start, f2end, widthGenerator);
579
580
581 Conflict.generateConflictPair(ConflictType.SPLIT, new SplitConflictRule(), false, lane1, longitudinalPosition1, length1,
582 dir1, geometry1, gtuType, lane2, longitudinalPosition2, length2, dir2, geometry2, gtuType, simulator);
583
584 numberSplitConflicts.incrementAndGet();
585 }
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604 @SuppressWarnings("checkstyle:parameternumber")
605 private static void buildCrossingConflict(final Lane lane1, final GTUDirectionality dir1, final double f1start,
606 final double f1end, final Lane lane2, final GTUDirectionality dir2, final double f2start, final double f2end,
607 final GTUType gtuType, final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator,
608 final boolean permitted) throws NetworkException, OTSGeometryException
609 {
610
611
612
613 double f1startDirected;
614 double f2startDirected;
615 if ((dir1.isPlus() && f1end < f1start) || (dir1.isMinus() && f1end > f1start))
616 {
617 f1startDirected = f1end;
618 }
619 else
620 {
621 f1startDirected = f1start;
622 }
623 if ((dir2.isPlus() && f2end < f2start) || (dir2.isMinus() && f2end > f2start))
624 {
625 f2startDirected = f2end;
626 }
627 else
628 {
629 f2startDirected = f2start;
630 }
631
632
633 Length longitudinalPosition1 = lane1.getLength().times(f1startDirected);
634 Length longitudinalPosition2 = lane2.getLength().times(f2startDirected);
635 Length length1 = lane1.getLength().times(Math.abs(f1end - f1start));
636 Length length2 = lane2.getLength().times(Math.abs(f2end - f2start));
637
638
639 OTSLine3D geometry1 = getGeometry(lane1, f1start, f1end, widthGenerator);
640 OTSLine3D geometry2 = getGeometry(lane2, f2start, f2end, widthGenerator);
641
642
643 ConflictRule conflictRule;
644 if (lane1.getParentLink().getPriority().isBusStop() || lane2.getParentLink().getPriority().isBusStop())
645 {
646 Throw.when(lane1.getParentLink().getPriority().isBusStop() && lane2.getParentLink().getPriority().isBusStop(),
647 IllegalArgumentException.class, "Merge conflict between two links with bus stop priority not supported.");
648 conflictRule = new BusStopConflictRule(simulator);
649 }
650 else
651 {
652 conflictRule = new DefaultConflictRule();
653 }
654
655
656 Conflict.generateConflictPair(ConflictType.CROSSING, conflictRule, permitted, lane1, longitudinalPosition1, length1,
657 dir1, geometry1, gtuType, lane2, longitudinalPosition2, length2, dir2, geometry2, gtuType, simulator);
658
659 numberCrossConflicts.incrementAndGet();
660 }
661
662
663
664
665
666
667
668
669
670
671 private static OTSLine3D getGeometry(final Lane lane, final double fStart, final double fEnd,
672 final WidthGenerator widthGenerator) throws OTSGeometryException
673 {
674
675 double f1;
676 double f2;
677 if (fEnd > fStart)
678 {
679 f1 = fStart;
680 f2 = fEnd;
681 }
682 else
683 {
684 f1 = fEnd;
685 f2 = fStart;
686 }
687 if (f1 == f2)
688 {
689 SimLogger.always().debug("f1 (" + f1 + ") equals f2 (" + f2 + "); problematic lane is " + lane.toString());
690
691 if (f1 > 0)
692 {
693 f1 = f1 - f1 / 1000;
694 }
695 else
696 {
697 f2 = f2 + f2 / 1000;
698 }
699 }
700 OTSLine3D centerLine = lane.getCenterLine().extractFractional(f1, f2);
701 OTSLine3D left = centerLine.offsetLine(widthGenerator.getWidth(lane, f1) / 2, widthGenerator.getWidth(lane, f2) / 2);
702 OTSLine3D right =
703 centerLine.offsetLine(-widthGenerator.getWidth(lane, f1) / 2, -widthGenerator.getWidth(lane, f2) / 2).reverse();
704 OTSPoint3D[] points = new OTSPoint3D[left.size() + right.size()];
705 System.arraycopy(left.getPoints(), 0, points, 0, left.size());
706 System.arraycopy(right.getPoints(), 0, points, left.size(), right.size());
707 return new OTSLine3D(points);
708 }
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723 private static class Intersection implements Comparable<Intersection>
724 {
725
726
727 private final double fraction1;
728
729
730 private final double fraction2;
731
732
733 private final int combo;
734
735
736
737
738
739
740 Intersection(final double fraction1, final double fraction2, final int combo)
741 {
742 this.fraction1 = fraction1;
743 this.fraction2 = fraction2;
744 this.combo = combo;
745 }
746
747
748
749
750 public final double getFraction1()
751 {
752 return this.fraction1;
753 }
754
755
756
757
758 public final double getFraction2()
759 {
760 return this.fraction2;
761 }
762
763
764
765
766 public final int getCombo()
767 {
768 return this.combo;
769 }
770
771
772 @Override
773 public int compareTo(final Intersection o)
774 {
775 int out = Double.compare(this.fraction1, o.fraction1);
776 if (out != 0)
777 {
778 return out;
779 }
780 out = Double.compare(this.fraction2, o.fraction2);
781 if (out != 0)
782 {
783 return out;
784 }
785 return Integer.compare(this.combo, o.combo);
786 }
787
788
789 @Override
790 public int hashCode()
791 {
792 final int prime = 31;
793 int result = 1;
794 result = prime * result + this.combo;
795 long temp;
796 temp = Double.doubleToLongBits(this.fraction1);
797 result = prime * result + (int) (temp ^ (temp >>> 32));
798 temp = Double.doubleToLongBits(this.fraction2);
799 result = prime * result + (int) (temp ^ (temp >>> 32));
800 return result;
801 }
802
803
804 @Override
805 public boolean equals(final Object obj)
806 {
807 if (this == obj)
808 {
809 return true;
810 }
811 if (obj == null)
812 {
813 return false;
814 }
815 if (getClass() != obj.getClass())
816 {
817 return false;
818 }
819 Intersection other = (Intersection) obj;
820 if (this.combo != other.combo)
821 {
822 return false;
823 }
824 if (Double.doubleToLongBits(this.fraction1) != Double.doubleToLongBits(other.fraction1))
825 {
826 return false;
827 }
828 if (Double.doubleToLongBits(this.fraction2) != Double.doubleToLongBits(other.fraction2))
829 {
830 return false;
831 }
832 return true;
833 }
834
835
836
837
838
839
840
841
842
843 public static SortedSet<Intersection> getIntersectionList(final OTSLine3D line1, final OTSLine3D line2, final int combo)
844 throws OTSGeometryException
845 {
846 SortedSet<Intersection> out = new TreeSet<>();
847
848
849
850
851 double cumul1 = 0.0;
852 OTSPoint3D start1 = null;
853 OTSPoint3D end1 = line1.get(0);
854 for (int i = 0; i < line1.size() - 1; i++)
855 {
856 start1 = end1;
857 end1 = line1.get(i + 1);
858
859 double cumul2 = 0.0;
860 OTSPoint3D start2 = null;
861 OTSPoint3D end2 = line2.get(0);
862
863 for (int j = 0; j < line2.size() - 1; j++)
864 {
865 start2 = end2;
866 end2 = line2.get(j + 1);
867
868 OTSPoint3D p = OTSPoint3D.intersectionOfLineSegments(start1, end1, start2, end2);
869 if (p != null)
870 {
871
872 double dx = p.x - start1.x;
873 double dy = p.y - start1.y;
874 double length1 = cumul1 + Math.sqrt(dx * dx + dy * dy);
875 dx = p.x - start2.x;
876 dy = p.y - start2.y;
877 double length2 = cumul2 + Math.sqrt(dx * dx + dy * dy);
878 out.add(new Intersection(length1 / line1.getLengthSI(), length2 / line2.getLengthSI(), combo));
879 }
880
881 double dx = end2.x - start2.x;
882 double dy = end2.y - start2.y;
883 cumul2 += Math.sqrt(dx * dx + dy * dy);
884 }
885
886 double dx = end1.x - start1.x;
887 double dy = end1.y - start1.y;
888 cumul1 += Math.sqrt(dx * dx + dy * dy);
889 }
890
891 return out;
892 }
893
894
895 @Override
896 public String toString()
897 {
898 return "Intersection [fraction1=" + this.fraction1 + ", fraction2=" + this.fraction2 + ", combo=" + this.combo
899 + "]";
900 }
901
902 }
903
904
905
906
907
908
909
910
911
912
913
914
915
916 public interface WidthGenerator
917 {
918
919
920
921
922
923
924
925 double getWidth(Lane lane, double fraction);
926
927 }
928
929
930
931
932
933
934
935
936
937
938
939
940
941 public static class FixedWidthGenerator implements WidthGenerator
942 {
943
944
945 private final double width;
946
947
948
949
950
951 public FixedWidthGenerator(final Length width)
952 {
953 this.width = width.si;
954 }
955
956
957 @Override
958 public final double getWidth(final Lane lane, final double fraction)
959 {
960 return this.width;
961 }
962
963
964 @Override
965 public final String toString()
966 {
967 return "FixedWidthGenerator [width=" + this.width + "]";
968 }
969
970 }
971
972
973
974
975
976
977
978
979
980
981
982
983
984 public static class RelativeWidthGenerator implements WidthGenerator
985 {
986
987
988 private final double factor;
989
990
991
992
993
994 public RelativeWidthGenerator(final double factor)
995 {
996 this.factor = factor;
997 }
998
999
1000 @Override
1001 public final double getWidth(final Lane lane, final double fraction)
1002 {
1003 return lane.getWidth(fraction).si * this.factor;
1004 }
1005
1006
1007 @Override
1008 public final String toString()
1009 {
1010 return "RelativeWidthGenerator [factor=" + this.factor + "]";
1011 }
1012
1013 }
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031 public static void buildConflictsParallel(final OTSRoadNetwork network, final GTUType gtuType,
1032 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator)
1033 throws OTSGeometryException
1034 {
1035 buildConflictsParallel(network, gtuType, simulator, widthGenerator, new LaneCombinationList(),
1036 new LaneCombinationList());
1037 }
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049 public static void buildConflictsParallel(final OTSRoadNetwork network, final GTUType gtuType,
1050 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator,
1051 final LaneCombinationListflict/LaneCombinationList.html#LaneCombinationList">LaneCombinationList ignoreList, final LaneCombinationList permittedList) throws OTSGeometryException
1052 {
1053
1054 ImmutableMap<String, Link> links = network.getLinkMap();
1055 List<Lane> lanes = new ArrayList<>();
1056 for (String linkId : links.keySet())
1057 {
1058 Link link = links.get(linkId);
1059 if (link instanceof CrossSectionLink)
1060 {
1061 for (CrossSectionElement element : ((CrossSectionLink) link).getCrossSectionElementList())
1062 {
1063 if (element instanceof Lane)
1064 {
1065 lanes.add((Lane) element);
1066 }
1067 }
1068 }
1069 }
1070 buildConflictsParallelBig(lanes, gtuType, simulator, widthGenerator, ignoreList, permittedList);
1071 }
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081 public static void buildConflictsParallel(final List<Lane> lanes, final GTUType gtuType,
1082 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator)
1083 throws OTSGeometryException
1084 {
1085 buildConflictsParallelBig(lanes, gtuType, simulator, widthGenerator, new LaneCombinationList(),
1086 new LaneCombinationList());
1087 }
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099 public static void buildConflictsParallelSmall(final List<Lane> lanes, final GTUType gtuType,
1100 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator,
1101 final LaneCombinationListflict/LaneCombinationList.html#LaneCombinationList">LaneCombinationList ignoreList, final LaneCombinationList permittedList) throws OTSGeometryException
1102 {
1103
1104 long totalCombinations = ((long) lanes.size()) * ((long) lanes.size() - 1) / 2;
1105 System.out.println("PARALLEL GENERATING OF CONFLICTS (SMALL JOBS). " + totalCombinations + " COMBINATIONS");
1106 long lastReported = 0;
1107 Map<Lane, OTSLine3D> leftEdges = new LinkedHashMap<>();
1108 Map<Lane, OTSLine3D> rightEdges = new LinkedHashMap<>();
1109
1110
1111 for (Lane lane : lanes)
1112 {
1113 lane.getContour().getEnvelope();
1114 }
1115
1116
1117 int cores = Runtime.getRuntime().availableProcessors();
1118 System.out.println("USING " + cores + " CORES");
1119 ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(cores);
1120 AtomicInteger numberOfJobs = new AtomicInteger(0);
1121 final int maxqueue = 2 * cores;
1122
1123 for (int i = 0; i < lanes.size(); i++)
1124 {
1125 long combinationsDone = totalCombinations - ((long) (lanes.size() - i)) * ((long) (lanes.size() - i)) / 2;
1126 if (combinationsDone / 100000000 > lastReported)
1127 {
1128 SimLogger.always()
1129 .debug(String.format(
1130 "generating conflicts at %.0f%% (generated %d merge conflicts, %d split "
1131 + "conflicts, %d crossing conflicts)",
1132 100.0 * combinationsDone / totalCombinations, numberMergeConflicts.get(),
1133 numberSplitConflicts.get(), numberCrossConflicts.get()));
1134 lastReported = combinationsDone / 100000000;
1135 }
1136 Lane lane1 = lanes.get(i);
1137 for (GTUDirectionality dir1 : lane1.getLaneType().getDirectionality(gtuType).getDirectionalities())
1138 {
1139 ImmutableMap<Lane, GTUDirectionality> down1 = lane1.downstreamLanes(dir1, gtuType);
1140 ImmutableMap<Lane, GTUDirectionality> up1 = lane1.upstreamLanes(dir1, gtuType);
1141
1142 for (int j = i + 1; j < lanes.size(); j++)
1143 {
1144 Lane lane2 = lanes.get(j);
1145 if (ignoreList.contains(lane1, lane2))
1146 {
1147 continue;
1148 }
1149
1150 try
1151 {
1152 if (!lane1.getContour().intersects(lane2.getContour()))
1153 {
1154 continue;
1155 }
1156 }
1157 catch (Exception e)
1158 {
1159 System.err.println("Contour problem - lane1 = [" + lane1.getFullId() + "], lane2 = ["
1160 + lane2.getFullId() + "]; skipped");
1161 continue;
1162 }
1163
1164 boolean permitted = permittedList.contains(lane1, lane2);
1165
1166 for (GTUDirectionality dir2 : lane2.getLaneType().getDirectionality(gtuType).getDirectionalities())
1167 {
1168 while (numberOfJobs.get() > maxqueue)
1169 {
1170 try
1171 {
1172 Thread.sleep(1);
1173 }
1174 catch (InterruptedException exception)
1175 {
1176
1177 }
1178 }
1179 numberOfJobs.incrementAndGet();
1180 ImmutableMap<Lane, GTUDirectionality> down2 = lane2.downstreamLanes(dir2, gtuType);
1181 ImmutableMap<Lane, GTUDirectionality> up2 = lane2.upstreamLanes(dir2, gtuType);
1182 ConflictBuilderRecordSmall cbr = new ConflictBuilderRecordSmall(lane1, dir1, down1, up1, lane2, dir2,
1183 down2, up2, gtuType, permitted, simulator, widthGenerator, leftEdges, rightEdges);
1184 executor.execute(new CbrTaskSmall(numberOfJobs, cbr));
1185 }
1186 }
1187 }
1188 }
1189
1190 long time = System.currentTimeMillis();
1191
1192 while (numberOfJobs.get() > 0 && System.currentTimeMillis() - time < 60000)
1193 {
1194 try
1195 {
1196 Thread.sleep(10);
1197 }
1198 catch (InterruptedException exception)
1199 {
1200
1201 }
1202 }
1203
1204 executor.shutdown();
1205 while (!executor.isTerminated())
1206 {
1207 try
1208 {
1209 Thread.sleep(1);
1210 }
1211 catch (InterruptedException exception)
1212 {
1213
1214 }
1215 }
1216
1217 SimLogger.always()
1218 .debug(String.format(
1219 "generating conflicts complete (generated %d merge conflicts, %d split "
1220 + "conflicts, %d crossing conflicts)",
1221 numberMergeConflicts.get(), numberSplitConflicts.get(), numberCrossConflicts.get()));
1222 }
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234 public static void buildConflictsParallelBig(final List<Lane> lanes, final GTUType gtuType,
1235 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator,
1236 final LaneCombinationListflict/LaneCombinationList.html#LaneCombinationList">LaneCombinationList ignoreList, final LaneCombinationList permittedList) throws OTSGeometryException
1237 {
1238
1239 long totalCombinations = ((long) lanes.size()) * ((long) lanes.size() - 1) / 2;
1240 System.out.println("PARALLEL GENERATING OF CONFLICTS (BIG JOBS). " + totalCombinations + " COMBINATIONS");
1241 long lastReported = 0;
1242 Map<Lane, OTSLine3D> leftEdges = new LinkedHashMap<>();
1243 Map<Lane, OTSLine3D> rightEdges = new LinkedHashMap<>();
1244
1245
1246 for (Lane lane : lanes)
1247 {
1248 lane.getContour().getEnvelope();
1249 }
1250
1251
1252 int cores = Runtime.getRuntime().availableProcessors();
1253 System.out.println("USING " + cores + " CORES");
1254 ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(cores);
1255 AtomicInteger numberOfJobs = new AtomicInteger(0);
1256 final int maxqueue = 200;
1257
1258 for (int i = 0; i < lanes.size(); i++)
1259 {
1260 long combinationsDone = totalCombinations - ((long) (lanes.size() - i)) * ((long) (lanes.size() - i)) / 2;
1261 if (combinationsDone / 100000000 > lastReported)
1262 {
1263 SimLogger.always()
1264 .debug(String.format(
1265 "generating conflicts at %.0f%% (generated %d merge conflicts, %d split "
1266 + "conflicts, %d crossing conflicts)",
1267 100.0 * combinationsDone / totalCombinations, numberMergeConflicts.get(),
1268 numberSplitConflicts.get(), numberCrossConflicts.get()));
1269 lastReported = combinationsDone / 100000000;
1270 }
1271 Lane lane1 = lanes.get(i);
1272 for (GTUDirectionality dir1 : lane1.getLaneType().getDirectionality(gtuType).getDirectionalities())
1273 {
1274 ImmutableMap<Lane, GTUDirectionality> down1 = lane1.downstreamLanes(dir1, gtuType);
1275 ImmutableMap<Lane, GTUDirectionality> up1 = lane1.upstreamLanes(dir1, gtuType);
1276
1277 while (numberOfJobs.get() > maxqueue)
1278 {
1279 try
1280 {
1281 Thread.sleep(0, 10);
1282 }
1283 catch (InterruptedException exception)
1284 {
1285
1286 }
1287 }
1288 numberOfJobs.incrementAndGet();
1289
1290 ConflictBuilderRecordBig cbr = new ConflictBuilderRecordBig(i, lanes, ignoreList, permittedList, lane1, dir1,
1291 down1, up1, gtuType, simulator, widthGenerator, leftEdges, rightEdges);
1292 executor.execute(new CbrTaskBig(numberOfJobs, cbr));
1293
1294 }
1295 }
1296
1297 long time = System.currentTimeMillis();
1298
1299 while (numberOfJobs.get() > 0 && System.currentTimeMillis() - time < 60000)
1300 {
1301 try
1302 {
1303 Thread.sleep(10);
1304 }
1305 catch (InterruptedException exception)
1306 {
1307
1308 }
1309 }
1310
1311 executor.shutdown();
1312 while (!executor.isTerminated())
1313 {
1314 try
1315 {
1316 Thread.sleep(1);
1317 }
1318 catch (InterruptedException exception)
1319 {
1320
1321 }
1322 }
1323
1324 SimLogger.always()
1325 .debug(String.format(
1326 "generating conflicts complete (generated %d merge conflicts, %d split "
1327 + "conflicts, %d crossing conflicts)",
1328 numberMergeConflicts.get(), numberSplitConflicts.get(), numberCrossConflicts.get()));
1329 }
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341 public static void buildConflictsParallel(final OTSRoadNetwork network, final Map<String, Set<Link>> conflictCandidateMap,
1342 final GTUType gtuType, final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator)
1343 throws OTSGeometryException
1344 {
1345 for (String conflictId : conflictCandidateMap.keySet())
1346 {
1347
1348 List<Lane> lanes = new ArrayList<>();
1349 for (Link link : conflictCandidateMap.get(conflictId))
1350 {
1351 if (link instanceof CrossSectionLink)
1352 {
1353 for (CrossSectionElement element : ((CrossSectionLink) link).getCrossSectionElementList())
1354 {
1355 if (element instanceof Lane)
1356 {
1357 lanes.add((Lane) element);
1358 }
1359 }
1360 }
1361 }
1362
1363 SimLogger.setAllLogLevel(Level.WARNING);
1364 buildConflicts(lanes, gtuType, simulator, widthGenerator, new LaneCombinationListrk/lane/conflict/LaneCombinationList.html#LaneCombinationList">LaneCombinationList(), new LaneCombinationList());
1365 SimLogger.setAllLogLevel(Level.DEBUG);
1366 }
1367 }
1368
1369
1370 static class CbrTaskSmall implements Runnable
1371 {
1372
1373 final ConflictBuilderRecordSmall cbr;
1374
1375
1376 final AtomicInteger nrOfJobs;
1377
1378
1379
1380
1381
1382 CbrTaskSmall(final AtomicInteger nrOfJobs, final ConflictBuilderRecordSmall cbr)
1383 {
1384 this.nrOfJobs = nrOfJobs;
1385 this.cbr = cbr;
1386 }
1387
1388 @Override
1389 public void run()
1390 {
1391
1392 try
1393 {
1394 buildConflictsSmall(this.cbr);
1395 }
1396 catch (Exception e)
1397 {
1398 e.printStackTrace();
1399 }
1400 this.nrOfJobs.decrementAndGet();
1401 }
1402
1403 }
1404
1405
1406
1407
1408
1409 static void buildConflictsSmall(final ConflictBuilderRecordSmall cbr)
1410 {
1411
1412 try
1413 {
1414 buildConflicts(cbr.lane1, cbr.dir1, cbr.down1, cbr.up1, cbr.lane2, cbr.dir2, cbr.down2, cbr.up2, cbr.gtuType,
1415 cbr.permitted, cbr.simulator, cbr.widthGenerator, cbr.leftEdges, cbr.rightEdges, false);
1416 }
1417 catch (NetworkException | OTSGeometryException ne)
1418 {
1419 throw new RuntimeException("Conflict build with bad combination of types / rules.", ne);
1420 }
1421 }
1422
1423
1424 @SuppressWarnings("checkstyle:visibilitymodifier")
1425 static class ConflictBuilderRecordSmall
1426 {
1427
1428 final Lane lane1;
1429
1430
1431 final GTUDirectionality dir1;
1432
1433
1434 final ImmutableMap<Lane, GTUDirectionality> down1;
1435
1436
1437 final ImmutableMap<Lane, GTUDirectionality> up1;
1438
1439
1440 final Lane lane2;
1441
1442
1443 final GTUDirectionality dir2;
1444
1445
1446 final ImmutableMap<Lane, GTUDirectionality> down2;
1447
1448
1449 final ImmutableMap<Lane, GTUDirectionality> up2;
1450
1451
1452 final GTUType gtuType;
1453
1454
1455 final boolean permitted;
1456
1457
1458 final DEVSSimulatorInterface.TimeDoubleUnit simulator;
1459
1460
1461 final WidthGenerator widthGenerator;
1462
1463
1464 final Map<Lane, OTSLine3D> leftEdges;
1465
1466
1467 final Map<Lane, OTSLine3D> rightEdges;
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486 @SuppressWarnings("checkstyle:parameternumber")
1487 ConflictBuilderRecordSmall(final Lane lane1, final GTUDirectionality dir1,
1488 final ImmutableMap<Lane, GTUDirectionality> down1, final ImmutableMap<Lane, GTUDirectionality> up1,
1489 final Lane lane2, final GTUDirectionality dir2, final ImmutableMap<Lane, GTUDirectionality> down2,
1490 final ImmutableMap<Lane, GTUDirectionality> up2, final GTUType gtuType, final boolean permitted,
1491 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator,
1492 final Map<Lane, OTSLine3D> leftEdges, final Map<Lane, OTSLine3D> rightEdges)
1493 {
1494 this.lane1 = lane1;
1495 this.dir1 = dir1;
1496 this.down1 = down1;
1497 this.up1 = up1;
1498 this.lane2 = lane2;
1499 this.dir2 = dir2;
1500 this.down2 = down2;
1501 this.up2 = up2;
1502 this.gtuType = gtuType;
1503 this.permitted = permitted;
1504 this.simulator = simulator;
1505 this.widthGenerator = widthGenerator;
1506 this.leftEdges = leftEdges;
1507 this.rightEdges = rightEdges;
1508 }
1509 }
1510
1511
1512 static class CbrTaskBig implements Runnable
1513 {
1514
1515 final ConflictBuilderRecordBig cbr;
1516
1517
1518 final AtomicInteger nrOfJobs;
1519
1520
1521
1522
1523
1524 CbrTaskBig(final AtomicInteger nrOfJobs, final ConflictBuilderRecordBig cbr)
1525 {
1526 this.nrOfJobs = nrOfJobs;
1527 this.cbr = cbr;
1528 }
1529
1530 @Override
1531 public void run()
1532 {
1533
1534 try
1535 {
1536 for (int j = this.cbr.starti + 1; j < this.cbr.lanes.size(); j++)
1537 {
1538 Lane lane2 = this.cbr.lanes.get(j);
1539 if (this.cbr.ignoreList.contains(this.cbr.lane1, lane2))
1540 {
1541 continue;
1542 }
1543
1544 try
1545 {
1546 if (!this.cbr.lane1.getContour().intersects(lane2.getContour()))
1547 {
1548 continue;
1549 }
1550 }
1551 catch (Exception e)
1552 {
1553 System.err.println("Contour problem - lane1 = [" + this.cbr.lane1.getFullId() + "], lane2 = ["
1554 + lane2.getFullId() + "]; skipped");
1555 continue;
1556 }
1557
1558 boolean permitted = this.cbr.permittedList.contains(this.cbr.lane1, lane2);
1559
1560 for (GTUDirectionality dir2 : lane2.getLaneType().getDirectionality(this.cbr.gtuType).getDirectionalities())
1561 {
1562 ImmutableMap<Lane, GTUDirectionality> down2 = lane2.downstreamLanes(dir2, this.cbr.gtuType);
1563 ImmutableMap<Lane, GTUDirectionality> up2 = lane2.upstreamLanes(dir2, this.cbr.gtuType);
1564
1565 try
1566 {
1567 buildConflicts(this.cbr.lane1, this.cbr.dir1, this.cbr.down1, this.cbr.up1, lane2, dir2, down2, up2,
1568 this.cbr.gtuType, permitted, this.cbr.simulator, this.cbr.widthGenerator,
1569 this.cbr.leftEdges, this.cbr.rightEdges, false);
1570 }
1571 catch (NetworkException | OTSGeometryException ne)
1572 {
1573 SimLogger.always().error(ne, "Conflict build with bad combination of types / rules.");
1574 }
1575 }
1576 }
1577
1578 }
1579 catch (Exception e)
1580 {
1581 e.printStackTrace();
1582 }
1583 this.nrOfJobs.decrementAndGet();
1584 }
1585 }
1586
1587
1588 @SuppressWarnings("checkstyle:visibilitymodifier")
1589 static class ConflictBuilderRecordBig
1590 {
1591
1592 final int starti;
1593
1594
1595 final List<Lane> lanes;
1596
1597
1598 final LaneCombinationList ignoreList;
1599
1600
1601 final LaneCombinationList permittedList;
1602
1603
1604 final Lane lane1;
1605
1606
1607 final GTUDirectionality dir1;
1608
1609
1610 final ImmutableMap<Lane, GTUDirectionality> down1;
1611
1612
1613 final ImmutableMap<Lane, GTUDirectionality> up1;
1614
1615
1616 final GTUType gtuType;
1617
1618
1619 final DEVSSimulatorInterface.TimeDoubleUnit simulator;
1620
1621
1622 final WidthGenerator widthGenerator;
1623
1624
1625 final Map<Lane, OTSLine3D> leftEdges;
1626
1627
1628 final Map<Lane, OTSLine3D> rightEdges;
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646 @SuppressWarnings("checkstyle:parameternumber")
1647 ConflictBuilderRecordBig(final int starti, final List<Lane> lanes, final LaneCombinationList ignoreList,
1648 final LaneCombinationList permittedList, final Lane lane1, final GTUDirectionality dir1,
1649 final ImmutableMap<Lane, GTUDirectionality> down1, final ImmutableMap<Lane, GTUDirectionality> up1,
1650 final GTUType gtuType, final DEVSSimulatorInterface.TimeDoubleUnit simulator,
1651 final WidthGenerator widthGenerator, final Map<Lane, OTSLine3D> leftEdges,
1652 final Map<Lane, OTSLine3D> rightEdges)
1653 {
1654 this.starti = starti;
1655 this.lanes = lanes;
1656 this.ignoreList = ignoreList;
1657 this.permittedList = permittedList;
1658 this.lane1 = lane1;
1659 this.dir1 = dir1;
1660 this.down1 = down1;
1661 this.up1 = up1;
1662 this.gtuType = gtuType;
1663 this.simulator = simulator;
1664 this.widthGenerator = widthGenerator;
1665 this.leftEdges = leftEdges;
1666 this.rightEdges = rightEdges;
1667 }
1668 }
1669
1670 }