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