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