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.gtu.behavioralcharacteristics.ParameterFactory;
41 import org.opentrafficsim.core.idgenerator.IdGenerator;
42 import org.opentrafficsim.core.network.Node;
43 import org.opentrafficsim.core.network.OTSNetwork;
44 import org.opentrafficsim.core.network.route.Route;
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.factory.xml.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.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 OTSNetwork 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 OTSNetwork 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 XmlNetworkLaneParser nlp = new XmlNetworkLaneParser(this.simulator);
179 this.network = nlp.build(url, false);
180 ConflictBuilder.buildConflicts(this.network, GTUType.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 OTSNetwork 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
348
349
350
351 public CharacteristicsGenerator(final DEVSSimulatorInterface.TimeDoubleUnit simulator, final double[] probabilities,
352 final OTSNetwork network)
353 {
354 this.simulator = simulator;
355 this.probabilities = probabilities;
356 List<Node> carNodesN = new ArrayList<>();
357 carNodesN.add(network.getNode("A"));
358 carNodesN.add(network.getNode("B"));
359 carNodesN.add(network.getNode("C"));
360 carNodesN.add(network.getNode("D"));
361 carNodesN.add(network.getNode("E"));
362 carNodesN.add(network.getNode("F"));
363 carNodesN.add(network.getNode("G"));
364 carNodesN.add(network.getNode("H"));
365 carNodesN.add(network.getNode("I"));
366 carNodesN.add(network.getNode("J"));
367 carNodesN.add(network.getNode("K"));
368 carNodesN.add(network.getNode("L"));
369 carNodesN.add(network.getNode("M"));
370 List<Node> carNodesO = new ArrayList<>(carNodesN);
371 carNodesN.add(network.getNode("N"));
372 carNodesO.add(network.getNode("O"));
373 this.carRouteN = new Route("carN", carNodesN);
374 this.carRouteO = new Route("carO", carNodesO);
375 this.busNodes1 = new ArrayList<>();
376 this.busNodes1.add(network.getNode("A"));
377 this.busNodes1.add(network.getNode("B"));
378 this.busNodes1.add(network.getNode("B1"));
379 this.busNodes1.add(network.getNode("B2"));
380 this.busNodes1.add(network.getNode("D"));
381 this.busNodes1.add(network.getNode("E"));
382 this.busNodes1.add(network.getNode("F"));
383 this.busNodes1.add(network.getNode("G"));
384 this.busNodes1.add(network.getNode("H"));
385 this.busNodes1.add(network.getNode("I"));
386 this.busNodes1.add(network.getNode("I1"));
387 this.busNodes1.add(network.getNode("I2"));
388 this.busNodes1.add(network.getNode("J"));
389 this.busNodes1.add(network.getNode("K"));
390 this.busNodes1.add(network.getNode("K1"));
391 this.busNodes1.add(network.getNode("K2"));
392 this.busNodes1.add(network.getNode("L"));
393 this.busNodes1.add(network.getNode("M"));
394 this.busNodes1.add(network.getNode("N"));
395
396 this.busNodes2 = new ArrayList<>();
397 this.busNodes2.add(network.getNode("A"));
398 this.busNodes2.add(network.getNode("B"));
399 this.busNodes2.add(network.getNode("C"));
400 this.busNodes2.add(network.getNode("C1"));
401 this.busNodes2.add(network.getNode("C2"));
402 this.busNodes2.add(network.getNode("E"));
403 this.busNodes2.add(network.getNode("F"));
404 this.busNodes2.add(network.getNode("G"));
405 this.busNodes2.add(network.getNode("H"));
406 this.busNodes2.add(network.getNode("I"));
407 this.busNodes2.add(network.getNode("J"));
408 this.busNodes2.add(network.getNode("K"));
409 this.busNodes2.add(network.getNode("K1"));
410 this.busNodes2.add(network.getNode("K2"));
411 this.busNodes2.add(network.getNode("K3"));
412 this.busNodes2.add(network.getNode("L"));
413 this.busNodes2.add(network.getNode("M"));
414 this.busNodes2.add(network.getNode("O"));
415
416 this.plannerFactory =
417 new LaneBasedStrategicalRoutePlannerFactory(new LMRSFactoryCarBus(), new ParameterFactoryCarBus());
418 }
419
420
421 @Override
422 public LaneBasedGTUCharacteristics draw() throws ProbabilityException, ParameterException, GTUException
423 {
424
425 double r = this.simulator.getReplication().getStream("generation").nextDouble();
426 int classNum = r < this.probabilities[0] ? 0 : r < this.probabilities[0] + this.probabilities[1] ? 1 : 2;
427 r = this.simulator.getReplication().getStream("generation").nextDouble();
428 GTUType gtuType;
429 Length length;
430 Length width;
431 Speed maximumSpeed;
432 Route route;
433 switch (classNum)
434 {
435 case 0:
436 {
437 gtuType = new GTUType("CAR", GTUType.CAR);
438 length = new Length(4.0, LengthUnit.SI);
439 width = new Length(1.8, LengthUnit.SI);
440 maximumSpeed = new Speed(200.0, SpeedUnit.KM_PER_HOUR);
441 route = r < 0.5 ? this.carRouteN : this.carRouteO;
442 break;
443 }
444 case 1:
445 {
446 gtuType = new GTUType("BUS1", GTUType.SCHEDULED_BUS);
447 length = new Length(8.0, LengthUnit.SI);
448 width = new Length(2.0, LengthUnit.SI);
449 maximumSpeed = new Speed(100.0, SpeedUnit.KM_PER_HOUR);
450 BusSchedule schedule = new BusSchedule("bus1." + this.simulator.getSimulatorTime(), this.busNodes1, "1");
451 Time now = this.simulator.getSimulatorTime();
452 schedule.addBusStop("Cafe Boszicht.1", now.plus(new Duration(70.0, DurationUnit.SI)), this.longDwellTime,
453 true);
454 schedule.addBusStop("Herberg De Deugd", now.plus(new Duration(100.0, DurationUnit.SI)), this.shortDwellTime,
455 false);
456 schedule.addBusStop("De Vleeshoeve", now.plus(new Duration(120.0, DurationUnit.SI)), this.shortDwellTime,
457 false);
458 schedule.addBusStop("Dorpshuys", now.plus(new Duration(200.0, DurationUnit.SI)), this.longDwellTime, true);
459 schedule.addBusStop("De verkeerde afslag", now.plus(new Duration(270.0, DurationUnit.SI)),
460 this.longDwellTime, true);
461 route = schedule;
462 break;
463 }
464 case 2:
465 {
466 gtuType = new GTUType("BUS2", GTUType.SCHEDULED_BUS);
467 length = new Length(12.0, LengthUnit.SI);
468 width = new Length(2.0, LengthUnit.SI);
469 maximumSpeed = new Speed(100.0, SpeedUnit.KM_PER_HOUR);
470 BusSchedule schedule = new BusSchedule("bus2." + this.simulator.getSimulatorTime(), this.busNodes2, "2");
471 Time now = this.simulator.getSimulatorTime();
472 schedule.addBusStop("Cafe Boszicht.2", now.plus(new Duration(80.0, DurationUnit.SI)), this.longDwellTime,
473 true);
474 schedule.addBusStop("De Vleeshoeve", now.plus(new Duration(110.0, DurationUnit.SI)), this.shortDwellTime,
475 false);
476 schedule.addBusStop("Kippenboerderij De Scharrelaar", now.plus(new Duration(180.0, DurationUnit.SI)),
477 this.longDwellTime, false);
478 schedule.addBusStop("De verkeerde afslag", now.plus(new Duration(260.0, DurationUnit.SI)),
479 this.longDwellTime, true);
480 route = schedule;
481 break;
482 }
483 default:
484 throw new RuntimeException("Reaching default of switch case.");
485 }
486
487 GTUCharacteristics gtuCharacteristics = new GTUCharacteristics(gtuType, length, width, maximumSpeed,
488 Acceleration.createSI(3.0), Acceleration.createSI(-8.0), length.multiplyBy(0.5));
489
490 return new LaneBasedGTUCharacteristics(gtuCharacteristics, this.plannerFactory, route, null, null,
491 VehicleModel.MINMAX);
492 }
493
494 }
495
496
497
498
499
500
501
502
503
504
505
506
507 private static class LMRSFactoryCarBus implements LaneBasedTacticalPlannerFactory<LMRS>
508 {
509
510
511 LMRSFactoryCarBus()
512 {
513 }
514
515
516 @Override
517 public final Parameters getParameters()
518 {
519 ParameterSet parameters = new ParameterSet();
520 parameters.setDefaultParameters(ParameterTypes.class);
521 parameters.setDefaultParameters(LmrsParameters.class);
522 parameters.setDefaultParameters(ConflictUtil.class);
523 parameters.setDefaultParameters(AbstractIDM.class);
524 return parameters;
525 }
526
527
528 @Override
529 public final LMRS create(final LaneBasedGTU gtu) throws GTUException
530 {
531 DefaultLMRSPerceptionFactory pFac = new DefaultLMRSPerceptionFactory();
532 LMRS lmrs = new LMRS(new IDMPlus(), gtu, pFac.generatePerception(gtu), Synchronization.PASSIVE, Cooperation.PASSIVE,
533 GapAcceptance.INFORMED, Tailgating.NONE);
534 lmrs.setDefaultIncentives();
535 if (gtu.getGTUType().isOfType(GTUType.SCHEDULED_BUS))
536 {
537 lmrs.addMandatoryIncentive(new IncentiveBusStop());
538 lmrs.addAccelerationIncentive(new AccelerationBusStop());
539 lmrs.getPerception().addPerceptionCategory(new DirectBusStopPerception(lmrs.getPerception()));
540 }
541 return lmrs;
542 }
543
544 }
545
546
547
548
549
550
551
552
553
554
555
556
557 private static class ParameterFactoryCarBus implements ParameterFactory
558 {
559
560
561 ParameterFactoryCarBus()
562 {
563 }
564
565
566 @Override
567 public void setValues(final Parameters parameters, final GTUType gtuType) throws ParameterException
568 {
569
570 parameters.setParameter(ParameterTypes.LOOKAHEAD, new Length(100.0, LengthUnit.METER));
571 if (gtuType.isOfType(GTUType.CAR))
572 {
573 parameters.setParameter(LmrsParameters.VGAIN, new Speed(3.0, SpeedUnit.METER_PER_SECOND));
574 }
575 else if (gtuType.isOfType(GTUType.SCHEDULED_BUS))
576 {
577 parameters.setParameter(ParameterTypes.A, new Acceleration(0.8, AccelerationUnit.METER_PER_SECOND_2));
578 }
579 else
580 {
581 throw new RuntimeException("Unable to determine characteristics for GTU of type " + gtuType);
582 }
583
584 }
585
586 }
587
588 }