1 package org.opentrafficsim.ahfe;
2
3 import java.rmi.RemoteException;
4 import java.util.LinkedHashMap;
5 import java.util.LinkedHashSet;
6 import java.util.Map;
7 import java.util.Random;
8 import java.util.Set;
9
10 import org.djunits.unit.AccelerationUnit;
11 import org.djunits.unit.DurationUnit;
12 import org.djunits.unit.FrequencyUnit;
13 import org.djunits.unit.LengthUnit;
14 import org.djunits.unit.SpeedUnit;
15 import org.djunits.unit.TimeUnit;
16 import org.djunits.value.ValueRuntimeException;
17 import org.djunits.value.storage.StorageType;
18 import org.djunits.value.vdouble.scalar.Acceleration;
19 import org.djunits.value.vdouble.scalar.Duration;
20 import org.djunits.value.vdouble.scalar.Frequency;
21 import org.djunits.value.vdouble.scalar.Length;
22 import org.djunits.value.vdouble.scalar.Speed;
23 import org.djunits.value.vdouble.scalar.Time;
24 import org.djunits.value.vdouble.vector.FrequencyVector;
25 import org.djunits.value.vdouble.vector.TimeVector;
26 import org.djunits.value.vdouble.vector.base.DoubleVector;
27 import org.djutils.exceptions.Throw;
28 import org.djutils.exceptions.Try;
29 import org.opentrafficsim.base.parameters.ParameterException;
30 import org.opentrafficsim.base.parameters.ParameterSet;
31 import org.opentrafficsim.base.parameters.ParameterTypes;
32 import org.opentrafficsim.base.parameters.Parameters;
33 import org.opentrafficsim.core.animation.gtu.colorer.GTUColorer;
34 import org.opentrafficsim.core.distributions.ConstantGenerator;
35 import org.opentrafficsim.core.distributions.Distribution;
36 import org.opentrafficsim.core.distributions.Distribution.FrequencyAndObject;
37 import org.opentrafficsim.core.distributions.Generator;
38 import org.opentrafficsim.core.distributions.ProbabilityException;
39 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
40 import org.opentrafficsim.core.gtu.GTUDirectionality;
41 import org.opentrafficsim.core.gtu.GTUException;
42 import org.opentrafficsim.core.gtu.GTUType;
43 import org.opentrafficsim.core.gtu.perception.DirectEgoPerception;
44 import org.opentrafficsim.core.gtu.perception.EgoPerception;
45 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
46 import org.opentrafficsim.core.idgenerator.IdGenerator;
47 import org.opentrafficsim.core.network.NetworkException;
48 import org.opentrafficsim.core.network.route.FixedRouteGenerator;
49 import org.opentrafficsim.core.network.route.Route;
50 import org.opentrafficsim.core.parameters.ParameterFactory;
51 import org.opentrafficsim.core.parameters.ParameterFactoryByType;
52 import org.opentrafficsim.core.units.distributions.ContinuousDistDoubleScalar;
53 import org.opentrafficsim.road.gtu.generator.GeneratorPositions;
54 import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator;
55 import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator.RoomChecker;
56 import org.opentrafficsim.road.gtu.generator.TTCRoomChecker;
57 import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedTemplateGTUType;
58 import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedTemplateGTUTypeDistribution;
59 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
60 import org.opentrafficsim.road.gtu.lane.perception.CategoricalLanePerception;
61 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
62 import org.opentrafficsim.road.gtu.lane.perception.PerceptionFactory;
63 import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
64 import org.opentrafficsim.road.gtu.lane.perception.categories.AnticipationTrafficPerception;
65 import org.opentrafficsim.road.gtu.lane.perception.categories.DirectInfrastructurePerception;
66 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.Anticipation;
67 import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedTacticalPlannerFactory;
68 import org.opentrafficsim.road.gtu.lane.tactical.following.AbstractIDM;
69 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
70 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModelFactory;
71 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlus;
72 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusFactory;
73 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveKeep;
74 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveRoute;
75 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveSpeedWithCourtesy;
76 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRS;
77 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Cooperation;
78 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Desire;
79 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.GapAcceptance;
80 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
81 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Synchronization;
82 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Tailgating;
83 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.VoluntaryIncentive;
84 import org.opentrafficsim.road.gtu.strategical.od.Interpolation;
85 import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
86 import org.opentrafficsim.road.network.OTSRoadNetwork;
87 import org.opentrafficsim.road.network.lane.CrossSectionLink;
88 import org.opentrafficsim.road.network.lane.DirectedLanePosition;
89 import org.opentrafficsim.road.network.lane.Lane;
90
91 import nl.tudelft.simulation.dsol.SimRuntimeException;
92 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
93 import nl.tudelft.simulation.jstats.distributions.DistNormal;
94 import nl.tudelft.simulation.jstats.distributions.DistUniform;
95 import nl.tudelft.simulation.jstats.streams.MersenneTwister;
96 import nl.tudelft.simulation.jstats.streams.StreamInterface;
97
98
99
100
101
102
103
104
105
106
107
108
109 public final class AHFEUtil
110 {
111
112
113
114
115 private AHFEUtil()
116 {
117
118 }
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142 @SuppressWarnings("checkstyle:parameternumber")
143 public static void createDemand(final OTSRoadNetwork network, final GTUColorer gtuColorer,
144 final OTSSimulatorInterface simulator, final int replication, final String anticipationStrategy,
145 final Duration reactionTime, final Duration anticipationTime, final double truckFraction, final Time simulationTime,
146 final Frequency leftDemand, final Frequency rightDemand, final double leftFraction, final double distanceError,
147 final double speedError, final double accelerationError)
148 throws ValueRuntimeException, ParameterException, GTUException, SimRuntimeException, ProbabilityException
149 {
150
151 Random seedGenerator = new Random(replication);
152 Map<String, StreamInterface> streams = new LinkedHashMap<>();
153 streams.put("headwayGeneration", new MersenneTwister(Math.abs(seedGenerator.nextLong()) + 1));
154 streams.put("gtuClass", new MersenneTwister(Math.abs(seedGenerator.nextLong()) + 1));
155 streams.put("perception", new MersenneTwister(Math.abs(seedGenerator.nextLong()) + 1));
156 simulator.getReplication().setStreams(streams);
157
158 TTCRoomChecker roomChecker = new TTCRoomChecker(new Duration(10.0, DurationUnit.SI));
159 IdGenerator idGenerator = new IdGenerator("");
160
161 CarFollowingModelFactory<IDMPlus> idmPlusFactory = new IDMPlusFactory(streams.get("gtuClass"));
162 PerceptionFactory delayedPerceptionFactory = Try.assign(
163 () -> new DelayedPerceptionFactory(
164 (Anticipation) Anticipation.class.getDeclaredField(anticipationStrategy.toUpperCase()).get(null)),
165 "Exception while obtaining anticipation value %s", anticipationStrategy);
166 ParameterSet params = new ParameterSet();
167 params.setDefaultParameter(AbstractIDM.DELTA);
168 params.setParameter(ParameterTypes.TR, reactionTime);
169 params.setParameter(DelayedNeighborsPerception.TA, anticipationTime);
170 params.setDefaultParameter(DelayedNeighborsPerception.TAUE);
171 params.setParameter(DelayedNeighborsPerception.SERROR, distanceError);
172 params.setParameter(DelayedNeighborsPerception.VERROR, speedError);
173 params.setParameter(DelayedNeighborsPerception.AERROR, accelerationError);
174 LaneBasedTacticalPlannerFactory<LMRS> tacticalFactory =
175 new LMRSFactoryAHFE(idmPlusFactory, params, delayedPerceptionFactory);
176
177 ParameterFactoryByType bcFactory = new ParameterFactoryByType();
178
179
180 Length perception = new Length(1.0, LengthUnit.KILOMETER);
181 Acceleration b = new Acceleration(2.09, AccelerationUnit.SI);
182 GTUType gtuType = new GTUType("car", network.getGtuType(GTUType.DEFAULTS.CAR));
183 bcFactory.addParameter(gtuType, ParameterTypes.FSPEED,
184 new DistNormal(streams.get("gtuClass"), 123.7 / 120, 12.0 / 120));
185 bcFactory.addParameter(gtuType, ParameterTypes.B, b);
186
187
188 bcFactory.addParameter(gtuType, ParameterTypes.PERCEPTION, perception);
189 gtuType = new GTUType("truck", network.getGtuType(GTUType.DEFAULTS.TRUCK));
190 bcFactory.addParameter(gtuType, ParameterTypes.A, new Acceleration(0.8, AccelerationUnit.SI));
191 bcFactory.addParameter(gtuType, ParameterTypes.B, b);
192
193
194 bcFactory.addParameter(gtuType, ParameterTypes.PERCEPTION, perception);
195 bcFactory.addParameter(gtuType, ParameterTypes.FSPEED, 2.0);
196
197 Route leftRoute = new Route("left");
198 Route rightRoute = new Route("right");
199 try
200 {
201 leftRoute.addNode(network.getNode("LEFTINPRE"));
202 leftRoute.addNode(network.getNode("LEFTIN"));
203 leftRoute.addNode(network.getNode("STARTCONVERGE"));
204 leftRoute.addNode(network.getNode("STARTWEAVING"));
205 leftRoute.addNode(network.getNode("NARROWING"));
206 leftRoute.addNode(network.getNode("EXIT"));
207 rightRoute.addNode(network.getNode("RIGHTINPRE"));
208 rightRoute.addNode(network.getNode("RIGHTIN"));
209 rightRoute.addNode(network.getNode("STARTWEAVING"));
210 rightRoute.addNode(network.getNode("NARROWING"));
211 rightRoute.addNode(network.getNode("EXIT"));
212 }
213 catch (NetworkException exception)
214 {
215 exception.printStackTrace();
216 }
217 Generator<Route> fixedRouteGeneratorLeft = new FixedRouteGenerator(leftRoute);
218 Generator<Route> fixedRouteGeneratorRight = new FixedRouteGenerator(rightRoute);
219
220 LaneBasedStrategicalRoutePlannerFactory strategicalFactory =
221 new LaneBasedStrategicalRoutePlannerFactory(tacticalFactory, bcFactory);
222 ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> speedCar =
223 new ContinuousDistDoubleScalar.Rel<>(new DistUniform(streams.get("gtuClass"), 160, 200), SpeedUnit.KM_PER_HOUR);
224 ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> speedTruck =
225 new ContinuousDistDoubleScalar.Rel<>(new DistNormal(streams.get("gtuClass"), 80, 2.5), SpeedUnit.KM_PER_HOUR);
226
227 LaneBasedTemplateGTUType carLeft =
228 new LaneBasedTemplateGTUType(new GTUType("car", network.getGtuType(GTUType.DEFAULTS.CAR)),
229 new ConstantGenerator<>(Length.instantiateSI(4.0)), new ConstantGenerator<>(Length.instantiateSI(2.0)),
230 speedCar, strategicalFactory, fixedRouteGeneratorLeft);
231 LaneBasedTemplateGTUType truckLeft =
232 new LaneBasedTemplateGTUType(new GTUType("truck", network.getGtuType(GTUType.DEFAULTS.TRUCK)),
233 new ConstantGenerator<>(Length.instantiateSI(15.0)), new ConstantGenerator<>(Length.instantiateSI(2.5)),
234 speedTruck, strategicalFactory, fixedRouteGeneratorLeft);
235 LaneBasedTemplateGTUType carRight =
236 new LaneBasedTemplateGTUType(new GTUType("car", network.getGtuType(GTUType.DEFAULTS.CAR)),
237 new ConstantGenerator<>(Length.instantiateSI(4.0)), new ConstantGenerator<>(Length.instantiateSI(2.0)),
238 speedCar, strategicalFactory, fixedRouteGeneratorRight);
239 LaneBasedTemplateGTUType truckRight =
240 new LaneBasedTemplateGTUType(new GTUType("truck", network.getGtuType(GTUType.DEFAULTS.TRUCK)),
241 new ConstantGenerator<>(Length.instantiateSI(15.0)), new ConstantGenerator<>(Length.instantiateSI(2.5)),
242 speedTruck, strategicalFactory, fixedRouteGeneratorRight);
243
244
245
246
247 Distribution<LaneBasedTemplateGTUType> gtuTypeGeneratorLeftLeft = new Distribution<>(streams.get("gtuClass"));
248 Distribution<LaneBasedTemplateGTUType> gtuTypeGeneratorLeftRight = new Distribution<>(streams.get("gtuClass"));
249 Distribution<LaneBasedTemplateGTUType> gtuTypeGeneratorRightLeft = new Distribution<>(streams.get("gtuClass"));
250 Distribution<LaneBasedTemplateGTUType> gtuTypeGeneratorRightRight = new Distribution<>(streams.get("gtuClass"));
251 if (truckFraction < 1 - leftFraction)
252 {
253 double p = truckFraction / (1 - leftFraction);
254
255 gtuTypeGeneratorLeftLeft.add(new FrequencyAndObject<>(1.0, carLeft));
256 gtuTypeGeneratorLeftRight.add(new FrequencyAndObject<>(1.0 - p, carLeft));
257 gtuTypeGeneratorLeftRight.add(new FrequencyAndObject<>(p, truckLeft));
258
259 gtuTypeGeneratorRightLeft.add(new FrequencyAndObject<>(1.0, carRight));
260 gtuTypeGeneratorRightRight.add(new FrequencyAndObject<>(1.0 - p, carRight));
261 gtuTypeGeneratorRightRight.add(new FrequencyAndObject<>(p, truckRight));
262 }
263 else
264 {
265 double p = (truckFraction - (1 - leftFraction)) / leftFraction;
266 gtuTypeGeneratorLeftLeft.add(new FrequencyAndObject<>(1.0 - p, carLeft));
267 gtuTypeGeneratorLeftLeft.add(new FrequencyAndObject<>(p, truckLeft));
268 gtuTypeGeneratorLeftRight.add(new FrequencyAndObject<>(1.0, truckLeft));
269
270 gtuTypeGeneratorRightLeft.add(new FrequencyAndObject<>(1.0 - p, carRight));
271 gtuTypeGeneratorRightLeft.add(new FrequencyAndObject<>(p, truckRight));
272 gtuTypeGeneratorRightRight.add(new FrequencyAndObject<>(1.0, truckRight));
273 }
274
275 TimeVector timeVector =
276 DoubleVector.instantiate(new double[] {0, 360, 1560, 2160, 3960}, TimeUnit.BASE_SECOND, StorageType.DENSE);
277 double leftLeft = leftDemand.si * leftFraction;
278 FrequencyVector leftLeftDemandPattern = DoubleVector.instantiate(
279 new double[] {leftLeft * 0.5, leftLeft * 0.5, leftLeft, leftLeft, 0.0}, FrequencyUnit.SI, StorageType.DENSE);
280 double leftRight = leftDemand.si * (1 - leftFraction);
281 FrequencyVector leftRightDemandPattern =
282 DoubleVector.instantiate(new double[] {leftRight * 0.5, leftRight * 0.5, leftRight, leftRight, 0.0},
283 FrequencyUnit.SI, StorageType.DENSE);
284 double rightLeft = rightDemand.si * leftFraction;
285 FrequencyVector rightLeftDemandPattern =
286 DoubleVector.instantiate(new double[] {rightLeft * 0.5, rightLeft * 0.5, rightLeft, rightLeft, 0.0},
287 FrequencyUnit.SI, StorageType.DENSE);
288 double rightRight = rightDemand.si * (1 - leftFraction);
289 FrequencyVector rightRightDemandPattern =
290 DoubleVector.instantiate(new double[] {rightRight * 0.5, rightRight * 0.5, rightRight, rightRight, 0.0},
291 FrequencyUnit.SI, StorageType.DENSE);
292
293 HeadwayGeneratorDemand leftLeftHeadways = new HeadwayGeneratorDemand(timeVector, leftLeftDemandPattern, simulator);
294 HeadwayGeneratorDemand leftRightHeadways = new HeadwayGeneratorDemand(timeVector, leftRightDemandPattern, simulator);
295 HeadwayGeneratorDemand rightLeftHeadways = new HeadwayGeneratorDemand(timeVector, rightLeftDemandPattern, simulator);
296 HeadwayGeneratorDemand rightRightHeadways = new HeadwayGeneratorDemand(timeVector, rightRightDemandPattern, simulator);
297
298 Speed genSpeed = new Speed(120.0, SpeedUnit.KM_PER_HOUR);
299 CrossSectionLink leftLink = (CrossSectionLink) network.getLink("LEFTINPRE");
300 CrossSectionLink rightLink = (CrossSectionLink) network.getLink("RIGHTINPRE");
301 makeGenerator(getLane(leftLink, "FORWARD1"), genSpeed, "LEFTLEFT", idGenerator, simulator, network,
302 gtuTypeGeneratorLeftLeft, leftLeftHeadways, gtuColorer, roomChecker, bcFactory, tacticalFactory, simulationTime,
303 streams.get("gtuClass"));
304 makeGenerator(getLane(leftLink, "FORWARD2"), genSpeed, "LEFTRIGHT", idGenerator, simulator, network,
305 gtuTypeGeneratorLeftRight, leftRightHeadways, gtuColorer, roomChecker, bcFactory, tacticalFactory,
306 simulationTime, streams.get("gtuClass"));
307 makeGenerator(getLane(rightLink, "FORWARD1"), genSpeed, "RIGHTLEFT", idGenerator, simulator, network,
308 gtuTypeGeneratorRightLeft, rightLeftHeadways, gtuColorer, roomChecker, bcFactory, tacticalFactory,
309 simulationTime, streams.get("gtuClass"));
310 makeGenerator(getLane(rightLink, "FORWARD2"), genSpeed, "RIGHTRIGHT", idGenerator, simulator, network,
311 gtuTypeGeneratorRightRight, rightRightHeadways, gtuColorer, roomChecker, bcFactory, tacticalFactory,
312 simulationTime, streams.get("gtuClass"));
313
314 }
315
316
317
318
319
320
321
322 private static Lane getLane(final CrossSectionLink link, final String id)
323 {
324 for (Lane lane : link.getLanes())
325 {
326 if (lane.getId().equals(id))
327 {
328 return lane;
329 }
330 }
331 throw new RuntimeException("Could not find lane " + id + " on link " + link.getId());
332 }
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354 private static void makeGenerator(final Lane lane, final Speed generationSpeed, final String id,
355 final IdGenerator idGenerator, final OTSSimulatorInterface simulator, final OTSRoadNetwork network,
356 final Distribution<LaneBasedTemplateGTUType> distribution, final HeadwayGeneratorDemand headwayGenerator,
357 final GTUColorer gtuColorer, final RoomChecker roomChecker, final ParameterFactory bcFactory,
358 final LaneBasedTacticalPlannerFactory<?> tacticalFactory, final Time simulationTime, final StreamInterface stream)
359 throws SimRuntimeException, ProbabilityException, GTUException, ParameterException
360 {
361 Set<DirectedLanePosition> initialLongitudinalPositions = new LinkedHashSet<>();
362
363 initialLongitudinalPositions
364 .add(new DirectedLanePosition(lane, new Length(10.0, LengthUnit.SI), GTUDirectionality.DIR_PLUS));
365 LaneBasedTemplateGTUTypeDistribution characteristicsGenerator = new LaneBasedTemplateGTUTypeDistribution(distribution);
366 new LaneBasedGTUGenerator(id, headwayGenerator, characteristicsGenerator,
367 GeneratorPositions.create(initialLongitudinalPositions, stream), network, simulator, roomChecker, idGenerator);
368 }
369
370
371
372
373
374
375
376
377
378
379
380
381 private static class LMRSFactoryAHFE implements LaneBasedTacticalPlannerFactory<LMRS>
382 {
383
384
385 private final CarFollowingModelFactory<? extends CarFollowingModel> carFollowingModelFactory;
386
387
388 private final Parameters defaultCarFollowingParameters;
389
390
391 private final PerceptionFactory perceptionFactory;
392
393
394
395
396
397
398
399
400
401 LMRSFactoryAHFE(final CarFollowingModelFactory<? extends CarFollowingModel> carFollowingModelFactory,
402 final Parameters defaultCarFollowingParameters, final PerceptionFactory perceptionFactory) throws GTUException
403 {
404 this.carFollowingModelFactory = carFollowingModelFactory;
405 this.defaultCarFollowingParameters = defaultCarFollowingParameters;
406 this.perceptionFactory = perceptionFactory;
407 }
408
409
410 @Override
411 public final Parameters getParameters()
412 {
413 ParameterSet parameters = new ParameterSet();
414 parameters.setDefaultParameters(ParameterTypes.class);
415 parameters.setDefaultParameters(LmrsParameters.class);
416 this.defaultCarFollowingParameters.setAllIn(parameters);
417 return parameters;
418 }
419
420
421 @Override
422 public final LMRS create(final LaneBasedGTU gtu) throws GTUException
423 {
424 LMRS lmrs = new LMRS(this.carFollowingModelFactory.generateCarFollowingModel(), gtu,
425 this.perceptionFactory.generatePerception(gtu), Synchronization.PASSIVE, Cooperation.PASSIVE,
426 GapAcceptance.INFORMED, Tailgating.NONE);
427 lmrs.addMandatoryIncentive(new IncentiveRoute());
428 lmrs.addVoluntaryIncentive(new IncentiveSpeedWithCourtesy());
429 if (gtu.getGTUType().getId().equals("car"))
430 {
431 lmrs.addVoluntaryIncentive(new IncentiveKeep());
432 }
433 else
434 {
435 lmrs.addVoluntaryIncentive(new KeepRightTruck());
436 }
437 return lmrs;
438 }
439
440
441 @Override
442 public final String toString()
443 {
444 return "LMRSFactory [car-following=" + this.carFollowingModelFactory + "]";
445 }
446
447 }
448
449
450
451
452
453
454
455
456
457
458
459
460
461 private static class DelayedPerceptionFactory implements PerceptionFactory
462 {
463
464
465 private final Anticipation anticipation;
466
467
468
469
470
471 DelayedPerceptionFactory(final Anticipation anticipation)
472 {
473 this.anticipation = anticipation;
474 }
475
476
477 @Override
478 public LanePerception generatePerception(final LaneBasedGTU gtu)
479 {
480 LanePerception perception = new CategoricalLanePerception(gtu);
481 perception.addPerceptionCategory(new DirectEgoPerception(perception));
482
483 perception.addPerceptionCategory(new DirectInfrastructurePerception(perception));
484
485 perception.addPerceptionCategory(new DelayedNeighborsPerception(perception, this.anticipation));
486
487 perception.addPerceptionCategory(new AnticipationTrafficPerception(perception));
488 return perception;
489 }
490
491
492 @Override
493 public Parameters getParameters()
494 {
495 return new ParameterSet();
496 }
497
498 }
499
500
501
502
503
504
505
506
507
508
509
510
511 private static class KeepRightTruck implements VoluntaryIncentive
512 {
513
514
515
516
517 KeepRightTruck()
518 {
519 }
520
521
522 @Override
523 public Desire determineDesire(final Parameters parameters, final LanePerception perception,
524 final CarFollowingModel carFollowingModel, final Desire mandatoryDesire, final Desire voluntaryDesire)
525 throws ParameterException, OperationalPlanException
526 {
527 if (perception.getLaneStructure().getRootRecord().getRight() != null
528 && perception.getLaneStructure().getRootRecord().getRight().getRight() != null
529 && perception.getPerceptionCategory(EgoPerception.class).getSpeed()
530 .gt(parameters.getParameter(ParameterTypes.VCONG)))
531 {
532
533 return new Desire(0, 1);
534 }
535 if (mandatoryDesire.getRight() < 0 || voluntaryDesire.getRight() < 0
536 || !perception.getLaneStructure().getExtendedCrossSection().contains(RelativeLane.RIGHT))
537 {
538
539 return new Desire(0, 0);
540 }
541
542 return new Desire(0, 1.0);
543 }
544
545 }
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560 private static class HeadwayGeneratorDemand implements Generator<Duration>
561 {
562
563
564 private final Interpolation interpolation;
565
566
567 private final TimeVector timeVector;
568
569
570 private final FrequencyVector demandVector;
571
572
573 private final SimulatorInterface.TimeDoubleUnit simulator;
574
575
576 private static final String HEADWAY_STREAM = "headwayGeneration";
577
578
579
580
581
582
583 HeadwayGeneratorDemand(final TimeVector timeVector, final FrequencyVector demandVector,
584 final SimulatorInterface.TimeDoubleUnit simulator)
585 {
586 this(timeVector, demandVector, simulator, Interpolation.STEPWISE);
587 }
588
589
590
591
592
593
594
595 HeadwayGeneratorDemand(final TimeVector timeVector, final FrequencyVector demandVector,
596 final SimulatorInterface.TimeDoubleUnit simulator, final Interpolation interpolation)
597 {
598 Throw.whenNull(timeVector, "Time vector may not be null.");
599 Throw.whenNull(demandVector, "Demand vector may not be null.");
600 Throw.whenNull(simulator, "Simulator may not be null.");
601 Throw.whenNull(interpolation, "Interpolation may not be null.");
602 Throw.whenNull(simulator.getReplication().getStream(HEADWAY_STREAM),
603 "Could not obtain random stream '" + HEADWAY_STREAM + "'.");
604 for (int i = 0; i < timeVector.size() - 1; i++)
605 {
606 try
607 {
608 Throw.when(timeVector.get(i).ge(timeVector.get(i + 1)), IllegalArgumentException.class,
609 "Time vector is not increasing.");
610 }
611 catch (ValueRuntimeException exception)
612 {
613 throw new RuntimeException(
614 "Value out of range of time vector. Note that HeadwayGenerator does not create a safe copy.",
615 exception);
616 }
617 }
618 Throw.when(timeVector.size() != demandVector.size(), IllegalArgumentException.class,
619 "Time and flow vector should be of the same size.");
620 Throw.when(timeVector.size() < 2, IllegalArgumentException.class,
621 "Time and flow vector should be at least of size 2.");
622 this.timeVector = timeVector;
623 this.demandVector = demandVector;
624 this.simulator = simulator;
625 this.interpolation = interpolation;
626 }
627
628
629 @Override
630 public final Duration draw() throws ProbabilityException, ParameterException
631 {
632 Time time = this.simulator.getSimulatorTime();
633 try
634 {
635 Throw.when(time.lt(this.timeVector.get(0)), IllegalArgumentException.class,
636 "Cannot return a headway at time before first time in vector.");
637
638
639 int i = 0;
640 while (this.timeVector.get(i + 1).lt(time) && i < this.timeVector.size() - 1)
641 {
642 i++;
643 }
644 try
645 {
646 return nextArrival(i, time.minus(this.timeVector.get(i)), 1.0).minus(time);
647 }
648 catch (RemoteException exception)
649 {
650 throw new RuntimeException("Could not obtain replication.", exception);
651 }
652 }
653 catch (ValueRuntimeException exception)
654 {
655 throw new RuntimeException(
656 "Value out of range of time or demand vector. Note that HeadwayGenerator does not create safe copies.",
657 exception);
658 }
659 }
660
661
662
663
664
665
666
667
668
669
670
671 private Time nextArrival(final int i, final Duration start, final double fractionRemaining)
672 throws ValueRuntimeException, RemoteException
673 {
674
675
676 if (i == this.timeVector.size() - 1)
677 {
678 return new Time(Double.POSITIVE_INFINITY, TimeUnit.DEFAULT);
679 }
680
681
682 if (this.demandVector.get(i).equals(Frequency.ZERO))
683 {
684
685 return nextArrival(i + 1, Duration.ZERO,
686 this.simulator.getReplication().getStream(HEADWAY_STREAM).nextDouble());
687 }
688
689
690 Frequency demand;
691 if (this.interpolation.isStepWise())
692 {
693 demand = this.demandVector.get(i);
694 }
695 else
696 {
697 double f = start.si / (this.timeVector.get(i + 1).si - this.timeVector.get(i).si);
698 demand = Frequency.interpolate(this.demandVector.get(i), this.demandVector.get(i + 1), f);
699 }
700 double t = -Math.log(this.simulator.getReplication().getStream(HEADWAY_STREAM).nextDouble()) / demand.si;
701
702
703 Time arrival = new Time(this.timeVector.get(i).si + start.si + t * fractionRemaining, TimeUnit.DEFAULT);
704
705
706 if (arrival.gt(this.timeVector.get(i + 1)))
707 {
708 double inStep = this.timeVector.get(i + 1).si - (this.timeVector.get(i).si + start.si);
709 return nextArrival(i + 1, Duration.ZERO, fractionRemaining - inStep / t);
710 }
711
712 return arrival;
713
714 }
715
716
717 @Override
718 public final String toString()
719 {
720 return "HeadwayGeneratorDemand [interpolation=" + this.interpolation + ", timeVector=" + this.timeVector
721 + ", demandVector=" + this.demandVector + ", simulator=" + this.simulator + "]";
722 }
723
724 }
725
726 }