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