1 package org.opentrafficsim.ahfe;
2
3 import java.awt.Color;
4 import java.io.BufferedWriter;
5 import java.io.IOException;
6 import java.net.URL;
7 import java.util.ArrayList;
8 import java.util.LinkedHashSet;
9 import java.util.List;
10 import java.util.Set;
11
12 import org.djunits.unit.FrequencyUnit;
13 import org.djunits.unit.SpeedUnit;
14 import org.djunits.unit.TimeUnit;
15 import org.djunits.value.ValueRuntimeException;
16 import org.djunits.value.storage.StorageType;
17 import org.djunits.value.vdouble.scalar.Acceleration;
18 import org.djunits.value.vdouble.scalar.Duration;
19 import org.djunits.value.vdouble.scalar.Frequency;
20 import org.djunits.value.vdouble.scalar.Length;
21 import org.djunits.value.vdouble.scalar.Speed;
22 import org.djunits.value.vdouble.vector.FrequencyVector;
23 import org.djunits.value.vdouble.vector.TimeVector;
24 import org.djunits.value.vdouble.vector.base.DoubleVector;
25 import org.djutils.cli.CliException;
26 import org.djutils.cli.CliUtil;
27 import org.djutils.exceptions.Throw;
28 import org.djutils.exceptions.Try;
29 import org.djutils.io.URLResource;
30 import org.opentrafficsim.base.CompressedFileWriter;
31 import org.opentrafficsim.base.parameters.ParameterException;
32 import org.opentrafficsim.base.parameters.ParameterSet;
33 import org.opentrafficsim.base.parameters.ParameterTypeDouble;
34 import org.opentrafficsim.base.parameters.ParameterTypeDuration;
35 import org.opentrafficsim.base.parameters.ParameterTypes;
36 import org.opentrafficsim.base.parameters.Parameters;
37 import org.opentrafficsim.base.parameters.constraint.DualBound;
38 import org.opentrafficsim.base.parameters.constraint.NumericConstraint;
39 import org.opentrafficsim.core.animation.gtu.colorer.AccelerationGTUColorer;
40 import org.opentrafficsim.core.animation.gtu.colorer.SpeedGTUColorer;
41 import org.opentrafficsim.core.animation.gtu.colorer.SwitchableGTUColorer;
42 import org.opentrafficsim.core.distributions.Distribution;
43 import org.opentrafficsim.core.distributions.Distribution.FrequencyAndObject;
44 import org.opentrafficsim.core.distributions.Generator;
45 import org.opentrafficsim.core.distributions.ProbabilityException;
46 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
47 import org.opentrafficsim.core.gtu.AbstractGTU;
48 import org.opentrafficsim.core.gtu.GTUException;
49 import org.opentrafficsim.core.gtu.GTUType;
50 import org.opentrafficsim.core.gtu.perception.DirectEgoPerception;
51 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
52 import org.opentrafficsim.core.network.Node;
53 import org.opentrafficsim.core.network.OTSNetwork;
54 import org.opentrafficsim.core.parameters.ParameterFactoryByType;
55 import org.opentrafficsim.core.perception.HistoryManagerDEVS;
56 import org.opentrafficsim.core.units.distributions.ContinuousDistSpeed;
57 import org.opentrafficsim.draw.core.OTSDrawingException;
58 import org.opentrafficsim.draw.factory.DefaultAnimationFactory;
59 import org.opentrafficsim.kpi.interfaces.LaneDataInterface;
60 import org.opentrafficsim.kpi.sampling.KpiGtuDirectionality;
61 import org.opentrafficsim.kpi.sampling.KpiLaneDirection;
62 import org.opentrafficsim.kpi.sampling.SpaceTimeRegion;
63 import org.opentrafficsim.kpi.sampling.data.ExtendedDataTypeNumber;
64 import org.opentrafficsim.road.gtu.colorer.DesiredHeadwayColorer;
65 import org.opentrafficsim.road.gtu.colorer.DesiredSpeedColorer;
66 import org.opentrafficsim.road.gtu.colorer.FixedColor;
67 import org.opentrafficsim.road.gtu.colorer.GTUTypeColorer;
68 import org.opentrafficsim.road.gtu.colorer.IncentiveColorer;
69 import org.opentrafficsim.road.gtu.colorer.ReactionTimeColorer;
70 import org.opentrafficsim.road.gtu.colorer.SynchronizationColorer;
71 import org.opentrafficsim.road.gtu.colorer.TaskColorer;
72 import org.opentrafficsim.road.gtu.colorer.TaskSaturationColorer;
73 import org.opentrafficsim.road.gtu.colorer.TotalDesireColorer;
74 import org.opentrafficsim.road.gtu.generator.od.DefaultGTUCharacteristicsGeneratorOD;
75 import org.opentrafficsim.road.gtu.generator.od.ODApplier;
76 import org.opentrafficsim.road.gtu.generator.od.ODOptions;
77 import org.opentrafficsim.road.gtu.generator.od.StrategicalPlannerFactorySupplierOD;
78 import org.opentrafficsim.road.gtu.lane.CollisionDetector;
79 import org.opentrafficsim.road.gtu.lane.CollisionException;
80 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
81 import org.opentrafficsim.road.gtu.lane.perception.CategoricalLanePerception;
82 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
83 import org.opentrafficsim.road.gtu.lane.perception.PerceptionCollectable;
84 import org.opentrafficsim.road.gtu.lane.perception.PerceptionFactory;
85 import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
86 import org.opentrafficsim.road.gtu.lane.perception.categories.AnticipationTrafficPerception;
87 import org.opentrafficsim.road.gtu.lane.perception.categories.DirectInfrastructurePerception;
88 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.Anticipation;
89 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.DirectNeighborsPerception;
90 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.Estimation;
91 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.HeadwayGtuType.PerceivedHeadwayGtuType;
92 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.NeighborsPerception;
93 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.TaskHeadwayCollector;
94 import org.opentrafficsim.road.gtu.lane.perception.headway.HeadwayGTU;
95 import org.opentrafficsim.road.gtu.lane.perception.mental.AbstractTask;
96 import org.opentrafficsim.road.gtu.lane.perception.mental.AdaptationHeadway;
97 import org.opentrafficsim.road.gtu.lane.perception.mental.AdaptationSituationalAwareness;
98 import org.opentrafficsim.road.gtu.lane.perception.mental.Fuller;
99 import org.opentrafficsim.road.gtu.lane.perception.mental.Fuller.BehavioralAdaptation;
100 import org.opentrafficsim.road.gtu.lane.perception.mental.Task;
101 import org.opentrafficsim.road.gtu.lane.perception.mental.TaskManager;
102 import org.opentrafficsim.road.gtu.lane.tactical.following.AbstractIDM;
103 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModelFactory;
104 import org.opentrafficsim.road.gtu.lane.tactical.following.DesiredSpeedModel;
105 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlus;
106 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.AccelerationIncentive;
107 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.DefaultLMRSPerceptionFactory;
108 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveCourtesy;
109 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveGetInLane;
110 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveKeep;
111 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveRoute;
112 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveSocioSpeed;
113 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveSpeed;
114 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveSpeedWithCourtesy;
115 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveStayRight;
116 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRSFactory;
117 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.SocioDesiredSpeed;
118 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Cooperation;
119 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.GapAcceptance;
120 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
121 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.MandatoryIncentive;
122 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Synchronization;
123 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Tailgating;
124 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.VoluntaryIncentive;
125 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
126 import org.opentrafficsim.road.gtu.strategical.od.Categorization;
127 import org.opentrafficsim.road.gtu.strategical.od.Category;
128 import org.opentrafficsim.road.gtu.strategical.od.Interpolation;
129 import org.opentrafficsim.road.gtu.strategical.od.ODMatrix;
130 import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
131 import org.opentrafficsim.road.network.OTSRoadNetwork;
132 import org.opentrafficsim.road.network.factory.xml.parser.XmlNetworkLaneParser;
133 import org.opentrafficsim.road.network.lane.CrossSectionLink;
134 import org.opentrafficsim.road.network.sampling.GtuData;
135 import org.opentrafficsim.road.network.sampling.LinkData;
136 import org.opentrafficsim.road.network.sampling.RoadSampler;
137 import org.opentrafficsim.road.network.sampling.data.LeaderId;
138 import org.opentrafficsim.road.network.sampling.data.ReactionTime;
139 import org.opentrafficsim.road.network.sampling.data.TimeToCollision;
140 import org.opentrafficsim.swing.script.AbstractSimulationScript;
141
142 import nl.tudelft.simulation.jstats.distributions.DistLogNormal;
143 import nl.tudelft.simulation.jstats.distributions.DistNormal;
144 import nl.tudelft.simulation.jstats.distributions.DistTriangular;
145 import nl.tudelft.simulation.jstats.streams.StreamInterface;
146 import picocli.CommandLine.Option;
147
148
149
150
151
152
153
154
155
156
157
158
159 public final class AnticipationRelianceScript extends AbstractSimulationScript
160 {
161
162
163 private static final long serialVersionUID = 20200516L;
164
165
166 static final ParameterTypeDuration HEXP = new ParameterTypeDuration("Hexp",
167 "Exponential decay of car-following task by headway.", Duration.instantiateSI(4.0), NumericConstraint.POSITIVE);
168
169
170 static final ParameterTypeDouble ALPHA = new ParameterTypeDouble("alpha",
171 "Fraction of primary task that can be reduced by anticipation reliance.", 0.8, DualBound.UNITINTERVAL);
172
173
174 static final ParameterTypeDouble BETA = new ParameterTypeDouble("beta",
175 "Fraction of auxiliary tasks that can be reduced by anticipation reliance.", 0.6, DualBound.UNITINTERVAL);
176
177
178 private static Length ignoreStart = Length.instantiateSI(2900);
179
180
181 private static Length ignoreEnd = Length.instantiateSI(1000);
182
183
184 private RoadSampler sampler;
185
186
187 @Option(names = {"-f", "--fTruck"}, description = "Truck fraction", defaultValue = "0.05")
188 private double fTruck;
189
190
191 @Option(names = "--leftDemand", description = "Left demand", defaultValue = "3500/h")
192 private Frequency leftDemand;
193
194
195 @Option(names = "--rightDemand", description = "Right demand", defaultValue = "3200/h")
196 private Frequency rightDemand;
197
198
199 @Option(names = "--sampler", description = "Sampler", negatable = true, defaultValue = "false")
200 private boolean doSampler;
201
202
203 @Option(names = "--scenario", description = "Scenario", defaultValue = "test")
204 private String scenario;
205
206
207 @Option(names = "--outputDir", description = "Output directory", defaultValue = "")
208 private String outputDir;
209
210
211 @Option(names = "--tasks", description = "Use tasks", negatable = true, defaultValue = "false")
212 private boolean tasks;
213
214
215 @Option(names = "--strategies", description = "Use strategies", negatable = true, defaultValue = "false")
216 private boolean strategies;
217
218
219 @Option(names = "--adaptation", description = "Use adaptation", negatable = true, defaultValue = "false")
220 private boolean adaptation;
221
222
223 @Option(names = "--alpha", description = "Alpha: maximum lane-change reduction", defaultValue = "0.8")
224 private double alpha;
225
226
227 @Option(names = "--beta", description = "Beta: maximum car-following reduction", defaultValue = "0.6")
228 private double beta;
229
230
231 @Option(names = "--fUnderestimate", description = "Fraction underestimation", defaultValue = "0.75")
232 private double fractionUnderestimation;
233
234
235
236
237
238 public static void main(final String... args)
239 {
240
241 AnticipationRelianceScript script = new AnticipationRelianceScript();
242 if (script.isAutorun())
243 {
244 System.out.println("Running " + script.scenario + "_" + script.getSeed());
245 }
246
247
248
249
250
251
252
253 try
254 {
255 CliUtil.execute(script, args);
256 script.start();
257 }
258 catch (Throwable throwable)
259 {
260
261 Throwable original = throwable;
262 while (throwable != null)
263 {
264 if (throwable instanceof CollisionException)
265 {
266 double tCollision = script.getSimulator().getSimulatorTime().si;
267 script.onSimulationEnd();
268 String file = script.getOutputFileStart() + "_collision.txt";
269 BufferedWriter writer = CompressedFileWriter.create(file, false);
270 try
271 {
272 writer.write(String.format("Collision at: %.6f", tCollision));
273 writer.newLine();
274 writer.write(throwable.getMessage());
275 writer.close();
276 }
277 catch (IOException ex)
278 {
279 System.err.println("Unable to write to file.");
280 }
281 System.exit(0);
282 }
283 throwable = throwable.getCause();
284 }
285 throw new RuntimeException(original);
286 }
287 }
288
289
290
291
292
293 private String getOutputFileStart()
294 {
295 return this.outputDir + this.scenario + "_" + getSeed();
296 }
297
298
299
300
301 private AnticipationRelianceScript()
302 {
303 super("Distraction", "Distraction simulation");
304 setGtuColorer(SwitchableGTUColorer.builder().addActiveColorer(new FixedColor(Color.BLUE, "Blue"))
305 .addColorer(new TaskColorer("car-following")).addColorer(new TaskColorer("lane-changing"))
306 .addColorer(new TaskSaturationColorer()).addColorer(new ReactionTimeColorer(Duration.instantiateSI(1.0)))
307 .addColorer(GTUTypeColorer.DEFAULT).addColorer(new SpeedGTUColorer(new Speed(150, SpeedUnit.KM_PER_HOUR)))
308 .addColorer(
309 new DesiredSpeedColorer(new Speed(50, SpeedUnit.KM_PER_HOUR), new Speed(150, SpeedUnit.KM_PER_HOUR)))
310 .addColorer(new AccelerationGTUColorer(Acceleration.instantiateSI(-6.0), Acceleration.instantiateSI(2)))
311 .addColorer(new SynchronizationColorer())
312 .addColorer(new DesiredHeadwayColorer(Duration.instantiateSI(0.56), Duration.instantiateSI(2.4)))
313 .addColorer(new TotalDesireColorer()).addColorer(new IncentiveColorer(IncentiveRoute.class))
314 .addColorer(new IncentiveColorer(IncentiveSpeedWithCourtesy.class))
315 .addColorer(new IncentiveColorer(IncentiveSpeed.class)).addColorer(new IncentiveColorer(IncentiveKeep.class))
316 .addColorer(new IncentiveColorer(IncentiveGetInLane.class))
317 .addColorer(new IncentiveColorer(IncentiveCourtesy.class))
318 .addColorer(new IncentiveColorer(IncentiveSocioSpeed.class)).build());
319 try
320 {
321 CliUtil.changeOptionDefault(this, "warmupTime", "360s");
322 CliUtil.changeOptionDefault(this, "simulationTime", "3960s");
323 }
324 catch (NoSuchFieldException | IllegalStateException | IllegalArgumentException | CliException exception)
325 {
326 throw new RuntimeException(exception);
327 }
328 }
329
330
331 @Override
332 protected void onSimulationEnd()
333 {
334 if (this.sampler != null)
335 {
336 this.sampler.getSamplerData().writeToFile(getOutputFileStart() + ".csv");
337 }
338 }
339
340
341 @Override
342 protected OTSRoadNetwork setupSimulation(final OTSSimulatorInterface sim) throws Exception
343 {
344 AbstractGTU.ALIGNED = true;
345
346
347 URL xmlURL = URLResource.getResource("/resources/AHFE/Network.xml");
348 OTSRoadNetwork network = new OTSRoadNetwork("Distraction", true, sim);
349 new CollisionDetector(network);
350 XmlNetworkLaneParser.build(xmlURL, network, false);
351
352
353
354
355
356
357 List<Node> origins = new ArrayList<>();
358 origins.add(network.getNode("LEFTINPRE"));
359 origins.add(network.getNode("RIGHTINPRE"));
360 List<Node> destinations = new ArrayList<>();
361 destinations.add(network.getNode("EXIT"));
362 Categorization categorization = new Categorization("Distraction", GTUType.class);
363 TimeVector globalTime =
364 DoubleVector.instantiate(new double[] {0, 360, 1560, 2160, 3960}, TimeUnit.BASE_SECOND, StorageType.DENSE);
365 ODMatrix od = new ODMatrix("Distraction", origins, destinations, categorization, globalTime, Interpolation.LINEAR);
366 Category carCategory = new Category(categorization, network.getGtuType(GTUType.DEFAULTS.CAR));
367 Category truckCategory = new Category(categorization, network.getGtuType(GTUType.DEFAULTS.TRUCK));
368 FrequencyVector leftDemandPatternCar =
369 getDemand(this.leftDemand.getInUnit(FrequencyUnit.PER_HOUR) * (1.0 - this.fTruck));
370 FrequencyVector leftDemandPatternTruck = getDemand(this.leftDemand.getInUnit(FrequencyUnit.PER_HOUR) * this.fTruck);
371 FrequencyVector rightDemandPatternCar =
372 getDemand(this.rightDemand.getInUnit(FrequencyUnit.PER_HOUR) * (1.0 - this.fTruck));
373 FrequencyVector rightDemandPatternTruck = getDemand(this.rightDemand.getInUnit(FrequencyUnit.PER_HOUR) * this.fTruck);
374 od.putDemandVector(network.getNode("LEFTINPRE"), network.getNode("EXIT"), carCategory, leftDemandPatternCar);
375 od.putDemandVector(network.getNode("LEFTINPRE"), network.getNode("EXIT"), truckCategory, leftDemandPatternTruck);
376 od.putDemandVector(network.getNode("RIGHTINPRE"), network.getNode("EXIT"), carCategory, rightDemandPatternCar);
377 od.putDemandVector(network.getNode("RIGHTINPRE"), network.getNode("EXIT"), truckCategory, rightDemandPatternTruck);
378 ODOptions odOptions = new ODOptions()
379 .set(ODOptions.GTU_TYPE, new DefaultGTUCharacteristicsGeneratorOD(new DistractionFactorySupplier()))
380 .set(ODOptions.INSTANT_LC, true);
381 ODApplier.applyOD(network, od, odOptions);
382
383
384 sim.getReplication()
385 .setHistoryManager(new HistoryManagerDEVS(sim, Duration.instantiateSI(2.0), Duration.instantiateSI(1.0)));
386
387
388 if (this.doSampler)
389 {
390 RoadSampler.Factory factory = RoadSampler.build(network);
391 factory.registerExtendedDataType(new TimeToCollision());
392 factory.registerExtendedDataType(new TaskSaturationDataType());
393 factory.registerExtendedDataType(new LeaderId());
394 factory.registerExtendedDataType(new ReactionTime());
395 factory.registerExtendedDataType(new SituationalAwarenessDataType());
396 if (this.tasks)
397 {
398 factory.registerExtendedDataType(new TaskAnticipationRelianceDataType("car-following"));
399 factory.registerExtendedDataType(new TaskDemandDataType("car-following"));
400 factory.registerExtendedDataType(new TaskAnticipationRelianceDataType("lane-changing"));
401 factory.registerExtendedDataType(new TaskDemandDataType("lane-changing"));
402 }
403 this.sampler = factory.create();
404
405 LinkData linkData = new LinkData((CrossSectionLink) network.getLink("LEFTIN"));
406 registerLinkToSampler(linkData, ignoreStart, linkData.getLength());
407 linkData = new LinkData((CrossSectionLink) network.getLink("RIGHTIN"));
408 registerLinkToSampler(linkData, ignoreStart, linkData.getLength());
409 linkData = new LinkData((CrossSectionLink) network.getLink("CONVERGE"));
410 registerLinkToSampler(linkData, Length.ZERO, linkData.getLength());
411 linkData = new LinkData((CrossSectionLink) network.getLink("WEAVING"));
412 registerLinkToSampler(linkData, Length.ZERO, linkData.getLength());
413 linkData = new LinkData((CrossSectionLink) network.getLink("END"));
414 registerLinkToSampler(linkData, Length.ZERO, linkData.getLength().minus(ignoreEnd));
415 }
416
417
418 return network;
419 }
420
421
422
423
424
425
426
427 private void registerLinkToSampler(final LinkData linkData, final Length startDistance, final Length endDistance)
428 {
429 for (LaneDataInterface laneData : linkData.getLaneDatas())
430 {
431 Length start = laneData.getLength().times(startDistance.si / linkData.getLength().si);
432 Length end = laneData.getLength().times(endDistance.si / linkData.getLength().si);
433 this.sampler
434 .registerSpaceTimeRegion(new SpaceTimeRegion(new KpiLaneDirection(laneData, KpiGtuDirectionality.DIR_PLUS),
435 start, end, getStartTime().plus(getWarmupTime()), getStartTime().plus(getSimulationTime())));
436 }
437 }
438
439
440
441
442
443
444
445 private static FrequencyVector getDemand(final double demand) throws ValueRuntimeException
446 {
447 return DoubleVector.instantiate(new double[] {demand * 0.5, demand * 0.5, demand, demand, 0.0}, FrequencyUnit.PER_HOUR,
448 StorageType.DENSE);
449 }
450
451
452 @Override
453 protected void animateNetwork(final OTSNetwork net)
454 {
455 try
456 {
457 DefaultAnimationFactory.animateXmlNetwork(net, getGtuColorer());
458 }
459 catch (OTSDrawingException exception)
460 {
461 throw new RuntimeException("Exception while creating network animation.", exception);
462 }
463 }
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481 private class DistractionFactorySupplier implements StrategicalPlannerFactorySupplierOD
482 {
483
484
485 private LaneBasedStrategicalRoutePlannerFactory factoryCar = null;
486
487
488 private LaneBasedStrategicalRoutePlannerFactory factoryTruck = null;
489
490
491 DistractionFactorySupplier()
492 {
493 }
494
495
496 @SuppressWarnings("synthetic-access")
497 @Override
498 public LaneBasedStrategicalPlannerFactory<?> getFactory(final Node origin, final Node destination,
499 final Category category, final StreamInterface randomStream) throws GTUException
500 {
501 OTSRoadNetwork network = (OTSRoadNetwork) origin.getNetwork();
502 if (this.factoryCar == null)
503 {
504
505 CarFollowingModelFactory<IDMPlus> cfFactoryCar =
506 new IdmPlusFactoryAR(() -> AnticipationRelianceScript.this.strategies
507 ? new SocioDesiredSpeed(AbstractIDM.DESIRED_SPEED) : AbstractIDM.DESIRED_SPEED);
508 CarFollowingModelFactory<IDMPlus> cfFactoryTruck = new IdmPlusFactoryAR(() -> AbstractIDM.DESIRED_SPEED);
509
510
511 Distribution<Estimation> estimation;
512 try
513 {
514 estimation = new Distribution<>(randomStream);
515 estimation.add(new FrequencyAndObject<>(AnticipationRelianceScript.this.fractionUnderestimation,
516 Estimation.UNDERESTIMATION));
517 estimation.add(new FrequencyAndObject<>(1.0 - AnticipationRelianceScript.this.fractionUnderestimation,
518 Estimation.OVERESTIMATION));
519 }
520 catch (ProbabilityException ex)
521 {
522 throw new GTUException("Random stream is null.", ex);
523 }
524 PerceptionFactory perceptionFactory = new LmrsPerceptionFactoryAR(estimation);
525
526
527 Tailgating tailgating = AnticipationRelianceScript.this.strategies ? Tailgating.PRESSURE : Tailgating.NONE;
528
529
530 Set<MandatoryIncentive> mandatoryIncentives = new LinkedHashSet<>();
531 mandatoryIncentives.add(new IncentiveRoute());
532 Set<VoluntaryIncentive> voluntaryIncentivesCar = new LinkedHashSet<>();
533 Set<VoluntaryIncentive> voluntaryIncentivesTruck = new LinkedHashSet<>();
534 voluntaryIncentivesCar.add(new IncentiveSpeedWithCourtesy());
535 voluntaryIncentivesCar.add(new IncentiveKeep());
536 if (AnticipationRelianceScript.this.strategies)
537 {
538 voluntaryIncentivesCar.add(new IncentiveSocioSpeed());
539 }
540 voluntaryIncentivesTruck.addAll(voluntaryIncentivesCar);
541 voluntaryIncentivesTruck.add(new IncentiveStayRight());
542
543
544 Set<AccelerationIncentive> accelerationIncentives = new LinkedHashSet<>();
545
546
547 ParameterFactoryByType params = new ParameterFactoryByType();
548 params.addParameter(network.getGtuType(GTUType.DEFAULTS.CAR), ParameterTypes.FSPEED,
549 new DistNormal(randomStream, 123.7 / 120.0, 12.0 / 120.0));
550 params.addParameter(network.getGtuType(GTUType.DEFAULTS.TRUCK), ParameterTypes.A,
551 Acceleration.instantiateSI(0.4));
552 if (AnticipationRelianceScript.this.strategies)
553 {
554 params.addParameter(Tailgating.RHO, 0.0);
555 params.addParameter(network.getGtuType(GTUType.DEFAULTS.CAR), LmrsParameters.SOCIO,
556 new DistTriangular(randomStream, 0.0, 0.25, 1.0));
557 params.addParameter(network.getGtuType(GTUType.DEFAULTS.TRUCK), LmrsParameters.SOCIO, 1.0);
558 params.addParameter(network.getGtuType(GTUType.DEFAULTS.CAR), LmrsParameters.VGAIN,
559 new ContinuousDistSpeed(new DistLogNormal(randomStream, 3.3789, 0.4), SpeedUnit.KM_PER_HOUR));
560 params.addParameter(network.getGtuType(GTUType.DEFAULTS.TRUCK), LmrsParameters.VGAIN,
561 new Speed(50.0, SpeedUnit.KM_PER_HOUR));
562 params.addParameter(ParameterTypes.TMAX, Duration.instantiateSI(1.6));
563 }
564 if (AnticipationRelianceScript.this.adaptation)
565 {
566 params.addParameter(AdaptationHeadway.BETA_T, 1.0);
567 }
568
569
570 this.factoryCar = new LaneBasedStrategicalRoutePlannerFactory(new LMRSFactory(cfFactoryCar, perceptionFactory,
571 Synchronization.PASSIVE, Cooperation.PASSIVE, GapAcceptance.INFORMED, tailgating, mandatoryIncentives,
572 voluntaryIncentivesCar, accelerationIncentives), params);
573 this.factoryTruck = new LaneBasedStrategicalRoutePlannerFactory(new LMRSFactory(cfFactoryTruck,
574 perceptionFactory, Synchronization.PASSIVE, Cooperation.PASSIVE, GapAcceptance.INFORMED, tailgating,
575 mandatoryIncentives, voluntaryIncentivesTruck, accelerationIncentives), params);
576 }
577 return category.get(GTUType.class).isOfType(network.getGtuType(GTUType.DEFAULTS.TRUCK)) ? this.factoryTruck
578 : this.factoryCar;
579 }
580 }
581
582
583
584
585
586
587 private class CarFollowingTaskAR extends AbstractTask
588 {
589
590 CarFollowingTaskAR()
591 {
592 super("car-following");
593 }
594
595
596 @Override
597 public double calculateTaskDemand(final LanePerception perception, final LaneBasedGTU gtuCF,
598 final Parameters parameters) throws ParameterException, GTUException
599 {
600 try
601 {
602 NeighborsPerception neighbors = perception.getPerceptionCategory(NeighborsPerception.class);
603 PerceptionCollectable<HeadwayGTU, LaneBasedGTU> leaders = neighbors.getLeaders(RelativeLane.CURRENT);
604 Duration headway = leaders.collect(new TaskHeadwayCollector(gtuCF.getSpeed()));
605 return headway == null ? 0.0 : Math.exp(-headway.si / parameters.getParameter(HEXP).si);
606 }
607 catch (OperationalPlanException ex)
608 {
609 throw new GTUException(ex);
610 }
611 }
612 }
613
614
615 private class LaneChangeTaskAR extends AbstractTask
616 {
617
618 LaneChangeTaskAR()
619 {
620 super("lane-changing");
621 }
622
623
624 @Override
625 public double calculateTaskDemand(final LanePerception perception, final LaneBasedGTU gtuLC,
626 final Parameters parameters) throws ParameterException, GTUException
627 {
628 return Math.max(0.0,
629 Math.max(parameters.getParameter(LmrsParameters.DLEFT), parameters.getParameter(LmrsParameters.DRIGHT)));
630 }
631 }
632
633
634 private class LmrsPerceptionFactoryAR extends DefaultLMRSPerceptionFactory
635 {
636
637 private final Distribution<Estimation> estimation;
638
639
640
641
642
643 LmrsPerceptionFactoryAR(final Distribution<Estimation> estimation)
644 {
645 this.estimation = estimation;
646 }
647
648
649 @SuppressWarnings("synthetic-access")
650 @Override
651 public LanePerception generatePerception(final LaneBasedGTU gtu)
652 {
653 Set<Task> tasksSet = new LinkedHashSet<>();
654 if (AnticipationRelianceScript.this.tasks)
655 {
656 tasksSet.add(new CarFollowingTaskAR());
657 tasksSet.add(new LaneChangeTaskAR());
658 }
659
660 Set<BehavioralAdaptation> behavioralAdapatations = new LinkedHashSet<>();
661 behavioralAdapatations.add(new AdaptationSituationalAwareness());
662 if (AnticipationRelianceScript.this.adaptation)
663 {
664 behavioralAdapatations.add(new AdaptationHeadway());
665 }
666 LanePerception perception;
667 if (AnticipationRelianceScript.this.tasks)
668 {
669 Fuller fuller = new Fuller(tasksSet, behavioralAdapatations, new TaskManagerAR());
670 perception = new CategoricalLanePerception(gtu, fuller);
671 }
672 else
673 {
674 perception = new CategoricalLanePerception(gtu);
675 }
676 perception.addPerceptionCategory(new DirectEgoPerception<>(perception));
677 perception.addPerceptionCategory(new DirectInfrastructurePerception(perception));
678 Estimation est = Try.assign(() -> this.estimation.draw(), "Probability exception while drawing estimation.");
679 perception.addPerceptionCategory(
680 new DirectNeighborsPerception(perception, new PerceivedHeadwayGtuType(est, Anticipation.CONSTANT_SPEED)));
681 perception.addPerceptionCategory(new AnticipationTrafficPerception(perception));
682 return perception;
683 }
684
685
686 @SuppressWarnings("synthetic-access")
687 @Override
688 public Parameters getParameters() throws ParameterException
689 {
690 Parameters params = super.getParameters();
691 params.setParameter(HEXP, Duration.instantiateSI(4.0));
692 params.setParameter(ALPHA, AnticipationRelianceScript.this.alpha);
693 params.setParameter(BETA, AnticipationRelianceScript.this.beta);
694 params.setParameter(Fuller.TC, 1.0);
695 params.setParameter(Fuller.TS_CRIT, 1.0);
696 params.setParameter(Fuller.TS_MAX, 2.0);
697 params.setParameter(AdaptationSituationalAwareness.SA, 1.0);
698 params.setParameter(AdaptationSituationalAwareness.SA_MAX, 1.0);
699 params.setParameter(AdaptationSituationalAwareness.SA_MIN, 0.5);
700 params.setParameter(AdaptationSituationalAwareness.TR_MAX, Duration.instantiateSI(2.0));
701 params.setParameter(ParameterTypes.TR, Duration.ZERO);
702 params.setParameter(AdaptationHeadway.BETA_T, 1.0);
703 return params;
704 }
705 }
706
707
708 private class TaskManagerAR implements TaskManager
709 {
710
711 @Override
712 public void manage(final Set<Task> tasksMan, final LanePerception perception, final LaneBasedGTU gtu,
713 final Parameters parameters) throws ParameterException, GTUException
714 {
715 Task primary = null;
716 Set<Task> auxiliaryTasks = new LinkedHashSet<>();
717 for (Task task : tasksMan)
718 {
719 if (task.getId().equals("lane-changing"))
720 {
721 primary = task;
722 }
723 else
724 {
725 auxiliaryTasks.add(task);
726 }
727 }
728 Throw.whenNull(primary, "There is no task with id 'lane-changing'.");
729 double primaryTaskDemand = primary.calculateTaskDemand(perception, gtu, parameters);
730 primary.setTaskDemand(primaryTaskDemand);
731
732 double a = parameters.getParameter(ALPHA);
733 double b = parameters.getParameter(BETA);
734 primary.setAnticipationReliance(a * primaryTaskDemand * (1.0 - primaryTaskDemand));
735 for (Task auxiliary : auxiliaryTasks)
736 {
737 double auxiliaryTaskLoad = auxiliary.calculateTaskDemand(perception, gtu, parameters);
738 auxiliary.setTaskDemand(auxiliaryTaskLoad);
739
740 auxiliary.setAnticipationReliance(b * auxiliaryTaskLoad * primaryTaskDemand);
741 }
742 }
743 }
744
745
746 private class IdmPlusFactoryAR implements CarFollowingModelFactory<IDMPlus>
747 {
748
749 private final Generator<DesiredSpeedModel> desiredSpeedModelGenerator;
750
751
752
753
754
755 IdmPlusFactoryAR(final Generator<DesiredSpeedModel> desiredSpeedModelGenerator)
756 {
757 this.desiredSpeedModelGenerator = desiredSpeedModelGenerator;
758 }
759
760
761 @Override
762 public Parameters getParameters() throws ParameterException
763 {
764 ParameterSet parameters = new ParameterSet();
765 parameters.setDefaultParameters(AbstractIDM.class);
766 return parameters;
767 }
768
769
770 @Override
771 public IDMPlus generateCarFollowingModel()
772 {
773 return new IDMPlus(AbstractIDM.HEADWAY,
774 Try.assign(() -> this.desiredSpeedModelGenerator.draw(), "Unexpected exception."));
775 }
776 }
777
778
779 private class TaskSaturationDataType extends ExtendedDataTypeNumber<GtuData>
780 {
781
782
783
784
785 TaskSaturationDataType()
786 {
787 super("TS");
788 }
789
790
791 @Override
792 public Float getValue(final GtuData gtu)
793 {
794 Double ts = gtu.getGtu().getParameters().getParameterOrNull(Fuller.TS);
795 if (ts != null)
796 {
797 return (float) (double) ts;
798 }
799 return Float.NaN;
800 }
801
802 }
803
804
805 private class TaskAnticipationRelianceDataType extends ExtendedDataTypeNumber<GtuData>
806 {
807
808
809 private String taskId;
810
811
812
813
814
815 TaskAnticipationRelianceDataType(final String taskId)
816 {
817 super(taskId + "_AR");
818 this.taskId = taskId;
819 }
820
821
822 @Override
823 public Float getValue(final GtuData gtu)
824 {
825 return (float) ((Fuller) gtu.getGtu().getTacticalPlanner().getPerception().getMental())
826 .getAnticipationReliance(this.taskId);
827 }
828
829 }
830
831
832 private class TaskDemandDataType extends ExtendedDataTypeNumber<GtuData>
833 {
834
835
836 private String taskId;
837
838
839
840
841
842 TaskDemandDataType(final String taskId)
843 {
844 super(taskId + "_TD");
845 this.taskId = taskId;
846 }
847
848
849 @Override
850 public Float getValue(final GtuData gtu)
851 {
852 return (float) ((Fuller) gtu.getGtu().getTacticalPlanner().getPerception().getMental()).getTaskDemand(this.taskId);
853 }
854
855 }
856
857
858 private class SituationalAwarenessDataType extends ExtendedDataTypeNumber<GtuData>
859 {
860
861
862
863
864 SituationalAwarenessDataType()
865 {
866 super("SA");
867 }
868
869
870 @Override
871 public Float getValue(final GtuData gtu)
872 {
873 Double ts = gtu.getGtu().getParameters().getParameterOrNull(AdaptationSituationalAwareness.SA);
874 if (ts != null)
875 {
876 return (float) (double) ts;
877 }
878 return Float.NaN;
879 }
880
881 }
882
883 }