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