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