1 package org.opentrafficsim.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.djutils.exceptions.Throw;
30 import org.djutils.exceptions.Try;
31 import org.opentrafficsim.base.parameters.ParameterException;
32 import org.opentrafficsim.base.parameters.ParameterSet;
33 import org.opentrafficsim.base.parameters.ParameterTypes;
34 import org.opentrafficsim.base.parameters.Parameters;
35 import org.opentrafficsim.core.animation.gtu.colorer.GTUColorer;
36 import org.opentrafficsim.core.distributions.ConstantGenerator;
37 import org.opentrafficsim.core.distributions.Distribution;
38 import org.opentrafficsim.core.distributions.Distribution.FrequencyAndObject;
39 import org.opentrafficsim.core.distributions.Generator;
40 import org.opentrafficsim.core.distributions.ProbabilityException;
41 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
42 import org.opentrafficsim.core.gtu.GTUDirectionality;
43 import org.opentrafficsim.core.gtu.GTUException;
44 import org.opentrafficsim.core.gtu.GTUType;
45 import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterFactory;
46 import org.opentrafficsim.core.gtu.behavioralcharacteristics.ParameterFactoryByType;
47 import org.opentrafficsim.core.gtu.perception.DirectEgoPerception;
48 import org.opentrafficsim.core.gtu.perception.EgoPerception;
49 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
50 import org.opentrafficsim.core.idgenerator.IdGenerator;
51 import org.opentrafficsim.core.network.NetworkException;
52 import org.opentrafficsim.core.network.OTSNetwork;
53 import org.opentrafficsim.core.network.route.FixedRouteGenerator;
54 import org.opentrafficsim.core.network.route.Route;
55 import org.opentrafficsim.core.network.route.RouteGenerator;
56 import org.opentrafficsim.core.units.distributions.ContinuousDistDoubleScalar;
57 import org.opentrafficsim.road.gtu.generator.GeneratorPositions;
58 import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator;
59 import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator.RoomChecker;
60 import org.opentrafficsim.road.gtu.generator.TTCRoomChecker;
61 import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedTemplateGTUType;
62 import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedTemplateGTUTypeDistribution;
63 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
64 import org.opentrafficsim.road.gtu.lane.perception.CategoricalLanePerception;
65 import org.opentrafficsim.road.gtu.lane.perception.LanePerception;
66 import org.opentrafficsim.road.gtu.lane.perception.PerceptionFactory;
67 import org.opentrafficsim.road.gtu.lane.perception.RelativeLane;
68 import org.opentrafficsim.road.gtu.lane.perception.categories.AnticipationTrafficPerception;
69 import org.opentrafficsim.road.gtu.lane.perception.categories.DirectInfrastructurePerception;
70 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.Anticipation;
71 import org.opentrafficsim.road.gtu.lane.perception.categories.neighbors.DelayedNeighborsPerception;
72 import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedTacticalPlannerFactory;
73 import org.opentrafficsim.road.gtu.lane.tactical.following.AbstractIDM;
74 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModel;
75 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModelFactory;
76 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlus;
77 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusFactory;
78 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveKeep;
79 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveRoute;
80 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveSpeedWithCourtesy;
81 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRS;
82 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Cooperation;
83 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Desire;
84 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.GapAcceptance;
85 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
86 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Synchronization;
87 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Tailgating;
88 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.VoluntaryIncentive;
89 import org.opentrafficsim.road.gtu.strategical.od.Interpolation;
90 import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
91 import org.opentrafficsim.road.network.lane.CrossSectionLink;
92 import org.opentrafficsim.road.network.lane.DirectedLanePosition;
93 import org.opentrafficsim.road.network.lane.Lane;
94
95 import nl.tudelft.simulation.dsol.SimRuntimeException;
96 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
97 import nl.tudelft.simulation.jstats.distributions.DistNormal;
98 import nl.tudelft.simulation.jstats.distributions.DistUniform;
99 import nl.tudelft.simulation.jstats.streams.MersenneTwister;
100 import nl.tudelft.simulation.jstats.streams.StreamInterface;
101
102
103
104
105
106
107
108
109
110
111
112
113 public final class AHFEUtil
114 {
115
116
117
118
119 private AHFEUtil()
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
146 @SuppressWarnings("checkstyle:parameternumber")
147 public static void createDemand(final OTSNetwork network, final GTUColorer gtuColorer,
148 final OTSSimulatorInterface simulator, final int replication, final String anticipationStrategy,
149 final Duration reactionTime, final Duration anticipationTime, final double truckFraction, final Time simulationTime,
150 final Frequency leftDemand, final Frequency rightDemand, final double leftFraction, final double distanceError,
151 final double speedError, final double accelerationError)
152 throws ValueException, ParameterException, GTUException, SimRuntimeException, ProbabilityException
153 {
154
155 Random seedGenerator = new Random(replication);
156 Map<String, StreamInterface> streams = new HashMap<>();
157 streams.put("headwayGeneration", new MersenneTwister(Math.abs(seedGenerator.nextLong()) + 1));
158 streams.put("gtuClass", new MersenneTwister(Math.abs(seedGenerator.nextLong()) + 1));
159 streams.put("perception", new MersenneTwister(Math.abs(seedGenerator.nextLong()) + 1));
160 simulator.getReplication().setStreams(streams);
161
162 TTCRoomChecker roomChecker = new TTCRoomChecker(new Duration(10.0, DurationUnit.SI));
163 IdGenerator idGenerator = new IdGenerator("");
164
165 CarFollowingModelFactory<IDMPlus> idmPlusFactory = new IDMPlusFactory(streams.get("gtuClass"));
166 PerceptionFactory delayedPerceptionFactory = Try.assign(
167 () -> new DelayedPerceptionFactory(
168 (Anticipation) Anticipation.class.getDeclaredField(anticipationStrategy.toUpperCase()).get(null)),
169 "Exception while obtaining anticipation value %s", anticipationStrategy);
170 ParameterSet params = new ParameterSet();
171 params.setDefaultParameter(AbstractIDM.DELTA);
172 params.setParameter(ParameterTypes.TR, reactionTime);
173 params.setParameter(DelayedNeighborsPerception.TA, anticipationTime);
174 params.setDefaultParameter(DelayedNeighborsPerception.TAUE);
175 params.setParameter(DelayedNeighborsPerception.SERROR, distanceError);
176 params.setParameter(DelayedNeighborsPerception.VERROR, speedError);
177 params.setParameter(DelayedNeighborsPerception.AERROR, accelerationError);
178 LaneBasedTacticalPlannerFactory<LMRS> tacticalFactory =
179 new LMRSFactoryAHFE(idmPlusFactory, params, delayedPerceptionFactory);
180
181 ParameterFactoryByType bcFactory = new ParameterFactoryByType();
182
183
184 Length perception = new Length(1.0, LengthUnit.KILOMETER);
185 Acceleration b = new Acceleration(2.09, AccelerationUnit.SI);
186 GTUType gtuType = new GTUType("car", CAR);
187 bcFactory.addParameter(gtuType, ParameterTypes.FSPEED,
188 new DistNormal(streams.get("gtuClass"), 123.7 / 120, 12.0 / 120));
189 bcFactory.addParameter(gtuType, ParameterTypes.B, b);
190
191
192 bcFactory.addParameter(gtuType, ParameterTypes.PERCEPTION, perception);
193 gtuType = new GTUType("truck", TRUCK);
194 bcFactory.addParameter(gtuType, ParameterTypes.A, new Acceleration(0.8, AccelerationUnit.SI));
195 bcFactory.addParameter(gtuType, ParameterTypes.B, b);
196
197
198 bcFactory.addParameter(gtuType, ParameterTypes.PERCEPTION, perception);
199 bcFactory.addParameter(gtuType, ParameterTypes.FSPEED, 2.0);
200
201 Route leftRoute = new Route("left");
202 Route rightRoute = new Route("right");
203 try
204 {
205 leftRoute.addNode(network.getNode("LEFTINPRE"));
206 leftRoute.addNode(network.getNode("LEFTIN"));
207 leftRoute.addNode(network.getNode("STARTCONVERGE"));
208 leftRoute.addNode(network.getNode("STARTWEAVING"));
209 leftRoute.addNode(network.getNode("NARROWING"));
210 leftRoute.addNode(network.getNode("EXIT"));
211 rightRoute.addNode(network.getNode("RIGHTINPRE"));
212 rightRoute.addNode(network.getNode("RIGHTIN"));
213 rightRoute.addNode(network.getNode("STARTWEAVING"));
214 rightRoute.addNode(network.getNode("NARROWING"));
215 rightRoute.addNode(network.getNode("EXIT"));
216 }
217 catch (NetworkException exception)
218 {
219 exception.printStackTrace();
220 }
221 RouteGenerator fixedRouteGeneratorLeft = new FixedRouteGenerator(leftRoute);
222 RouteGenerator fixedRouteGeneratorRight = new FixedRouteGenerator(rightRoute);
223
224 LaneBasedStrategicalRoutePlannerFactory strategicalFactory =
225 new LaneBasedStrategicalRoutePlannerFactory(tacticalFactory, bcFactory);
226 ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> speedCar =
227 new ContinuousDistDoubleScalar.Rel<>(new DistUniform(streams.get("gtuClass"), 160, 200), SpeedUnit.KM_PER_HOUR);
228 ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> speedTruck =
229 new ContinuousDistDoubleScalar.Rel<>(new DistNormal(streams.get("gtuClass"), 80, 2.5), SpeedUnit.KM_PER_HOUR);
230
231 LaneBasedTemplateGTUType carLeft =
232 new LaneBasedTemplateGTUType(new GTUType("car", CAR), new ConstantGenerator<>(Length.createSI(4.0)),
233 new ConstantGenerator<>(Length.createSI(2.0)), speedCar, strategicalFactory, fixedRouteGeneratorLeft);
234 LaneBasedTemplateGTUType truckLeft =
235 new LaneBasedTemplateGTUType(new GTUType("truck", TRUCK), new ConstantGenerator<>(Length.createSI(15.0)),
236 new ConstantGenerator<>(Length.createSI(2.5)), speedTruck, strategicalFactory, fixedRouteGeneratorLeft);
237 LaneBasedTemplateGTUType carRight =
238 new LaneBasedTemplateGTUType(new GTUType("car", CAR), new ConstantGenerator<>(Length.createSI(4.0)),
239 new ConstantGenerator<>(Length.createSI(2.0)), speedCar, strategicalFactory, fixedRouteGeneratorRight);
240 LaneBasedTemplateGTUType truckRight = new LaneBasedTemplateGTUType(new GTUType("truck", TRUCK),
241 new ConstantGenerator<>(Length.createSI(15.0)), new ConstantGenerator<>(Length.createSI(2.5)), speedTruck,
242 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 new TimeVector(new double[] { 0, 360, 1560, 2160, 3960 }, TimeUnit.BASE_SECOND, StorageType.DENSE);
277 double leftLeft = leftDemand.si * leftFraction;
278 FrequencyVector leftLeftDemandPattern = new FrequencyVector(
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 new FrequencyVector(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 new FrequencyVector(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 new FrequencyVector(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 OTSNetwork 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 HashSet<>();
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 public 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 public 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 (ValueException 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 (ValueException 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 ValueException, RemoteException
673 {
674
675
676 if (i == this.timeVector.size() - 1)
677 {
678 return new Time(Double.POSITIVE_INFINITY, TimeUnit.BASE);
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.BASE);
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 }