1 package org.opentrafficsim.road.gtu.lane.tactical.lmrs;
2
3 import java.util.ArrayList;
4 import java.util.LinkedHashMap;
5 import java.util.LinkedHashSet;
6 import java.util.List;
7 import java.util.Map;
8 import java.util.Map.Entry;
9 import java.util.Set;
10 import java.util.function.BiFunction;
11 import java.util.function.Function;
12 import java.util.function.Supplier;
13 import java.util.stream.Collectors;
14 import java.util.stream.Stream;
15
16 import org.djunits.unit.SpeedUnit;
17 import org.djunits.value.vdouble.scalar.Duration;
18 import org.djutils.exceptions.Throw;
19 import org.djutils.exceptions.Try;
20 import org.opentrafficsim.base.parameters.ParameterException;
21 import org.opentrafficsim.base.parameters.ParameterSet;
22 import org.opentrafficsim.base.parameters.ParameterTypes;
23 import org.opentrafficsim.base.parameters.Parameters;
24 import org.opentrafficsim.core.definitions.DefaultsNl;
25 import org.opentrafficsim.core.gtu.GtuException;
26 import org.opentrafficsim.core.gtu.GtuType;
27 import org.opentrafficsim.core.gtu.perception.DirectEgoPerception;
28 import org.opentrafficsim.core.parameters.ParameterFactoryOneShot;
29 import org.opentrafficsim.core.units.distributions.ContinuousDistSpeed;
30 import org.opentrafficsim.road.gtu.lane.LaneBasedGtu;
31 import org.opentrafficsim.road.gtu.lane.perception.CategoricalLanePerception;
32 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
33 import org.opentrafficsim.road.gtu.lane.perception.categories.AnticipationTrafficPerception;
34 import org.opentrafficsim.road.gtu.lane.perception.categories.DirectInfrastructurePerception;
35 import org.opentrafficsim.road.gtu.lane.perception.categories.DirectIntersectionPerception;
36 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.Anticipation;
37 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.DirectNeighborsPerception;
38 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.Estimation;
39 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.PerceivedGtuType;
40 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.PerceivedGtuType.AnticipationPerceivedGtuType;
41 import org.opentrafficsim.road.gtu.lane.perception.mental.AdaptationHeadway;
42 import org.opentrafficsim.road.gtu.lane.perception.mental.AdaptationLaneChangeDesire;
43 import org.opentrafficsim.road.gtu.lane.perception.mental.AdaptationSituationalAwareness;
44 import org.opentrafficsim.road.gtu.lane.perception.mental.AdaptationSpeed;
45 import org.opentrafficsim.road.gtu.lane.perception.mental.BehavioralAdaptation;
46 import org.opentrafficsim.road.gtu.lane.perception.mental.FactorEstimation;
47 import org.opentrafficsim.road.gtu.lane.perception.mental.Fuller;
48 import org.opentrafficsim.road.gtu.lane.perception.mental.Mental;
49 import org.opentrafficsim.road.gtu.lane.perception.mental.SumFuller;
50 import org.opentrafficsim.road.gtu.lane.perception.mental.ar.ArFuller;
51 import org.opentrafficsim.road.gtu.lane.perception.mental.ar.ArTask;
52 import org.opentrafficsim.road.gtu.lane.perception.mental.ar.ArTaskCarFollowing;
53 import org.opentrafficsim.road.gtu.lane.perception.mental.ar.ArTaskCarFollowingExp;
54 import org.opentrafficsim.road.gtu.lane.perception.mental.ar.ArTaskLaneChanging;
55 import org.opentrafficsim.road.gtu.lane.perception.mental.ar.ArTaskLaneChangingD;
56 import org.opentrafficsim.road.gtu.lane.perception.mental.ar.ArTaskRoadSideDistraction;
57 import org.opentrafficsim.road.gtu.lane.perception.mental.channel.AdaptationSpeedChannel;
58 import org.opentrafficsim.road.gtu.lane.perception.mental.channel.AdaptationUpdateTime;
59 import org.opentrafficsim.road.gtu.lane.perception.mental.channel.ChannelFuller;
60 import org.opentrafficsim.road.gtu.lane.perception.mental.channel.ChannelMental;
61 import org.opentrafficsim.road.gtu.lane.perception.mental.channel.ChannelTask;
62 import org.opentrafficsim.road.gtu.lane.perception.mental.channel.ChannelTaskAcceleration;
63 import org.opentrafficsim.road.gtu.lane.perception.mental.channel.ChannelTaskCarFollowing;
64 import org.opentrafficsim.road.gtu.lane.perception.mental.channel.ChannelTaskConflict;
65 import org.opentrafficsim.road.gtu.lane.perception.mental.channel.ChannelTaskCooperation;
66 import org.opentrafficsim.road.gtu.lane.perception.mental.channel.ChannelTaskLaneChange;
67 import org.opentrafficsim.road.gtu.lane.perception.mental.channel.ChannelTaskRoadSideDistraction;
68 import org.opentrafficsim.road.gtu.lane.perception.mental.channel.ChannelTaskScan;
69 import org.opentrafficsim.road.gtu.lane.perception.mental.channel.ChannelTaskSignal;
70 import org.opentrafficsim.road.gtu.lane.perception.mental.channel.ChannelTaskTrafficLight;
71 import org.opentrafficsim.road.gtu.lane.perception.mental.channel.IntersectionPerceptionChannel;
72 import org.opentrafficsim.road.gtu.lane.perception.mental.channel.NeighborsPerceptionChannel;
73 import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedTacticalPlannerFactory;
74 import org.opentrafficsim.road.gtu.lane.tactical.following.AbstractIdm;
75 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
76 import org.opentrafficsim.road.gtu.lane.tactical.following.DesiredHeadwayModel;
77 import org.opentrafficsim.road.gtu.lane.tactical.following.DesiredSpeedModel;
78 import org.opentrafficsim.road.gtu.lane.tactical.following.Idm;
79 import org.opentrafficsim.road.gtu.lane.tactical.following.IdmPlus;
80 import org.opentrafficsim.road.gtu.lane.tactical.util.ConflictUtil;
81 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Cooperation;
82 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.GapAcceptance;
83 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
84 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsUtil;
85 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.MandatoryIncentive;
86 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Synchronization;
87 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Tailgating;
88 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.VoluntaryIncentive;
89
90 import nl.tudelft.simulation.jstats.distributions.DistLogNormal;
91 import nl.tudelft.simulation.jstats.distributions.DistNormalTrunc;
92 import nl.tudelft.simulation.jstats.distributions.DistTriangular;
93 import nl.tudelft.simulation.jstats.streams.StreamInterface;
94 import picocli.CommandLine.ITypeConverter;
95 import picocli.CommandLine.Option;
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
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
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303 public class LmrsFactory<T extends AbstractIncentivesTacticalPlanner> extends ParameterFactoryOneShot
304 implements LaneBasedTacticalPlannerFactory<T>
305 {
306
307
308 private Map<Setting<?>, List<?>> state;
309
310
311 private StreamInterface stream;
312
313
314 private ContinuousDistSpeed vGainDist;
315
316
317 private DistTriangular sigmaDist;
318
319
320 private DistNormalTrunc fSpeedDist;
321
322
323 private final List<TacticalPlannerProvider<T>> lmrsProvider;
324
325
326 @Option(names = {"--gtuTypes"}, description = "GTU type IDs in order of multi-valued arguments.",
327 defaultValue = "NL.CAR|NL.TRUCK", split = "\\|", splitSynopsisLabel = "|")
328 private final List<String> gtuTypes;
329
330
331
332
333 @Option(names = {"--carFollowingModel"}, description = "Car-following model: IDM or IDM_PLUS.", defaultValue = "IDM_PLUS",
334 split = "\\|", splitSynopsisLabel = "|", converter = CarFollowingModelConverter.class)
335 private List<BiFunction<DesiredHeadwayModel, DesiredSpeedModel, CarFollowingModel>> carFollowingModel =
336 listOf((h, v) -> new IdmPlus(h, v));
337
338
339 @Option(names = {"--synchronization"},
340 description = "Lane change synchronization: PASSIVE, PASSIVE_MOVING, ALIGN_GAP or ACTIVE.",
341 defaultValue = "PASSIVE", split = "\\|", splitSynopsisLabel = "|", converter = SynchronizationConverter.class)
342 private List<Synchronization> synchronization = listOf(Synchronization.PASSIVE);
343
344
345 @Option(names = {"--cooperation"}, description = "Lane change cooperation: PASSIVE, PASSIVE_MOVING or ACTIVE.",
346 defaultValue = "PASSIVE", split = "\\|", splitSynopsisLabel = "|", converter = CooperationConverter.class)
347 private List<Cooperation> cooperation = listOf(Cooperation.PASSIVE);
348
349
350 @Option(names = {"--gapAcceptance"}, description = "Lane change gap-acceptance: INFORMED or EGO_HEADWAY.",
351 defaultValue = "INFORMED", split = "\\|", splitSynopsisLabel = "|", converter = GapAcceptanceConverter.class)
352 private List<GapAcceptance> gapAcceptance = listOf(GapAcceptance.INFORMED);
353
354
355
356
357 @Option(names = {"--incentiveRoute"}, description = "Mandatory lane change incentive for route.", defaultValue = "true",
358 split = "\\|", splitSynopsisLabel = "|", negatable = true)
359 private List<Boolean> incentiveRoute = listOf(true);
360
361
362 @Option(names = {"--incentiveGetInLane"},
363 description = "Mandatory lane change incentive to join slow traffic at split and not block other traffic.",
364 defaultValue = "false", split = "\\|", splitSynopsisLabel = "|", negatable = true)
365 private List<Boolean> incentiveGetInLane = listOf(false);
366
367
368 private List<Set<Supplier<MandatoryIncentive>>> customMandatoryIncentives = List.of(new LinkedHashSet<>());
369
370
371
372
373 @Option(names = {"--incentiveSpeedWithCourtesy"}, description = "Voluntary lane change incentive for speed with courtesy.",
374 defaultValue = "true", split = "\\|", splitSynopsisLabel = "|", negatable = true)
375 private List<Boolean> incentiveSpeedWithCourtesy = listOf(true);
376
377
378 @Option(names = {"--incentiveCourtesy"}, description = "Voluntary lane change incentive for cooperative lane changes.",
379 defaultValue = "false", split = "\\|", splitSynopsisLabel = "|", negatable = true)
380 private List<Boolean> incentiveCourtesy = listOf(false);
381
382
383 @Option(names = {"--incentiveQueue"}, description = "Voluntary lane change incentive to join the shortest queue.",
384 defaultValue = "false", split = "\\|", splitSynopsisLabel = "|", negatable = true)
385 private List<Boolean> incentiveQueue = listOf(false);
386
387
388 @Option(names = {"--incentiveStayRight"},
389 description = "Voluntary lane change incentive for trucks to stay in rightmost two lanes.", defaultValue = "false",
390 split = "\\|", splitSynopsisLabel = "|", negatable = true)
391 private List<Boolean> incentiveStayRight = listOf(false);
392
393
394 @Option(names = {"--incentiveKeep"}, description = "Voluntary lane change incentive to keep to the slow lane.",
395 defaultValue = "true", split = "\\|", splitSynopsisLabel = "|", negatable = true)
396 private List<Boolean> incentiveKeep = listOf(true);
397
398
399 private List<Set<Supplier<VoluntaryIncentive>>> customVoluntaryIncentives = List.of(new LinkedHashSet<>());
400
401
402
403
404 @Option(names = {"--accelerationSpeedLimitTransition"},
405 description = "Acceleration incentive to slow down prior to a lower speed limit.", defaultValue = "false",
406 split = "\\|", splitSynopsisLabel = "|", negatable = true)
407 private List<Boolean> accelerationSpeedLimitTransition = listOf(false);
408
409
410 @Option(names = {"--accelerationTrafficLights"}, description = "Acceleration incentive to approach traffic lights.",
411 defaultValue = "false", split = "\\|", splitSynopsisLabel = "|", negatable = true)
412 private List<Boolean> accelerationTrafficLights = listOf(false);
413
414
415 @Option(names = {"--accelerationConflicts"}, description = "Acceleration incentive to approach intersection conflicts.",
416 defaultValue = "false", split = "\\|", splitSynopsisLabel = "|", negatable = true)
417 private List<Boolean> accelerationConflicts = listOf(false);
418
419
420 @Option(names = {"--accelerationNoRightOvertake"},
421 description = "Acceleration incentive to not overtake traffic in the left lane.", defaultValue = "false",
422 split = "\\|", splitSynopsisLabel = "|", negatable = true)
423 private List<Boolean> accelerationNoRightOvertake = listOf(false);
424
425
426 private List<Set<Supplier<AccelerationIncentive>>> customAccelerationIncentives = List.of(new LinkedHashSet<>());
427
428
429
430
431 @Option(names = {"--fullerImplementation"},
432 description = "Implementation of Fuller: NONE, SUMMATIVE, ANTICIPATION_RELIANCE or ATTENTION_MATRIX.",
433 defaultValue = "ATTENTION_MATRIX", split = "\\|", splitSynopsisLabel = "|")
434 private List<FullerImplementation> fullerImplementation = listOf(FullerImplementation.NONE);
435
436
437 @Option(names = {"--primaryTask"}, description = "Id of primary task under ANTICIPATION_RELIANCE.",
438 defaultValue = "lane-changing", split = "\\|", splitSynopsisLabel = "|")
439 private List<String> primaryTask = listOf("lane-changing");
440
441
442 @Option(names = {"--anticipation"}, description = "Enables temporal constant-speed anticipation.", defaultValue = "true",
443 split = "\\|", splitSynopsisLabel = "|", negatable = true)
444 private List<Boolean> temporalAnticipation = listOf(true);
445
446
447 @Option(names = {"--fractionOverEstimation"},
448 description = "Fraction of drivers over-estimating speed and distance [0..1].", defaultValue = "0.0", split = "\\|",
449 splitSynopsisLabel = "|")
450 private List<Double> fractionOverEstimation = listOf(1.0);
451
452
453
454
455 @Option(names = {"--carFollowingTask"}, description = "Enables car-following task.", defaultValue = "true", split = "\\|",
456 splitSynopsisLabel = "|", negatable = true)
457 private List<Boolean> carFollowingTask = listOf(true);
458
459
460 @Option(names = {"--alternateCarFollowingTask"}, description = "Enables alternate car-following task (exponential).",
461 defaultValue = "false", split = "\\|", splitSynopsisLabel = "|", negatable = true)
462 private List<Boolean> alternateCarFollowingTask = listOf(false);
463
464
465 @Option(names = {"--freeAccelerationTask"},
466 description = "Enables free acceleration task, useful when updateTimeAdaptation is true.", defaultValue = "false",
467 split = "\\|", splitSynopsisLabel = "|", negatable = true)
468 private List<Boolean> freeAccelerationTask = listOf(false);
469
470
471 @Option(names = {"--trafficLightsTask"}, description = "Enables traffic light task.", defaultValue = "false", split = "\\|",
472 splitSynopsisLabel = "|", negatable = true)
473 private List<Boolean> trafficLightsTask = listOf(false);
474
475
476 @Option(names = {"--signalTask"}, description = "Enables signal task.", defaultValue = "true", split = "\\|",
477 splitSynopsisLabel = "|", negatable = true)
478 private List<Boolean> signalTask = listOf(true);
479
480
481 @Option(names = {"--laneChangingTask"}, description = "Enables lane-change task.", defaultValue = "true", split = "\\|",
482 splitSynopsisLabel = "|", negatable = true)
483 private List<Boolean> laneChangingTask = listOf(true);
484
485
486 @Option(names = {"--alternateLaneChangingTask"}, description = "Enables alternate lane-changing task (lane change desire).",
487 defaultValue = "false", split = "\\|", splitSynopsisLabel = "|", negatable = true)
488 private List<Boolean> alternateLaneChangingTask = listOf(false);
489
490
491 @Option(names = {"--cooperationTask"}, description = "Enables cooperation task.", defaultValue = "true", split = "\\|",
492 splitSynopsisLabel = "|", negatable = true)
493 private List<Boolean> cooperationTask = listOf(true);
494
495
496 @Option(names = {"--conflictsTask"}, description = "Enables conflict task.", defaultValue = "false", split = "\\|",
497 splitSynopsisLabel = "|", negatable = true)
498 private List<Boolean> conflictsTask = listOf(false);
499
500
501 @Option(names = {"--roadSideDistractionTask"}, description = "Enables road-side distraction task.", defaultValue = "false",
502 split = "\\|", splitSynopsisLabel = "|", negatable = true)
503 private List<Boolean> roadSideDistractionTask = listOf(false);
504
505
506
507
508 @Option(names = {"--speedAdaptation"}, description = "Enables behavioral speed adaptation.", defaultValue = "true",
509 split = "\\|", splitSynopsisLabel = "|", negatable = true)
510 private List<Boolean> speedAdaptation = listOf(true);
511
512
513 @Option(names = {"--headwayAdaptation"}, description = "Enables behavioral headway adaptation.", defaultValue = "true",
514 split = "\\|", splitSynopsisLabel = "|", negatable = true)
515 private List<Boolean> headwayAdaptation = listOf(true);
516
517
518 @Option(names = {"--laneChangeAdaptation"}, description = "Enables behavioral voluntary lane change adaptation.",
519 defaultValue = "false", split = "\\|", splitSynopsisLabel = "|", negatable = true)
520 private List<Boolean> laneChangeAdaptation = listOf(false);
521
522
523 @Option(names = {"--updateTimeAdaptation"}, description = "Enables behavioral update time adaptation.",
524 defaultValue = "false", split = "\\|", splitSynopsisLabel = "|", negatable = true)
525 private List<Boolean> updateTimeAdaptation = listOf(false);
526
527
528
529
530 @Option(names = {"--tailgating"},
531 description = "Enables tailgating. Without tailgating, any social interaction still results in social pressure.",
532 defaultValue = "false", split = "\\|", splitSynopsisLabel = "|", negatable = true)
533 private List<Boolean> tailgating = listOf(false);
534
535
536 @Option(names = {"--socioLaneChange"}, description = "Enables lane changes due to social pressure.", defaultValue = "false",
537 split = "\\|", splitSynopsisLabel = "|", negatable = true)
538 private List<Boolean> socioLaneChange = listOf(false);
539
540
541 @Option(names = {"--socioSpeed"}, description = "Enables speed increase due to social pressure.", defaultValue = "false",
542 split = "\\|", splitSynopsisLabel = "|", negatable = true)
543 private List<Boolean> socioSpeed = listOf(false);
544
545
546
547
548
549
550
551 @SafeVarargs
552 private static <V> List<V> listOf(final V... values)
553 {
554 return Stream.of(values).collect(Collectors.toCollection(ArrayList::new));
555 }
556
557
558
559
560
561
562 public LmrsFactory(final TacticalPlannerProvider<T> lmrsProvider)
563 {
564 this(List.of(DefaultsNl.CAR, DefaultsNl.TRUCK), lmrsProvider);
565 }
566
567
568
569
570
571
572
573 public LmrsFactory(final List<GtuType> gtuTypes, final TacticalPlannerProvider<T> lmrsProvider)
574 {
575 Throw.whenNull(gtuTypes, "gtuTypes");
576 Throw.whenNull(lmrsProvider, "lmrsProvider");
577 this.gtuTypes = gtuTypes.stream().map((g) -> g.getId()).collect(Collectors.toCollection(ArrayList::new));
578 this.lmrsProvider = listOf(lmrsProvider);
579 }
580
581
582
583
584
585
586
587
588
589 public LmrsFactory(final List<GtuType> gtuTypes, final List<TacticalPlannerProvider<T>> lmrsProviders)
590 {
591 Throw.whenNull(gtuTypes, "gtuTypes");
592 Throw.whenNull(lmrsProviders, "lmrsProviders");
593 Throw.when(gtuTypes.size() != lmrsProviders.size(), IllegalArgumentException.class,
594 "gtuTypes and lmrsProviders are not of equal size");
595 this.gtuTypes = gtuTypes.stream().map((g) -> g.getId()).collect(Collectors.toList());
596 this.lmrsProvider = new ArrayList<>(lmrsProviders);
597 }
598
599
600
601
602
603
604 @Override
605 public void setOneShotMode()
606 {
607 super.setOneShotMode();
608 this.state = new LinkedHashMap<>();
609 }
610
611
612
613
614
615
616 @SuppressWarnings("unchecked")
617 protected <V> void resetState()
618 {
619 if (this.state == null)
620 {
621 return;
622 }
623 for (Entry<Setting<?>, List<?>> entry : this.state.entrySet())
624 {
625 List<V> values = (List<V>) entry.getKey().getListFunction().apply(this);
626 values.clear();
627 values.addAll((List<V>) entry.getValue());
628 }
629 this.state = null;
630 }
631
632
633
634
635
636
637 @SuppressWarnings("hiddenfield")
638 public LmrsFactory<T> setStream(final StreamInterface stream)
639 {
640 this.stream = stream;
641 this.vGainDist = new ContinuousDistSpeed(new DistLogNormal(stream, 3.379, 0.4), SpeedUnit.KM_PER_HOUR);
642 this.sigmaDist = new DistTriangular(stream, 0.0, 0.25, 1.0);
643 this.fSpeedDist = new DistNormalTrunc(stream, 123.7 / 120.0, 0.1, 0.8, 50.0);
644 return this;
645 }
646
647
648
649
650
651
652
653
654 public <V> LmrsFactory<T> set(final Setting<V> setting, final V value)
655 {
656 Throw.whenNull(value, "value");
657 final List<V> values = setting.getListFunction().apply(this);
658 saveState(setting, values);
659 values.clear();
660 values.add(value);
661 return this;
662 }
663
664
665
666
667
668
669
670
671
672
673 public <V> LmrsFactory<T> set(final Setting<V> setting, final V value, final GtuType gtuType)
674 {
675 Throw.whenNull(value, "value");
676 Throw.whenNull(gtuType, "gtuType");
677
678 int gtuTypeIndex = this.gtuTypes.indexOf(gtuType.getId());
679 Throw.when(gtuTypeIndex < 0, IllegalArgumentException.class, "GTU type %s not defined.", gtuType.getId());
680
681 final List<V> values = setting.getListFunction().apply(this);
682 saveState(setting, values);
683
684
685
686
687
688
689
690 while (values.size() < this.gtuTypes.size())
691 {
692 values.add(null);
693 }
694 values.set(gtuTypeIndex, value);
695 return this;
696 }
697
698
699
700
701
702
703
704 protected <V> void saveState(final Setting<V> setting, final List<V> values)
705 {
706 if (this.state != null && !this.state.containsKey(setting))
707 {
708 this.state.put(setting, new ArrayList<>(values));
709 }
710 }
711
712
713
714
715
716
717
718
719
720 protected <V> V get(final Setting<V> setting, final GtuType gtuType)
721 {
722 return get(setting.getListFunction().apply(this), gtuType, gtuType);
723 }
724
725
726
727
728
729
730
731
732 protected <V> V get(final List<V> values, final GtuType gtuType)
733 {
734 return get(values, gtuType, gtuType);
735 }
736
737
738
739
740
741
742
743
744
745 private <V> V get(final List<V> values, final GtuType gtuType, final GtuType originalGtuType)
746 {
747 Throw.when(values.size() > 1 && this.gtuTypes.size() > values.size(), IllegalArgumentException.class,
748 "Argument has %s values %s but %s GTU types are defined.", values.size(), values, this.gtuTypes.size());
749 if (values.size() == 1)
750 {
751 return values.get(0);
752 }
753 int index = this.gtuTypes.indexOf(gtuType.getId());
754 if (index < 0 || values.get(index) == null)
755 {
756 return get(values,
757 gtuType.getParent().orElseThrow(() -> new IllegalArgumentException(
758 "Unable to obtain setting value for GTU type " + originalGtuType.getId() + " or any parent.")),
759 originalGtuType);
760 }
761 return values.get(index);
762 }
763
764 @Override
765 public Parameters getParameters(final GtuType gtuType) throws ParameterException
766 {
767 ParameterSet parameters = new ParameterSet();
768 parameters.setDefaultParameters(LmrsUtil.class);
769 parameters.setDefaultParameters(LmrsParameters.class);
770 parameters.setDefaultParameters(AbstractIdm.class);
771 parameters.setDefaultParameters(ConflictUtil.class);
772 parameters.setDefaultParameter(ParameterTypes.T0);
773 parameters.setDefaultParameter(ParameterTypes.LANE_STRUCTURE);
774 parameters.setDefaultParameter(ParameterTypes.LOOKBACK);
775 parameters.setDefaultParameter(ParameterTypes.LOOKAHEAD);
776 parameters.setDefaultParameter(ParameterTypes.VCONG);
777 parameters.setDefaultParameter(ParameterTypes.LCDUR);
778
779
780 if (!FullerImplementation.NONE.equals(get(this.fullerImplementation, gtuType)))
781 {
782 parameters.setParameter(ParameterTypes.TR, Duration.ZERO);
783 parameters.setDefaultParameter(AdaptationSituationalAwareness.TR_MAX);
784 parameters.setParameter(ChannelFuller.EST_FACTOR, 1.0);
785 parameters.setParameter(Fuller.OVER_EST,
786 this.stream.nextDouble() <= get(this.fractionOverEstimation, gtuType) ? 1.0 : -1.0);
787 parameters.setDefaultParameter(ChannelTaskScan.TDSCAN);
788 if (get(this.headwayAdaptation, gtuType))
789 {
790 parameters.setDefaultParameter(AdaptationHeadway.BETA_T);
791 }
792 if (get(this.speedAdaptation, gtuType))
793 {
794 parameters.setDefaultParameter(AdaptationSpeed.BETA_V0);
795 }
796
797 if (FullerImplementation.ATTENTION_MATRIX.equals(get(this.fullerImplementation, gtuType)))
798 {
799
800 parameters.setDefaultParameters(ChannelFuller.class);
801 parameters.setDefaultParameters(ChannelMental.class);
802 if (get(this.updateTimeAdaptation, gtuType))
803 {
804 parameters.setDefaultParameter(AdaptationUpdateTime.DT_MIN);
805 parameters.setDefaultParameter(AdaptationUpdateTime.DT_MAX);
806 }
807 if (get(this.carFollowingTask, gtuType))
808 {
809 parameters.setDefaultParameter(ArTaskCarFollowingExp.HEXP);
810 }
811 if (get(this.trafficLightsTask, gtuType) || get(this.conflictsTask, gtuType))
812 {
813
814 parameters.setDefaultParameter(ChannelTaskConflict.HEGO);
815 parameters.setDefaultParameter(ChannelTaskConflict.HCONF);
816 }
817 if (get(this.signalTask, gtuType))
818 {
819 parameters.setDefaultParameter(ChannelTaskSignal.TDSIGNAL);
820 }
821 }
822 else
823 {
824
825 parameters.setDefaultParameters(Fuller.class);
826 parameters.setDefaultParameters(SumFuller.class);
827 parameters.setDefaultParameter(AdaptationSituationalAwareness.SA);
828 parameters.setDefaultParameter(AdaptationSituationalAwareness.SA_MIN);
829 parameters.setDefaultParameter(AdaptationSituationalAwareness.SA_MAX);
830 if (FullerImplementation.ANTICIPATION_RELIANCE.equals(get(this.fullerImplementation, gtuType)))
831 {
832 parameters.setDefaultParameter(ArFuller.ALPHA);
833 parameters.setDefaultParameter(ArFuller.BETA);
834 }
835 if (get(this.alternateCarFollowingTask, gtuType))
836 {
837 parameters.setDefaultParameter(ArTaskCarFollowingExp.HEXP);
838 }
839 }
840
841 }
842
843
844 if (anySocialInteractions())
845 {
846 parameters.setDefaultParameter(Tailgating.RHO);
847 }
848
849 if (get(this.tailgating, gtuType))
850 {
851 parameters.setParameter(ParameterTypes.TMAX, Duration.ofSI(1.6));
852 }
853 if (get(this.socioLaneChange, gtuType) || get(this.socioSpeed, gtuType))
854 {
855 parameters.setParameter(LmrsParameters.VGAIN, this.vGainDist.get());
856 parameters.setParameter(LmrsParameters.SOCIO, this.sigmaDist.draw());
857 }
858 parameters.setParameter(ParameterTypes.FSPEED, this.fSpeedDist.draw());
859 return parameters;
860 }
861
862 @Override
863 public T create(final LaneBasedGtu gtu) throws GtuException
864 {
865 GtuType gtuType = gtu.getType();
866
867
868 DesiredSpeedModel desiredSpeedModel =
869 get(this.socioSpeed, gtuType) ? new SocioDesiredSpeed(AbstractIdm.DESIRED_SPEED) : AbstractIdm.DESIRED_SPEED;
870 CarFollowingModel cfModel = get(this.carFollowingModel, gtuType).apply(AbstractIdm.HEADWAY, desiredSpeedModel);
871
872
873 LanePerception perception = getPerception(gtu);
874
875
876 Synchronization sync = get(this.synchronization, gtuType);
877 Cooperation coop = get(this.cooperation, gtuType);
878 GapAcceptance gapAccept = get(this.gapAcceptance, gtuType);
879 Tailgating tail = get(this.tailgating, gtuType) ? Tailgating.PRESSURE
880 : (anySocialInteractions() ? Tailgating.RHO_ONLY : Tailgating.NONE);
881 T tacticalPlanner = get(this.lmrsProvider, gtuType).from(cfModel, gtu, perception, sync, coop, gapAccept, tail);
882
883
884 if (get(this.incentiveRoute, gtuType))
885 {
886 tacticalPlanner.addMandatoryIncentive(IncentiveRoute.SINGLETON);
887 }
888 if (get(this.incentiveGetInLane, gtuType))
889 {
890 tacticalPlanner.addMandatoryIncentive(IncentiveGetInLane.SINGLETON);
891 }
892 get(this.customMandatoryIncentives, gtuType).forEach((s) -> tacticalPlanner.addMandatoryIncentive(s.get()));
893
894
895 if (get(this.incentiveSpeedWithCourtesy, gtuType))
896 {
897 tacticalPlanner.addVoluntaryIncentive(IncentiveSpeedWithCourtesy.SINGLETON);
898 }
899 if (get(this.incentiveCourtesy, gtuType))
900 {
901 tacticalPlanner.addVoluntaryIncentive(IncentiveCourtesy.SINGLETON);
902 }
903 if (get(this.incentiveQueue, gtuType))
904 {
905 tacticalPlanner.addVoluntaryIncentive(IncentiveQueue.SINGLETON);
906 }
907 if (get(this.incentiveStayRight, gtuType))
908 {
909 tacticalPlanner.addVoluntaryIncentive(IncentiveStayRight.SINGLETON);
910 }
911 if (get(this.incentiveKeep, gtuType))
912 {
913 tacticalPlanner.addVoluntaryIncentive(IncentiveKeep.SINGLETON);
914 }
915 if (get(this.socioLaneChange, gtuType))
916 {
917 tacticalPlanner.addVoluntaryIncentive(IncentiveSocioSpeed.SINGLETON);
918 }
919 get(this.customVoluntaryIncentives, gtuType).forEach((s) -> tacticalPlanner.addVoluntaryIncentive(s.get()));
920
921
922 if (get(this.accelerationSpeedLimitTransition, gtuType))
923 {
924 tacticalPlanner.addAccelerationIncentive(AccelerationSpeedLimitTransition.SINGLETON);
925 }
926 if (get(this.accelerationTrafficLights, gtuType))
927 {
928 tacticalPlanner.addAccelerationIncentive(AccelerationTrafficLights.SINGLETON);
929 }
930 if (get(this.accelerationConflicts, gtuType))
931 {
932 tacticalPlanner.addAccelerationIncentive(new AccelerationConflicts());
933 }
934 if (get(this.accelerationNoRightOvertake, gtuType))
935 {
936 tacticalPlanner.addAccelerationIncentive(AccelerationNoRightOvertake.SINGLETON);
937 }
938 get(this.customAccelerationIncentives, gtuType).forEach((s) -> tacticalPlanner.addAccelerationIncentive(s.get()));
939
940 resetState();
941
942 return tacticalPlanner;
943 }
944
945
946
947
948
949 private boolean anySocialInteractions()
950 {
951 return this.tailgating.contains(true) || this.socioLaneChange.contains(true) || this.socioSpeed.contains(true);
952 }
953
954
955
956
957
958
959 protected LanePerception getPerception(final LaneBasedGtu gtu)
960 {
961 GtuType gtuType = gtu.getType();
962
963 Mental mental;
964 Estimation estimation;
965 Anticipation anticipation;
966
967 if (FullerImplementation.ATTENTION_MATRIX.equals(get(this.fullerImplementation, gtuType)))
968 {
969
970 LinkedHashSet<Function<LanePerception, Set<ChannelTask>>> taskSuppliers = new LinkedHashSet<>();
971 addChannelTask(taskSuppliers, get(this.carFollowingTask, gtuType), ChannelTaskCarFollowing.SUPPLIER);
972 addChannelTask(taskSuppliers, get(this.freeAccelerationTask, gtuType), ChannelTaskAcceleration.SUPPLIER);
973 addChannelTask(taskSuppliers, get(this.trafficLightsTask, gtuType), ChannelTaskTrafficLight.SUPPLIER);
974 addChannelTask(taskSuppliers, get(this.signalTask, gtuType), ChannelTaskSignal.SUPPLIER);
975 addChannelTask(taskSuppliers, get(this.laneChangingTask, gtuType), ChannelTaskLaneChange.SUPPLIER);
976 addChannelTask(taskSuppliers, get(this.cooperationTask, gtuType), ChannelTaskCooperation.SUPPLIER);
977
978 addChannelTask(taskSuppliers, get(this.conflictsTask, gtuType), ChannelTaskConflict.SUPPLIER);
979 addChannelTask(taskSuppliers, get(this.roadSideDistractionTask, gtuType),
980 new ChannelTaskRoadSideDistraction.Supplier(gtu));
981 addChannelTask(taskSuppliers, true, ChannelTaskScan.SUPPLIER);
982
983
984 Set<BehavioralAdaptation> behavioralAdapatations = new LinkedHashSet<>();
985 if (get(this.speedAdaptation, gtuType))
986 {
987 behavioralAdapatations.add(new AdaptationSpeedChannel());
988 }
989 if (get(this.headwayAdaptation, gtuType))
990 {
991 behavioralAdapatations.add(new AdaptationHeadway());
992 }
993 if (get(this.laneChangeAdaptation, gtuType))
994 {
995 behavioralAdapatations.add(AdaptationLaneChangeDesire.SINGLETON);
996 }
997 if (get(this.updateTimeAdaptation, gtuType))
998 {
999 behavioralAdapatations.add(AdaptationUpdateTime.SINGLETON);
1000 }
1001
1002 mental = new ChannelFuller(taskSuppliers, behavioralAdapatations);
1003
1004 estimation = FactorEstimation.SINGLETON;
1005 anticipation = get(this.temporalAnticipation, gtuType) ? Anticipation.CONSTANT_SPEED : Anticipation.NONE;
1006 }
1007 else if (FullerImplementation.NONE.equals(get(this.fullerImplementation, gtuType)))
1008 {
1009 mental = null;
1010 estimation = Estimation.NONE;
1011 anticipation = Anticipation.NONE;
1012 }
1013 else
1014 {
1015
1016 Set<ArTask> tasks = new LinkedHashSet<>();
1017 FullerImplementation fullerImpl = get(this.fullerImplementation, gtuType);
1018
1019
1020 if (get(this.carFollowingTask, gtuType))
1021 {
1022 Throw.when(get(this.alternateCarFollowingTask, gtuType), IllegalStateException.class,
1023 "Both carFollowingTask and alternateCarFollowingTask are true");
1024 tasks.add(ArTaskCarFollowing.SINGLETON);
1025 }
1026 else if (get(this.alternateCarFollowingTask, gtuType))
1027 {
1028 tasks.add(ArTaskCarFollowingExp.SINGLETON);
1029 }
1030 if (get(this.laneChangingTask, gtuType))
1031 {
1032 Throw.when(get(this.alternateLaneChangingTask, gtuType), IllegalStateException.class,
1033 "Both laneChangingTask and alternateLaneChangingTask are true");
1034 tasks.add(ArTaskLaneChanging.SINGLETON);
1035 }
1036 else if (get(this.alternateLaneChangingTask, gtuType))
1037 {
1038 tasks.add(ArTaskLaneChangingD.SINGLETON);
1039 }
1040 if (get(this.roadSideDistractionTask, gtuType))
1041 {
1042 tasks.add(new ArTaskRoadSideDistraction(gtu));
1043 }
1044
1045
1046 Set<BehavioralAdaptation> behavioralAdapatations = new LinkedHashSet<>();
1047 if (get(this.speedAdaptation, gtuType))
1048 {
1049 behavioralAdapatations.add(new AdaptationSpeed());
1050 }
1051 if (get(this.headwayAdaptation, gtuType))
1052 {
1053 behavioralAdapatations.add(new AdaptationHeadway());
1054 }
1055 if (get(this.laneChangeAdaptation, gtuType))
1056 {
1057 behavioralAdapatations.add(AdaptationLaneChangeDesire.SINGLETON);
1058 }
1059 behavioralAdapatations.add(new AdaptationSituationalAwareness());
1060
1061
1062 if (FullerImplementation.SUMMATIVE.equals(fullerImpl))
1063 {
1064 mental = new SumFuller<>(tasks, behavioralAdapatations);
1065 }
1066 else if (FullerImplementation.ANTICIPATION_RELIANCE.equals(fullerImpl))
1067 {
1068 mental = new ArFuller(tasks, behavioralAdapatations, get(this.primaryTask, gtuType));
1069 }
1070 else
1071 {
1072 throw new IllegalArgumentException("Unable to load Fuller model from setting " + fullerImpl);
1073 }
1074
1075 estimation = FactorEstimation.SINGLETON;
1076 anticipation = get(this.temporalAnticipation, gtuType) ? Anticipation.CONSTANT_SPEED : Anticipation.NONE;
1077 }
1078
1079
1080 LanePerception perception = new CategoricalLanePerception(gtu, mental);
1081 perception.addPerceptionCategory(new DirectEgoPerception<>(perception));
1082 perception.addPerceptionCategory(new DirectInfrastructurePerception(perception));
1083 perception.addPerceptionCategory(new AnticipationTrafficPerception(perception));
1084 if (FullerImplementation.NONE.equals(get(this.fullerImplementation, gtuType)))
1085 {
1086 perception.addPerceptionCategory(new DirectNeighborsPerception(perception, PerceivedGtuType.WRAP));
1087 perception.addPerceptionCategory(new DirectIntersectionPerception(perception, PerceivedGtuType.WRAP));
1088 }
1089 else if (FullerImplementation.ATTENTION_MATRIX.equals(get(this.fullerImplementation, gtuType)))
1090 {
1091 perception.addPerceptionCategory(new NeighborsPerceptionChannel(perception, estimation, anticipation));
1092 perception.addPerceptionCategory(new IntersectionPerceptionChannel(perception, estimation, anticipation));
1093 }
1094 else
1095 {
1096 PerceivedGtuType headwayGtuType = new AnticipationPerceivedGtuType(estimation, anticipation, () ->
1097 {
1098 return Try.assign(() -> gtu.getParameters().getParameter(ParameterTypes.TR),
1099 "Unable to obtain reaction time parameter");
1100 });
1101 perception.addPerceptionCategory(new DirectNeighborsPerception(perception, headwayGtuType));
1102 perception.addPerceptionCategory(new DirectIntersectionPerception(perception, headwayGtuType));
1103 }
1104 return perception;
1105 }
1106
1107
1108
1109
1110
1111
1112
1113 private void addChannelTask(final LinkedHashSet<Function<LanePerception, Set<ChannelTask>>> taskSuppliers,
1114 final boolean task, final Function<LanePerception, Set<ChannelTask>> supplier)
1115 {
1116 if (task)
1117 {
1118 taskSuppliers.add(supplier);
1119 }
1120 }
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130 public interface TacticalPlannerProvider<P extends AbstractIncentivesTacticalPlanner>
1131 {
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143 P from(CarFollowingModel carFollowingModel, LaneBasedGtu gtu, LanePerception lanePerception,
1144 Synchronization synchronization, Cooperation cooperation, GapAcceptance gapAcceptance, Tailgating tailgating);
1145 }
1146
1147
1148
1149
1150
1151 public static final class Setting<V>
1152 {
1153
1154
1155
1156 public static final Setting<BiFunction<DesiredHeadwayModel, DesiredSpeedModel, CarFollowingModel>> CAR_FOLLOWING_MODEL =
1157 new Setting<>((factory) -> factory.carFollowingModel);
1158
1159
1160 public static final Setting<Synchronization> SYNCHRONIZATION = new Setting<>((factory) -> factory.synchronization);
1161
1162
1163 public static final Setting<Cooperation> COOPERATION = new Setting<>((factory) -> factory.cooperation);
1164
1165
1166 public static final Setting<GapAcceptance> GAP_ACCEPTANCE = new Setting<>((factory) -> factory.gapAcceptance);
1167
1168
1169
1170
1171 public static final Setting<Boolean> INCENTIVE_ROUTE = new Setting<>((factory) -> factory.incentiveRoute);
1172
1173
1174 public static final Setting<Boolean> INCENTIVE_GET_IN_LANE = new Setting<>((factory) -> factory.incentiveGetInLane);
1175
1176
1177 public static final Setting<Set<Supplier<MandatoryIncentive>>> CUSTOM_MANDATORY_INCENTIVES =
1178 new Setting<>((factory) -> factory.customMandatoryIncentives);
1179
1180
1181
1182
1183 public static final Setting<Boolean> INCENTIVE_SPEED_WITH_COURTESY =
1184 new Setting<>((factory) -> factory.incentiveSpeedWithCourtesy);
1185
1186
1187 public static final Setting<Boolean> INCENTIVE_COURTESY = new Setting<>((factory) -> factory.incentiveCourtesy);
1188
1189
1190 public static final Setting<Boolean> INCENTIVE_QUEUE = new Setting<>((factory) -> factory.incentiveQueue);
1191
1192
1193 public static final Setting<Boolean> INCENTIVE_STAY_RIGHT = new Setting<>((factory) -> factory.incentiveStayRight);
1194
1195
1196 public static final Setting<Boolean> INCENTIVE_KEEP = new Setting<>((factory) -> factory.incentiveKeep);
1197
1198
1199 public static final Setting<Set<Supplier<VoluntaryIncentive>>> CUSTOM_VOLUNTARY_INCENTIVES =
1200 new Setting<>((factory) -> factory.customVoluntaryIncentives);
1201
1202
1203
1204
1205 public static final Setting<Boolean> ACCELERATION_SPEED_LIMIT_TRANSITION =
1206 new Setting<>((factory) -> factory.accelerationSpeedLimitTransition);
1207
1208
1209 public static final Setting<Boolean> ACCELERATION_TRAFFIC_LIGHTS =
1210 new Setting<>((factory) -> factory.accelerationTrafficLights);
1211
1212
1213 public static final Setting<Boolean> ACCELERATION_CONFLICTS = new Setting<>((factory) -> factory.accelerationConflicts);
1214
1215
1216 public static final Setting<Boolean> ACCELERATION_NO_RIGHT_OVERTAKE =
1217 new Setting<>((factory) -> factory.accelerationNoRightOvertake);
1218
1219
1220 public static final Setting<Set<Supplier<AccelerationIncentive>>> CUSTOM_ACCELERATION_INCENTIVES =
1221 new Setting<>((factory) -> factory.customAccelerationIncentives);
1222
1223
1224
1225
1226 public static final Setting<FullerImplementation> FULLER_IMPLEMENTATION =
1227 new Setting<>((factory) -> factory.fullerImplementation);
1228
1229
1230 public static final Setting<String> PRIMARY_TASK = new Setting<>((factory) -> factory.primaryTask);
1231
1232
1233 public static final Setting<Boolean> TEMPORAL_ANTICIPATION = new Setting<>((factory) -> factory.temporalAnticipation);
1234
1235
1236 public static final Setting<Double> FRACTION_OVERESTIMATION =
1237 new Setting<>((factory) -> factory.fractionOverEstimation);
1238
1239
1240
1241
1242 public static final Setting<Boolean> TASK_CAR_FOLLOWING = new Setting<>((factory) -> factory.carFollowingTask);
1243
1244
1245 public static final Setting<Boolean> TASK_CAR_FOLLOWING_ALTERNATE =
1246 new Setting<>((factory) -> factory.alternateCarFollowingTask);
1247
1248
1249 public static final Setting<Boolean> TASK_FREE_ACCELERATION = new Setting<>((factory) -> factory.freeAccelerationTask);
1250
1251
1252 public static final Setting<Boolean> TASK_TRAFFIC_LIGHTS = new Setting<>((factory) -> factory.trafficLightsTask);
1253
1254
1255 public static final Setting<Boolean> TASK_SIGNAL = new Setting<>((factory) -> factory.signalTask);
1256
1257
1258 public static final Setting<Boolean> TASK_LANE_CHANGE = new Setting<>((factory) -> factory.laneChangingTask);
1259
1260
1261 public static final Setting<Boolean> TASK_LANE_CHANGE_ALTERNATE =
1262 new Setting<>((factory) -> factory.alternateLaneChangingTask);
1263
1264
1265 public static final Setting<Boolean> TASK_COOPERATION = new Setting<>((factory) -> factory.cooperationTask);
1266
1267
1268 public static final Setting<Boolean> TASK_CONFLICTS = new Setting<>((factory) -> factory.conflictsTask);
1269
1270
1271 public static final Setting<Boolean> TASK_ROADSIDE_DISTRACTION =
1272 new Setting<>((factory) -> factory.roadSideDistractionTask);
1273
1274
1275
1276
1277 public static final Setting<Boolean> ADAPTATION_SPEED = new Setting<>((factory) -> factory.speedAdaptation);
1278
1279
1280 public static final Setting<Boolean> ADAPTATION_HEADWAY = new Setting<>((factory) -> factory.headwayAdaptation);
1281
1282
1283 public static final Setting<Boolean> ADAPTATION_LANE_CHANGE = new Setting<>((factory) -> factory.laneChangeAdaptation);
1284
1285
1286 public static final Setting<Boolean> ADAPTATION_UPDATE_TIME = new Setting<>((factory) -> factory.updateTimeAdaptation);
1287
1288
1289
1290
1291 public static final Setting<Boolean> SOCIO_TAILGATING = new Setting<>((factory) -> factory.tailgating);
1292
1293
1294 public static final Setting<Boolean> SOCIO_LANE_CHANGE = new Setting<>((factory) -> factory.socioLaneChange);
1295
1296
1297 public static final Setting<Boolean> SOCIO_SPEED = new Setting<>((factory) -> factory.socioSpeed);
1298
1299
1300 private final Function<LmrsFactory<?>, List<V>> listFunction;
1301
1302
1303
1304
1305
1306 private Setting(final Function<LmrsFactory<?>, List<V>> listFunction)
1307 {
1308 this.listFunction = listFunction;
1309 }
1310
1311
1312
1313
1314
1315 public Function<LmrsFactory<?>, List<V>> getListFunction()
1316 {
1317 return this.listFunction;
1318 }
1319 }
1320
1321
1322
1323
1324 public enum FullerImplementation
1325 {
1326
1327 NONE,
1328
1329
1330 SUMMATIVE,
1331
1332
1333
1334
1335
1336 ANTICIPATION_RELIANCE,
1337
1338
1339 ATTENTION_MATRIX;
1340 }
1341
1342
1343
1344
1345 private static class CarFollowingModelConverter
1346 implements ITypeConverter<BiFunction<DesiredHeadwayModel, DesiredSpeedModel, CarFollowingModel>>
1347 {
1348
1349
1350
1351 @SuppressWarnings({"unused", "redundantModifier"})
1352 public CarFollowingModelConverter()
1353 {
1354
1355 }
1356
1357 @Override
1358 public BiFunction<DesiredHeadwayModel, DesiredSpeedModel, CarFollowingModel> convert(final String value)
1359 throws Exception
1360 {
1361 switch (value.toLowerCase())
1362 {
1363 case "idm":
1364 return (h, v) -> new Idm(h, v);
1365 case "idm_plus":
1366 return (h, v) -> new IdmPlus(h, v);
1367 default:
1368 throw new IllegalArgumentException(
1369 "Unable to parse car following model " + value + ". Use any of IDM or IDM_PLUS.");
1370 }
1371 }
1372 }
1373
1374
1375
1376
1377 private static class SynchronizationConverter implements ITypeConverter<Synchronization>
1378 {
1379
1380
1381
1382 @SuppressWarnings({"unused", "redundantModifier"})
1383 public SynchronizationConverter()
1384 {
1385
1386 }
1387
1388 @Override
1389 public Synchronization convert(final String value) throws Exception
1390 {
1391 switch (value.toLowerCase())
1392 {
1393 case "passive":
1394 return Synchronization.PASSIVE;
1395 case "passive_moving":
1396 return Synchronization.PASSIVE_MOVING;
1397 case "align_gap":
1398 return Synchronization.ALIGN_GAP;
1399 case "active":
1400 return Synchronization.ACTIVE;
1401 default:
1402 throw new IllegalArgumentException("Unable to parse synchronization " + value
1403 + ". Use any of PASSIVE, PASSIVE_MOVING, ALIGN_GAP or ACTIVE.");
1404 }
1405 }
1406 }
1407
1408
1409
1410
1411 private static class CooperationConverter implements ITypeConverter<Cooperation>
1412 {
1413
1414
1415
1416 @SuppressWarnings({"unused", "redundantModifier"})
1417 public CooperationConverter()
1418 {
1419
1420 }
1421
1422 @Override
1423 public Cooperation convert(final String value) throws Exception
1424 {
1425 switch (value.toLowerCase())
1426 {
1427 case "passive":
1428 return Cooperation.PASSIVE;
1429 case "passive_moving":
1430 return Cooperation.PASSIVE_MOVING;
1431 case "active":
1432 return Cooperation.ACTIVE;
1433 default:
1434 throw new IllegalArgumentException(
1435 "Unable to parse cooperation " + value + ". Use any of PASSIVE, PASSIVE_MOVING or ACTIVE.");
1436 }
1437 }
1438 }
1439
1440
1441
1442
1443 private static class GapAcceptanceConverter implements ITypeConverter<GapAcceptance>
1444 {
1445
1446
1447
1448 @SuppressWarnings({"unused", "redundantModifier"})
1449 public GapAcceptanceConverter()
1450 {
1451
1452 }
1453
1454 @Override
1455 public GapAcceptance convert(final String value) throws Exception
1456 {
1457 switch (value.toLowerCase())
1458 {
1459 case "informed":
1460 return GapAcceptance.INFORMED;
1461 case "ego_headway":
1462 return GapAcceptance.EGO_HEADWAY;
1463 default:
1464 throw new IllegalArgumentException(
1465 "Unable to parse gap-acceptance " + value + ". Use any of INFORMED or EGO_HEADWAY.");
1466 }
1467 }
1468 }
1469
1470 }