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