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