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