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