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