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