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