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