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