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 this.simulator.getReplication().setStreams(streams);
177 try
178 {
179 URL xmlURL = URLResource.getResource("/conflict/BusStreet.xml");
180 this.network = new OTSRoadNetwork("BusStreet", true, getSimulator());
181 XmlNetworkLaneParser.build(xmlURL, this.network, true);
182
183
184 Lane lane = ((CrossSectionLink) this.network.getLink("B1B2")).getLanes().get(0);
185 BusStop stop = new BusStop("Cafe Boszicht.1", lane, lane.getLength(), "Cafe Boszicht", this.simulator);
186 Set<String> lines1 = new LinkedHashSet<>();
187 lines1.add("1");
188 stop.setLines(lines1);
189
190 lane = ((CrossSectionLink) this.network.getLink("C1C2")).getLanes().get(0);
191 stop = new BusStop("Cafe Boszicht.2", lane, lane.getLength(), "Cafe Boszicht", this.simulator);
192 Set<String> lines2 = new LinkedHashSet<>();
193 lines2.add("2");
194 stop.setLines(lines2);
195
196 lane = ((CrossSectionLink) this.network.getLink("EF")).getLanes().get(0);
197 stop = new BusStop("Herberg De Deugd", lane, new Length(75.0, LengthUnit.SI), "Herberg De Deugd",
198 this.simulator);
199 stop.setLines(lines1);
200
201 lane = ((CrossSectionLink) this.network.getLink("FG")).getLanes().get(1);
202 stop = new BusStop("De Vleeshoeve", lane, new Length(75.0, LengthUnit.SI), "De Vleeshoeve", this.simulator);
203 Set<String> lines12 = new LinkedHashSet<>();
204 lines12.add("1");
205 lines12.add("2");
206 stop.setLines(lines12);
207
208 lane = ((CrossSectionLink) this.network.getLink("GH")).getLanes().get(2);
209 stop = new BusStop("Kippenboerderij De Scharrelaar", lane, new Length(50.0, LengthUnit.SI),
210 "Kippenboerderij De Scharrelaar", this.simulator);
211 stop.setLines(lines2);
212
213 lane = ((CrossSectionLink) this.network.getLink("I1I2")).getLanes().get(0);
214 stop = new BusStop("Dorpshuys", lane, lane.getLength(), "Dorpshuys", this.simulator);
215 stop.setLines(lines1);
216
217 lane = ((CrossSectionLink) this.network.getLink("K1K2")).getLanes().get(0);
218 stop = new BusStop("De verkeerde afslag", lane, lane.getLength(), "De verkeerde afslag", this.simulator);
219 stop.setLines(lines12);
220
221 makeGenerator(streams.get("generation"));
222
223 }
224 catch (Exception exception)
225 {
226 exception.printStackTrace();
227 }
228 }
229
230
231 @Override
232 public OTSRoadNetwork getNetwork()
233 {
234 return this.network;
235 }
236
237
238
239
240
241
242
243
244
245 private void makeGenerator(final StreamInterface stream)
246 throws GTUException, SimRuntimeException, ProbabilityException, ParameterException
247 {
248 Lane lane = ((CrossSectionLink) this.network.getLink("AB")).getLanes().get(0);
249 String id = lane.getId();
250 Set<DirectedLanePosition> initialLongitudinalPositions = new LinkedHashSet<>();
251 initialLongitudinalPositions
252 .add(new DirectedLanePosition(lane, new Length(10.0, LengthUnit.SI), GTUDirectionality.DIR_PLUS));
253 Generator<Duration> headwayGenerator =
254 new HeadwayGenerator(new Frequency(800, FrequencyUnit.PER_HOUR), this.simulator);
255 LaneBasedGTUCharacteristicsGenerator characteristicsGenerator =
256 new CharacteristicsGenerator(this.simulator, new double[] {0.9, 0.06, 0.04}, this.network);
257 RoomChecker roomChecker = new TTCRoomChecker(new Duration(10.0, DurationUnit.SI));
258 LaneBasedGTUGenerator gen = new LaneBasedGTUGenerator(id, headwayGenerator, characteristicsGenerator,
259 GeneratorPositions.create(initialLongitudinalPositions, stream), this.network, this.simulator, roomChecker,
260 new IdGenerator(""));
261 gen.setInstantaneousLaneChange(true);
262 }
263
264
265 @Override
266 public Serializable getSourceId()
267 {
268 return "BusStreetModel";
269 }
270 }
271
272
273
274
275
276
277
278
279
280
281
282
283 private static class HeadwayGenerator implements Generator<Duration>
284 {
285
286
287 private final Frequency demand;
288
289
290 private final SimulatorInterface.TimeDoubleUnit simulator;
291
292
293
294
295
296 HeadwayGenerator(final Frequency demand, final SimulatorInterface.TimeDoubleUnit simulator)
297 {
298 this.demand = demand;
299 this.simulator = simulator;
300 }
301
302
303 @Override
304 public Duration draw() throws ProbabilityException, ParameterException
305 {
306 return new Duration(
307 -Math.log(this.simulator.getReplication().getStream("generation").nextDouble()) / this.demand.si,
308 DurationUnit.SI);
309 }
310
311 }
312
313
314
315
316
317
318
319
320
321
322
323
324 public static class CharacteristicsGenerator implements LaneBasedGTUCharacteristicsGenerator
325 {
326
327
328 private final DEVSSimulatorInterface.TimeDoubleUnit simulator;
329
330
331 private final double[] probabilities;
332
333
334 private final LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> plannerFactory;
335
336
337 private final Route carRouteN;
338
339
340 private final Route carRouteO;
341
342
343 private final List<Node> busNodes1;
344
345
346 private final List<Node> busNodes2;
347
348
349 private final Duration shortDwellTime = new Duration(15.0, DurationUnit.SI);
350
351
352 private final Duration longDwellTime = new Duration(60.0, DurationUnit.SI);
353
354
355 private OTSRoadNetwork network;
356
357
358
359
360
361
362 public CharacteristicsGenerator(final DEVSSimulatorInterface.TimeDoubleUnit simulator, final double[] probabilities,
363 final OTSRoadNetwork network)
364 {
365 this.simulator = simulator;
366 this.probabilities = probabilities;
367 this.network = network;
368 List<Node> carNodesN = new ArrayList<>();
369 carNodesN.add(network.getNode("A"));
370 carNodesN.add(network.getNode("B"));
371 carNodesN.add(network.getNode("C"));
372 carNodesN.add(network.getNode("D"));
373 carNodesN.add(network.getNode("E"));
374 carNodesN.add(network.getNode("F"));
375 carNodesN.add(network.getNode("G"));
376 carNodesN.add(network.getNode("H"));
377 carNodesN.add(network.getNode("I"));
378 carNodesN.add(network.getNode("J"));
379 carNodesN.add(network.getNode("K"));
380 carNodesN.add(network.getNode("L"));
381 carNodesN.add(network.getNode("M"));
382 List<Node> carNodesO = new ArrayList<>(carNodesN);
383 carNodesN.add(network.getNode("N"));
384 carNodesO.add(network.getNode("O"));
385 this.carRouteN = new Route("carN", carNodesN);
386 this.carRouteO = new Route("carO", carNodesO);
387 this.busNodes1 = new ArrayList<>();
388 this.busNodes1.add(network.getNode("A"));
389 this.busNodes1.add(network.getNode("B"));
390 this.busNodes1.add(network.getNode("B1"));
391 this.busNodes1.add(network.getNode("B2"));
392 this.busNodes1.add(network.getNode("D"));
393 this.busNodes1.add(network.getNode("E"));
394 this.busNodes1.add(network.getNode("F"));
395 this.busNodes1.add(network.getNode("G"));
396 this.busNodes1.add(network.getNode("H"));
397 this.busNodes1.add(network.getNode("I"));
398 this.busNodes1.add(network.getNode("I1"));
399 this.busNodes1.add(network.getNode("I2"));
400 this.busNodes1.add(network.getNode("J"));
401 this.busNodes1.add(network.getNode("K"));
402 this.busNodes1.add(network.getNode("K1"));
403 this.busNodes1.add(network.getNode("K2"));
404 this.busNodes1.add(network.getNode("L"));
405 this.busNodes1.add(network.getNode("M"));
406 this.busNodes1.add(network.getNode("N"));
407
408 this.busNodes2 = new ArrayList<>();
409 this.busNodes2.add(network.getNode("A"));
410 this.busNodes2.add(network.getNode("B"));
411 this.busNodes2.add(network.getNode("C"));
412 this.busNodes2.add(network.getNode("C1"));
413 this.busNodes2.add(network.getNode("C2"));
414 this.busNodes2.add(network.getNode("E"));
415 this.busNodes2.add(network.getNode("F"));
416 this.busNodes2.add(network.getNode("G"));
417 this.busNodes2.add(network.getNode("H"));
418 this.busNodes2.add(network.getNode("I"));
419 this.busNodes2.add(network.getNode("J"));
420 this.busNodes2.add(network.getNode("K"));
421 this.busNodes2.add(network.getNode("K1"));
422 this.busNodes2.add(network.getNode("K2"));
423 this.busNodes2.add(network.getNode("K3"));
424 this.busNodes2.add(network.getNode("L"));
425 this.busNodes2.add(network.getNode("M"));
426 this.busNodes2.add(network.getNode("O"));
427
428 this.plannerFactory =
429 new LaneBasedStrategicalRoutePlannerFactory(new LMRSFactoryCarBus(), new ParameterFactoryCarBus());
430 }
431
432
433 @Override
434 public LaneBasedGTUCharacteristics draw() throws ProbabilityException, ParameterException, GTUException
435 {
436 double r = this.simulator.getReplication().getStream("generation").nextDouble();
437 int classNum = r < this.probabilities[0] ? 0 : r < this.probabilities[0] + this.probabilities[1] ? 1 : 2;
438 r = this.simulator.getReplication().getStream("generation").nextDouble();
439 GTUType gtuType;
440 Length length;
441 Length width;
442 Speed maximumSpeed;
443 Route route;
444 switch (classNum)
445 {
446 case 0:
447 {
448 gtuType = new GTUType("CAR", this.network.getGtuType(GTUType.DEFAULTS.CAR));
449 length = new Length(4.0, LengthUnit.SI);
450 width = new Length(1.8, LengthUnit.SI);
451 maximumSpeed = new Speed(200.0, SpeedUnit.KM_PER_HOUR);
452 route = r < 0.5 ? this.carRouteN : this.carRouteO;
453 break;
454 }
455 case 1:
456 {
457 gtuType = new GTUType("BUS1", this.network.getGtuType(GTUType.DEFAULTS.SCHEDULED_BUS));
458 length = new Length(8.0, LengthUnit.SI);
459 width = new Length(2.0, LengthUnit.SI);
460 maximumSpeed = new Speed(100.0, SpeedUnit.KM_PER_HOUR);
461 BusSchedule schedule = new BusSchedule("bus1." + this.simulator.getSimulatorTime(), this.busNodes1, "1");
462 Time now = this.simulator.getSimulatorTime();
463 schedule.addBusStop("Cafe Boszicht.1", now.plus(new Duration(70.0, DurationUnit.SI)), this.longDwellTime,
464 true);
465 schedule.addBusStop("Herberg De Deugd", now.plus(new Duration(100.0, DurationUnit.SI)), this.shortDwellTime,
466 false);
467 schedule.addBusStop("De Vleeshoeve", now.plus(new Duration(120.0, DurationUnit.SI)), this.shortDwellTime,
468 false);
469 schedule.addBusStop("Dorpshuys", now.plus(new Duration(200.0, DurationUnit.SI)), this.longDwellTime, true);
470 schedule.addBusStop("De verkeerde afslag", now.plus(new Duration(270.0, DurationUnit.SI)),
471 this.longDwellTime, true);
472 route = schedule;
473 break;
474 }
475 case 2:
476 {
477 gtuType = new GTUType("BUS2", this.network.getGtuType(GTUType.DEFAULTS.SCHEDULED_BUS));
478 length = new Length(12.0, LengthUnit.SI);
479 width = new Length(2.0, LengthUnit.SI);
480 maximumSpeed = new Speed(100.0, SpeedUnit.KM_PER_HOUR);
481 BusSchedule schedule = new BusSchedule("bus2." + this.simulator.getSimulatorTime(), this.busNodes2, "2");
482 Time now = this.simulator.getSimulatorTime();
483 schedule.addBusStop("Cafe Boszicht.2", now.plus(new Duration(80.0, DurationUnit.SI)), this.longDwellTime,
484 true);
485 schedule.addBusStop("De Vleeshoeve", now.plus(new Duration(110.0, DurationUnit.SI)), this.shortDwellTime,
486 false);
487 schedule.addBusStop("Kippenboerderij De Scharrelaar", now.plus(new Duration(180.0, DurationUnit.SI)),
488 this.longDwellTime, false);
489 schedule.addBusStop("De verkeerde afslag", now.plus(new Duration(260.0, DurationUnit.SI)),
490 this.longDwellTime, true);
491 route = schedule;
492 break;
493 }
494 default:
495 throw new RuntimeException("Reaching default of switch case.");
496 }
497
498 GTUCharacteristics gtuCharacteristics = new GTUCharacteristics(gtuType, length, width, maximumSpeed,
499 Acceleration.instantiateSI(3.0), Acceleration.instantiateSI(-8.0), length.times(0.5));
500
501 return new LaneBasedGTUCharacteristics(gtuCharacteristics, this.plannerFactory, route, null, null,
502 VehicleModel.MINMAX);
503 }
504
505 }
506
507
508
509
510
511
512
513
514
515
516
517
518 private static class LMRSFactoryCarBus implements LaneBasedTacticalPlannerFactory<LMRS>
519 {
520
521
522 LMRSFactoryCarBus()
523 {
524 }
525
526
527 @Override
528 public final Parameters getParameters()
529 {
530 ParameterSet parameters = new ParameterSet();
531 parameters.setDefaultParameters(ParameterTypes.class);
532 parameters.setDefaultParameters(LmrsParameters.class);
533 parameters.setDefaultParameters(ConflictUtil.class);
534 parameters.setDefaultParameters(AbstractIDM.class);
535 return parameters;
536 }
537
538
539 @Override
540 public final LMRS create(final LaneBasedGTU gtu) throws GTUException
541 {
542 DefaultLMRSPerceptionFactory pFac = new DefaultLMRSPerceptionFactory();
543 LMRS lmrs = new LMRS(new IDMPlus(), gtu, pFac.generatePerception(gtu), Synchronization.PASSIVE, Cooperation.PASSIVE,
544 GapAcceptance.INFORMED, Tailgating.NONE);
545 lmrs.setDefaultIncentives();
546 if (gtu.getGTUType().isOfType(GTUType.DEFAULTS.SCHEDULED_BUS))
547 {
548 lmrs.addMandatoryIncentive(new IncentiveBusStop());
549 lmrs.addAccelerationIncentive(new AccelerationBusStop());
550 lmrs.getPerception().addPerceptionCategory(new DirectBusStopPerception(lmrs.getPerception()));
551 }
552 return lmrs;
553 }
554
555 }
556
557
558
559
560
561
562
563
564
565
566
567
568 private static class ParameterFactoryCarBus implements ParameterFactory
569 {
570
571
572 ParameterFactoryCarBus()
573 {
574 }
575
576
577 @Override
578 public void setValues(final Parameters parameters, final GTUType gtuType) throws ParameterException
579 {
580
581 parameters.setParameter(ParameterTypes.LOOKAHEAD, new Length(100.0, LengthUnit.METER));
582 if (gtuType.isOfType(GTUType.DEFAULTS.CAR))
583 {
584 parameters.setParameter(LmrsParameters.VGAIN, new Speed(3.0, SpeedUnit.METER_PER_SECOND));
585 }
586 else if (gtuType.isOfType(GTUType.DEFAULTS.SCHEDULED_BUS))
587 {
588 parameters.setParameter(ParameterTypes.A, new Acceleration(0.8, AccelerationUnit.METER_PER_SECOND_2));
589 }
590 else
591 {
592 throw new RuntimeException("Unable to determine characteristics for GTU of type " + gtuType);
593 }
594
595 }
596
597 }
598
599 }