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