1 package org.opentrafficsim.demo.conflict;
2
3 import java.awt.Dimension;
4 import java.io.Serializable;
5 import java.net.URL;
6 import java.rmi.RemoteException;
7 import java.util.ArrayList;
8 import java.util.LinkedHashMap;
9 import java.util.LinkedHashSet;
10 import java.util.List;
11 import java.util.Map;
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.base.parameters.Parameters;
32 import org.opentrafficsim.core.distributions.Generator;
33 import org.opentrafficsim.core.distributions.ProbabilityException;
34 import org.opentrafficsim.core.dsol.AbstractOTSModel;
35 import org.opentrafficsim.core.dsol.OTSAnimator;
36 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
37 import org.opentrafficsim.core.gtu.GTUCharacteristics;
38 import org.opentrafficsim.core.gtu.GTUDirectionality;
39 import org.opentrafficsim.core.gtu.GTUException;
40 import org.opentrafficsim.core.gtu.GTUType;
41 import org.opentrafficsim.core.idgenerator.IdGenerator;
42 import org.opentrafficsim.core.network.Node;
43 import org.opentrafficsim.core.network.route.Route;
44 import org.opentrafficsim.core.parameters.ParameterFactory;
45 import org.opentrafficsim.demo.conflict.BusStreetDemo.BusStreetModel;
46 import org.opentrafficsim.draw.core.OTSDrawingException;
47 import org.opentrafficsim.road.gtu.generator.GeneratorPositions;
48 import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator;
49 import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator.RoomChecker;
50 import org.opentrafficsim.road.gtu.generator.TTCRoomChecker;
51 import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedGTUCharacteristics;
52 import org.opentrafficsim.road.gtu.generator.characteristics.LaneBasedGTUCharacteristicsGenerator;
53 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
54 import org.opentrafficsim.road.gtu.lane.VehicleModel;
55 import org.opentrafficsim.road.gtu.lane.perception.categories.DirectBusStopPerception;
56 import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedTacticalPlannerFactory;
57 import org.opentrafficsim.road.gtu.lane.tactical.following.AbstractIDM;
58 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlus;
59 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.AccelerationBusStop;
60 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.DefaultLMRSPerceptionFactory;
61 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.IncentiveBusStop;
62 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRS;
63 import org.opentrafficsim.road.gtu.lane.tactical.pt.BusSchedule;
64 import org.opentrafficsim.road.gtu.lane.tactical.util.ConflictUtil;
65 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Cooperation;
66 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.GapAcceptance;
67 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.LmrsParameters;
68 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Synchronization;
69 import org.opentrafficsim.road.gtu.lane.tactical.util.lmrs.Tailgating;
70 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
71 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
72 import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
73 import org.opentrafficsim.road.network.OTSRoadNetwork;
74 import org.opentrafficsim.road.network.factory.xml.parser.XmlNetworkLaneParser;
75 import org.opentrafficsim.road.network.lane.CrossSectionLink;
76 import org.opentrafficsim.road.network.lane.DirectedLanePosition;
77 import org.opentrafficsim.road.network.lane.Lane;
78 import org.opentrafficsim.road.network.lane.object.BusStop;
79 import org.opentrafficsim.swing.gui.OTSAnimationPanel;
80 import org.opentrafficsim.swing.gui.OTSSimulationApplication;
81
82 import nl.tudelft.simulation.dsol.SimRuntimeException;
83 import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
84 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
85 import nl.tudelft.simulation.jstats.streams.MersenneTwister;
86 import nl.tudelft.simulation.jstats.streams.StreamInterface;
87 import nl.tudelft.simulation.language.DSOLException;
88
89
90
91
92
93
94
95
96
97
98
99 public class BusStreetDemo extends OTSSimulationApplication<BusStreetModel>
100 {
101
102 private static final long serialVersionUID = 20161211L;
103
104
105
106
107
108
109
110
111 public BusStreetDemo(final String title, final OTSAnimationPanel panel, final BusStreetModel model)
112 throws OTSDrawingException
113 {
114 super(model, panel);
115 OTSRoadNetwork network = model.getNetwork();
116 System.out.println(network.getLinkMap());
117 }
118
119
120
121
122
123 public static void main(final String[] args)
124 {
125 demo(true);
126 }
127
128
129
130
131
132 public static void demo(final boolean exitOnClose)
133 {
134 try
135 {
136 OTSAnimator simulator = new OTSAnimator("BusStreetDemo");
137 BusStreetModel busModel = new BusStreetModel(simulator);
138 simulator.initialize(Time.ZERO, Duration.ZERO, Duration.instantiateSI(3600.0), busModel);
139 OTSAnimationPanel animationPanel = new OTSAnimationPanel(busModel.getNetwork().getExtent(), new Dimension(800, 600),
140 simulator, busModel, DEFAULT_COLORER, busModel.getNetwork());
141 BusStreetDemo/BusStreetDemo.html#BusStreetDemo">BusStreetDemo app = new BusStreetDemo("Bus street demo", animationPanel, busModel);
142 app.setExitOnClose(exitOnClose);
143 animationPanel.enableSimulationControlButtons();
144 }
145 catch (SimRuntimeException | NamingException | RemoteException | OTSDrawingException | DSOLException exception)
146 {
147 exception.printStackTrace();
148 }
149 }
150
151
152
153
154 public static class BusStreetModel extends AbstractOTSModel
155 {
156
157 private static final long serialVersionUID = 20161211L;
158
159
160 private OTSRoadNetwork network;
161
162
163
164
165 public BusStreetModel(final OTSSimulatorInterface simulator)
166 {
167 super(simulator);
168 }
169
170
171 @Override
172 public void constructModel() throws SimRuntimeException
173 {
174 Map<String, StreamInterface> streams = new LinkedHashMap<>();
175 streams.put("generation", new MersenneTwister(100L));
176 getStreamInformation().addStream("generation", streams.get("generation"));
177
178 try
179 {
180 URL xmlURL = URLResource.getResource("/conflict/BusStreet.xml");
181 this.network = new OTSRoadNetwork("BusStreet", true, getSimulator());
182 XmlNetworkLaneParser.build(xmlURL, this.network, true);
183
184
185 Lane lane = ((CrossSectionLink) this.network.getLink("B1B2")).getLanes().get(0);
186 BusStop stop = new BusStop("Cafe Boszicht.1", lane, lane.getLength(), "Cafe Boszicht", this.simulator);
187 Set<String> lines1 = new LinkedHashSet<>();
188 lines1.add("1");
189 stop.setLines(lines1);
190
191 lane = ((CrossSectionLink) this.network.getLink("C1C2")).getLanes().get(0);
192 stop = new BusStop("Cafe Boszicht.2", lane, lane.getLength(), "Cafe Boszicht", this.simulator);
193 Set<String> lines2 = new LinkedHashSet<>();
194 lines2.add("2");
195 stop.setLines(lines2);
196
197 lane = ((CrossSectionLink) this.network.getLink("EF")).getLanes().get(0);
198 stop = new BusStop("Herberg De Deugd", lane, new Length(75.0, LengthUnit.SI), "Herberg De Deugd",
199 this.simulator);
200 stop.setLines(lines1);
201
202 lane = ((CrossSectionLink) this.network.getLink("FG")).getLanes().get(1);
203 stop = new BusStop("De Vleeshoeve", lane, new Length(75.0, LengthUnit.SI), "De Vleeshoeve", this.simulator);
204 Set<String> lines12 = new LinkedHashSet<>();
205 lines12.add("1");
206 lines12.add("2");
207 stop.setLines(lines12);
208
209 lane = ((CrossSectionLink) this.network.getLink("GH")).getLanes().get(2);
210 stop = new BusStop("Kippenboerderij De Scharrelaar", lane, new Length(50.0, LengthUnit.SI),
211 "Kippenboerderij De Scharrelaar", this.simulator);
212 stop.setLines(lines2);
213
214 lane = ((CrossSectionLink) this.network.getLink("I1I2")).getLanes().get(0);
215 stop = new BusStop("Dorpshuys", lane, lane.getLength(), "Dorpshuys", this.simulator);
216 stop.setLines(lines1);
217
218 lane = ((CrossSectionLink) this.network.getLink("K1K2")).getLanes().get(0);
219 stop = new BusStop("De verkeerde afslag", lane, lane.getLength(), "De verkeerde afslag", this.simulator);
220 stop.setLines(lines12);
221
222 makeGenerator(streams.get("generation"));
223
224 }
225 catch (Exception exception)
226 {
227 exception.printStackTrace();
228 }
229 }
230
231
232 @Override
233 public OTSRoadNetwork getNetwork()
234 {
235 return this.network;
236 }
237
238
239
240
241
242
243
244
245
246 private void makeGenerator(final StreamInterface stream)
247 throws GTUException, SimRuntimeException, ProbabilityException, ParameterException
248 {
249 Lane lane = ((CrossSectionLink) this.network.getLink("AB")).getLanes().get(0);
250 String id = lane.getId();
251 Set<DirectedLanePosition> initialLongitudinalPositions = new LinkedHashSet<>();
252 initialLongitudinalPositions
253 .add(new DirectedLanePosition(lane, new Length(10.0, LengthUnit.SI), GTUDirectionality.DIR_PLUS));
254 Generator<Duration> headwayGenerator =
255 new HeadwayGenerator(new Frequency(800, FrequencyUnit.PER_HOUR), this.simulator);
256 LaneBasedGTUCharacteristicsGenerator characteristicsGenerator =
257 new CharacteristicsGenerator(this.simulator, new double[] {0.9, 0.06, 0.04}, this.network);
258 RoomChecker roomChecker = new TTCRoomChecker(new Duration(10.0, DurationUnit.SI));
259 LaneBasedGTUGenerator gen = new LaneBasedGTUGenerator(id, headwayGenerator, characteristicsGenerator,
260 GeneratorPositions.create(initialLongitudinalPositions, stream), this.network, this.simulator, roomChecker,
261 new IdGenerator(""));
262 gen.setInstantaneousLaneChange(true);
263 }
264
265
266 @Override
267 public Serializable getSourceId()
268 {
269 return "BusStreetModel";
270 }
271 }
272
273
274
275
276
277
278
279
280
281
282
283
284 private static class HeadwayGenerator implements Generator<Duration>
285 {
286
287
288 private final Frequency demand;
289
290
291 private final SimulatorInterface.TimeDoubleUnit simulator;
292
293
294
295
296
297 HeadwayGenerator(final Frequency demand, final SimulatorInterface.TimeDoubleUnit simulator)
298 {
299 this.demand = demand;
300 this.simulator = simulator;
301 }
302
303
304 @Override
305 public Duration draw() throws ProbabilityException, ParameterException
306 {
307 return new Duration(
308 -Math.log(this.simulator.getModel().getStream("generation").nextDouble()) / this.demand.si,
309 DurationUnit.SI);
310 }
311
312 }
313
314
315
316
317
318
319
320
321
322
323
324
325 public static class CharacteristicsGenerator implements LaneBasedGTUCharacteristicsGenerator
326 {
327
328
329 private final DEVSSimulatorInterface.TimeDoubleUnit simulator;
330
331
332 private final double[] probabilities;
333
334
335 private final LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> plannerFactory;
336
337
338 private final Route carRouteN;
339
340
341 private final Route carRouteO;
342
343
344 private final List<Node> busNodes1;
345
346
347 private final List<Node> busNodes2;
348
349
350 private final Duration shortDwellTime = new Duration(15.0, DurationUnit.SI);
351
352
353 private final Duration longDwellTime = new Duration(60.0, DurationUnit.SI);
354
355
356 private OTSRoadNetwork network;
357
358
359
360
361
362
363 public CharacteristicsGenerator(final DEVSSimulatorInterface.TimeDoubleUnit simulator, final double[] probabilities,
364 final OTSRoadNetwork network)
365 {
366 this.simulator = simulator;
367 this.probabilities = probabilities;
368 this.network = network;
369 List<Node> carNodesN = new ArrayList<>();
370 carNodesN.add(network.getNode("A"));
371 carNodesN.add(network.getNode("B"));
372 carNodesN.add(network.getNode("C"));
373 carNodesN.add(network.getNode("D"));
374 carNodesN.add(network.getNode("E"));
375 carNodesN.add(network.getNode("F"));
376 carNodesN.add(network.getNode("G"));
377 carNodesN.add(network.getNode("H"));
378 carNodesN.add(network.getNode("I"));
379 carNodesN.add(network.getNode("J"));
380 carNodesN.add(network.getNode("K"));
381 carNodesN.add(network.getNode("L"));
382 carNodesN.add(network.getNode("M"));
383 List<Node> carNodesO = new ArrayList<>(carNodesN);
384 carNodesN.add(network.getNode("N"));
385 carNodesO.add(network.getNode("O"));
386 this.carRouteN = new Route("carN", carNodesN);
387 this.carRouteO = new Route("carO", carNodesO);
388 this.busNodes1 = new ArrayList<>();
389 this.busNodes1.add(network.getNode("A"));
390 this.busNodes1.add(network.getNode("B"));
391 this.busNodes1.add(network.getNode("B1"));
392 this.busNodes1.add(network.getNode("B2"));
393 this.busNodes1.add(network.getNode("D"));
394 this.busNodes1.add(network.getNode("E"));
395 this.busNodes1.add(network.getNode("F"));
396 this.busNodes1.add(network.getNode("G"));
397 this.busNodes1.add(network.getNode("H"));
398 this.busNodes1.add(network.getNode("I"));
399 this.busNodes1.add(network.getNode("I1"));
400 this.busNodes1.add(network.getNode("I2"));
401 this.busNodes1.add(network.getNode("J"));
402 this.busNodes1.add(network.getNode("K"));
403 this.busNodes1.add(network.getNode("K1"));
404 this.busNodes1.add(network.getNode("K2"));
405 this.busNodes1.add(network.getNode("L"));
406 this.busNodes1.add(network.getNode("M"));
407 this.busNodes1.add(network.getNode("N"));
408
409 this.busNodes2 = new ArrayList<>();
410 this.busNodes2.add(network.getNode("A"));
411 this.busNodes2.add(network.getNode("B"));
412 this.busNodes2.add(network.getNode("C"));
413 this.busNodes2.add(network.getNode("C1"));
414 this.busNodes2.add(network.getNode("C2"));
415 this.busNodes2.add(network.getNode("E"));
416 this.busNodes2.add(network.getNode("F"));
417 this.busNodes2.add(network.getNode("G"));
418 this.busNodes2.add(network.getNode("H"));
419 this.busNodes2.add(network.getNode("I"));
420 this.busNodes2.add(network.getNode("J"));
421 this.busNodes2.add(network.getNode("K"));
422 this.busNodes2.add(network.getNode("K1"));
423 this.busNodes2.add(network.getNode("K2"));
424 this.busNodes2.add(network.getNode("K3"));
425 this.busNodes2.add(network.getNode("L"));
426 this.busNodes2.add(network.getNode("M"));
427 this.busNodes2.add(network.getNode("O"));
428
429 this.plannerFactory =
430 new LaneBasedStrategicalRoutePlannerFactory(new LMRSFactoryCarBus(), new ParameterFactoryCarBus());
431 }
432
433
434 @Override
435 public LaneBasedGTUCharacteristics draw() throws ProbabilityException, ParameterException, GTUException
436 {
437 double r = this.simulator.getModel().getStream("generation").nextDouble();
438 int classNum = r < this.probabilities[0] ? 0 : r < this.probabilities[0] + this.probabilities[1] ? 1 : 2;
439 r = this.simulator.getModel().getStream("generation").nextDouble();
440 GTUType gtuType;
441 Length length;
442 Length width;
443 Speed maximumSpeed;
444 Route route;
445 switch (classNum)
446 {
447 case 0:
448 {
449 gtuType = new GTUType("CAR", this.network.getGtuType(GTUType.DEFAULTS.CAR));
450 length = new Length(4.0, LengthUnit.SI);
451 width = new Length(1.8, LengthUnit.SI);
452 maximumSpeed = new Speed(200.0, SpeedUnit.KM_PER_HOUR);
453 route = r < 0.5 ? this.carRouteN : this.carRouteO;
454 break;
455 }
456 case 1:
457 {
458 gtuType = new GTUType("BUS1", this.network.getGtuType(GTUType.DEFAULTS.SCHEDULED_BUS));
459 length = new Length(8.0, LengthUnit.SI);
460 width = new Length(2.0, LengthUnit.SI);
461 maximumSpeed = new Speed(100.0, SpeedUnit.KM_PER_HOUR);
462 BusSchedule schedule = new BusSchedule("bus1." + this.simulator.getSimulatorTime(), this.busNodes1, "1");
463 Time now = this.simulator.getSimulatorTime();
464 schedule.addBusStop("Cafe Boszicht.1", now.plus(new Duration(70.0, DurationUnit.SI)), this.longDwellTime,
465 true);
466 schedule.addBusStop("Herberg De Deugd", now.plus(new Duration(100.0, DurationUnit.SI)), this.shortDwellTime,
467 false);
468 schedule.addBusStop("De Vleeshoeve", now.plus(new Duration(120.0, DurationUnit.SI)), this.shortDwellTime,
469 false);
470 schedule.addBusStop("Dorpshuys", now.plus(new Duration(200.0, DurationUnit.SI)), this.longDwellTime, true);
471 schedule.addBusStop("De verkeerde afslag", now.plus(new Duration(270.0, DurationUnit.SI)),
472 this.longDwellTime, true);
473 route = schedule;
474 break;
475 }
476 case 2:
477 {
478 gtuType = new GTUType("BUS2", this.network.getGtuType(GTUType.DEFAULTS.SCHEDULED_BUS));
479 length = new Length(12.0, LengthUnit.SI);
480 width = new Length(2.0, LengthUnit.SI);
481 maximumSpeed = new Speed(100.0, SpeedUnit.KM_PER_HOUR);
482 BusSchedule schedule = new BusSchedule("bus2." + this.simulator.getSimulatorTime(), this.busNodes2, "2");
483 Time now = this.simulator.getSimulatorTime();
484 schedule.addBusStop("Cafe Boszicht.2", now.plus(new Duration(80.0, DurationUnit.SI)), this.longDwellTime,
485 true);
486 schedule.addBusStop("De Vleeshoeve", now.plus(new Duration(110.0, DurationUnit.SI)), this.shortDwellTime,
487 false);
488 schedule.addBusStop("Kippenboerderij De Scharrelaar", now.plus(new Duration(180.0, DurationUnit.SI)),
489 this.longDwellTime, false);
490 schedule.addBusStop("De verkeerde afslag", now.plus(new Duration(260.0, DurationUnit.SI)),
491 this.longDwellTime, true);
492 route = schedule;
493 break;
494 }
495 default:
496 throw new RuntimeException("Reaching default of switch case.");
497 }
498
499 GTUCharacteristics gtuCharacteristics = new GTUCharacteristics(gtuType, length, width, maximumSpeed,
500 Acceleration.instantiateSI(3.0), Acceleration.instantiateSI(-8.0), length.times(0.5));
501
502 return new LaneBasedGTUCharacteristics(gtuCharacteristics, this.plannerFactory, route, null, null,
503 VehicleModel.MINMAX);
504 }
505
506 }
507
508
509
510
511
512
513
514
515
516
517
518
519 private static class LMRSFactoryCarBus implements LaneBasedTacticalPlannerFactory<LMRS>
520 {
521
522
523 LMRSFactoryCarBus()
524 {
525 }
526
527
528 @Override
529 public final Parameters getParameters()
530 {
531 ParameterSet parameters = new ParameterSet();
532 parameters.setDefaultParameters(ParameterTypes.class);
533 parameters.setDefaultParameters(LmrsParameters.class);
534 parameters.setDefaultParameters(ConflictUtil.class);
535 parameters.setDefaultParameters(AbstractIDM.class);
536 return parameters;
537 }
538
539
540 @Override
541 public final LMRS create(final LaneBasedGTU gtu) throws GTUException
542 {
543 DefaultLMRSPerceptionFactory pFac = new DefaultLMRSPerceptionFactory();
544 LMRS lmrs = new LMRS(new IDMPlus(), gtu, pFac.generatePerception(gtu), Synchronization.PASSIVE, Cooperation.PASSIVE,
545 GapAcceptance.INFORMED, Tailgating.NONE);
546 lmrs.setDefaultIncentives();
547 if (gtu.getGTUType().isOfType(GTUType.DEFAULTS.SCHEDULED_BUS))
548 {
549 lmrs.addMandatoryIncentive(new IncentiveBusStop());
550 lmrs.addAccelerationIncentive(new AccelerationBusStop());
551 lmrs.getPerception().addPerceptionCategory(new DirectBusStopPerception(lmrs.getPerception()));
552 }
553 return lmrs;
554 }
555
556 }
557
558
559
560
561
562
563
564
565
566
567
568
569 private static class ParameterFactoryCarBus implements ParameterFactory
570 {
571
572
573 ParameterFactoryCarBus()
574 {
575 }
576
577
578 @Override
579 public void setValues(final Parameters parameters, final GTUType gtuType) throws ParameterException
580 {
581
582 parameters.setParameter(ParameterTypes.LOOKAHEAD, new Length(100.0, LengthUnit.METER));
583 if (gtuType.isOfType(GTUType.DEFAULTS.CAR))
584 {
585 parameters.setParameter(LmrsParameters.VGAIN, new Speed(3.0, SpeedUnit.METER_PER_SECOND));
586 }
587 else if (gtuType.isOfType(GTUType.DEFAULTS.SCHEDULED_BUS))
588 {
589 parameters.setParameter(ParameterTypes.A, new Acceleration(0.8, AccelerationUnit.METER_PER_SECOND_2));
590 }
591 else
592 {
593 throw new RuntimeException("Unable to determine characteristics for GTU of type " + gtuType);
594 }
595
596 }
597
598 }
599
600 }