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