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