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