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