1 package org.opentrafficsim.demo.carFollowing;
2
3 import java.awt.Container;
4 import java.awt.Frame;
5 import java.awt.geom.Rectangle2D;
6 import java.io.IOException;
7 import java.net.URL;
8 import java.rmi.RemoteException;
9 import java.util.ArrayList;
10 import java.util.Iterator;
11 import java.util.LinkedHashSet;
12 import java.util.List;
13 import java.util.Random;
14 import java.util.Set;
15
16 import javax.naming.NamingException;
17 import javax.swing.JComponent;
18 import javax.swing.JPanel;
19 import javax.swing.JScrollPane;
20 import javax.swing.SwingUtilities;
21
22 import nl.tudelft.simulation.dsol.SimRuntimeException;
23 import nl.tudelft.simulation.dsol.animation.D2.Renderable2D;
24 import nl.tudelft.simulation.dsol.gui.swing.HTMLPanel;
25 import nl.tudelft.simulation.dsol.gui.swing.TablePanel;
26 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
27 import nl.tudelft.simulation.jstats.distributions.DistContinuous;
28 import nl.tudelft.simulation.jstats.distributions.DistTriangular;
29 import nl.tudelft.simulation.jstats.streams.MersenneTwister;
30 import nl.tudelft.simulation.language.d3.DirectedPoint;
31
32 import org.djunits.unit.AccelerationUnit;
33 import org.djunits.unit.LengthUnit;
34 import org.djunits.unit.TimeUnit;
35 import org.djunits.unit.UNITS;
36 import org.djunits.value.vdouble.scalar.Acceleration;
37 import org.djunits.value.vdouble.scalar.DoubleScalar;
38 import org.djunits.value.vdouble.scalar.Length;
39 import org.djunits.value.vdouble.scalar.Speed;
40 import org.djunits.value.vdouble.scalar.Time;
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.plan.operational.OperationalPlan;
52 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlan.Segment;
53 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
54 import org.opentrafficsim.core.network.LongitudinalDirectionality;
55 import org.opentrafficsim.core.network.NetworkException;
56 import org.opentrafficsim.core.network.OTSNetwork;
57 import org.opentrafficsim.core.network.OTSNode;
58 import org.opentrafficsim.graphs.AccelerationContourPlot;
59 import org.opentrafficsim.graphs.ContourPlot;
60 import org.opentrafficsim.graphs.DensityContourPlot;
61 import org.opentrafficsim.graphs.FlowContourPlot;
62 import org.opentrafficsim.graphs.LaneBasedGTUSampler;
63 import org.opentrafficsim.graphs.SpeedContourPlot;
64 import org.opentrafficsim.graphs.TrajectoryPlot;
65 import org.opentrafficsim.road.gtu.animation.DefaultCarAnimation;
66 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
67 import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
68 import org.opentrafficsim.road.gtu.lane.driver.LaneBasedBehavioralCharacteristics;
69 import org.opentrafficsim.road.gtu.lane.perception.LanePerceptionFull;
70 import org.opentrafficsim.road.gtu.lane.tactical.AbstractLaneBasedTacticalPlanner;
71 import org.opentrafficsim.road.gtu.lane.tactical.LanePathInfo;
72 import org.opentrafficsim.road.gtu.lane.tactical.following.AccelerationStep;
73 import org.opentrafficsim.road.gtu.lane.tactical.following.GTUFollowingModelOld;
74 import org.opentrafficsim.road.gtu.lane.tactical.following.HeadwayGTU;
75 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMOld;
76 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusOld;
77 import org.opentrafficsim.road.gtu.lane.tactical.lanechangemobil.AbstractLaneChangeModel;
78 import org.opentrafficsim.road.gtu.lane.tactical.lanechangemobil.Egoistic;
79 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
80 import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlanner;
81 import org.opentrafficsim.road.network.factory.LaneFactory;
82 import org.opentrafficsim.road.network.lane.CrossSectionLink;
83 import org.opentrafficsim.road.network.lane.DirectedLanePosition;
84 import org.opentrafficsim.road.network.lane.Lane;
85 import org.opentrafficsim.road.network.lane.LaneType;
86 import org.opentrafficsim.road.network.lane.Sensor;
87 import org.opentrafficsim.road.network.lane.SinkSensor;
88 import org.opentrafficsim.road.network.lane.changing.OvertakingConditions;
89 import org.opentrafficsim.simulationengine.AbstractWrappableAnimation;
90 import org.opentrafficsim.simulationengine.OTSSimulationException;
91 import org.opentrafficsim.simulationengine.properties.AbstractProperty;
92 import org.opentrafficsim.simulationengine.properties.BooleanProperty;
93 import org.opentrafficsim.simulationengine.properties.CompoundProperty;
94 import org.opentrafficsim.simulationengine.properties.IDMPropertySet;
95 import org.opentrafficsim.simulationengine.properties.ProbabilityDistributionProperty;
96 import org.opentrafficsim.simulationengine.properties.PropertyException;
97 import org.opentrafficsim.simulationengine.properties.SelectionProperty;
98
99
100
101
102
103
104
105
106
107
108
109 public class StraightPerception extends AbstractWrappableAnimation implements UNITS
110 {
111
112 private StraightPerceptionModel model;
113
114
115 public StraightPerception()
116 {
117 ArrayList<AbstractProperty<?>> outputProperties = new ArrayList<AbstractProperty<?>>();
118 outputProperties.add(new BooleanProperty("Density", "Density contour plot", true, false, 0));
119 outputProperties.add(new BooleanProperty("Flow", "Flow contour plot", true, false, 1));
120 outputProperties.add(new BooleanProperty("Speed", "Speed contour plot", true, false, 2));
121 outputProperties.add(new BooleanProperty("Acceleration", "Acceleration contour plot", true, false, 3));
122 outputProperties.add(new BooleanProperty("Trajectories", "Trajectory (time/distance) diagram", true, false, 4));
123 this.properties.add(new CompoundProperty("Output graphs", "Select the graphical output", outputProperties,
124 true, 1000));
125 }
126
127
128 @Override
129 public final void stopTimersThreads()
130 {
131 super.stopTimersThreads();
132 this.model = null;
133 }
134
135
136
137
138
139
140 public static void main(final String[] args) throws SimRuntimeException
141 {
142 SwingUtilities.invokeLater(new Runnable()
143 {
144 @Override
145 public void run()
146 {
147 try
148 {
149 StraightPerception straight = new StraightPerception();
150 ArrayList<AbstractProperty<?>> localProperties = straight.getProperties();
151 try
152 {
153 localProperties.add(new ProbabilityDistributionProperty("Traffic composition",
154 "<html>Mix of passenger cars and trucks</html>", new String[]{"passenger car", "truck"},
155 new Double[]{0.8, 0.2}, false, 10));
156 }
157 catch (PropertyException exception)
158 {
159 exception.printStackTrace();
160 }
161 localProperties.add(new SelectionProperty("Car following model",
162 "<html>The car following model determines "
163 + "the acceleration that a vehicle will make taking into account "
164 + "nearby vehicles, infrastructural restrictions (e.g. speed limit, "
165 + "curvature of the road) capabilities of the vehicle and personality "
166 + "of the driver.</html>", new String[]{"IDM", "IDM+"}, 1, false, 1));
167 localProperties.add(IDMPropertySet.makeIDMPropertySet("Car", new Acceleration(1.0,
168 METER_PER_SECOND_2), new Acceleration(1.5, METER_PER_SECOND_2), new Length.Rel(2.0, METER),
169 new Time.Rel(1.0, SECOND), 2));
170 localProperties.add(IDMPropertySet.makeIDMPropertySet("Truck", new Acceleration(0.5,
171 METER_PER_SECOND_2), new Acceleration(1.25, METER_PER_SECOND_2), new Length.Rel(2.0, METER),
172 new Time.Rel(1.0, SECOND), 3));
173 straight.buildAnimator(new Time.Abs(0.0, SECOND), new Time.Rel(0.0, SECOND), new Time.Rel(3600.0,
174 SECOND), localProperties, null, true);
175 straight.panel.getTabbedPane().addTab("info", straight.makeInfoPane());
176 }
177 catch (SimRuntimeException | NamingException | OTSSimulationException exception)
178 {
179 exception.printStackTrace();
180 }
181 }
182 });
183 }
184
185
186 @Override
187 protected final Rectangle2D.Double makeAnimationRectangle()
188 {
189 return new Rectangle2D.Double(0, -100, 5000, 200);
190 }
191
192
193 @Override
194 protected final OTSModelInterface makeModel(final GTUColorer colorer)
195 {
196 this.model = new StraightPerceptionModel(this.savedUserModifiedProperties, colorer);
197 return this.model;
198 }
199
200
201
202
203 protected final JComponent makeInfoPane()
204 {
205
206 String helpSource =
207 "/" + StraightPerceptionModel.class.getPackage().getName().replace('.', '/') + "/IDMPlus.html";
208 URL page = StraightPerceptionModel.class.getResource(helpSource);
209 if (page != null)
210 {
211 try
212 {
213 HTMLPanel htmlPanel = new HTMLPanel(page);
214 return new JScrollPane(htmlPanel);
215 }
216 catch (IOException exception)
217 {
218 exception.printStackTrace();
219 }
220 }
221 return new JPanel();
222 }
223
224
225 @Override
226 protected final JPanel makeCharts() throws OTSSimulationException
227 {
228
229
230 AbstractProperty<?> output =
231 new CompoundProperty("", "", this.properties, false, 0).findByShortName("Output graphs");
232 if (null == output)
233 {
234 throw new Error("Cannot find output properties");
235 }
236 ArrayList<BooleanProperty> graphs = new ArrayList<BooleanProperty>();
237 if (output instanceof CompoundProperty)
238 {
239 CompoundProperty outputProperties = (CompoundProperty) output;
240 for (AbstractProperty<?> ap : outputProperties.getValue())
241 {
242 if (ap instanceof BooleanProperty)
243 {
244 BooleanProperty bp = (BooleanProperty) ap;
245 if (bp.getValue())
246 {
247 graphs.add(bp);
248 }
249 }
250 }
251 }
252 else
253 {
254 throw new Error("output properties should be compound");
255 }
256 int graphCount = graphs.size();
257 int columns = (int) Math.ceil(Math.sqrt(graphCount));
258 int rows = 0 == columns ? 0 : (int) Math.ceil(graphCount * 1.0 / columns);
259 TablePanel charts = new TablePanel(columns, rows);
260
261 for (int i = 0; i < graphCount; i++)
262 {
263 String graphName = graphs.get(i).getShortName();
264 Container container = null;
265 LaneBasedGTUSampler graph;
266 if (graphName.contains("Trajectories"))
267 {
268 List<Lane> path = new ArrayList<Lane>();
269 path.add(this.model.getLane());
270 TrajectoryPlot tp = new TrajectoryPlot("TrajectoryPlot", new Time.Rel(0.5, SECOND), path);
271 tp.setTitle("Trajectory Graph");
272 tp.setExtendedState(Frame.MAXIMIZED_BOTH);
273 graph = tp;
274 container = tp.getContentPane();
275 }
276 else
277 {
278 ContourPlot cp;
279 if (graphName.contains("Density"))
280 {
281 cp = new DensityContourPlot("DensityPlot", this.model.getPath());
282 cp.setTitle("Density Contour Graph");
283 }
284 else if (graphName.contains("Speed"))
285 {
286 cp = new SpeedContourPlot("SpeedPlot", this.model.getPath());
287 cp.setTitle("Speed Contour Graph");
288 }
289 else if (graphName.contains("Flow"))
290 {
291 cp = new FlowContourPlot("FlowPlot", this.model.getPath());
292 cp.setTitle("Flow Contour Graph");
293 }
294 else if (graphName.contains("Acceleration"))
295 {
296 cp = new AccelerationContourPlot("AccelerationPlot", this.model.getPath());
297 cp.setTitle("Acceleration Contour Graph");
298 }
299 else
300 {
301 throw new Error("Unhandled type of contourplot: " + graphName);
302 }
303 graph = cp;
304 container = cp.getContentPane();
305 }
306
307 charts.setCell(container, i % columns, i / columns);
308 this.model.getPlots().add(graph);
309 }
310 return charts;
311 }
312
313
314 @Override
315 public final String shortName()
316 {
317 return "Straight lane";
318 }
319
320
321 @Override
322 public final String description()
323 {
324 return "<html><h1>Simulation of a straight one-lane road with opening bridge</H1>"
325 + "Simulation of a single lane road of 5 km length. Vehicles are generated at a constant rate of "
326 + "1500 veh/hour. At time 300s a blockade is inserted at position 4km; this blockade is removed at "
327 + "time 420s. This blockade simulates a bridge opening.<br>"
328 + "The blockade causes a traffic jam that slowly dissolves after the blockade is removed.<br>"
329 + "Selected trajectory and contour plots are generated during the simulation.</html>";
330 }
331
332 }
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355 class StraightPerceptionModel implements OTSModelInterface, UNITS
356 {
357
358 private static final long serialVersionUID = 20140815L;
359
360
361 private OTSDEVSSimulatorInterface simulator;
362
363
364 private OTSNetwork network = new OTSNetwork("network");
365
366
367 private Time.Rel headway;
368
369
370 private int carsCreated = 0;
371
372
373 private GTUType gtuType = GTUType.makeGTUType("Car");
374
375
376 private GTUFollowingModelOld carFollowingModelCars;
377
378
379 private GTUFollowingModelOld carFollowingModelTrucks;
380
381
382 private double carProbability;
383
384
385 private AbstractLaneChangeModel laneChangeModel = new Egoistic();
386
387
388 private LaneBasedIndividualGTU block = null;
389
390
391 private Length.Rel minimumDistance = new Length.Rel(0, METER);
392
393
394 private Length.Rel maximumDistance = new Length.Rel(5000, METER);
395
396
397 private Lane lane;
398
399
400 private ArrayList<LaneBasedGTUSampler> plots = new ArrayList<LaneBasedGTUSampler>();
401
402
403 private ArrayList<AbstractProperty<?>> properties = null;
404
405
406 private Random randomGenerator = new Random(12345);
407
408
409 private final GTUColorer gtuColorer;
410
411
412
413
414
415 StraightPerceptionModel(final ArrayList<AbstractProperty<?>> properties, final GTUColorer gtuColorer)
416 {
417 this.properties = properties;
418 this.gtuColorer = gtuColorer;
419 }
420
421
422 private List<Lane> path = new ArrayList<Lane>();
423
424
425 private Speed speedLimit = new Speed(100, KM_PER_HOUR);
426
427
428 @SuppressWarnings("visibilitymodifier")
429 DistContinuous perceptionIntervalDist = new DistTriangular(new MersenneTwister(2), 0.25, 1, 2);
430
431
432 @SuppressWarnings("visibilitymodifier")
433 DistContinuous forwardHeadwayDist = new DistTriangular(new MersenneTwister(20), 20, 50, 100);
434
435
436
437
438 public List<Lane> getPath()
439 {
440 return new ArrayList<Lane>(this.path);
441 }
442
443
444 @Override
445 public final
446 void
447 constructModel(
448 final SimulatorInterface<DoubleScalar.Abs<TimeUnit>, DoubleScalar.Rel<TimeUnit>, OTSSimTimeDouble> theSimulator)
449 throws SimRuntimeException, RemoteException
450 {
451 this.simulator = (OTSDEVSSimulatorInterface) theSimulator;
452 OTSNode from = new OTSNode("From", new OTSPoint3D(getMinimumDistance().getSI(), 0, 0));
453 OTSNode to = new OTSNode("To", new OTSPoint3D(getMaximumDistance().getSI(), 0, 0));
454 OTSNode end = new OTSNode("End", new OTSPoint3D(getMaximumDistance().getSI() + 50.0, 0, 0));
455 try
456 {
457 LaneType laneType = new LaneType("CarLane");
458 laneType.addCompatibility(this.gtuType);
459 this.lane =
460 LaneFactory.makeLane("Lane", from, to, null, laneType, this.speedLimit, this.simulator,
461 LongitudinalDirectionality.DIR_PLUS);
462 this.path.add(this.lane);
463 CrossSectionLink endLink =
464 LaneFactory.makeLink("endLink", to, end, null, LongitudinalDirectionality.DIR_PLUS);
465
466 Lane sinkLane =
467 new Lane(endLink, "sinkLane", this.lane.getLateralCenterPosition(1.0),
468 this.lane.getLateralCenterPosition(1.0), this.lane.getWidth(1.0), this.lane.getWidth(1.0),
469 laneType, LongitudinalDirectionality.DIR_PLUS, this.speedLimit, new OvertakingConditions.None());
470 Sensor sensor = new SinkSensor(sinkLane, new Length.Rel(10.0, METER), this.simulator);
471 sinkLane.addSensor(sensor, GTUType.ALL);
472 String carFollowingModelName = null;
473 CompoundProperty propertyContainer = new CompoundProperty("", "", this.properties, false, 0);
474 AbstractProperty<?> cfmp = propertyContainer.findByShortName("Car following model");
475 if (null == cfmp)
476 {
477 throw new Error("Cannot find \"Car following model\" property");
478 }
479 if (cfmp instanceof SelectionProperty)
480 {
481 carFollowingModelName = ((SelectionProperty) cfmp).getValue();
482 }
483 else
484 {
485 throw new Error("\"Car following model\" property has wrong type");
486 }
487 Iterator<AbstractProperty<ArrayList<AbstractProperty<?>>>> iterator =
488 new CompoundProperty("", "", this.properties, false, 0).iterator();
489 while (iterator.hasNext())
490 {
491 AbstractProperty<?> ap = iterator.next();
492 if (ap instanceof SelectionProperty)
493 {
494 SelectionProperty sp = (SelectionProperty) ap;
495 if ("Car following model".equals(sp.getShortName()))
496 {
497 carFollowingModelName = sp.getValue();
498 }
499 }
500 else if (ap instanceof ProbabilityDistributionProperty)
501 {
502 ProbabilityDistributionProperty pdp = (ProbabilityDistributionProperty) ap;
503 String modelName = ap.getShortName();
504 if (modelName.equals("Traffic composition"))
505 {
506 this.carProbability = pdp.getValue()[0];
507 }
508 }
509 else if (ap instanceof CompoundProperty)
510 {
511 CompoundProperty cp = (CompoundProperty) ap;
512 if (ap.getShortName().equals("Output graphs"))
513 {
514 continue;
515 }
516 if (ap.getShortName().contains("IDM"))
517 {
518 Acceleration a = IDMPropertySet.getA(cp);
519 Acceleration b = IDMPropertySet.getB(cp);
520 Length.Rel s0 = IDMPropertySet.getS0(cp);
521 Time.Rel tSafe = IDMPropertySet.getTSafe(cp);
522 GTUFollowingModelOld gtuFollowingModel = null;
523 if (carFollowingModelName.equals("IDM"))
524 {
525 gtuFollowingModel = new IDMOld(a, b, s0, tSafe, 1.0);
526 }
527 else if (carFollowingModelName.equals("IDM+"))
528 {
529 gtuFollowingModel = new IDMPlusOld(a, b, s0, tSafe, 1.0);
530 }
531 else
532 {
533 throw new Error("Unknown gtu following model: " + carFollowingModelName);
534 }
535 if (ap.getShortName().contains(" Car "))
536 {
537 this.carFollowingModelCars = gtuFollowingModel;
538 }
539 else if (ap.getShortName().contains(" Truck "))
540 {
541 this.carFollowingModelTrucks = gtuFollowingModel;
542 }
543 else
544 {
545 throw new Error("Cannot determine gtu type for " + ap.getShortName());
546 }
547
548
549
550
551
552 }
553 }
554 }
555
556
557 this.headway = new Time.Rel(3600.0 / 1500.0, SECOND);
558
559 this.simulator.scheduleEventAbs(new DoubleScalar.Abs<TimeUnit>(0.0, SECOND), this, this, "generateCar",
560 null);
561
562 this.simulator.scheduleEventAbs(new DoubleScalar.Abs<TimeUnit>(300, SECOND), this, this, "createBlock",
563 null);
564
565 this.simulator.scheduleEventAbs(new DoubleScalar.Abs<TimeUnit>(420, SECOND), this, this, "removeBlock",
566 null);
567
568 for (int t = 1; t <= 1800; t++)
569 {
570 this.simulator.scheduleEventAbs(new DoubleScalar.Abs<TimeUnit>(t - 0.001, SECOND), this, this,
571 "drawGraphs", null);
572 }
573 }
574 catch (SimRuntimeException | NamingException | NetworkException | OTSGeometryException exception)
575 {
576 exception.printStackTrace();
577 }
578 }
579
580
581
582
583 protected final void drawGraphs()
584 {
585 for (LaneBasedGTUSampler plot : this.plots)
586 {
587 plot.reGraph();
588 }
589 }
590
591
592
593
594 protected final void createBlock()
595 {
596 Length.Rel initialPosition = new Length.Rel(4000, METER);
597 Set<DirectedLanePosition> initialPositions = new LinkedHashSet<>(1);
598 try
599 {
600 initialPositions.add(new DirectedLanePosition(this.lane, initialPosition, GTUDirectionality.DIR_PLUS));
601 LaneBasedBehavioralCharacteristics drivingCharacteristics =
602 new LaneBasedBehavioralCharacteristics(this.carFollowingModelCars, this.laneChangeModel);
603 LaneBasedStrategicalPlanner strategicalPlanner =
604 new LaneBasedStrategicalRoutePlanner(drivingCharacteristics,
605 new GTUFollowingTacticalPlannerNoPerceive());
606 this.block =
607 new LaneBasedIndividualGTU("999999", this.gtuType, initialPositions, new Speed(0.0, KM_PER_HOUR),
608 new Length.Rel(4, METER), new Length.Rel(1.8, METER), new Speed(0.0, KM_PER_HOUR), this.simulator,
609 strategicalPlanner, new LanePerceptionFull(), DefaultCarAnimation.class, this.gtuColorer,
610 this.network);
611 }
612 catch (SimRuntimeException | NamingException | NetworkException | GTUException | OTSGeometryException exception)
613 {
614 exception.printStackTrace();
615 }
616 }
617
618
619
620
621 protected final void removeBlock()
622 {
623 this.block.destroy();
624 this.block = null;
625 }
626
627
628
629
630 protected final void generateCar()
631 {
632 boolean generateTruck = this.randomGenerator.nextDouble() > this.carProbability;
633 Length.Rel initialPosition = new Length.Rel(0, METER);
634 Speed initialSpeed = new Speed(100, KM_PER_HOUR);
635 Set<DirectedLanePosition> initialPositions = new LinkedHashSet<>(1);
636 try
637 {
638 initialPositions.add(new DirectedLanePosition(this.lane, initialPosition, GTUDirectionality.DIR_PLUS));
639 Length.Rel vehicleLength = new Length.Rel(generateTruck ? 15 : 4, METER);
640 GTUFollowingModelOld gtuFollowingModel;
641 if (generateTruck)
642 {
643 Acceleration a = new Acceleration(0.5, AccelerationUnit.METER_PER_SECOND_2);
644 Acceleration b = new Acceleration(1.25, AccelerationUnit.METER_PER_SECOND_2);
645 Length.Rel s0 = new Length.Rel(4, LengthUnit.METER);
646 Time.Rel tSafe = new Time.Rel(2.0, TimeUnit.SECOND);
647 gtuFollowingModel = new IDMPlusOld(a, b, s0, tSafe, 1.0);
648 }
649 else
650 {
651 Acceleration a = new Acceleration(2.0, AccelerationUnit.METER_PER_SECOND_2);
652 Acceleration b = new Acceleration(3, AccelerationUnit.METER_PER_SECOND_2);
653 Length.Rel s0 = new Length.Rel(2.0, LengthUnit.METER);
654 Time.Rel tSafe = new Time.Rel(1.0, TimeUnit.SECOND);
655 gtuFollowingModel = new IDMPlusOld(a, b, s0, tSafe, 1.0);
656 }
657 LaneBasedBehavioralCharacteristics drivingCharacteristics =
658 new LaneBasedBehavioralCharacteristics(gtuFollowingModel, this.laneChangeModel);
659 LaneBasedStrategicalPlanner strategicalPlanner =
660 new LaneBasedStrategicalRoutePlanner(drivingCharacteristics,
661 new GTUFollowingTacticalPlannerNoPerceive());
662 LaneBasedPerceivingCar car =
663 new LaneBasedPerceivingCar("" + (++this.carsCreated), this.gtuType, initialPositions, initialSpeed,
664 vehicleLength, new Length.Rel(1.8, METER), new Speed(200, KM_PER_HOUR), this.simulator,
665 strategicalPlanner, new LanePerceptionFull(), DefaultCarAnimation.class, this.gtuColorer,
666 this.network);
667 this.simulator.scheduleEventRel(this.headway, this, this, "generateCar", null);
668 car.setPerceptionInterval(new Time.Rel(this.perceptionIntervalDist.draw(), TimeUnit.SECOND));
669 car.getStrategicalPlanner().getDrivingCharacteristics()
670 .setForwardHeadwayDistance(new Length.Rel(this.forwardHeadwayDist.draw(), LengthUnit.METER));
671 }
672 catch (SimRuntimeException | NamingException | NetworkException | GTUException | OTSGeometryException exception)
673 {
674 exception.printStackTrace();
675 }
676 }
677
678
679 @Override
680 public final SimulatorInterface<DoubleScalar.Abs<TimeUnit>, DoubleScalar.Rel<TimeUnit>, OTSSimTimeDouble>
681 getSimulator() throws RemoteException
682 {
683 return this.simulator;
684 }
685
686
687
688
689 public final ArrayList<LaneBasedGTUSampler> getPlots()
690 {
691 return this.plots;
692 }
693
694
695
696
697 public final Length.Rel getMinimumDistance()
698 {
699 return this.minimumDistance;
700 }
701
702
703
704
705 public final Length.Rel getMaximumDistance()
706 {
707 return this.maximumDistance;
708 }
709
710
711
712
713 public Lane getLane()
714 {
715 return this.lane;
716 }
717
718
719
720
721 class LaneBasedPerceivingCar extends LaneBasedIndividualGTU
722 {
723
724 private static final long serialVersionUID = 1L;
725
726
727 private Time.Rel perceptionInterval = new Time.Rel(0.5, TimeUnit.SECOND);
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748 @SuppressWarnings("checkstyle:parameternumber")
749 LaneBasedPerceivingCar(final String id, final GTUType gtuType,
750 final Set<DirectedLanePosition> initialLongitudinalPositions, final Speed initialSpeed,
751 final Length.Rel length, final Length.Rel width, final Speed maximumVelocity,
752 final OTSDEVSSimulatorInterface simulator, final LaneBasedStrategicalPlanner strategicalPlanner,
753 final LanePerceptionFull perception, final OTSNetwork network) throws NamingException, NetworkException,
754 SimRuntimeException, GTUException, OTSGeometryException
755 {
756 super(id, gtuType, initialLongitudinalPositions, initialSpeed, length, width, maximumVelocity, simulator,
757 strategicalPlanner, perception, network);
758 perceive();
759 }
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784 @SuppressWarnings("checkstyle:parameternumber")
785 LaneBasedPerceivingCar(final String id, final GTUType gtuType,
786 final Set<DirectedLanePosition> initialLongitudinalPositions, final Speed initialSpeed,
787 final Length.Rel length, final Length.Rel width, final Speed maximumVelocity,
788 final OTSDEVSSimulatorInterface simulator, final LaneBasedStrategicalPlanner strategicalPlanner,
789 final LanePerceptionFull perception, final Class<? extends Renderable2D> animationClass,
790 final GTUColorer gtuColorer, final OTSNetwork network) throws NamingException, NetworkException,
791 SimRuntimeException, GTUException, OTSGeometryException
792 {
793 super(id, gtuType, initialLongitudinalPositions, initialSpeed, length, width, maximumVelocity, simulator,
794 strategicalPlanner, perception, animationClass, gtuColorer, network);
795 perceive();
796 }
797
798
799
800
801 public void setPerceptionInterval(final Time.Rel perceptionInterval)
802 {
803 this.perceptionInterval = perceptionInterval;
804 }
805
806
807
808
809
810
811
812 public void perceive() throws SimRuntimeException, GTUException, NetworkException
813 {
814 getPerception().perceive();
815 getSimulator().scheduleEventRel(this.perceptionInterval, this, this, "perceive", null);
816 }
817 }
818
819
820
821
822 class GTUFollowingTacticalPlannerNoPerceive extends AbstractLaneBasedTacticalPlanner
823 {
824
825 private static final long serialVersionUID = 20151125L;
826
827
828
829
830 GTUFollowingTacticalPlannerNoPerceive()
831 {
832 super();
833 }
834
835
836 @Override
837 public OperationalPlan generateOperationalPlan(final GTU gtu, final Time.Abs startTime,
838 final DirectedPoint locationAtStartTime) throws OperationalPlanException, NetworkException, GTUException
839 {
840
841 LaneBasedGTU laneBasedGTU = (LaneBasedGTU) gtu;
842 LanePerceptionFull perception = laneBasedGTU.getPerception();
843
844
845 if (laneBasedGTU.getMaximumVelocity().si < OperationalPlan.DRIFTING_SPEED_SI)
846 {
847
848 return new OperationalPlan(laneBasedGTU, locationAtStartTime, startTime, new Time.Rel(
849 perceptionIntervalDist.draw(), TimeUnit.SECOND));
850 }
851
852
853 GTUFollowingModelOld gtuFollowingModel =
854 laneBasedGTU.getStrategicalPlanner().getDrivingCharacteristics().getGTUFollowingModel();
855
856
857 LanePathInfo lanePathInfo =
858 buildLanePathInfo(laneBasedGTU, laneBasedGTU.getBehavioralCharacteristics().getForwardHeadwayDistance());
859 Length.Rel maxDistance = lanePathInfo.getPath().getLength();
860
861
862 HeadwayGTU headwayGTU = perception.getForwardHeadwayGTU();
863 AccelerationStep accelerationStep = null;
864 if (headwayGTU.getGtuId() == null)
865 {
866 accelerationStep =
867 gtuFollowingModel.computeAccelerationStepWithNoLeader(laneBasedGTU, maxDistance,
868 perception.getSpeedLimit());
869 }
870 else
871 {
872
873 accelerationStep =
874 gtuFollowingModel.computeAccelerationStep(laneBasedGTU, headwayGTU.getGtuSpeed(),
875 headwayGTU.getDistance(), maxDistance, perception.getSpeedLimit());
876 }
877
878
879 if (accelerationStep.getAcceleration().si < 1E-6
880 && laneBasedGTU.getVelocity().si < OperationalPlan.DRIFTING_SPEED_SI)
881 {
882 return new OperationalPlan(laneBasedGTU, locationAtStartTime, startTime, accelerationStep.getDuration());
883 }
884
885 List<Segment> operationalPlanSegmentList = new ArrayList<>();
886 if (accelerationStep.getAcceleration().si == 0.0)
887 {
888 Segment segment = new OperationalPlan.SpeedSegment(accelerationStep.getDuration());
889 operationalPlanSegmentList.add(segment);
890 }
891 else
892 {
893 Segment segment =
894 new OperationalPlan.AccelerationSegment(accelerationStep.getDuration(),
895 accelerationStep.getAcceleration());
896 operationalPlanSegmentList.add(segment);
897 }
898 OperationalPlan op =
899 new OperationalPlan(laneBasedGTU, lanePathInfo.getPath(), startTime, gtu.getVelocity(),
900 operationalPlanSegmentList);
901 return op;
902 }
903 }
904 }