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.simulators.DEVSSimulatorInterface;
34
35
36
37
38
39
40
41
42
43
44
45
46 public final class ConflictBuilder
47 {
48
49 private static AtomicInteger numberMergeConflicts = new AtomicInteger(0);
50
51
52 private static AtomicInteger numberSplitConflicts = new AtomicInteger(0);
53
54
55 private static AtomicInteger numberCrossConflicts = new AtomicInteger(0);
56
57
58 public static final WidthGenerator DEFAULT_WIDTH_GENERATOR = new RelativeWidthGenerator(0.8);
59
60
61
62
63 private ConflictBuilder()
64 {
65
66 }
67
68
69
70
71
72
73
74
75
76 public static void buildConflicts(final OTSRoadNetwork network, final GTUType gtuType,
77 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator)
78 throws OTSGeometryException
79 {
80 buildConflicts(network, gtuType, simulator, widthGenerator, new LaneCombinationListrk/lane/conflict/LaneCombinationList.html#LaneCombinationList">LaneCombinationList(), new LaneCombinationList());
81 }
82
83
84
85
86
87
88
89
90
91
92
93 public static void buildConflicts(final OTSRoadNetwork network, final GTUType gtuType,
94 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator,
95 final LaneCombinationListflict/LaneCombinationList.html#LaneCombinationList">LaneCombinationList ignoreList, final LaneCombinationList permittedList) throws OTSGeometryException
96 {
97
98 ImmutableMap<String, Link> links = network.getLinkMap();
99 List<Lane> lanes = new ArrayList<>();
100 for (String linkId : links.keySet())
101 {
102 Link link = links.get(linkId);
103 if (link instanceof CrossSectionLink)
104 {
105 for (CrossSectionElement element : ((CrossSectionLink) link).getCrossSectionElementList())
106 {
107 if (element instanceof Lane)
108 {
109 lanes.add((Lane) element);
110 }
111 }
112 }
113 }
114 buildConflicts(lanes, gtuType, simulator, widthGenerator, ignoreList, permittedList);
115 }
116
117
118
119
120
121
122
123
124
125 public static void buildConflicts(final List<Lane> lanes, final GTUType gtuType,
126 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator)
127 throws OTSGeometryException
128 {
129 buildConflicts(lanes, gtuType, simulator, widthGenerator, new LaneCombinationListrk/lane/conflict/LaneCombinationList.html#LaneCombinationList">LaneCombinationList(), new LaneCombinationList());
130 }
131
132
133
134
135
136
137
138
139
140
141
142 public static void buildConflicts(final List<Lane> lanes, final GTUType gtuType,
143 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator,
144 final LaneCombinationListflict/LaneCombinationList.html#LaneCombinationList">LaneCombinationList ignoreList, final LaneCombinationList permittedList) throws OTSGeometryException
145 {
146
147 long totalCombinations = ((long) lanes.size()) * ((long) lanes.size() - 1) / 2;
148 simulator.getLogger().always().debug("GENERATING CONFLICTS (NON-PARALLEL MODE). {} COMBINATIONS", totalCombinations);
149 long lastReported = 0;
150 Map<Lane, OTSLine3D> leftEdges = new LinkedHashMap<>();
151 Map<Lane, OTSLine3D> rightEdges = new LinkedHashMap<>();
152
153 for (int i = 0; i < lanes.size(); i++)
154 {
155 long combinationsDone = totalCombinations - ((long) (lanes.size() - i)) * ((long) (lanes.size() - i)) / 2;
156 if (combinationsDone / 100000000 > lastReported)
157 {
158 simulator.getLogger().always()
159 .debug(String.format(
160 "generating conflicts at %.0f%% (generated %d merge conflicts, %d split "
161 + "conflicts, %d crossing conflicts)",
162 100.0 * combinationsDone / totalCombinations, numberMergeConflicts.get(),
163 numberSplitConflicts.get(), numberCrossConflicts.get()));
164 lastReported = combinationsDone / 100000000;
165 }
166 Lane lane1 = lanes.get(i);
167 for (GTUDirectionality dir1 : lane1.getLaneType().getDirectionality(gtuType).getDirectionalities())
168 {
169 ImmutableMap<Lane, GTUDirectionality> down1 = lane1.downstreamLanes(dir1, gtuType);
170 ImmutableMap<Lane, GTUDirectionality> up1 = lane1.upstreamLanes(dir1, gtuType);
171
172 for (int j = i + 1; j < lanes.size(); j++)
173 {
174 Lane lane2 = lanes.get(j);
175 if (ignoreList.contains(lane1, lane2))
176 {
177 continue;
178 }
179 boolean permitted = permittedList.contains(lane1, lane2);
180
181 for (GTUDirectionality dir2 : lane2.getLaneType().getDirectionality(gtuType).getDirectionalities())
182 {
183 ImmutableMap<Lane, GTUDirectionality> down2 = lane2.downstreamLanes(dir2, gtuType);
184 ImmutableMap<Lane, GTUDirectionality> up2 = lane2.upstreamLanes(dir2, gtuType);
185
186 try
187 {
188 buildConflicts(lane1, dir1, down1, up1, lane2, dir2, down2, up2, gtuType, permitted, simulator,
189 widthGenerator, leftEdges, rightEdges, true);
190 }
191 catch (NetworkException ne)
192 {
193 throw new RuntimeException("Conflict build with bad combination of types / rules.", ne);
194 }
195 }
196 }
197 }
198 }
199 simulator.getLogger().always()
200 .debug(String.format(
201 "generating conflicts complete (generated %d merge conflicts, %d split "
202 + "conflicts, %d crossing conflicts)",
203 numberMergeConflicts.get(), numberSplitConflicts.get(), numberCrossConflicts.get()));
204 }
205
206
207
208
209
210
211
212
213
214
215
216
217 @SuppressWarnings("checkstyle:parameternumber")
218 public static void buildConflicts(final Lane lane1, Lane_keyword">final GTUDirectionality dir1, final Lane lane2,
219 final GTUDirectionality dir2, final GTUType gtuType, final DEVSSimulatorInterface.TimeDoubleUnit simulator,
220 final WidthGenerator widthGenerator) throws OTSGeometryException
221 {
222 buildConflicts(lane1, dir1, lane2, dir2, gtuType, simulator, widthGenerator, false);
223 }
224
225
226
227
228
229
230
231
232
233
234
235
236
237 @SuppressWarnings("checkstyle:parameternumber")
238 public static void buildConflicts(final Lane lane1, Lane_keyword">final GTUDirectionality dir1, final Lane lane2,
239 final GTUDirectionality dir2, final GTUType gtuType, final DEVSSimulatorInterface.TimeDoubleUnit simulator,
240 final WidthGenerator widthGenerator, final boolean permitted) throws OTSGeometryException
241 {
242 ImmutableMap<Lane, GTUDirectionality> down1 = lane1.downstreamLanes(dir1, gtuType);
243 ImmutableMap<Lane, GTUDirectionality> up1 = lane1.upstreamLanes(dir1, gtuType);
244 ImmutableMap<Lane, GTUDirectionality> down2 = lane2.downstreamLanes(dir2, gtuType);
245 ImmutableMap<Lane, GTUDirectionality> up2 = lane2.upstreamLanes(dir2, gtuType);
246 try
247 {
248 buildConflicts(lane1, dir1, down1, up1, lane2, dir2, down2, up2, gtuType, permitted, simulator, widthGenerator,
249 new LinkedHashMap<>(), new LinkedHashMap<>(), true);
250 }
251 catch (NetworkException ne)
252 {
253 throw new RuntimeException("Conflict build with bad combination of types / rules.", ne);
254 }
255 }
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277 @SuppressWarnings({"checkstyle:parameternumber", "checkstyle:methodlength"})
278 static void buildConflicts(final Lane lane1, final GTUDirectionality dir1,
279 final ImmutableMap<Lane, GTUDirectionality> down1, final ImmutableMap<Lane, GTUDirectionality> up1,
280 final Lane lane2, final GTUDirectionality dir2, final ImmutableMap<Lane, GTUDirectionality> down2,
281 final ImmutableMap<Lane, GTUDirectionality> up2, final GTUType gtuType, final boolean permitted,
282 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator,
283 final Map<Lane, OTSLine3D> leftEdges, final Map<Lane, OTSLine3D> rightEdges, final boolean intersectionCheck)
284 throws OTSGeometryException, NetworkException
285 {
286
287 if (intersectionCheck)
288 {
289 if (!lane1.getContour().intersects(lane2.getContour()))
290 {
291 return;
292 }
293 }
294
295
296
297
298 OTSLine3D left1;
299 OTSLine3D right1;
300 synchronized (lane1)
301 {
302 left1 = leftEdges.get(lane1);
303 right1 = rightEdges.get(lane1);
304 OTSLine3D line1 = lane1.getCenterLine();
305 if (null == left1)
306 {
307 left1 = line1.offsetLine(widthGenerator.getWidth(lane1, 0.0) / 2, widthGenerator.getWidth(lane1, 1.0) / 2);
308 leftEdges.put(lane1, left1);
309 }
310 if (null == right1)
311 {
312 right1 = line1.offsetLine(-widthGenerator.getWidth(lane1, 0.0) / 2, -widthGenerator.getWidth(lane1, 1.0) / 2);
313 rightEdges.put(lane1, right1);
314 }
315 }
316
317 OTSLine3D left2;
318 OTSLine3D right2;
319 synchronized (lane2)
320 {
321 left2 = leftEdges.get(lane2);
322 right2 = rightEdges.get(lane2);
323 OTSLine3D line2 = lane2.getCenterLine();
324 if (null == left2)
325 {
326 left2 = line2.offsetLine(widthGenerator.getWidth(lane2, 0.0) / 2, widthGenerator.getWidth(lane2, 1.0) / 2);
327 leftEdges.put(lane2, left2);
328 }
329 if (null == right2)
330 {
331 right2 = line2.offsetLine(-widthGenerator.getWidth(lane2, 0.0) / 2, -widthGenerator.getWidth(lane2, 1.0) / 2);
332 rightEdges.put(lane2, right2);
333 }
334 }
335
336
337 SortedSet<Intersection> intersections = Intersection.getIntersectionList(left1, left2, 0);
338 intersections.addAll(Intersection.getIntersectionList(left1, right2, 1));
339 intersections.addAll(Intersection.getIntersectionList(right1, left2, 2));
340 intersections.addAll(Intersection.getIntersectionList(right1, right2, 3));
341
342
343 ImmutableIterator<ImmutableEntry<Lane, GTUDirectionality>> iterator1 = down1.entrySet().iterator();
344 ImmutableIterator<ImmutableEntry<Lane, GTUDirectionality>> iterator2 = down2.entrySet().iterator();
345 boolean merge = false;
346 while (iterator1.hasNext() && !merge)
347 {
348 ImmutableEntry<Lane, GTUDirectionality> next1 = iterator1.next();
349 while (iterator2.hasNext() && !merge)
350 {
351 ImmutableEntry<Lane, GTUDirectionality> next2 = iterator2.next();
352 if (next1.equals(next2))
353 {
354
355 double fraction1 = Double.NaN;
356 double fraction2 = Double.NaN;
357 for (Intersection intersection : intersections)
358 {
359
360 if (intersection.getCombo() == 1 || intersection.getCombo() == 2)
361 {
362 fraction1 = intersection.getFraction1();
363 fraction2 = intersection.getFraction2();
364 }
365 }
366
367 Iterator<Intersection> iterator = intersections.iterator();
368 while (iterator.hasNext())
369 {
370 if (iterator.next().getFraction1() >= fraction1)
371 {
372 iterator.remove();
373 }
374 }
375 if (Double.isNaN(fraction1))
376 {
377 simulator.getLogger().always().warn("Fixing fractions of merge conflict");
378 fraction1 = 0;
379 fraction2 = 0;
380 }
381
382 buildMergeConflict(lane1, dir1, fraction1, lane2, dir2, fraction2, gtuType, simulator, widthGenerator,
383 permitted);
384
385 merge = true;
386 }
387 }
388 }
389
390
391 iterator1 = up1.entrySet().iterator();
392 iterator2 = up2.entrySet().iterator();
393 boolean split = false;
394 while (iterator1.hasNext() && !split)
395 {
396 ImmutableEntry<Lane, GTUDirectionality> prev1 = iterator1.next();
397 while (iterator2.hasNext() && !split)
398 {
399 ImmutableEntry<Lane, GTUDirectionality> prev2 = iterator2.next();
400 if (prev1.equals(prev2))
401 {
402
403 double fraction1 = Double.NaN;
404 double fraction2 = Double.NaN;
405 for (Intersection intersection : intersections)
406 {
407
408 if (intersection.getCombo() == 1 || intersection.getCombo() == 2)
409 {
410 fraction1 = intersection.getFraction1();
411 fraction2 = intersection.getFraction2();
412 break;
413 }
414 }
415
416 Iterator<Intersection> iterator = intersections.iterator();
417 while (iterator.hasNext())
418 {
419 if (iterator.next().getFraction1() <= fraction1)
420 {
421 iterator.remove();
422 }
423 else
424 {
425
426 break;
427 }
428 }
429 if (Double.isNaN(fraction1))
430 {
431 simulator.getLogger().always().warn("Fixing fractions of split conflict");
432 fraction1 = 1;
433 fraction2 = 1;
434 }
435
436 buildSplitConflict(lane1, dir1, fraction1, lane2, dir2, fraction2, gtuType, simulator, widthGenerator);
437
438 split = true;
439 }
440 }
441 }
442
443
444 if (!lane1.getParentLink().equals(lane2.getParentLink()))
445 {
446 boolean[] crossed = new boolean[4];
447 Iterator<Intersection> iterator = intersections.iterator();
448 double f1Start = Double.NaN;
449 double f2Start = Double.NaN;
450 double f2End = Double.NaN;
451 while (iterator.hasNext())
452 {
453 Intersection intersection = iterator.next();
454
455 if (Double.isNaN(f1Start))
456 {
457 f1Start = intersection.getFraction1();
458 }
459 f2Start = Double.isNaN(f2Start) ? intersection.getFraction2() : Math.min(f2Start, intersection.getFraction2());
460 f2End = Double.isNaN(f2End) ? intersection.getFraction2() : Math.max(f2End, intersection.getFraction2());
461
462 crossed[intersection.getCombo()] = !crossed[intersection.getCombo()];
463
464 if ((crossed[0] && crossed[1] && crossed[2] && crossed[3])
465 || (!crossed[0] && !crossed[1] && !crossed[2] && !crossed[3]))
466 {
467 if (dir2.isMinus())
468 {
469 double f2Temp = f2Start;
470 f2Start = f2End;
471 f2End = f2Temp;
472 }
473 if (Double.isNaN(f1Start) || Double.isNaN(f2Start) || Double.isNaN(f2End))
474 {
475 simulator.getLogger().always().warn("NOT YET Fixing fractions of crossing conflict");
476 }
477 buildCrossingConflict(lane1, dir1, f1Start, intersection.getFraction1(), lane2, dir2, f2Start, f2End,
478 gtuType, simulator, widthGenerator, permitted);
479 f1Start = Double.NaN;
480 f2Start = Double.NaN;
481 f2End = Double.NaN;
482 }
483 }
484 }
485
486 }
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503 @SuppressWarnings("checkstyle:parameternumber")
504 private static void buildMergeConflict(final Lane lane1, final GTUDirectionality dir1, final double f1start,
505 final Lane lane2, final GTUDirectionality dir2, final double f2start, final GTUType gtuType,
506 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator, final boolean permitted)
507 throws NetworkException, OTSGeometryException
508 {
509
510
511 double f1end = dir1.isPlus() ? 1.0 : 0.0;
512 double f2end = dir2.isPlus() ? 1.0 : 0.0;
513
514
515 Length longitudinalPosition1 = lane1.getLength().times(f1start);
516 Length longitudinalPosition2 = lane2.getLength().times(f2start);
517 Length length1 = lane1.getLength().times(Math.abs(f1end - f1start));
518 Length length2 = lane2.getLength().times(Math.abs(f2end - f2start));
519
520
521 OTSLine3D geometry1 = getGeometry(lane1, f1start, f1end, widthGenerator);
522 OTSLine3D geometry2 = getGeometry(lane2, f2start, f2end, widthGenerator);
523
524
525 ConflictRule conflictRule;
526 if (lane1.getParentLink().getPriority().isBusStop() || lane2.getParentLink().getPriority().isBusStop())
527 {
528 Throw.when(lane1.getParentLink().getPriority().isBusStop() && lane2.getParentLink().getPriority().isBusStop(),
529 IllegalArgumentException.class, "Merge conflict between two links with bus stop priority not supported.");
530 conflictRule = new BusStopConflictRule(simulator);
531 }
532 else
533 {
534 conflictRule = new DefaultConflictRule();
535 }
536
537
538 Conflict.generateConflictPair(ConflictType.MERGE, conflictRule, permitted, lane1, longitudinalPosition1, length1, dir1,
539 geometry1, gtuType, lane2, longitudinalPosition2, length2, dir2, geometry2, gtuType, simulator);
540
541 numberMergeConflicts.incrementAndGet();
542 }
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558 @SuppressWarnings("checkstyle:parameternumber")
559 private static void buildSplitConflict(final Lane lane1, final GTUDirectionality dir1, finalLanetrong class="jxr_keyword">double f1end, final Lane lane2,
560 final GTUDirectionality dir2, final double f2end, final GTUType gtuType,
561 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator)
562 throws NetworkException, OTSGeometryException
563 {
564
565
566 double f1start = dir1.isPlus() ? 0.0 : 1.0;
567 double f2start = dir2.isPlus() ? 0.0 : 1.0;
568
569
570 Length longitudinalPosition1 = lane1.getLength().times(f1start);
571 Length longitudinalPosition2 = lane2.getLength().times(f2start);
572 Length length1 = lane1.getLength().times(Math.abs(f1end - f1start));
573 Length length2 = lane2.getLength().times(Math.abs(f2end - f2start));
574
575
576 OTSLine3D geometry1 = getGeometry(lane1, f1start, f1end, widthGenerator);
577 OTSLine3D geometry2 = getGeometry(lane2, f2start, f2end, widthGenerator);
578
579
580 Conflict.generateConflictPair(ConflictType.SPLIT, new SplitConflictRule(), false, lane1, longitudinalPosition1, length1,
581 dir1, geometry1, gtuType, lane2, longitudinalPosition2, length2, dir2, geometry2, gtuType, simulator);
582
583 numberSplitConflicts.incrementAndGet();
584 }
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603 @SuppressWarnings("checkstyle:parameternumber")
604 private static void buildCrossingConflict(final Lane lane1, final GTUDirectionality dir1, final double f1start,
605 final double f1end, final Lane lane2, final GTUDirectionality dir2, final double f2start, final double f2end,
606 final GTUType gtuType, final DEVSSimulatorInterface.TimeDoubleUnit simulator, final WidthGenerator widthGenerator,
607 final boolean permitted) throws NetworkException, OTSGeometryException
608 {
609
610
611
612 double f1startDirected;
613 double f2startDirected;
614 if ((dir1.isPlus() && f1end < f1start) || (dir1.isMinus() && f1end > f1start))
615 {
616 f1startDirected = f1end;
617 }
618 else
619 {
620 f1startDirected = f1start;
621 }
622 if ((dir2.isPlus() && f2end < f2start) || (dir2.isMinus() && f2end > f2start))
623 {
624 f2startDirected = f2end;
625 }
626 else
627 {
628 f2startDirected = f2start;
629 }
630
631
632 Length longitudinalPosition1 = lane1.getLength().times(f1startDirected);
633 Length longitudinalPosition2 = lane2.getLength().times(f2startDirected);
634 Length length1 = lane1.getLength().times(Math.abs(f1end - f1start));
635 Length length2 = lane2.getLength().times(Math.abs(f2end - f2start));
636
637
638 OTSLine3D geometry1 = getGeometry(lane1, f1start, f1end, widthGenerator);
639 OTSLine3D geometry2 = getGeometry(lane2, f2start, f2end, widthGenerator);
640
641
642 ConflictRule conflictRule;
643 if (lane1.getParentLink().getPriority().isBusStop() || lane2.getParentLink().getPriority().isBusStop())
644 {
645 Throw.when(lane1.getParentLink().getPriority().isBusStop() && lane2.getParentLink().getPriority().isBusStop(),
646 IllegalArgumentException.class, "Merge conflict between two links with bus stop priority not supported.");
647 conflictRule = new BusStopConflictRule(simulator);
648 }
649 else
650 {
651 conflictRule = new DefaultConflictRule();
652 }
653
654
655 Conflict.generateConflictPair(ConflictType.CROSSING, conflictRule, permitted, lane1, longitudinalPosition1, length1,
656 dir1, geometry1, gtuType, lane2, longitudinalPosition2, length2, dir2, geometry2, gtuType, simulator);
657
658 numberCrossConflicts.incrementAndGet();
659 }
660
661
662
663
664
665
666
667
668
669
670 private static OTSLine3D getGeometry(final Lane lane, final double fStart, final double fEnd,
671 final WidthGenerator widthGenerator) throws OTSGeometryException
672 {
673
674 double f1;
675 double f2;
676 if (fEnd > fStart)
677 {
678 f1 = fStart;
679 f2 = fEnd;
680 }
681 else
682 {
683 f1 = fEnd;
684 f2 = fStart;
685 }
686 if (f1 == f2)
687 {
688 lane.getParentLink().getSimulator().getLogger().always()
689 .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 simulator.getLogger().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 simulator.getLogger().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 simulator.getLogger().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 simulator.getLogger().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 simulator.getLogger().setAllLogLevel(Level.WARNING);
1364 buildConflicts(lanes, gtuType, simulator, widthGenerator, new LaneCombinationListrk/lane/conflict/LaneCombinationList.html#LaneCombinationList">LaneCombinationList(), new LaneCombinationList());
1365 simulator.getLogger().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 lane2.getParentLink().getSimulator().getLogger().always().error(ne,
1574 "Conflict build with bad combination of types / rules.");
1575 }
1576 }
1577 }
1578
1579 }
1580 catch (Exception e)
1581 {
1582 e.printStackTrace();
1583 }
1584 this.nrOfJobs.decrementAndGet();
1585 }
1586 }
1587
1588
1589 @SuppressWarnings("checkstyle:visibilitymodifier")
1590 static class ConflictBuilderRecordBig
1591 {
1592
1593 final int starti;
1594
1595
1596 final List<Lane> lanes;
1597
1598
1599 final LaneCombinationList ignoreList;
1600
1601
1602 final LaneCombinationList permittedList;
1603
1604
1605 final Lane lane1;
1606
1607
1608 final GTUDirectionality dir1;
1609
1610
1611 final ImmutableMap<Lane, GTUDirectionality> down1;
1612
1613
1614 final ImmutableMap<Lane, GTUDirectionality> up1;
1615
1616
1617 final GTUType gtuType;
1618
1619
1620 final DEVSSimulatorInterface.TimeDoubleUnit simulator;
1621
1622
1623 final WidthGenerator widthGenerator;
1624
1625
1626 final Map<Lane, OTSLine3D> leftEdges;
1627
1628
1629 final Map<Lane, OTSLine3D> rightEdges;
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647 @SuppressWarnings("checkstyle:parameternumber")
1648 ConflictBuilderRecordBig(final int starti, final List<Lane> lanes, final LaneCombinationList ignoreList,
1649 final LaneCombinationList permittedList, final Lane lane1, final GTUDirectionality dir1,
1650 final ImmutableMap<Lane, GTUDirectionality> down1, final ImmutableMap<Lane, GTUDirectionality> up1,
1651 final GTUType gtuType, final DEVSSimulatorInterface.TimeDoubleUnit simulator,
1652 final WidthGenerator widthGenerator, final Map<Lane, OTSLine3D> leftEdges,
1653 final Map<Lane, OTSLine3D> rightEdges)
1654 {
1655 this.starti = starti;
1656 this.lanes = lanes;
1657 this.ignoreList = ignoreList;
1658 this.permittedList = permittedList;
1659 this.lane1 = lane1;
1660 this.dir1 = dir1;
1661 this.down1 = down1;
1662 this.up1 = up1;
1663 this.gtuType = gtuType;
1664 this.simulator = simulator;
1665 this.widthGenerator = widthGenerator;
1666 this.leftEdges = leftEdges;
1667 this.rightEdges = rightEdges;
1668 }
1669 }
1670
1671 }