1 package org.opentrafficsim.demo.carFollowing;
2
3 import java.awt.Color;
4 import java.awt.Container;
5 import java.awt.Frame;
6 import java.awt.geom.Rectangle2D;
7 import java.rmi.RemoteException;
8 import java.util.ArrayList;
9 import java.util.HashSet;
10 import java.util.Iterator;
11 import java.util.LinkedHashSet;
12 import java.util.List;
13 import java.util.Set;
14
15 import javax.naming.NamingException;
16 import javax.swing.JPanel;
17
18 import nl.tudelft.simulation.dsol.SimRuntimeException;
19 import nl.tudelft.simulation.dsol.gui.swing.TablePanel;
20 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
21 import nl.tudelft.simulation.jstats.distributions.DistContinuous;
22 import nl.tudelft.simulation.jstats.distributions.DistErlang;
23 import nl.tudelft.simulation.jstats.distributions.DistUniform;
24 import nl.tudelft.simulation.jstats.streams.MersenneTwister;
25 import nl.tudelft.simulation.jstats.streams.StreamInterface;
26
27 import org.djunits.unit.LengthUnit;
28 import org.djunits.unit.SpeedUnit;
29 import org.djunits.unit.TimeUnit;
30 import org.djunits.unit.UNITS;
31 import org.djunits.value.vdouble.scalar.Acceleration;
32 import org.djunits.value.vdouble.scalar.DoubleScalar;
33 import org.djunits.value.vdouble.scalar.DoubleScalar.Abs;
34 import org.djunits.value.vdouble.scalar.Duration;
35 import org.djunits.value.vdouble.scalar.Length;
36 import org.djunits.value.vdouble.scalar.Speed;
37 import org.djunits.value.vdouble.scalar.Time;
38 import org.opentrafficsim.core.distributions.Distribution;
39 import org.opentrafficsim.core.distributions.Distribution.FrequencyAndObject;
40 import org.opentrafficsim.core.distributions.Generator;
41 import org.opentrafficsim.core.distributions.ProbabilityException;
42 import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
43 import org.opentrafficsim.core.dsol.OTSModelInterface;
44 import org.opentrafficsim.core.dsol.OTSSimTimeDouble;
45 import org.opentrafficsim.core.geometry.OTSGeometryException;
46 import org.opentrafficsim.core.geometry.OTSPoint3D;
47 import org.opentrafficsim.core.gtu.GTU;
48 import org.opentrafficsim.core.gtu.GTUDirectionality;
49 import org.opentrafficsim.core.gtu.GTUException;
50 import org.opentrafficsim.core.gtu.GTUType;
51 import org.opentrafficsim.core.gtu.animation.GTUColorer;
52 import org.opentrafficsim.core.gtu.animation.SwitchableGTUColorer;
53 import org.opentrafficsim.core.gtu.behavioralcharacteristics.BehavioralCharacteristics;
54 import org.opentrafficsim.core.idgenerator.IdGenerator;
55 import org.opentrafficsim.core.network.LongitudinalDirectionality;
56 import org.opentrafficsim.core.network.NetworkException;
57 import org.opentrafficsim.core.network.Node;
58 import org.opentrafficsim.core.network.OTSNetwork;
59 import org.opentrafficsim.core.network.OTSNode;
60 import org.opentrafficsim.core.network.route.FixedRouteGenerator;
61 import org.opentrafficsim.core.network.route.ProbabilisticRouteGenerator;
62 import org.opentrafficsim.core.network.route.Route;
63 import org.opentrafficsim.core.network.route.RouteGenerator;
64 import org.opentrafficsim.core.units.distributions.ContinuousDistDoubleScalar;
65 import org.opentrafficsim.graphs.LaneBasedGTUSampler;
66 import org.opentrafficsim.graphs.TrajectoryPlot;
67 import org.opentrafficsim.road.gtu.animation.DefaultCarAnimation;
68 import org.opentrafficsim.road.gtu.generator.LaneBasedGTUGenerator;
69 import org.opentrafficsim.road.gtu.lane.AbstractLaneBasedGTU;
70 import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
71 import org.opentrafficsim.road.gtu.lane.LaneBasedTemplateGTUType;
72 import org.opentrafficsim.road.gtu.lane.LaneBasedTemplateGTUTypeDistribution;
73 import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedCFLCTacticalPlannerFactory;
74 import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedGTUFollowingChange0TacticalPlannerFactory;
75 import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedGTUFollowingLaneChangeTacticalPlannerFactory;
76 import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedGTUFollowingTacticalPlanner;
77 import org.opentrafficsim.road.gtu.lane.tactical.following.AbstractIDM;
78 import org.opentrafficsim.road.gtu.lane.tactical.following.GTUFollowingModelOld;
79 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMOld;
80 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlus;
81 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusOld;
82 import org.opentrafficsim.road.gtu.lane.tactical.lanechangemobil.AbstractLaneChangeModel;
83 import org.opentrafficsim.road.gtu.lane.tactical.lanechangemobil.Altruistic;
84 import org.opentrafficsim.road.gtu.lane.tactical.lanechangemobil.Egoistic;
85 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRSFactory;
86 import org.opentrafficsim.road.gtu.lane.tactical.toledo.ToledoFactory;
87 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
88 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
89 import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlanner;
90 import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
91 import org.opentrafficsim.road.network.factory.LaneFactory;
92 import org.opentrafficsim.road.network.lane.CrossSectionLink;
93 import org.opentrafficsim.road.network.lane.DirectedLanePosition;
94 import org.opentrafficsim.road.network.lane.Lane;
95 import org.opentrafficsim.road.network.lane.LaneType;
96 import org.opentrafficsim.road.network.lane.Sensor;
97 import org.opentrafficsim.road.network.lane.SinkSensor;
98 import org.opentrafficsim.road.network.lane.changing.OvertakingConditions;
99 import org.opentrafficsim.simulationengine.AbstractWrappableAnimation;
100 import org.opentrafficsim.simulationengine.properties.AbstractProperty;
101 import org.opentrafficsim.simulationengine.properties.CompoundProperty;
102 import org.opentrafficsim.simulationengine.properties.ContinuousProperty;
103 import org.opentrafficsim.simulationengine.properties.IDMPropertySet;
104 import org.opentrafficsim.simulationengine.properties.ProbabilityDistributionProperty;
105 import org.opentrafficsim.simulationengine.properties.PropertyException;
106 import org.opentrafficsim.simulationengine.properties.SelectionProperty;
107
108
109
110
111
112
113
114
115
116
117
118 public class XMLNetworks extends AbstractWrappableAnimation implements UNITS
119 {
120
121 private static final long serialVersionUID = 20160422L;
122
123
124 private XMLNetworkModel model;
125
126
127
128
129 public XMLNetworks()
130 {
131 this.properties.add(new SelectionProperty("Network", "Network", "Network", new String[] {"Merge 1 plus 1 into 1",
132 "Merge 2 plus 1 into 2", "Merge 2 plus 2 into 4", "Split 1 into 1 plus 1", "Split 2 into 1 plus 2",
133 "Split 4 into 2 plus 2"}, 0, false, 0));
134 this.properties.add(new SelectionProperty("TacticalPlanner", "Tactical planner",
135 "<html>The tactical planner determines if a lane change is desired and possible.</html>", new String[] {"MOBIL",
136 "Verbraeck", "Verbraeck0"}, 0, false, 600));
137 this.properties.add(new SelectionProperty("LaneChanging", "Lane changing",
138 "<html>The lane change friendliness (if used -- eg just for MOBIL.</html>", new String[] {"Egoistic",
139 "Altruistic"}, 0, false, 600));
140 this.properties.add(new ContinuousProperty("FlowPerInputLane", "Flow per input lane", "Traffic flow per input lane",
141 500d, 0d, 3000d, "%.0f veh/h", false, 1));
142 }
143
144
145 @Override
146 public final void stopTimersThreads()
147 {
148 super.stopTimersThreads();
149 this.model = null;
150 }
151
152
153 @Override
154 protected final Rectangle2D.Double makeAnimationRectangle()
155 {
156 return new Rectangle2D.Double(-50, -300, 1300, 600);
157 }
158
159
160 @Override
161 protected final OTSModelInterface makeModel(final GTUColorer colorer)
162 {
163 this.model = new XMLNetworkModel(this.savedUserModifiedProperties, colorer);
164 return this.model;
165 }
166
167
168 @Override
169 protected final JPanel makeCharts()
170 {
171 int graphCount = this.model.pathCount();
172 int columns = 1;
173 int rows = 0 == columns ? 0 : (int) Math.ceil(graphCount * 1.0 / columns);
174 TablePanel charts = new TablePanel(columns, rows);
175 for (int graphIndex = 0; graphIndex < graphCount; graphIndex++)
176 {
177 TrajectoryPlot tp =
178 new TrajectoryPlot("Trajectories on lane " + (graphIndex + 1), new Duration(0.5, SECOND), this.model
179 .getPath(graphIndex));
180 tp.setTitle("Trajectory Graph");
181 tp.setExtendedState(Frame.MAXIMIZED_BOTH);
182 LaneBasedGTUSampler graph = tp;
183 Container container = tp.getContentPane();
184 charts.setCell(container, graphIndex % columns, graphIndex / columns);
185 this.model.getPlots().add(graph);
186 }
187 return charts;
188 }
189
190
191 @Override
192 public final String shortName()
193 {
194 return "Test networks";
195 }
196
197
198 @Override
199 public final String description()
200 {
201 return "<html><h1>Test Networks</h1>Prove that the test networks can be constructed and rendered on screen "
202 + "and that a mix of cars and trucks can run on them.<br>On the statistics tab, a trajectory plot "
203 + "is generated for each lane.</html>";
204 }
205
206 }
207
208
209
210
211
212
213
214
215
216
217
218 class XMLNetworkModel implements OTSModelInterface, UNITS
219 {
220
221 private static final long serialVersionUID = 20150304L;
222
223
224 private OTSDEVSSimulatorInterface simulator;
225
226
227 private OTSNetwork network = new OTSNetwork("network");
228
229
230 private ArrayList<LaneBasedGTUSampler> plots = new ArrayList<>();
231
232
233 private ArrayList<AbstractProperty<?>> properties = null;
234
235
236 private ArrayList<List<Lane>> paths = new ArrayList<>();
237
238
239 private Duration averageHeadway;
240
241
242 private Duration minimumHeadway;
243
244
245 DistContinuous headwayGenerator;
246
247
248 private Speed speedLimit = new Speed(60, KM_PER_HOUR);
249
250
251
252
253
254 GTUType gtuType = new GTUType("Car");
255
256
257 private GTUFollowingModelOld carFollowingModelCars;
258
259
260 private GTUFollowingModelOld carFollowingModelTrucks;
261
262
263 AbstractLaneChangeModel laneChangeModel = new Egoistic();
264
265
266 private double carProbability;
267
268
269
270
271
272
273
274
275 RouteGenerator routeGenerator;
276
277
278 private final GTUColorer gtuColorer;
279
280
281 private LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerGeneratorCars = null;
282
283
284 private LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerGeneratorTrucks = null;
285
286
287 IdGenerator idGenerator = new IdGenerator("");
288
289
290
291
292
293 XMLNetworkModel(final ArrayList<AbstractProperty<?>> userModifiedProperties, final GTUColorer gtuColorer)
294 {
295 this.gtuColorer = gtuColorer;
296 if (this.gtuColorer instanceof SwitchableGTUColorer)
297 {
298
299
300
301 }
302
303 this.properties = userModifiedProperties;
304 }
305
306
307
308
309
310 public final List<Lane> getPath(final int index)
311 {
312 return this.paths.get(index);
313 }
314
315
316
317
318
319 public final int pathCount()
320 {
321 return this.paths.size();
322 }
323
324
325
326
327 public final ArrayList<LaneBasedGTUSampler> getPlots()
328 {
329 return this.plots;
330 }
331
332
333 @Override
334 public final void constructModel(
335 final SimulatorInterface<DoubleScalar.Abs<TimeUnit>, DoubleScalar.Rel<TimeUnit>, OTSSimTimeDouble> theSimulator)
336 throws SimRuntimeException, RemoteException
337 {
338 this.simulator = (OTSDEVSSimulatorInterface) theSimulator;
339 OTSNode from = new OTSNode("From", new OTSPoint3D(0, 0, 0));
340 OTSNode end = new OTSNode("End", new OTSPoint3D(2000, 0, 0));
341 OTSNode from2a = new OTSNode("From2a", new OTSPoint3D(0, -50, 0));
342 OTSNode from2b = new OTSNode("From2b", new OTSPoint3D(490, -2, 0));
343 OTSNode firstVia = new OTSNode("Via1", new OTSPoint3D(500, 0, 0));
344 OTSNode end2a = new OTSNode("End2a", new OTSPoint3D(1020, -2, 0));
345 OTSNode end2b = new OTSNode("End2b", new OTSPoint3D(2000, -50, 0));
346 OTSNode secondVia = new OTSNode("Via2", new OTSPoint3D(1000, 0, 0));
347 CompoundProperty cp = null;
348 try
349 {
350 cp = new CompoundProperty("", "", "", this.properties, false, 0);
351 }
352 catch (PropertyException exception2)
353 {
354 exception2.printStackTrace();
355 }
356 String networkType = (String) cp.findByKey("Network").getValue();
357 boolean merge = networkType.startsWith("M");
358 int lanesOnMain = Integer.parseInt(networkType.split(" ")[merge ? 1 : 5]);
359 int lanesOnBranch = Integer.parseInt(networkType.split(" ")[3]);
360 int lanesOnCommon = lanesOnMain + lanesOnBranch;
361 int lanesOnCommonCompressed = Integer.parseInt(networkType.split(" ")[merge ? 5 : 1]);
362
363 Set<GTUType> compatibility = new HashSet<>();
364 compatibility.add(this.gtuType);
365 LaneType laneType = new LaneType("CarLane", compatibility);
366 try
367 {
368
369
370 String carFollowingModelName = null;
371 CompoundProperty propertyContainer = new CompoundProperty("", "", "", this.properties, false, 0);
372 AbstractProperty<?> cfmp = propertyContainer.findByKey("CarFollowingModel");
373 if (null == cfmp)
374 {
375 throw new Error("Cannot find \"Car following model\" property");
376 }
377 if (cfmp instanceof SelectionProperty)
378 {
379 carFollowingModelName = ((SelectionProperty) cfmp).getValue();
380 }
381 else
382 {
383 throw new Error("\"Car following model\" property has wrong type");
384 }
385
386
387 Iterator<AbstractProperty<List<AbstractProperty<?>>>> iterator =
388 new CompoundProperty("", "", "", this.properties, false, 0).iterator();
389 while (iterator.hasNext())
390 {
391 AbstractProperty<?> ap = iterator.next();
392 if (ap instanceof CompoundProperty)
393 {
394 cp = (CompoundProperty) ap;
395 if (ap.getKey().contains("IDM"))
396 {
397
398 Acceleration a = IDMPropertySet.getA(cp);
399 Acceleration b = IDMPropertySet.getB(cp);
400 Length s0 = IDMPropertySet.getS0(cp);
401 Duration tSafe = IDMPropertySet.getTSafe(cp);
402 GTUFollowingModelOld gtuFollowingModel = null;
403 if (carFollowingModelName.equals("IDM"))
404 {
405 gtuFollowingModel = new IDMOld(a, b, s0, tSafe, 1.0);
406 }
407 else if (carFollowingModelName.equals("IDM+"))
408 {
409 gtuFollowingModel = new IDMPlusOld(a, b, s0, tSafe, 1.0);
410 }
411 else
412 {
413 throw new Error("Unknown gtu following model: " + carFollowingModelName);
414 }
415 if (ap.getKey().contains("Car"))
416 {
417 this.carFollowingModelCars = gtuFollowingModel;
418 }
419 else if (ap.getKey().contains("Truck"))
420 {
421 this.carFollowingModelTrucks = gtuFollowingModel;
422 }
423 else
424 {
425 throw new Error("Cannot determine gtu type for " + ap.getKey());
426 }
427 }
428 }
429 }
430
431
432 cfmp = propertyContainer.findByKey("LaneChanging");
433 if (null == cfmp)
434 {
435 throw new Error("Cannot find \"Lane changing\" property");
436 }
437 if (cfmp instanceof SelectionProperty)
438 {
439 String laneChangeModelName = ((SelectionProperty) cfmp).getValue();
440 if ("Egoistic".equals(laneChangeModelName))
441 {
442 this.laneChangeModel = new Egoistic();
443 }
444 else if ("Altruistic".equals(laneChangeModelName))
445 {
446 this.laneChangeModel = new Altruistic();
447 }
448 else
449 {
450 throw new Error("Lane changing " + laneChangeModelName + " not implemented");
451 }
452 }
453 else
454 {
455 throw new Error("\"Lane changing\" property has wrong type");
456 }
457
458
459 iterator = new CompoundProperty("", "", "", this.properties, false, 0).iterator();
460 while (iterator.hasNext())
461 {
462 AbstractProperty<?> ap = iterator.next();
463 if (ap instanceof SelectionProperty)
464 {
465 SelectionProperty sp = (SelectionProperty) ap;
466 if ("TacticalPlanner".equals(sp.getKey()))
467 {
468 String tacticalPlannerName = sp.getValue();
469 if ("MOBIL".equals(tacticalPlannerName))
470 {
471 this.strategicalPlannerGeneratorCars =
472 new LaneBasedStrategicalRoutePlannerFactory(new LaneBasedCFLCTacticalPlannerFactory(
473 this.carFollowingModelCars, this.laneChangeModel));
474 this.strategicalPlannerGeneratorTrucks =
475 new LaneBasedStrategicalRoutePlannerFactory(new LaneBasedCFLCTacticalPlannerFactory(
476 this.carFollowingModelTrucks, this.laneChangeModel));
477 }
478 else if ("Verbraeck".equals(tacticalPlannerName))
479 {
480 this.strategicalPlannerGeneratorCars =
481 new LaneBasedStrategicalRoutePlannerFactory(
482 new LaneBasedGTUFollowingLaneChangeTacticalPlannerFactory(this.carFollowingModelCars));
483 this.strategicalPlannerGeneratorTrucks =
484 new LaneBasedStrategicalRoutePlannerFactory(
485 new LaneBasedGTUFollowingLaneChangeTacticalPlannerFactory(this.carFollowingModelTrucks));
486 }
487 else if ("Verbraeck0".equals(tacticalPlannerName))
488 {
489 this.strategicalPlannerGeneratorCars =
490 new LaneBasedStrategicalRoutePlannerFactory(
491 new LaneBasedGTUFollowingChange0TacticalPlannerFactory(this.carFollowingModelCars));
492 this.strategicalPlannerGeneratorTrucks =
493 new LaneBasedStrategicalRoutePlannerFactory(
494 new LaneBasedGTUFollowingChange0TacticalPlannerFactory(this.carFollowingModelTrucks));
495 }
496 else if ("LMRS".equals(tacticalPlannerName))
497 {
498
499 BehavioralCharacteristics defaultBehavioralCFCharacteristics = new BehavioralCharacteristics();
500 defaultBehavioralCFCharacteristics.setDefaultParameters(AbstractIDM.class);
501 this.strategicalPlannerGeneratorCars =
502 new LaneBasedStrategicalRoutePlannerFactory(new LMRSFactory(IDMPlus.class,
503 defaultBehavioralCFCharacteristics));
504 this.strategicalPlannerGeneratorTrucks =
505 new LaneBasedStrategicalRoutePlannerFactory(new LMRSFactory(IDMPlus.class,
506 defaultBehavioralCFCharacteristics));
507 }
508 else if ("Toledo".equals(tacticalPlannerName))
509 {
510 this.strategicalPlannerGeneratorCars =
511 new LaneBasedStrategicalRoutePlannerFactory(new ToledoFactory());
512 this.strategicalPlannerGeneratorTrucks =
513 new LaneBasedStrategicalRoutePlannerFactory(new ToledoFactory());
514 }
515 else
516 {
517 throw new Error("Don't know how to create a " + tacticalPlannerName + " tactical planner");
518 }
519 }
520
521 }
522 else if (ap instanceof ProbabilityDistributionProperty)
523 {
524 ProbabilityDistributionProperty pdp = (ProbabilityDistributionProperty) ap;
525 String modelName = ap.getKey();
526 if (modelName.equals("TrafficComposition"))
527 {
528 this.carProbability = pdp.getValue()[0];
529 }
530 }
531 else if (ap instanceof ContinuousProperty)
532 {
533 ContinuousProperty contP = (ContinuousProperty) ap;
534 if (contP.getKey().startsWith("Flow"))
535 {
536 this.averageHeadway = new Duration(3600.0 / contP.getValue(), SECOND);
537 this.minimumHeadway = new Duration(3, SECOND);
538 this.headwayGenerator =
539 new DistErlang(new MersenneTwister(1234), 4, DoubleScalar.minus(this.averageHeadway,
540 this.minimumHeadway).getSI());
541 }
542 }
543 else if (ap instanceof CompoundProperty)
544 {
545 CompoundProperty compoundProperty = (CompoundProperty) ap;
546 if (ap.getKey().equals("Output"))
547 {
548 continue;
549 }
550 if (ap.getKey().contains("IDM"))
551 {
552 Acceleration a = IDMPropertySet.getA(compoundProperty);
553 Acceleration b = IDMPropertySet.getB(compoundProperty);
554 Length s0 = IDMPropertySet.getS0(compoundProperty);
555 Duration tSafe = IDMPropertySet.getTSafe(compoundProperty);
556 GTUFollowingModelOld gtuFollowingModel = null;
557 if (carFollowingModelName.equals("IDM"))
558 {
559 gtuFollowingModel = new IDMOld(a, b, s0, tSafe, 1.0);
560 }
561 else if (carFollowingModelName.equals("IDM+"))
562 {
563 gtuFollowingModel = new IDMPlusOld(a, b, s0, tSafe, 1.0);
564 }
565 else
566 {
567 throw new Error("Unknown gtu following model: " + carFollowingModelName);
568 }
569 if (ap.getKey().contains("Car"))
570 {
571 this.carFollowingModelCars = gtuFollowingModel;
572 }
573 else if (ap.getKey().contains("Truck"))
574 {
575 this.carFollowingModelTrucks = gtuFollowingModel;
576 }
577 else
578 {
579 throw new Error("Cannot determine gtu type for " + ap.getKey());
580 }
581 }
582 }
583 }
584
585 Lane[] startLanes =
586 LaneFactory.makeMultiLane("From to FirstVia", from, firstVia, null, merge ? lanesOnMain
587 : lanesOnCommonCompressed, laneType, this.speedLimit, this.simulator,
588 LongitudinalDirectionality.DIR_PLUS);
589 setupGenerator(startLanes);
590 Lane[] common =
591 LaneFactory.makeMultiLane("FirstVia to SecondVia", firstVia, secondVia, null, lanesOnCommon, laneType,
592 this.speedLimit, this.simulator, LongitudinalDirectionality.DIR_PLUS);
593 if (merge)
594 {
595 for (int i = lanesOnCommonCompressed; i < lanesOnCommon; i++)
596 {
597 setupBlock(common[i]);
598 }
599 }
600 setupSink(LaneFactory.makeMultiLane("SecondVia to end", secondVia, end, null, merge ? lanesOnCommonCompressed
601 : lanesOnMain, laneType, this.speedLimit, this.simulator, LongitudinalDirectionality.DIR_PLUS), laneType);
602 if (merge)
603 {
604 setupGenerator(LaneFactory.makeMultiLane("From2a to From2b", from2a, from2b, null, lanesOnBranch, 0,
605 lanesOnCommon - lanesOnBranch, laneType, this.speedLimit, this.simulator,
606 LongitudinalDirectionality.DIR_PLUS));
607 LaneFactory.makeMultiLaneBezier("From2b to FirstVia", from2a, from2b, firstVia, secondVia, lanesOnBranch,
608 lanesOnCommon - lanesOnBranch, lanesOnCommon - lanesOnBranch, laneType, this.speedLimit, this.simulator,
609 LongitudinalDirectionality.DIR_PLUS);
610
611
612 ArrayList<Node> mainRouteNodes = new ArrayList<>();
613 mainRouteNodes.add(firstVia);
614 mainRouteNodes.add(secondVia);
615 mainRouteNodes.add(end);
616 Route mainRoute = new Route("main", mainRouteNodes);
617 this.routeGenerator = new FixedRouteGenerator(mainRoute);
618 }
619 else
620 {
621 LaneFactory.makeMultiLaneBezier("SecondVia to end2a", firstVia, secondVia, end2a, end2b, lanesOnBranch,
622 lanesOnCommon - lanesOnBranch, lanesOnCommon - lanesOnBranch, laneType, this.speedLimit, this.simulator,
623 LongitudinalDirectionality.DIR_PLUS);
624 setupSink(LaneFactory.makeMultiLane("end2a to end2b", end2a, end2b, null, lanesOnBranch, lanesOnCommon
625 - lanesOnBranch, 0, laneType, this.speedLimit, this.simulator, LongitudinalDirectionality.DIR_PLUS),
626 laneType);
627
628
629 List<FrequencyAndObject<Route>> routeProbabilities = new ArrayList<>();
630
631 ArrayList<Node> mainRouteNodes = new ArrayList<>();
632 mainRouteNodes.add(firstVia);
633 mainRouteNodes.add(secondVia);
634 mainRouteNodes.add(end);
635 Route mainRoute = new Route("main", mainRouteNodes);
636 routeProbabilities.add(new FrequencyAndObject<>(lanesOnMain, mainRoute));
637
638 ArrayList<Node> sideRouteNodes = new ArrayList<>();
639 sideRouteNodes.add(firstVia);
640 sideRouteNodes.add(secondVia);
641 sideRouteNodes.add(end2a);
642 sideRouteNodes.add(end2b);
643 Route sideRoute = new Route("side", sideRouteNodes);
644 routeProbabilities.add(new FrequencyAndObject<>(lanesOnBranch, sideRoute));
645 try
646 {
647 this.routeGenerator = new ProbabilisticRouteGenerator(routeProbabilities, new MersenneTwister(1234));
648 }
649 catch (ProbabilityException exception)
650 {
651 exception.printStackTrace();
652 }
653 }
654
655 for (int index = 0; index < lanesOnCommon; index++)
656 {
657 this.paths.add(new ArrayList<Lane>());
658 Lane lane = common[index];
659
660 while (lane.prevLanes(this.gtuType).size() > 0)
661 {
662 if (lane.prevLanes(this.gtuType).size() > 1)
663 {
664 throw new NetworkException("This network should not have lane merge points");
665 }
666 lane = lane.prevLanes(this.gtuType).keySet().iterator().next();
667 }
668
669 while (true)
670 {
671 this.paths.get(index).add(lane);
672 int branching = lane.nextLanes(this.gtuType).size();
673 if (branching == 0)
674 {
675 break;
676 }
677 if (branching > 1)
678 {
679 throw new NetworkException("This network should not have lane split points");
680 }
681 lane = lane.nextLanes(this.gtuType).keySet().iterator().next();
682 }
683 }
684 this.simulator.scheduleEventAbs(new DoubleScalar.Abs<>(0.999, SECOND), this, this, "drawGraphs", null);
685 }
686 catch (NamingException | NetworkException | GTUException | OTSGeometryException | ProbabilityException
687 | PropertyException exception1)
688 {
689 exception1.printStackTrace();
690 }
691 }
692
693
694
695
696
697
698
699
700
701 private Lane[] setupGenerator(final Lane[] lanes) throws SimRuntimeException, GTUException, ProbabilityException
702 {
703 for (Lane lane : lanes)
704 {
705 makeGenerator(lane);
706
707
708
709
710 }
711 return lanes;
712 }
713
714
715
716
717
718
719
720
721
722 private LaneBasedGTUGenerator makeGenerator(final Lane lane) throws GTUException, SimRuntimeException,
723 ProbabilityException
724 {
725 StreamInterface stream = new MersenneTwister(1234);
726 Distribution<LaneBasedTemplateGTUType> distribution = new Distribution<>(stream);
727 Length initialPosition = new Length(16, METER);
728 Set<DirectedLanePosition> initialPositions = new LinkedHashSet<>(1);
729 initialPositions.add(new DirectedLanePosition(lane, initialPosition, GTUDirectionality.DIR_PLUS));
730
731 LaneBasedTemplateGTUType template =
732 makeTemplate(stream, lane, new ContinuousDistDoubleScalar.Rel<Length, LengthUnit>(new DistUniform(stream, 3, 6),
733 METER), new ContinuousDistDoubleScalar.Rel<Length, LengthUnit>(new DistUniform(stream, 1.6, 2.0), METER),
734 new ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit>(new DistUniform(stream, 140, 180), KM_PER_HOUR),
735 new ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit>(new DistUniform(stream, 100, 125), KM_PER_HOUR),
736 initialPositions, this.strategicalPlannerGeneratorCars);
737
738 distribution.add(new FrequencyAndObject<>(this.carProbability, template));
739 template =
740 makeTemplate(stream, lane, new ContinuousDistDoubleScalar.Rel<Length, LengthUnit>(
741 new DistUniform(stream, 8, 14), METER), new ContinuousDistDoubleScalar.Rel<Length, LengthUnit>(
742 new DistUniform(stream, 2.0, 2.5), METER), new ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit>(
743 new DistUniform(stream, 100, 140), KM_PER_HOUR), new ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit>(
744 new DistUniform(stream, 80, 90), KM_PER_HOUR), initialPositions, this.strategicalPlannerGeneratorTrucks);
745
746 distribution.add(new FrequencyAndObject<>(1.0 - this.carProbability, template));
747 LaneBasedTemplateGTUTypeDistribution templateDistribution = new LaneBasedTemplateGTUTypeDistribution(distribution);
748 LaneBasedGTUGenerator.RoomChecker roomChecker = new CanPlaceDemoCode();
749 return new LaneBasedGTUGenerator(lane.getId(), new Generator<Duration>()
750 {
751 public Duration draw()
752 {
753 return new Duration(XMLNetworkModel.this.headwayGenerator.draw(), TimeUnit.SECOND);
754 }
755 }, Long.MAX_VALUE, new Time(0, TimeUnit.SI), new Time(Double.MAX_VALUE, TimeUnit.SI), this.gtuColorer,
756 templateDistribution, initialPositions, this.network,
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781 roomChecker);
782 }
783
784
785
786
787
788
789
790
791
792
793
794
795
796 LaneBasedTemplateGTUType makeTemplate(final StreamInterface stream, final Lane lane,
797 final ContinuousDistDoubleScalar.Rel<Length, LengthUnit> lengthDistribution,
798 final ContinuousDistDoubleScalar.Rel<Length, LengthUnit> widthDistribution,
799 final ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> maximumSpeedDistribution,
800 final ContinuousDistDoubleScalar.Rel<Speed, SpeedUnit> initialSpeedDistribution,
801 Set<DirectedLanePosition> initialPositions,
802 final LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerFactory) throws GTUException
803 {
804 return new LaneBasedTemplateGTUType(this.gtuType, this.idGenerator, new Generator<Length>()
805 {
806 public Length draw()
807 {
808 return lengthDistribution.draw();
809 }
810 }, new Generator<Length>()
811 {
812 public Length draw()
813 {
814 return widthDistribution.draw();
815 }
816 }, new Generator<Speed>()
817 {
818 public Speed draw()
819 {
820 return maximumSpeedDistribution.draw();
821 }
822 }, this.simulator,
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840 strategicalPlannerFactory, initialPositions, new Generator<Speed>()
841 {
842 public Speed draw()
843 {
844 return initialSpeedDistribution.draw();
845 }
846 }, this.network);
847
848 }
849
850
851
852
853
854
855
856
857
858 private Lane[] setupSink(final Lane[] lanes, final LaneType laneType) throws NetworkException, OTSGeometryException
859 {
860 CrossSectionLink link = lanes[0].getParentLink();
861 OTSNode to = link.getEndNode();
862 OTSNode from = link.getStartNode();
863 double endLinkLength = 50;
864 double endX = to.getPoint().x + (endLinkLength / link.getLength().getSI()) * (to.getPoint().x - from.getPoint().x);
865 double endY = to.getPoint().y + (endLinkLength / link.getLength().getSI()) * (to.getPoint().y - from.getPoint().y);
866 OTSNode end = new OTSNode("END", new OTSPoint3D(endX, endY, to.getPoint().z));
867 CrossSectionLink endLink = LaneFactory.makeLink("endLink", to, end, null, LongitudinalDirectionality.DIR_PLUS);
868 for (Lane lane : lanes)
869 {
870
871 Lane sinkLane =
872 new Lane(endLink, lane.getId() + "." + "sinkLane", lane.getLateralCenterPosition(1.0), lane
873 .getLateralCenterPosition(1.0), lane.getWidth(1.0), lane.getWidth(1.0), laneType,
874 LongitudinalDirectionality.DIR_PLUS, this.speedLimit, new OvertakingConditions.LeftAndRight());
875 Sensor sensor = new SinkSensor(sinkLane, new Length(10.0, METER), this.simulator);
876 sinkLane.addSensor(sensor, GTUType.ALL);
877 }
878 return lanes;
879 }
880
881
882
883
884
885
886
887
888
889
890
891 private Lane setupBlock(final Lane lane) throws NamingException, NetworkException, SimRuntimeException, GTUException,
892 OTSGeometryException
893 {
894 Length initialPosition = lane.getLength();
895 Set<DirectedLanePosition> initialPositions = new LinkedHashSet<>(1);
896 initialPositions.add(new DirectedLanePosition(lane, initialPosition, GTUDirectionality.DIR_PLUS));
897
898
899
900
901 BehavioralCharacteristics behavioralCharacteristics = DefaultsFactory.getDefaultBehavioralCharacteristics();
902 LaneBasedIndividualGTU block =
903 new LaneBasedIndividualGTU("999999", this.gtuType, new Length(1, METER), lane.getWidth(1), new Speed(0.0,
904 KM_PER_HOUR), this.simulator, DefaultCarAnimation.class, this.gtuColorer, this.network);
905 LaneBasedStrategicalPlanner strategicalPlanner =
906 new LaneBasedStrategicalRoutePlanner(behavioralCharacteristics, new LaneBasedGTUFollowingTacticalPlanner(
907 this.carFollowingModelCars, block), block);
908 block.init(strategicalPlanner, initialPositions, new Speed(0.0, KM_PER_HOUR));
909 return lane;
910 }
911
912
913
914
915 protected final void drawGraphs()
916 {
917 for (LaneBasedGTUSampler plot : this.plots)
918 {
919 plot.reGraph();
920 }
921
922 try
923 {
924 this.simulator.scheduleEventAbs(new Time(this.simulator.getSimulatorTime().get().getSI() + 1, SECOND), this,
925 this, "drawGraphs", null);
926 }
927 catch (SimRuntimeException exception)
928 {
929 exception.printStackTrace();
930 }
931
932 }
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012 @Override
1013 public SimulatorInterface<Abs<TimeUnit>, DoubleScalar.Rel<TimeUnit>, OTSSimTimeDouble> getSimulator()
1014 throws RemoteException
1015 {
1016 return this.simulator;
1017 }
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031 private class DirectionGTUColorer implements GTUColorer
1032 {
1033
1034 private List<LegendEntry> legend = new ArrayList<>();
1035
1036
1037 DirectionGTUColorer()
1038 {
1039 super();
1040 this.legend.add(new LegendEntry(Color.RED, "Right", "Go right"));
1041 this.legend.add(new LegendEntry(Color.BLUE, "Main", "Main route"));
1042 }
1043
1044
1045 @Override
1046 public Color getColor(final GTU gtu)
1047 {
1048 AbstractLaneBasedGTU laneBasedGTU = (AbstractLaneBasedGTU) gtu;
1049 Route route = ((LaneBasedStrategicalRoutePlanner) laneBasedGTU.getStrategicalPlanner()).getRoute();
1050 if (route == null)
1051 {
1052 return Color.black;
1053 }
1054 if (route.toString().toLowerCase().contains("end2"))
1055 {
1056 return Color.red;
1057 }
1058 if (route.toString().toLowerCase().contains("end"))
1059 {
1060 return Color.blue;
1061 }
1062 return Color.black;
1063 }
1064
1065
1066 @Override
1067 public List<LegendEntry> getLegend()
1068 {
1069 return this.legend;
1070 }
1071 }
1072
1073 }