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