1 package ahfe;
2
3 import static org.opentrafficsim.core.gtu.GTUType.CAR;
4 import static org.opentrafficsim.core.gtu.GTUType.TRUCK;
5
6 import java.rmi.RemoteException;
7 import java.util.HashMap;
8 import java.util.HashSet;
9 import java.util.Map;
10 import java.util.Random;
11 import java.util.Set;
12
13 import org.djunits.unit.AccelerationUnit;
14 import org.djunits.unit.DurationUnit;
15 import org.djunits.unit.FrequencyUnit;
16 import org.djunits.unit.LengthUnit;
17 import org.djunits.unit.SpeedUnit;
18 import org.djunits.unit.TimeUnit;
19 import org.djunits.value.StorageType;
20 import org.djunits.value.ValueException;
21 import org.djunits.value.vdouble.scalar.Acceleration;
22 import org.djunits.value.vdouble.scalar.Duration;
23 import org.djunits.value.vdouble.scalar.Frequency;
24 import org.djunits.value.vdouble.scalar.Length;
25 import org.djunits.value.vdouble.scalar.Speed;
26 import org.djunits.value.vdouble.scalar.Time;
27 import org.djunits.value.vdouble.vector.FrequencyVector;
28 import org.djunits.value.vdouble.vector.TimeVector;
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.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.gtu.GTUDirectionality;
39 import org.opentrafficsim.core.gtu.GTUException;
40 import org.opentrafficsim.core.gtu.GTUType;
41 import org.opentrafficsim.core.gtu.Try;
42 import org.opentrafficsim.core.gtu.animation.GTUColorer;
43 import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterFactory;
44 import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterFactoryByType;
45 import org.opentrafficsim.core.gtu.perception.DirectEgoPerception;
46 import org.opentrafficsim.core.gtu.perception.EgoPerception;
47 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
48 import org.opentrafficsim.core.idgenerator.IdGenerator;
49 import org.opentrafficsim.core.network.NetworkException;
50 import org.opentrafficsim.core.network.OTSNetwork;
51 import org.opentrafficsim.core.network.route.FixedRouteGenerator;
52 import org.opentrafficsim.core.network.route.Route;
53 import org.opentrafficsim.core.network.route.RouteGenerator;
54 import org.opentrafficsim.core.units.distributions.ContinuousDistDoubleScalar;
55 import org.opentrafficsim.road.gtu.generator.GeneratorPositions;
56 import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator;
57 import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator.RoomChecker;
58 import org.opentrafficsim.road.gtu.generator.TTCRoomChecker;
59 import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedTemplateGTUType;
60 import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedTemplateGTUTypeDistribution;
61 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
62 import org.opentrafficsim.road.gtu.lane.perception.CategoricalLanePerception;
63 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
64 import org.opentrafficsim.road.gtu.lane.perception.PerceptionFactory;
65 import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
66 import org.opentrafficsim.road.gtu.lane.perception.categories.Anticipation;
67 import org.opentrafficsim.road.gtu.lane.perception.categories.DelayedNeighborsPerception;
68 import org.opentrafficsim.road.gtu.lane.perception.categories.DirectInfrastructurePerception;
69 import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedTacticalPlannerFactory;
70 import org.opentrafficsim.road.gtu.lane.tactical.following.AbstractIDM;
71 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
72 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModelFactory;
73 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlus;
74 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusFactory;
75 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveKeep;
76 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveRoute;
77 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveSpeedWithCourtesy;
78 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRS;
79 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Cooperation;
80 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Desire;
81 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.GapAcceptance;
82 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
83 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Synchronization;
84 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Tailgating;
85 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.VoluntaryIncentive;
86 import org.opentrafficsim.road.gtu.strategical.od.Interpolation;
87 import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
88 import org.opentrafficsim.road.network.lane.CrossSectionLink;
89 import org.opentrafficsim.road.network.lane.DirectedLanePosition;
90 import org.opentrafficsim.road.network.lane.Lane;
91
92 import nl.tudelft.simulation.dsol.SimRuntimeException;
93 import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
94 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
95 import nl.tudelft.simulation.jstats.distributions.DistNormal;
96 import nl.tudelft.simulation.jstats.distributions.DistUniform;
97 import nl.tudelft.simulation.jstats.streams.MersenneTwister;
98 import nl.tudelft.simulation.jstats.streams.StreamInterface;
99 import nl.tudelft.simulation.language.Throw;
100
101
102
103
104
105
106
107
108
109
110
111
112 public final class AHFEUtil
113 {
114
115
116
117
118 private AHFEUtil()
119 {
120
121 }
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145 @SuppressWarnings("checkstyle:parameternumber")
146 public static void createDemand(final OTSNetwork network, final GTUColorer gtuColorer,
147 final DEVSSimulatorInterface.TimeDoubleUnit simulator, final int replication, final String anticipationStrategy,
148 final Duration reactionTime, final Duration anticipationTime, final double truckFraction, final Time simulationTime,
149 final Frequency leftDemand, final Frequency rightDemand, final double leftFraction, final double distanceError,
150 final double speedError, final double accelerationError)
151 throws ValueException, ParameterException, GTUException, SimRuntimeException, ProbabilityException
152 {
153
154 Random seedGenerator = new Random(replication);
155 Map<String, StreamInterface> streams = new HashMap<>();
156 streams.put("headwayGeneration", new MersenneTwister(Math.abs(seedGenerator.nextLong()) + 1));
157 streams.put("gtuClass", new MersenneTwister(Math.abs(seedGenerator.nextLong()) + 1));
158 streams.put("perception", new MersenneTwister(Math.abs(seedGenerator.nextLong()) + 1));
159 simulator.getReplication().setStreams(streams);
160
161 TTCRoomChecker roomChecker = new TTCRoomChecker(new Duration(10.0, DurationUnit.SI));
162 IdGenerator idGenerator = new IdGenerator("");
163
164 CarFollowingModelFactory<IDMPlus> idmPlusFactory = new IDMPlusFactory(streams.get("gtuClass"));
165 PerceptionFactory delayedPerceptionFactory = Try.assign(
166 () -> new DelayedPerceptionFactory(
167 (Anticipation) Anticipation.class.getDeclaredField(anticipationStrategy.toUpperCase()).get(null)),
168 "Exception while obtaining anticipation value %s", anticipationStrategy);
169 ParameterSet params = new ParameterSet();
170 params.setDefaultParameter(AbstractIDM.DELTA);
171 params.setParameter(ParameterTypes.TR, reactionTime);
172 params.setParameter(DelayedNeighborsPerception.TA, anticipationTime);
173 params.setDefaultParameter(DelayedNeighborsPerception.TAUE);
174 params.setParameter(DelayedNeighborsPerception.SERROR, distanceError);
175 params.setParameter(DelayedNeighborsPerception.VERROR, speedError);
176 params.setParameter(DelayedNeighborsPerception.AERROR, accelerationError);
177 LaneBasedTacticalPlannerFactory<LMRS> tacticalFactory =
178 new LMRSFactoryAHFE(idmPlusFactory, params, delayedPerceptionFactory);
179
180 ParameterFactoryByType bcFactory = new ParameterFactoryByType();
181
182
183 Length perception = new Length(1.0, LengthUnit.KILOMETER);
184 Acceleration b = new Acceleration(2.09, AccelerationUnit.SI);
185 GTUType gtuType = new GTUType("car", CAR);
186 bcFactory.addParameter(gtuType, ParameterTypes.FSPEED,
187 new DistNormal(streams.get("gtuClass"), 123.7 / 120, 12.0 / 120));
188 bcFactory.addParameter(gtuType, ParameterTypes.B, b);
189
190
191 bcFactory.addParameter(gtuType, ParameterTypes.PERCEPTION, perception);
192 gtuType = new GTUType("truck", TRUCK);
193 bcFactory.addParameter(gtuType, ParameterTypes.A, new Acceleration(0.8, AccelerationUnit.SI));
194 bcFactory.addParameter(gtuType, ParameterTypes.B, b);
195
196
197 bcFactory.addParameter(gtuType, ParameterTypes.PERCEPTION, perception);
198 bcFactory.addParameter(gtuType, ParameterTypes.FSPEED, 2.0);
199
200 Route leftRoute = new Route("left");
201 Route rightRoute = new Route("right");
202 try
203 {
204 leftRoute.addNode(network.getNode("LEFTINPRE"));
205 leftRoute.addNode(network.getNode("LEFTIN"));
206 leftRoute.addNode(network.getNode("STARTCONVERGE"));
207 leftRoute.addNode(network.getNode("STARTWEAVING"));
208 leftRoute.addNode(network.getNode("NARROWING"));
209 leftRoute.addNode(network.getNode("EXIT"));
210 rightRoute.addNode(network.getNode("RIGHTINPRE"));
211 rightRoute.addNode(network.getNode("RIGHTIN"));
212 rightRoute.addNode(network.getNode("STARTWEAVING"));
213 rightRoute.addNode(network.getNode("NARROWING"));
214 rightRoute.addNode(network.getNode("EXIT"));
215 }
216 catch (NetworkException exception)
217 {
218 exception.printStackTrace();
219 }
220 RouteGenerator fixedRouteGeneratorLeft = new FixedRouteGenerator(leftRoute);
221 RouteGenerator fixedRouteGeneratorRight = new FixedRouteGenerator(rightRoute);
222
223 LaneBasedStrategicalRoutePlannerFactory strategicalFactory =
224 new LaneBasedStrategicalRoutePlannerFactory(tacticalFactory, bcFactory);
225 ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> speedCar =
226 new ContinuousDistDoubleScalar.Rel<>(new DistUniform(streams.get("gtuClass"), 160, 200), SpeedUnit.KM_PER_HOUR);
227 ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> speedTruck =
228 new ContinuousDistDoubleScalar.Rel<>(new DistNormal(streams.get("gtuClass"), 80, 2.5), SpeedUnit.KM_PER_HOUR);
229
230 LaneBasedTemplateGTUType carLeft =
231 new LaneBasedTemplateGTUType(new GTUType("car", CAR), new ConstantGenerator<>(Length.createSI(4.0)),
232 new ConstantGenerator<>(Length.createSI(2.0)), speedCar, strategicalFactory, fixedRouteGeneratorLeft);
233 LaneBasedTemplateGTUType truckLeft =
234 new LaneBasedTemplateGTUType(new GTUType("truck", TRUCK), new ConstantGenerator<>(Length.createSI(15.0)),
235 new ConstantGenerator<>(Length.createSI(2.5)), speedTruck, strategicalFactory, fixedRouteGeneratorLeft);
236 LaneBasedTemplateGTUType carRight =
237 new LaneBasedTemplateGTUType(new GTUType("car", CAR), new ConstantGenerator<>(Length.createSI(4.0)),
238 new ConstantGenerator<>(Length.createSI(2.0)), speedCar, strategicalFactory, fixedRouteGeneratorRight);
239 LaneBasedTemplateGTUType truckRight = new LaneBasedTemplateGTUType(new GTUType("truck", TRUCK),
240 new ConstantGenerator<>(Length.createSI(15.0)), new ConstantGenerator<>(Length.createSI(2.5)), speedTruck,
241 strategicalFactory, fixedRouteGeneratorRight);
242
243
244
245
246 Distribution<LaneBasedTemplateGTUType> gtuTypeGeneratorLeftLeft = new Distribution<>(streams.get("gtuClass"));
247 Distribution<LaneBasedTemplateGTUType> gtuTypeGeneratorLeftRight = new Distribution<>(streams.get("gtuClass"));
248 Distribution<LaneBasedTemplateGTUType> gtuTypeGeneratorRightLeft = new Distribution<>(streams.get("gtuClass"));
249 Distribution<LaneBasedTemplateGTUType> gtuTypeGeneratorRightRight = new Distribution<>(streams.get("gtuClass"));
250 if (truckFraction < 1 - leftFraction)
251 {
252 double p = truckFraction / (1 - leftFraction);
253
254 gtuTypeGeneratorLeftLeft.add(new FrequencyAndObject<>(1.0, carLeft));
255 gtuTypeGeneratorLeftRight.add(new FrequencyAndObject<>(1.0 - p, carLeft));
256 gtuTypeGeneratorLeftRight.add(new FrequencyAndObject<>(p, truckLeft));
257
258 gtuTypeGeneratorRightLeft.add(new FrequencyAndObject<>(1.0, carRight));
259 gtuTypeGeneratorRightRight.add(new FrequencyAndObject<>(1.0 - p, carRight));
260 gtuTypeGeneratorRightRight.add(new FrequencyAndObject<>(p, truckRight));
261 }
262 else
263 {
264 double p = (truckFraction - (1 - leftFraction)) / leftFraction;
265 gtuTypeGeneratorLeftLeft.add(new FrequencyAndObject<>(1.0 - p, carLeft));
266 gtuTypeGeneratorLeftLeft.add(new FrequencyAndObject<>(p, truckLeft));
267 gtuTypeGeneratorLeftRight.add(new FrequencyAndObject<>(1.0, truckLeft));
268
269 gtuTypeGeneratorRightLeft.add(new FrequencyAndObject<>(1.0 - p, carRight));
270 gtuTypeGeneratorRightLeft.add(new FrequencyAndObject<>(p, truckRight));
271 gtuTypeGeneratorRightRight.add(new FrequencyAndObject<>(1.0, truckRight));
272 }
273
274 TimeVector timeVector =
275 new TimeVector(new double[] { 0, 360, 1560, 2160, 3960 }, TimeUnit.BASE_SECOND, StorageType.DENSE);
276 double leftLeft = leftDemand.si * leftFraction;
277 FrequencyVector leftLeftDemandPattern = new FrequencyVector(
278 new double[] { leftLeft * 0.5, leftLeft * 0.5, leftLeft, leftLeft, 0.0 }, FrequencyUnit.SI, StorageType.DENSE);
279 double leftRight = leftDemand.si * (1 - leftFraction);
280 FrequencyVector leftRightDemandPattern =
281 new FrequencyVector(new double[] { leftRight * 0.5, leftRight * 0.5, leftRight, leftRight, 0.0 },
282 FrequencyUnit.SI, StorageType.DENSE);
283 double rightLeft = rightDemand.si * leftFraction;
284 FrequencyVector rightLeftDemandPattern =
285 new FrequencyVector(new double[] { rightLeft * 0.5, rightLeft * 0.5, rightLeft, rightLeft, 0.0 },
286 FrequencyUnit.SI, StorageType.DENSE);
287 double rightRight = rightDemand.si * (1 - leftFraction);
288 FrequencyVector rightRightDemandPattern =
289 new FrequencyVector(new double[] { rightRight * 0.5, rightRight * 0.5, rightRight, rightRight, 0.0 },
290 FrequencyUnit.SI, StorageType.DENSE);
291
292 HeadwayGeneratorDemand leftLeftHeadways = new HeadwayGeneratorDemand(timeVector, leftLeftDemandPattern, simulator);
293 HeadwayGeneratorDemand leftRightHeadways = new HeadwayGeneratorDemand(timeVector, leftRightDemandPattern, simulator);
294 HeadwayGeneratorDemand rightLeftHeadways = new HeadwayGeneratorDemand(timeVector, rightLeftDemandPattern, simulator);
295 HeadwayGeneratorDemand rightRightHeadways = new HeadwayGeneratorDemand(timeVector, rightRightDemandPattern, simulator);
296
297 Speed genSpeed = new Speed(120.0, SpeedUnit.KM_PER_HOUR);
298 CrossSectionLink leftLink = (CrossSectionLink) network.getLink("LEFTINPRE");
299 CrossSectionLink rightLink = (CrossSectionLink) network.getLink("RIGHTINPRE");
300 makeGenerator(getLane(leftLink, "FORWARD1"), genSpeed, "LEFTLEFT", idGenerator, simulator, network,
301 gtuTypeGeneratorLeftLeft, leftLeftHeadways, gtuColorer, roomChecker, bcFactory, tacticalFactory, simulationTime,
302 streams.get("gtuClass"));
303 makeGenerator(getLane(leftLink, "FORWARD2"), genSpeed, "LEFTRIGHT", idGenerator, simulator, network,
304 gtuTypeGeneratorLeftRight, leftRightHeadways, gtuColorer, roomChecker, bcFactory, tacticalFactory,
305 simulationTime, streams.get("gtuClass"));
306 makeGenerator(getLane(rightLink, "FORWARD1"), genSpeed, "RIGHTLEFT", idGenerator, simulator, network,
307 gtuTypeGeneratorRightLeft, rightLeftHeadways, gtuColorer, roomChecker, bcFactory, tacticalFactory,
308 simulationTime, streams.get("gtuClass"));
309 makeGenerator(getLane(rightLink, "FORWARD2"), genSpeed, "RIGHTRIGHT", idGenerator, simulator, network,
310 gtuTypeGeneratorRightRight, rightRightHeadways, gtuColorer, roomChecker, bcFactory, tacticalFactory,
311 simulationTime, streams.get("gtuClass"));
312
313 }
314
315
316
317
318
319
320
321 private static Lane getLane(final CrossSectionLink link, final String id)
322 {
323 for (Lane lane : link.getLanes())
324 {
325 if (lane.getId().equals(id))
326 {
327 return lane;
328 }
329 }
330 throw new RuntimeException("Could not find lane " + id + " on link " + link.getId());
331 }
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353 private static void makeGenerator(final Lane lane, final Speed generationSpeed, final String id,
354 final IdGenerator idGenerator, final DEVSSimulatorInterface.TimeDoubleUnit simulator, final OTSNetwork network,
355 final Distribution<LaneBasedTemplateGTUType> distribution, final HeadwayGeneratorDemand headwayGenerator,
356 final GTUColorer gtuColorer, final RoomChecker roomChecker, final ParameterFactory bcFactory,
357 final LaneBasedTacticalPlannerFactory<?> tacticalFactory, final Time simulationTime, final StreamInterface stream)
358 throws SimRuntimeException, ProbabilityException, GTUException, ParameterException
359 {
360 Set<DirectedLanePosition> initialLongitudinalPositions = new HashSet<>();
361
362 initialLongitudinalPositions
363 .add(new DirectedLanePosition(lane, new Length(10.0, LengthUnit.SI), GTUDirectionality.DIR_PLUS));
364 LaneBasedTemplateGTUTypeDistribution characteristicsGenerator = new LaneBasedTemplateGTUTypeDistribution(distribution);
365 new LaneBasedGTUGenerator(id, headwayGenerator, gtuColorer, characteristicsGenerator,
366 GeneratorPositions.create(initialLongitudinalPositions, stream), network, simulator, roomChecker, idGenerator);
367 }
368
369
370
371
372
373
374
375
376
377
378
379
380 private static class LMRSFactoryAHFE implements LaneBasedTacticalPlannerFactory<LMRS>
381 {
382
383
384 private final CarFollowingModelFactory<? extends CarFollowingModel> carFollowingModelFactory;
385
386
387 private final Parameters defaultCarFollowingParameters;
388
389
390 private final PerceptionFactory perceptionFactory;
391
392
393
394
395
396
397
398
399 LMRSFactoryAHFE(final CarFollowingModelFactory<? extends CarFollowingModel> carFollowingModelFactory,
400 final Parameters defaultCarFollowingParameters, final PerceptionFactory perceptionFactory) throws GTUException
401 {
402 this.carFollowingModelFactory = carFollowingModelFactory;
403 this.defaultCarFollowingParameters = defaultCarFollowingParameters;
404 this.perceptionFactory = perceptionFactory;
405 }
406
407
408 @Override
409 public final Parameters getParameters()
410 {
411 ParameterSet parameters = new ParameterSet();
412 parameters.setDefaultParameters(ParameterTypes.class);
413 parameters.setDefaultParameters(LmrsParameters.class);
414 this.defaultCarFollowingParameters.setAllIn(parameters);
415 return parameters;
416 }
417
418
419 @Override
420 public final LMRS create(final LaneBasedGTU gtu) throws GTUException
421 {
422 LMRS lmrs = new LMRS(this.carFollowingModelFactory.generateCarFollowingModel(), gtu,
423 this.perceptionFactory.generatePerception(gtu), Synchronization.PASSIVE, Cooperation.PASSIVE,
424 GapAcceptance.INFORMED, Tailgating.NONE);
425 lmrs.addMandatoryIncentive(new IncentiveRoute());
426 lmrs.addVoluntaryIncentive(new IncentiveSpeedWithCourtesy());
427 if (gtu.getGTUType().getId().equals("car"))
428 {
429 lmrs.addVoluntaryIncentive(new IncentiveKeep());
430 }
431 else
432 {
433 lmrs.addVoluntaryIncentive(new KeepRightTruck());
434 }
435 return lmrs;
436 }
437
438
439 @Override
440 public final String toString()
441 {
442 return "LMRSFactory [car-following=" + this.carFollowingModelFactory + "]";
443 }
444
445 }
446
447
448
449
450
451
452
453
454
455
456
457
458
459 private static class DelayedPerceptionFactory implements PerceptionFactory
460 {
461
462
463 private final Anticipation anticipation;
464
465
466
467
468
469 DelayedPerceptionFactory(final Anticipation anticipation)
470 {
471 this.anticipation = anticipation;
472 }
473
474
475 @Override
476 public LanePerception generatePerception(final LaneBasedGTU gtu)
477 {
478 LanePerception perception = new CategoricalLanePerception(gtu);
479 perception.addPerceptionCategory(new DirectEgoPerception(perception));
480
481 perception.addPerceptionCategory(new DirectInfrastructurePerception(perception));
482
483 perception.addPerceptionCategory(new DelayedNeighborsPerception(perception, this.anticipation));
484
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 }