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