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