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