1 package org.opentrafficsim.demo.carFollowing;
2
3 import static org.opentrafficsim.core.gtu.GTUType.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.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.DurationUnit;
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.base.parameters.ParameterException;
39 import org.opentrafficsim.base.parameters.ParameterTypes;
40 import org.opentrafficsim.base.parameters.Parameters;
41 import org.opentrafficsim.core.dsol.OTSModelInterface;
42 import org.opentrafficsim.core.geometry.OTSGeometryException;
43 import org.opentrafficsim.core.geometry.OTSPoint3D;
44 import org.opentrafficsim.core.gtu.GTUDirectionality;
45 import org.opentrafficsim.core.gtu.GTUException;
46 import org.opentrafficsim.core.gtu.GTUType;
47 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlan;
48 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlan.Segment;
49 import org.opentrafficsim.core.gtu.plan.operational.OperationalPlanException;
50 import org.opentrafficsim.core.network.NetworkException;
51 import org.opentrafficsim.core.network.OTSNetwork;
52 import org.opentrafficsim.core.network.OTSNode;
53 import org.opentrafficsim.graphs.AccelerationContourPlot;
54 import org.opentrafficsim.graphs.ContourPlot;
55 import org.opentrafficsim.graphs.DensityContourPlot;
56 import org.opentrafficsim.graphs.FlowContourPlot;
57 import org.opentrafficsim.graphs.LaneBasedGTUSampler;
58 import org.opentrafficsim.graphs.SpeedContourPlot;
59 import org.opentrafficsim.graphs.TrajectoryPlot;
60 import org.opentrafficsim.road.animation.AnimationToggles;
61 import org.opentrafficsim.road.gtu.animation.DefaultCarAnimation;
62 import org.opentrafficsim.road.gtu.lane.LaneBasedGTU;
63 import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
64 import org.opentrafficsim.road.gtu.lane.perception.CategoricalLanePerception;
65 import org.opentrafficsim.road.gtu.lane.perception.categories.DefaultSimplePerception;
66 import org.opentrafficsim.road.gtu.lane.perception.headway.Headway;
67 import org.opentrafficsim.road.gtu.lane.tactical.AbstractLaneBasedTacticalPlanner;
68 import org.opentrafficsim.road.gtu.lane.tactical.LanePathInfo;
69 import org.opentrafficsim.road.gtu.lane.tactical.following.AccelerationStep;
70 import org.opentrafficsim.road.gtu.lane.tactical.following.GTUFollowingModelOld;
71 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMOld;
72 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusOld;
73 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
74 import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlanner;
75 import org.opentrafficsim.road.modelproperties.IDMPropertySet;
76 import org.opentrafficsim.road.network.factory.LaneFactory;
77 import org.opentrafficsim.road.network.lane.CrossSectionLink;
78 import org.opentrafficsim.road.network.lane.DirectedLanePosition;
79 import org.opentrafficsim.road.network.lane.Lane;
80 import org.opentrafficsim.road.network.lane.LaneType;
81 import org.opentrafficsim.road.network.lane.changing.OvertakingConditions;
82 import org.opentrafficsim.road.network.lane.object.sensor.SinkSensor;
83 import org.opentrafficsim.simulationengine.AbstractWrappableAnimation;
84 import org.opentrafficsim.simulationengine.OTSSimulationException;
85 import org.opentrafficsim.simulationengine.SimpleSimulatorInterface;
86
87 import nl.tudelft.simulation.dsol.SimRuntimeException;
88 import nl.tudelft.simulation.dsol.gui.swing.HTMLPanel;
89 import nl.tudelft.simulation.dsol.gui.swing.TablePanel;
90 import nl.tudelft.simulation.dsol.simtime.SimTimeDoubleUnit;
91 import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
92 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
93 import nl.tudelft.simulation.jstats.distributions.DistContinuous;
94 import nl.tudelft.simulation.jstats.distributions.DistTriangular;
95 import nl.tudelft.simulation.jstats.streams.MersenneTwister;
96 import nl.tudelft.simulation.language.d3.DirectedPoint;
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
127 .add(new BooleanProperty("AccelerationPlot", "Acceleration", "Acceleration contour plot", true, false, 3));
128 outputProperties.add(
129 new BooleanProperty("TrajectoryPlot", "Trajectories", "Trajectory (time/distance) diagram", true, 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>",
175 new String[] { "IDM", "IDM+" }, 1, false, 1));
176 localProperties.add(IDMPropertySet.makeIDMPropertySet("IDMCar", "Car",
177 new Acceleration(1.0, METER_PER_SECOND_2), new Acceleration(1.5, METER_PER_SECOND_2),
178 new Length(2.0, METER), new Duration(1.0, SECOND), 2));
179 localProperties.add(IDMPropertySet.makeIDMPropertySet("IDMTruck", "Truck",
180 new Acceleration(0.5, METER_PER_SECOND_2), new Acceleration(1.25, METER_PER_SECOND_2),
181 new Length(2.0, METER), new Duration(1.0, SECOND), 3));
182 straight.buildAnimator(Time.ZERO, Duration.ZERO, new Duration(3600.0, SECOND), 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 void addAnimationToggles()
196 {
197 AnimationToggles.setTextAnimationTogglesStandard(this);
198 }
199
200
201 @Override
202 protected final OTSModelInterface makeModel()
203 {
204 this.model = new StraightPerceptionModel(this.savedUserModifiedProperties);
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 void addTabs(final 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 addTab(getTabCount(), "statistics", 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 class StraightPerceptionModel implements OTSModelInterface, UNITS
361 {
362
363 private static final long serialVersionUID = 20140815L;
364
365
366 private DEVSSimulatorInterface.TimeDoubleUnit 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 = 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
409
410 StraightPerceptionModel(final List<Property<?>> properties)
411 {
412 this.properties = properties;
413 }
414
415
416 private List<Lane> path = new ArrayList<>();
417
418
419 private Speed speedLimit = new Speed(100, KM_PER_HOUR);
420
421
422 @SuppressWarnings("visibilitymodifier")
423 DistContinuous perceptionIntervalDist = new DistTriangular(new MersenneTwister(2), 0.25, 1, 2);
424
425
426 @SuppressWarnings("visibilitymodifier")
427 DistContinuous forwardHeadwayDist = new DistTriangular(new MersenneTwister(20), 20, 50, 100);
428
429
430
431
432 public List<Lane> getPath()
433 {
434 return new ArrayList<>(this.path);
435 }
436
437
438 @Override
439 public final void constructModel(final SimulatorInterface<Time, Duration, SimTimeDoubleUnit> theSimulator)
440 throws SimRuntimeException
441 {
442 this.simulator = (DEVSSimulatorInterface.TimeDoubleUnit) theSimulator;
443 try
444 {
445 OTSNode from = new OTSNode(this.network, "From", new OTSPoint3D(getMinimumDistance().getSI(), 0, 0));
446 OTSNode to = new OTSNode(this.network, "To", new OTSPoint3D(getMaximumDistance().getSI(), 0, 0));
447 OTSNode end = new OTSNode(this.network, "End", new OTSPoint3D(getMaximumDistance().getSI() + 50.0, 0, 0));
448 LaneType laneType = LaneType.TWO_WAY_LANE;
449 this.lane =
450 LaneFactory.makeLane(this.network, "Lane", from, to, null, laneType, this.speedLimit, this.simulator);
451 this.path.add(this.lane);
452 CrossSectionLink endLink = LaneFactory.makeLink(this.network, "endLink", to, end, null, this.simulator);
453
454 Lane sinkLane = new Lane(endLink, "sinkLane", this.lane.getLateralCenterPosition(1.0),
455 this.lane.getLateralCenterPosition(1.0), this.lane.getWidth(1.0), this.lane.getWidth(1.0), laneType,
456 this.speedLimit, new OvertakingConditions.None());
457 new SinkSensor(sinkLane, new Length(10.0, METER), this.simulator);
458 String carFollowingModelName = null;
459 CompoundProperty propertyContainer = new CompoundProperty("", "", "", this.properties, false, 0);
460 Property<?> cfmp = propertyContainer.findByKey("CarFollowingModel");
461 if (null == cfmp)
462 {
463 throw new Error("Cannot find \"Car following model\" property");
464 }
465 if (cfmp instanceof SelectionProperty)
466 {
467 carFollowingModelName = ((SelectionProperty) cfmp).getValue();
468 }
469 else
470 {
471 throw new Error("\"Car following model\" property has wrong type");
472 }
473 for (Property<?> ap : new CompoundProperty("", "", "", this.properties, false, 0))
474 {
475 if (ap instanceof SelectionProperty)
476 {
477 SelectionProperty sp = (SelectionProperty) ap;
478 if ("CarFollowingModel".equals(sp.getKey()))
479 {
480 carFollowingModelName = sp.getValue();
481 }
482 }
483 else if (ap instanceof ProbabilityDistributionProperty)
484 {
485 ProbabilityDistributionProperty pdp = (ProbabilityDistributionProperty) ap;
486 String modelName = ap.getKey();
487 if (modelName.equals("TrafficComposition"))
488 {
489 this.carProbability = pdp.getValue()[0];
490 }
491 }
492 else if (ap instanceof CompoundProperty)
493 {
494 CompoundProperty cp = (CompoundProperty) ap;
495 if (ap.getKey().equals("OutputGraphs"))
496 {
497 continue;
498 }
499 if (ap.getKey().contains("IDM"))
500 {
501 Acceleration a = IDMPropertySet.getA(cp);
502 Acceleration b = IDMPropertySet.getB(cp);
503 Length s0 = IDMPropertySet.getS0(cp);
504 Duration tSafe = IDMPropertySet.getTSafe(cp);
505 GTUFollowingModelOld gtuFollowingModel = null;
506 if (carFollowingModelName.equals("IDM"))
507 {
508 gtuFollowingModel = new IDMOld(a, b, s0, tSafe, 1.0);
509 }
510 else if (carFollowingModelName.equals("IDM+"))
511 {
512 gtuFollowingModel = new IDMPlusOld(a, b, s0, tSafe, 1.0);
513 }
514 else
515 {
516 throw new Error("Unknown gtu following model: " + carFollowingModelName);
517 }
518 if (ap.getKey().contains("Car"))
519 {
520 this.carFollowingModelCars = gtuFollowingModel;
521 }
522 else if (ap.getKey().contains("Truck"))
523 {
524 }
525 else
526 {
527 throw new Error("Cannot determine gtu type for " + ap.getKey());
528 }
529
530
531
532
533
534 }
535 }
536 }
537
538
539 this.headway = new Duration(3600.0 / 1500.0, SECOND);
540
541 this.simulator.scheduleEventAbs(Time.ZERO, this, this, "generateCar", null);
542
543 this.simulator.scheduleEventAbs(new Time(300, TimeUnit.BASE_SECOND), this, this, "createBlock", null);
544
545 this.simulator.scheduleEventAbs(new Time(420, TimeUnit.BASE_SECOND), this, this, "removeBlock", null);
546
547 for (int t = 1; t <= 1800; t++)
548 {
549 this.simulator.scheduleEventAbs(new Time(t - 0.001, TimeUnit.BASE_SECOND), this, this, "drawGraphs", null);
550 }
551 }
552 catch (SimRuntimeException | NamingException | NetworkException | OTSGeometryException
553 | PropertyException exception)
554 {
555 exception.printStackTrace();
556 }
557 }
558
559
560
561
562 protected final void drawGraphs()
563 {
564 for (LaneBasedGTUSampler plot : this.plots)
565 {
566 plot.reGraph();
567 }
568 }
569
570
571
572
573 protected final void createBlock()
574 {
575 Length initialPosition = new Length(4000, METER);
576 Set<DirectedLanePosition> initialPositions = new LinkedHashSet<>(1);
577 try
578 {
579 initialPositions.add(new DirectedLanePosition(this.lane, initialPosition, GTUDirectionality.DIR_PLUS));
580 Parameters parameters = DefaultsFactory.getDefaultParameters();
581
582 this.block = new LaneBasedIndividualGTU("999999", this.gtuType, new Length(4, METER), new Length(1.8, METER),
583 new Speed(0.0, KM_PER_HOUR), Length.createSI(2.0), this.simulator, this.network);
584 LaneBasedStrategicalPlanner strategicalPlanner = new LaneBasedStrategicalRoutePlanner(
585 new GTUFollowingTacticalPlannerNoPerceive(this.carFollowingModelCars, this.block), this.block);
586 this.block.setParameters(parameters);
587 this.block.initWithAnimation(strategicalPlanner, initialPositions, Speed.ZERO, DefaultCarAnimation.class,
588 StraightPerception.this.getColorer());
589 }
590 catch (SimRuntimeException | NamingException | NetworkException | GTUException | OTSGeometryException exception)
591 {
592 exception.printStackTrace();
593 }
594 }
595
596
597
598
599 protected final void removeBlock()
600 {
601 this.block.destroy();
602 this.block = null;
603 }
604
605
606
607
608
609 protected final void generateCar() throws ParameterException
610 {
611 boolean generateTruck = this.randomGenerator.nextDouble() > this.carProbability;
612 Length initialPosition = new Length(0, METER);
613 Speed initialSpeed = new Speed(100, KM_PER_HOUR);
614 Set<DirectedLanePosition> initialPositions = new LinkedHashSet<>(1);
615 try
616 {
617 initialPositions.add(new DirectedLanePosition(this.lane, initialPosition, GTUDirectionality.DIR_PLUS));
618 Length vehicleLength = new Length(generateTruck ? 15 : 4, METER);
619 GTUFollowingModelOld gtuFollowingModel;
620 if (generateTruck)
621 {
622 Acceleration a = new Acceleration(0.5, AccelerationUnit.METER_PER_SECOND_2);
623 Acceleration b = new Acceleration(1.25, AccelerationUnit.METER_PER_SECOND_2);
624
625 Length s0 = new Length(4, LengthUnit.METER);
626 Duration tSafe = new Duration(2.0, DurationUnit.SECOND);
627 gtuFollowingModel = new IDMPlusOld(a, b, s0, tSafe, 1.0);
628 }
629 else
630 {
631 Acceleration a = new Acceleration(2.0, AccelerationUnit.METER_PER_SECOND_2);
632 Acceleration b = new Acceleration(3, AccelerationUnit.METER_PER_SECOND_2);
633 Length s0 = new Length(2.0, LengthUnit.METER);
634 Duration tSafe = new Duration(1.0, DurationUnit.SECOND);
635 gtuFollowingModel = new IDMPlusOld(a, b, s0, tSafe, 1.0);
636 }
637 Parameters parameters = DefaultsFactory.getDefaultParameters();
638 LaneBasedPerceivingCar car = new LaneBasedPerceivingCar("" + (++this.carsCreated), this.gtuType, vehicleLength,
639 new Length(1.8, METER), new Speed(200, KM_PER_HOUR), this.simulator, this.network);
640 LaneBasedStrategicalPlanner strategicalPlanner = new LaneBasedStrategicalRoutePlanner(
641 new GTUFollowingTacticalPlannerNoPerceive(gtuFollowingModel, car), car);
642 car.setParameters(parameters);
643 car.initWithAnimation(strategicalPlanner, initialPositions, initialSpeed, DefaultCarAnimation.class,
644 StraightPerception.this.getColorer());
645 this.simulator.scheduleEventRel(this.headway, this, this, "generateCar", null);
646 car.setPerceptionInterval(new Duration(this.perceptionIntervalDist.draw(), DurationUnit.SECOND));
647 car.getParameters().setParameter(ParameterTypes.LOOKAHEAD,
648 new Length(this.forwardHeadwayDist.draw(), LengthUnit.METER));
649
650 }
651 catch (SimRuntimeException | NamingException | NetworkException | GTUException | OTSGeometryException exception)
652 {
653 exception.printStackTrace();
654 }
655 }
656
657
658 @Override
659 public final SimulatorInterface<Time, Duration, SimTimeDoubleUnit> getSimulator()
660 {
661 return this.simulator;
662 }
663
664
665 @Override
666 public OTSNetwork getNetwork()
667 {
668 return this.network;
669 }
670
671
672
673
674 public final List<LaneBasedGTUSampler> getPlots()
675 {
676 return this.plots;
677 }
678
679
680
681
682 public final Length getMinimumDistance()
683 {
684 return this.minimumDistance;
685 }
686
687
688
689
690 public final Length getMaximumDistance()
691 {
692 return this.maximumDistance;
693 }
694
695
696
697
698 public Lane getLane()
699 {
700 return this.lane;
701 }
702
703
704
705
706 class LaneBasedPerceivingCar extends LaneBasedIndividualGTU
707 {
708
709 private static final long serialVersionUID = 1L;
710
711
712 private Duration perceptionInterval = new Duration(0.5, DurationUnit.SECOND);
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729 LaneBasedPerceivingCar(final String id, final GTUType gtuType, final Length length, final Length width,
730 final Speed maximumSpeed, final DEVSSimulatorInterface.TimeDoubleUnit simulator, final OTSNetwork network)
731 throws NamingException, NetworkException, SimRuntimeException, GTUException, OTSGeometryException,
732 ParameterException
733 {
734 super(id, gtuType, length, width, maximumSpeed, length.multiplyBy(0.5), simulator, network);
735 perceive();
736 }
737
738
739
740
741 public void setPerceptionInterval(final Duration perceptionInterval)
742 {
743 this.perceptionInterval = perceptionInterval;
744 }
745
746
747
748
749
750
751
752
753 public void perceive() throws SimRuntimeException, GTUException, NetworkException, ParameterException
754 {
755 getTacticalPlanner().getPerception().perceive();
756 getSimulator().scheduleEventRel(this.perceptionInterval, this, this, "perceive", null);
757 }
758 }
759
760
761
762
763 class GTUFollowingTacticalPlannerNoPerceive extends AbstractLaneBasedTacticalPlanner
764 {
765
766 private static final long serialVersionUID = 20151125L;
767
768
769
770
771
772
773 GTUFollowingTacticalPlannerNoPerceive(final GTUFollowingModelOld carFollowingModel, final LaneBasedGTU gtu)
774 {
775 super(carFollowingModel, gtu, new CategoricalLanePerception(gtu));
776 }
777
778
779 @Override
780 public OperationalPlan generateOperationalPlan(final Time startTime, final DirectedPoint locationAtStartTime)
781 throws OperationalPlanException, NetworkException, GTUException, ParameterException
782 {
783
784
785
786 if (getGtu().getMaximumSpeed().si < OperationalPlan.DRIFTING_SPEED_SI)
787 {
788
789 return new OperationalPlan(getGtu(), locationAtStartTime, startTime,
790 new Duration(StraightPerceptionModel.this.perceptionIntervalDist.draw(), DurationUnit.SECOND));
791 }
792
793
794
795
796
797
798 LanePathInfo lanePathInfo =
799 buildLanePathInfo(getGtu(), getGtu().getParameters().getParameter(ParameterTypes.LOOKAHEAD));
800 Length maxDistance = lanePathInfo.getPath().getLength();
801
802
803 DefaultSimplePerception simplePerception = getPerception().getPerceptionCategory(DefaultSimplePerception.class);
804 Headway headwayGTU = simplePerception.getForwardHeadwayGTU();
805 AccelerationStep accelerationStep = null;
806 if (headwayGTU.getDistance().le(maxDistance))
807 {
808 accelerationStep = ((GTUFollowingModelOld) this.getCarFollowingModel())
809 .computeAccelerationStepWithNoLeader(getGtu(), maxDistance, simplePerception.getSpeedLimit());
810 }
811 else
812 {
813
814 accelerationStep = ((GTUFollowingModelOld) this.getCarFollowingModel()).computeAccelerationStep(getGtu(),
815 headwayGTU.getSpeed(), headwayGTU.getDistance(), maxDistance, simplePerception.getSpeedLimit());
816 }
817
818
819 if (accelerationStep.getAcceleration().si < 1E-6 && getGtu().getSpeed().si < OperationalPlan.DRIFTING_SPEED_SI)
820 {
821 return new OperationalPlan(getGtu(), locationAtStartTime, startTime, accelerationStep.getDuration());
822 }
823
824 List<Segment> operationalPlanSegmentList = new ArrayList<>();
825 if (accelerationStep.getAcceleration().si == 0.0)
826 {
827 Segment segment = new OperationalPlan.SpeedSegment(accelerationStep.getDuration());
828 operationalPlanSegmentList.add(segment);
829 }
830 else
831 {
832 Segment segment = new OperationalPlan.AccelerationSegment(accelerationStep.getDuration(),
833 accelerationStep.getAcceleration());
834 operationalPlanSegmentList.add(segment);
835 }
836 OperationalPlan op = new OperationalPlan(getGtu(), lanePathInfo.getPath(), startTime, getGtu().getSpeed(),
837 operationalPlanSegmentList);
838 return op;
839 }
840 }
841 }
842 }