1 package org.opentrafficsim.demo;
2
3 import java.awt.Dimension;
4 import java.net.URL;
5 import java.rmi.RemoteException;
6 import java.util.ArrayList;
7 import java.util.LinkedHashMap;
8 import java.util.LinkedHashSet;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.Random;
12 import java.util.Set;
13
14 import javax.naming.NamingException;
15
16 import org.djunits.unit.AccelerationUnit;
17 import org.djunits.unit.DurationUnit;
18 import org.djunits.unit.FrequencyUnit;
19 import org.djunits.unit.LengthUnit;
20 import org.djunits.unit.SpeedUnit;
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.djutils.io.URLResource;
28 import org.opentrafficsim.base.parameters.ParameterException;
29 import org.opentrafficsim.base.parameters.ParameterSet;
30 import org.opentrafficsim.base.parameters.ParameterTypes;
31 import org.opentrafficsim.core.animation.gtu.colorer.GtuColorer;
32 import org.opentrafficsim.core.definitions.DefaultsNl;
33 import org.opentrafficsim.core.distributions.ConstantGenerator;
34 import org.opentrafficsim.core.distributions.Distribution;
35 import org.opentrafficsim.core.distributions.Distribution.FrequencyAndObject;
36 import org.opentrafficsim.core.distributions.Generator;
37 import org.opentrafficsim.core.distributions.ProbabilityException;
38 import org.opentrafficsim.core.dsol.AbstractOtsModel;
39 import org.opentrafficsim.core.dsol.OtsAnimator;
40 import org.opentrafficsim.core.dsol.OtsSimulatorInterface;
41 import org.opentrafficsim.core.gtu.GtuException;
42 import org.opentrafficsim.core.gtu.GtuType;
43 import org.opentrafficsim.core.idgenerator.IdGenerator;
44 import org.opentrafficsim.core.network.NetworkException;
45 import org.opentrafficsim.core.network.Node;
46 import org.opentrafficsim.core.network.Link;
47 import org.opentrafficsim.core.network.route.ProbabilisticRouteGenerator;
48 import org.opentrafficsim.core.network.route.Route;
49 import org.opentrafficsim.core.parameters.ParameterFactory;
50 import org.opentrafficsim.core.parameters.ParameterFactoryByType;
51 import org.opentrafficsim.core.units.distributions.ContinuousDistDoubleScalar;
52 import org.opentrafficsim.demo.ShortMerge.ShortMergeModel;
53 import org.opentrafficsim.draw.core.OtsDrawingException;
54 import org.opentrafficsim.road.gtu.colorer.LmrsSwitchableColorer;
55 import org.opentrafficsim.road.gtu.generator.GeneratorPositions;
56 import org.opentrafficsim.road.gtu.generator.LaneBasedGtuGenerator;
57 import org.opentrafficsim.road.gtu.generator.LaneBasedGtuGenerator.RoomChecker;
58 import org.opentrafficsim.road.gtu.generator.TtcRoomChecker;
59 import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedGtuTemplate;
60 import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedGtuTemplateDistribution;
61 import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedTacticalPlannerFactory;
62 import org.opentrafficsim.road.gtu.lane.tactical.following.AbstractIdm;
63 import org.opentrafficsim.road.gtu.lane.tactical.following.CarFollowingModelFactory;
64 import org.opentrafficsim.road.gtu.lane.tactical.following.IdmPlus;
65 import org.opentrafficsim.road.gtu.lane.tactical.following.IdmPlusFactory;
66 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.AccelerationConflicts;
67 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.AccelerationIncentive;
68 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.AccelerationSpeedLimitTransition;
69 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.AccelerationTrafficLights;
70 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.DefaultLmrsPerceptionFactory;
71 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveCourtesy;
72 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveKeep;
73 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveRoute;
74 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveSocioSpeed;
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.lmrs.LmrsFactory;
78 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Cooperation;
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.MandatoryIncentive;
82 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Synchronization;
83 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Tailgating;
84 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.VoluntaryIncentive;
85 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalRoutePlannerFactory;
86 import org.opentrafficsim.road.network.RoadNetwork;
87 import org.opentrafficsim.road.network.factory.xml.parser.XmlNetworkLaneParser;
88 import org.opentrafficsim.road.network.lane.CrossSectionLink;
89 import org.opentrafficsim.road.network.lane.Lane;
90 import org.opentrafficsim.road.network.lane.LanePosition;
91 import org.opentrafficsim.road.network.lane.object.SpeedSign;
92 import org.opentrafficsim.swing.gui.AnimationToggles;
93 import org.opentrafficsim.swing.gui.OtsAnimationPanel;
94 import org.opentrafficsim.swing.gui.OtsSimulationApplication;
95
96 import nl.tudelft.simulation.dsol.SimRuntimeException;
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 import nl.tudelft.simulation.language.DSOLException;
102
103
104
105
106
107
108
109
110
111
112 public class ShortMerge extends OtsSimulationApplication<ShortMergeModel>
113 {
114
115 private static final long serialVersionUID = 20170407L;
116
117
118 static final String NETWORK = "shortMerge";
119
120
121 static final double TRUCK_FRACTION = 0.15;
122
123
124 static final double LEFT_FRACTION = 0.3;
125
126
127 static final Frequency MAIN_DEMAND = new Frequency(1000, FrequencyUnit.PER_HOUR);
128
129
130 static final Frequency RAMP_DEMAND = new Frequency(500, FrequencyUnit.PER_HOUR);
131
132
133 static final Synchronization SYNCHRONIZATION = Synchronization.ALIGN_GAP;
134
135
136 static final Cooperation COOPERATION = Cooperation.PASSIVE_MOVING;
137
138
139 static final boolean ADDITIONAL_INCENTIVES = true;
140
141
142 public static final Time SIMTIME = Time.instantiateSI(3600);
143
144
145
146
147
148
149
150
151 public ShortMerge(final String title, final OtsAnimationPanel panel, final ShortMergeModel model) throws OtsDrawingException
152 {
153 super(model, panel);
154 }
155
156
157 @Override
158 protected void setAnimationToggles()
159 {
160 AnimationToggles.setTextAnimationTogglesFull(getAnimationPanel());
161 getAnimationPanel().getAnimationPanel().toggleClass(Link.class);
162 getAnimationPanel().getAnimationPanel().toggleClass(Node.class);
163 getAnimationPanel().getAnimationPanel().showClass(SpeedSign.class);
164 }
165
166
167
168
169
170 public static void main(final String[] args)
171 {
172 demo(true);
173 }
174
175
176
177
178
179 public static void demo(final boolean exitOnClose)
180 {
181 try
182 {
183 OtsAnimator simulator = new OtsAnimator("ShortMerge");
184 final ShortMergeModel otsModel = new ShortMergeModel(simulator);
185 simulator.initialize(Time.ZERO, Duration.ZERO, Duration.instantiateSI(3600.0), otsModel);
186 OtsAnimationPanel animationPanel = new OtsAnimationPanel(otsModel.getNetwork().getExtent(), new Dimension(800, 600),
187 simulator, otsModel, new LmrsSwitchableColorer(DefaultsNl.GTU_TYPE_COLORS.toMap()), otsModel.getNetwork());
188 ShortMerge app = new ShortMerge("ShortMerge", animationPanel, otsModel);
189 app.setExitOnClose(exitOnClose);
190 animationPanel.enableSimulationControlButtons();
191 }
192 catch (SimRuntimeException | NamingException | RemoteException | OtsDrawingException | IndexOutOfBoundsException
193 | DSOLException exception)
194 {
195 exception.printStackTrace();
196 }
197 }
198
199
200
201
202
203
204
205
206
207
208
209 public static class ShortMergeModel extends AbstractOtsModel
210 {
211
212 private static final long serialVersionUID = 20170407L;
213
214
215 private RoadNetwork network;
216
217
218
219
220 public ShortMergeModel(final OtsSimulatorInterface simulator)
221 {
222 super(simulator);
223 }
224
225
226
227
228 public void setNetwork(final RoadNetwork network)
229 {
230 this.network = network;
231 }
232
233
234 @Override
235 public void constructModel() throws SimRuntimeException
236 {
237 try
238 {
239 URL xmlURL = URLResource.getResource("/resources/lmrs/" + NETWORK + ".xml");
240 this.network = new RoadNetwork("ShortMerge", getSimulator());
241 XmlNetworkLaneParser.build(xmlURL, this.network, false);
242 addGenerator();
243
244 }
245 catch (Exception exception)
246 {
247 exception.printStackTrace();
248 }
249 }
250
251
252 @Override
253 public RoadNetwork getNetwork()
254 {
255 return this.network;
256 }
257
258
259
260
261
262
263
264
265
266
267 private void addGenerator() throws ParameterException, GtuException, NetworkException, ProbabilityException,
268 SimRuntimeException, RemoteException
269 {
270
271 Random seedGenerator = new Random(1L);
272 Map<String, StreamInterface> streams = new LinkedHashMap<>();
273 StreamInterface stream = new MersenneTwister(Math.abs(seedGenerator.nextLong()) + 1);
274 streams.put("headwayGeneration", stream);
275 streams.put("gtuClass", new MersenneTwister(Math.abs(seedGenerator.nextLong()) + 1));
276 getStreamInformation().addStream("headwayGeneration", stream);
277 getStreamInformation().addStream("gtuClass", streams.get("gtuClass"));
278
279 TtcRoomChecker roomChecker = new TtcRoomChecker(new Duration(10.0, DurationUnit.SI));
280 IdGenerator idGenerator = new IdGenerator("");
281
282 CarFollowingModelFactory<IdmPlus> idmPlusFactory = new IdmPlusFactory(streams.get("gtuClass"));
283 ParameterSet params = new ParameterSet();
284 params.setDefaultParameter(AbstractIdm.DELTA);
285
286 Set<MandatoryIncentive> mandatoryIncentives = new LinkedHashSet<>();
287 Set<VoluntaryIncentive> voluntaryIncentives = new LinkedHashSet<>();
288 Set<AccelerationIncentive> accelerationIncentives = new LinkedHashSet<>();
289 mandatoryIncentives.add(new IncentiveRoute());
290 if (ADDITIONAL_INCENTIVES)
291 {
292
293 }
294 voluntaryIncentives.add(new IncentiveSpeedWithCourtesy());
295 voluntaryIncentives.add(new IncentiveKeep());
296 if (ADDITIONAL_INCENTIVES)
297 {
298 voluntaryIncentives.add(new IncentiveCourtesy());
299 voluntaryIncentives.add(new IncentiveSocioSpeed());
300 }
301 accelerationIncentives.add(new AccelerationSpeedLimitTransition());
302 accelerationIncentives.add(new AccelerationTrafficLights());
303 accelerationIncentives.add(new AccelerationConflicts());
304 LaneBasedTacticalPlannerFactory<Lmrs> tacticalFactory = new LmrsFactory(idmPlusFactory,
305 new DefaultLmrsPerceptionFactory(), SYNCHRONIZATION, COOPERATION, GapAcceptance.INFORMED, Tailgating.NONE,
306 mandatoryIncentives, voluntaryIncentives, accelerationIncentives);
307
308 GtuType car = DefaultsNl.CAR;
309 GtuType truck = DefaultsNl.TRUCK;
310 Route routeAE = this.network.getShortestRouteBetween(car, this.network.getNode("A"), this.network.getNode("E"));
311 Route routeAG = !NETWORK.equals("shortWeave") ? null
312 : this.network.getShortestRouteBetween(car, this.network.getNode("A"), this.network.getNode("G"));
313 Route routeFE = this.network.getShortestRouteBetween(car, this.network.getNode("F"), this.network.getNode("E"));
314 Route routeFG = !NETWORK.equals("shortWeave") ? null
315 : this.network.getShortestRouteBetween(car, this.network.getNode("F"), this.network.getNode("G"));
316
317 double leftFraction = NETWORK.equals("shortWeave") ? LEFT_FRACTION : 0.0;
318 List<FrequencyAndObject<Route>> routesA = new ArrayList<>();
319 routesA.add(new FrequencyAndObject<>(1.0 - leftFraction, routeAE));
320 routesA.add(new FrequencyAndObject<>(leftFraction, routeAG));
321 List<FrequencyAndObject<Route>> routesF = new ArrayList<>();
322 routesF.add(new FrequencyAndObject<>(1.0 - leftFraction, routeFE));
323 routesF.add(new FrequencyAndObject<>(leftFraction, routeFG));
324 Generator<Route> routeGeneratorA = new ProbabilisticRouteGenerator(routesA, stream);
325 Generator<Route> routeGeneratorF = new ProbabilisticRouteGenerator(routesF, stream);
326
327 Speed speedA = new Speed(120.0, SpeedUnit.KM_PER_HOUR);
328 Speed speedF = new Speed(20.0, SpeedUnit.KM_PER_HOUR);
329
330 CrossSectionLink linkA = (CrossSectionLink) this.network.getLink("AB");
331 CrossSectionLink linkF = (CrossSectionLink) this.network.getLink("FF2");
332
333 ParameterFactoryByType bcFactory = new ParameterFactoryByType();
334 bcFactory.addParameter(car, ParameterTypes.FSPEED, new DistNormal(stream, 123.7 / 120, 12.0 / 120));
335 bcFactory.addParameter(car, LmrsParameters.SOCIO, new DistNormal(stream, 0.5, 0.1));
336 bcFactory.addParameter(truck, ParameterTypes.A, new Acceleration(0.8, AccelerationUnit.SI));
337 bcFactory.addParameter(truck, LmrsParameters.SOCIO, new DistNormal(stream, 0.5, 0.1));
338 bcFactory.addParameter(Tailgating.RHO, Tailgating.RHO.getDefaultValue());
339
340 Generator<Duration> headwaysA1 = new HeadwayGenerator(getSimulator(), MAIN_DEMAND);
341 Generator<Duration> headwaysA2 = new HeadwayGenerator(getSimulator(), MAIN_DEMAND);
342 Generator<Duration> headwaysA3 = new HeadwayGenerator(getSimulator(), MAIN_DEMAND);
343 Generator<Duration> headwaysF = new HeadwayGenerator(getSimulator(), RAMP_DEMAND);
344
345
346 ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> speedCar =
347 new ContinuousDistDoubleScalar.Rel<>(new DistUniform(stream, 160, 200), SpeedUnit.KM_PER_HOUR);
348 ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> speedTruck =
349 new ContinuousDistDoubleScalar.Rel<>(new DistUniform(stream, 80, 95), SpeedUnit.KM_PER_HOUR);
350
351 LaneBasedStrategicalRoutePlannerFactory strategicalFactory =
352 new LaneBasedStrategicalRoutePlannerFactory(tacticalFactory, bcFactory);
353
354 LaneBasedGtuTemplate carA =
355 new LaneBasedGtuTemplate(car, new ConstantGenerator<>(Length.instantiateSI(4.0)),
356 new ConstantGenerator<>(Length.instantiateSI(2.0)), speedCar, strategicalFactory, routeGeneratorA);
357 LaneBasedGtuTemplate carF =
358 new LaneBasedGtuTemplate(car, new ConstantGenerator<>(Length.instantiateSI(4.0)),
359 new ConstantGenerator<>(Length.instantiateSI(2.0)), speedCar, strategicalFactory, routeGeneratorF);
360 LaneBasedGtuTemplate truckA = new LaneBasedGtuTemplate(truck,
361 new ConstantGenerator<>(Length.instantiateSI(15.0)), new ConstantGenerator<>(Length.instantiateSI(2.5)),
362 speedTruck, strategicalFactory, routeGeneratorA);
363 LaneBasedGtuTemplate truckF = new LaneBasedGtuTemplate(truck,
364 new ConstantGenerator<>(Length.instantiateSI(15.0)), new ConstantGenerator<>(Length.instantiateSI(2.5)),
365 speedTruck, strategicalFactory, routeGeneratorF);
366
367 Distribution<LaneBasedGtuTemplate> gtuTypeAllCarA = new Distribution<>(streams.get("gtuClass"));
368 gtuTypeAllCarA.add(new FrequencyAndObject<>(1.0, carA));
369
370 Distribution<LaneBasedGtuTemplate> gtuType1LaneF = new Distribution<>(streams.get("gtuClass"));
371 gtuType1LaneF.add(new FrequencyAndObject<>(1.0 - 2 * TRUCK_FRACTION, carF));
372 gtuType1LaneF.add(new FrequencyAndObject<>(2 * TRUCK_FRACTION, truckF));
373
374 Distribution<LaneBasedGtuTemplate> gtuType2ndLaneA = new Distribution<>(streams.get("gtuClass"));
375 gtuType2ndLaneA.add(new FrequencyAndObject<>(1.0 - 2 * TRUCK_FRACTION, carA));
376 gtuType2ndLaneA.add(new FrequencyAndObject<>(2 * TRUCK_FRACTION, truckA));
377
378 Distribution<LaneBasedGtuTemplate> gtuType3rdLaneA = new Distribution<>(streams.get("gtuClass"));
379 gtuType3rdLaneA.add(new FrequencyAndObject<>(1.0 - 3 * TRUCK_FRACTION, carA));
380 gtuType3rdLaneA.add(new FrequencyAndObject<>(3 * TRUCK_FRACTION, truckA));
381
382 GtuColorer colorer = new LmrsSwitchableColorer(DefaultsNl.GTU_TYPE_COLORS.toMap());
383 makeGenerator(getLane(linkA, "FORWARD1"), speedA, "gen1", idGenerator, gtuTypeAllCarA, headwaysA1, colorer,
384 roomChecker, bcFactory, tacticalFactory, SIMTIME, streams.get("gtuClass"));
385 if (NETWORK.equals("shortWeave"))
386 {
387 makeGenerator(getLane(linkA, "FORWARD2"), speedA, "gen2", idGenerator, gtuTypeAllCarA, headwaysA2, colorer,
388 roomChecker, bcFactory, tacticalFactory, SIMTIME, streams.get("gtuClass"));
389 makeGenerator(getLane(linkA, "FORWARD3"), speedA, "gen3", idGenerator, gtuType3rdLaneA, headwaysA3, colorer,
390 roomChecker, bcFactory, tacticalFactory, SIMTIME, streams.get("gtuClass"));
391 }
392 else
393 {
394 makeGenerator(getLane(linkA, "FORWARD2"), speedA, "gen2", idGenerator, gtuType2ndLaneA, headwaysA2, colorer,
395 roomChecker, bcFactory, tacticalFactory, SIMTIME, streams.get("gtuClass"));
396 }
397 makeGenerator(getLane(linkF, "FORWARD1"), speedF, "gen4", idGenerator, gtuType1LaneF, headwaysF, colorer,
398 roomChecker, bcFactory, tacticalFactory, SIMTIME, streams.get("gtuClass"));
399
400 new SpeedSign("sign1", getLane(linkA, "FORWARD1"), Length.instantiateSI(10), this.getSimulator(),
401 new Speed(130.0, SpeedUnit.KM_PER_HOUR), DefaultsNl.VEHICLE, Duration.ZERO,
402 new Duration(24, DurationUnit.HOUR));
403
404 }
405
406
407
408
409
410
411
412 private Lane getLane(final CrossSectionLink link, final String id)
413 {
414 return (Lane) link.getCrossSectionElement(id);
415 }
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436 private void makeGenerator(final Lane lane, final Speed generationSpeed, final String id, final IdGenerator idGenerator,
437 final Distribution<LaneBasedGtuTemplate> distribution, final Generator<Duration> headwayGenerator,
438 final GtuColorer gtuColorer, final RoomChecker roomChecker, final ParameterFactory bcFactory,
439 final LaneBasedTacticalPlannerFactory<?> tacticalFactory, final Time simulationTime,
440 final StreamInterface stream) throws SimRuntimeException, ProbabilityException, GtuException, ParameterException, NetworkException
441 {
442
443 Set<LanePosition> initialLongitudinalPositions = new LinkedHashSet<>();
444
445 initialLongitudinalPositions.add(new LanePosition(lane, new Length(5.0, LengthUnit.SI)));
446 LaneBasedGtuTemplateDistribution characteristicsGenerator =
447 new LaneBasedGtuTemplateDistribution(distribution);
448 new LaneBasedGtuGenerator(id, headwayGenerator, characteristicsGenerator,
449 GeneratorPositions.create(initialLongitudinalPositions, stream), this.network, getSimulator(), roomChecker,
450 idGenerator);
451 }
452
453 }
454
455
456
457
458
459
460
461
462
463
464
465 private static class HeadwayGenerator implements Generator<Duration>
466 {
467
468 private final OtsSimulatorInterface simulator;
469
470
471 private final Frequency demand;
472
473
474
475
476
477 HeadwayGenerator(final OtsSimulatorInterface simulator, final Frequency demand)
478 {
479 this.simulator = simulator;
480 this.demand = demand;
481 }
482
483
484 @Override
485 public Duration draw() throws ProbabilityException, ParameterException
486 {
487 return new Duration(
488 -Math.log(this.simulator.getModel().getStream("headwayGeneration").nextDouble()) / this.demand.si,
489 DurationUnit.SI);
490 }
491
492 }
493
494 }