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.rmi.RemoteException;
7 import java.util.ArrayList;
8 import java.util.Iterator;
9 import java.util.LinkedHashSet;
10 import java.util.List;
11 import java.util.Random;
12 import java.util.Set;
13
14 import javax.naming.NamingException;
15 import javax.swing.JPanel;
16 import javax.swing.SwingUtilities;
17
18 import nl.tudelft.simulation.dsol.SimRuntimeException;
19 import nl.tudelft.simulation.dsol.gui.swing.TablePanel;
20 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
21
22 import org.djunits.unit.TimeUnit;
23 import org.djunits.unit.UNITS;
24 import org.djunits.value.vdouble.scalar.Acceleration;
25 import org.djunits.value.vdouble.scalar.DoubleScalar;
26 import org.djunits.value.vdouble.scalar.DoubleScalar.Abs;
27 import org.djunits.value.vdouble.scalar.DoubleScalar.Rel;
28 import org.djunits.value.vdouble.scalar.Length;
29 import org.djunits.value.vdouble.scalar.Speed;
30 import org.djunits.value.vdouble.scalar.Time;
31 import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
32 import org.opentrafficsim.core.dsol.OTSModelInterface;
33 import org.opentrafficsim.core.dsol.OTSSimTimeDouble;
34 import org.opentrafficsim.core.geometry.OTSGeometryException;
35 import org.opentrafficsim.core.geometry.OTSPoint3D;
36 import org.opentrafficsim.core.gtu.GTUDirectionality;
37 import org.opentrafficsim.core.gtu.GTUException;
38 import org.opentrafficsim.core.gtu.GTUType;
39 import org.opentrafficsim.core.gtu.animation.GTUColorer;
40 import org.opentrafficsim.core.gtu.plan.tactical.TacticalPlanner;
41 import org.opentrafficsim.core.network.LongitudinalDirectionality;
42 import org.opentrafficsim.core.network.NetworkException;
43 import org.opentrafficsim.core.network.OTSNetwork;
44 import org.opentrafficsim.core.network.OTSNode;
45 import org.opentrafficsim.graphs.AccelerationContourPlot;
46 import org.opentrafficsim.graphs.ContourPlot;
47 import org.opentrafficsim.graphs.DensityContourPlot;
48 import org.opentrafficsim.graphs.FlowContourPlot;
49 import org.opentrafficsim.graphs.LaneBasedGTUSampler;
50 import org.opentrafficsim.graphs.SpeedContourPlot;
51 import org.opentrafficsim.graphs.TrajectoryPlot;
52 import org.opentrafficsim.road.gtu.animation.DefaultCarAnimation;
53 import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
54 import org.opentrafficsim.road.gtu.lane.driver.LaneBasedBehavioralCharacteristics;
55 import org.opentrafficsim.road.gtu.lane.perception.LanePerceptionFull;
56 import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedCFLCTacticalPlanner;
57 import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedGTUFollowingChange0TacticalPlanner;
58 import org.opentrafficsim.road.gtu.lane.tactical.LaneBasedGTUFollowingLaneChangeTacticalPlanner;
59 import org.opentrafficsim.road.gtu.lane.tactical.following.GTUFollowingModelOld;
60 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMOld;
61 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusOld;
62 import org.opentrafficsim.road.gtu.lane.tactical.lanechangemobil.AbstractLaneChangeModel;
63 import org.opentrafficsim.road.gtu.lane.tactical.lanechangemobil.Altruistic;
64 import org.opentrafficsim.road.gtu.lane.tactical.lanechangemobil.Egoistic;
65 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
66 import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlanner;
67 import org.opentrafficsim.road.network.factory.LaneFactory;
68 import org.opentrafficsim.road.network.lane.DirectedLanePosition;
69 import org.opentrafficsim.road.network.lane.Lane;
70 import org.opentrafficsim.road.network.lane.LaneType;
71 import org.opentrafficsim.simulationengine.AbstractWrappableAnimation;
72 import org.opentrafficsim.simulationengine.OTSSimulationException;
73 import org.opentrafficsim.simulationengine.properties.AbstractProperty;
74 import org.opentrafficsim.simulationengine.properties.BooleanProperty;
75 import org.opentrafficsim.simulationengine.properties.CompoundProperty;
76 import org.opentrafficsim.simulationengine.properties.ContinuousProperty;
77 import org.opentrafficsim.simulationengine.properties.IDMPropertySet;
78 import org.opentrafficsim.simulationengine.properties.IntegerProperty;
79 import org.opentrafficsim.simulationengine.properties.ProbabilityDistributionProperty;
80 import org.opentrafficsim.simulationengine.properties.PropertyException;
81 import org.opentrafficsim.simulationengine.properties.SelectionProperty;
82
83
84
85
86
87
88
89
90
91
92
93 public class CircularRoad extends AbstractWrappableAnimation implements UNITS
94 {
95
96 private RoadSimulationModel model;
97
98
99 public CircularRoad()
100 {
101 this.properties.add(new SelectionProperty("Lane changing", "<html>The lane change strategies vary in politeness.<br>"
102 + "Two types are implemented:<ul><li>Egoistic (looks only at personal gain).</li>"
103 + "<li>Altruistic (assigns effect on new and current follower the same weight as "
104 + "the personal gain).</html>", new String[] { "Egoistic", "Altruistic" }, 0, false, 500));
105 this.properties.add(new SelectionProperty("Tactical planner",
106 "<html>The tactical planner determines if a lane change is desired and possible.</html>", new String[] {
107 "MOBIL", "Verbraeck", "Verbraeck0" }, 0, false, 600));
108 this.properties.add(new IntegerProperty("Track length", "Circumference of the track", 2000, 500, 6000,
109 "Track length %dm", false, 10));
110 this.properties.add(new ContinuousProperty("Mean density", "Number of vehicles per km", 40.0, 5.0, 45.0,
111 "Density %.1f veh/km", false, 11));
112 this.properties.add(new ContinuousProperty("Density variability", "Variability of the number of vehicles per km", 0.0,
113 0.0, 1.0, "%.1f", false, 12));
114 ArrayList<AbstractProperty<?>> outputProperties = new ArrayList<AbstractProperty<?>>();
115 for (int lane = 1; lane <= 2; lane++)
116 {
117 String laneId = String.format("Lane %d ", lane);
118 outputProperties.add(new BooleanProperty(laneId + "Density", laneId + "Density contour plot", true, false, 0));
119 outputProperties.add(new BooleanProperty(laneId + "Flow", laneId + "Flow contour plot", true, false, 1));
120 outputProperties.add(new BooleanProperty(laneId + "Speed", laneId + "Speed contour plot", true, false, 2));
121 outputProperties.add(new BooleanProperty(laneId + "Acceleration", laneId + "Acceleration contour plot", true,
122 false, 3));
123 outputProperties.add(new BooleanProperty(laneId + "Trajectories", laneId + "Trajectory (time/distance) diagram",
124 true, false, 4));
125 }
126 this.properties.add(new CompoundProperty("Output graphs", "Select the graphical output", outputProperties, true, 1000));
127 }
128
129
130 @Override
131 public final void stopTimersThreads()
132 {
133 super.stopTimersThreads();
134 this.model = null;
135 }
136
137
138
139
140
141
142 public static void main(final String[] args) throws SimRuntimeException
143 {
144 SwingUtilities.invokeLater(new Runnable()
145 {
146 @Override
147 public void run()
148 {
149 try
150 {
151 CircularRoad circularRoad = new CircularRoad();
152 ArrayList<AbstractProperty<?>> propertyList = circularRoad.getProperties();
153 try
154 {
155 propertyList.add(new ProbabilityDistributionProperty("Traffic composition",
156 "<html>Mix of passenger cars and trucks</html>", new String[] { "passenger car", "truck" },
157 new Double[] { 0.8, 0.2 }, false, 10));
158 }
159 catch (PropertyException exception)
160 {
161 exception.printStackTrace();
162 }
163 propertyList.add(new SelectionProperty("Car following model", "<html>The car following model determines "
164 + "the acceleration that a vehicle will make taking into account "
165 + "nearby vehicles, infrastructural restrictions (e.g. speed limit, "
166 + "curvature of the road) capabilities of the vehicle and personality " + "of the driver.</html>",
167 new String[] { "IDM", "IDM+" }, 1, false, 1));
168 propertyList.add(IDMPropertySet
169 .makeIDMPropertySet("Car", new Acceleration(1.0, METER_PER_SECOND_2), new Acceleration(1.5,
170 METER_PER_SECOND_2), new Length.Rel(2.0, METER), new Time.Rel(1.0, SECOND), 2));
171 propertyList.add(IDMPropertySet.makeIDMPropertySet("Truck", new Acceleration(0.5, METER_PER_SECOND_2),
172 new Acceleration(1.25, METER_PER_SECOND_2), new Length.Rel(2.0, METER), new Time.Rel(1.0, SECOND),
173 3));
174
175 circularRoad.buildAnimator(new Time.Abs(0.0, SECOND), new Time.Rel(0.0, SECOND), new Time.Rel(3600.0,
176 SECOND), propertyList, null, true);
177 }
178 catch (SimRuntimeException | NamingException | OTSSimulationException exception)
179 {
180 exception.printStackTrace();
181 }
182 }
183 });
184 }
185
186
187 @Override
188 protected final OTSModelInterface makeModel(final GTUColorer colorer)
189 {
190 this.model = new RoadSimulationModel(getSavedUserModifiedProperties(), colorer);
191 return this.model;
192 }
193
194
195
196
197 private ArrayList<AbstractProperty<?>> getSavedUserModifiedProperties()
198 {
199 return this.savedUserModifiedProperties;
200 }
201
202
203 @Override
204 protected final Rectangle2D.Double makeAnimationRectangle()
205 {
206 return new Rectangle2D.Double(-350, -350, 700, 700);
207 }
208
209
210 @Override
211 protected final JPanel makeCharts() throws OTSSimulationException
212 {
213
214 AbstractProperty<?> output = new CompoundProperty("", "", this.properties, false, 0).findByShortName("Output graphs");
215 if (null == output)
216 {
217 throw new Error("Cannot find output properties");
218 }
219 ArrayList<BooleanProperty> graphs = new ArrayList<BooleanProperty>();
220 if (output instanceof CompoundProperty)
221 {
222 CompoundProperty outputProperties = (CompoundProperty) output;
223 for (AbstractProperty<?> ap : outputProperties.getValue())
224 {
225 if (ap instanceof BooleanProperty)
226 {
227 BooleanProperty bp = (BooleanProperty) ap;
228 if (bp.getValue())
229 {
230 graphs.add(bp);
231 }
232 }
233 }
234 }
235 else
236 {
237 throw new Error("output properties should be compound");
238 }
239
240 int graphCount = graphs.size();
241 int columns = (int) Math.ceil(Math.sqrt(graphCount));
242 int rows = 0 == columns ? 0 : (int) Math.ceil(graphCount * 1.0 / columns);
243 TablePanel charts = new TablePanel(columns, rows);
244
245 for (int i = 0; i < graphCount; i++)
246 {
247 String graphName = graphs.get(i).getShortName();
248 Container container = null;
249 LaneBasedGTUSampler graph;
250 int pos = graphName.indexOf(' ') + 1;
251 String laneNumberText = graphName.substring(pos, pos + 1);
252 int lane = Integer.parseInt(laneNumberText) - 1;
253
254 if (graphName.contains("Trajectories"))
255 {
256 TrajectoryPlot tp = new TrajectoryPlot(graphName, new Time.Rel(0.5, SECOND), this.model.getPath(lane));
257 tp.setTitle("Trajectory Graph");
258 tp.setExtendedState(Frame.MAXIMIZED_BOTH);
259 graph = tp;
260 container = tp.getContentPane();
261 }
262 else
263 {
264 ContourPlot cp;
265 if (graphName.contains("Density"))
266 {
267 cp = new DensityContourPlot(graphName, this.model.getPath(lane));
268 cp.setTitle("Density Contour Graph");
269 }
270 else if (graphName.contains("Speed"))
271 {
272 cp = new SpeedContourPlot(graphName, this.model.getPath(lane));
273 cp.setTitle("Speed Contour Graph");
274 }
275 else if (graphName.contains("Flow"))
276 {
277 cp = new FlowContourPlot(graphName, this.model.getPath(lane));
278 cp.setTitle("Flow Contour Graph");
279 }
280 else if (graphName.contains("Acceleration"))
281 {
282 cp = new AccelerationContourPlot(graphName, this.model.getPath(lane));
283 cp.setTitle("Acceleration Contour Graph");
284 }
285 else
286 {
287 throw new Error("Unhandled type of contourplot: " + graphName);
288 }
289 graph = cp;
290 container = cp.getContentPane();
291 }
292
293 charts.setCell(container, i % columns, i / columns);
294 this.model.getPlots().add(graph);
295 }
296
297 return charts;
298 }
299
300
301 @Override
302 public final String shortName()
303 {
304 return "Circular Road simulation";
305 }
306
307
308 @Override
309 public final String description()
310 {
311 return "<html><h1>Circular Road simulation</h1>" + "Vehicles are unequally distributed over a two lane ring road.<br>"
312 + "When simulation starts, all vehicles begin driving, some lane changes will occurr and some "
313 + "shockwaves should develop.<br>"
314 + "Trajectories and contourplots are generated during the simulation for both lanes.</html>";
315 }
316
317 }
318
319
320
321
322
323
324
325
326
327
328
329 class RoadSimulationModel implements OTSModelInterface, UNITS
330 {
331
332 private static final long serialVersionUID = 20141121L;
333
334
335 private OTSDEVSSimulatorInterface simulator;
336
337
338 private OTSNetwork network = new OTSNetwork("network");
339
340
341 private int carsCreated = 0;
342
343
344 private GTUFollowingModelOld carFollowingModelCars;
345
346
347 private GTUFollowingModelOld carFollowingModelTrucks;
348
349
350 private double carProbability;
351
352
353 private AbstractLaneChangeModel laneChangeModel;
354
355
356 private Length.Rel minimumDistance = new Length.Rel(0, METER);
357
358
359 private Speed speedLimit = new Speed(100, KM_PER_HOUR);
360
361
362 private ArrayList<LaneBasedGTUSampler> plots = new ArrayList<LaneBasedGTUSampler>();
363
364
365 private ArrayList<AbstractProperty<?>> properties = null;
366
367
368 private ArrayList<List<Lane>> paths = new ArrayList<List<Lane>>();
369
370
371 private Random randomGenerator = new Random(12345);
372
373
374 private final GTUColorer gtuColorer;
375
376
377 private TacticalPlanner tacticalPlanner = null;
378
379
380
381
382
383 public RoadSimulationModel(final ArrayList<AbstractProperty<?>> properties, final GTUColorer gtuColorer)
384 {
385 this.properties = properties;
386 this.gtuColorer = gtuColorer;
387 }
388
389
390
391
392
393 public List<Lane> getPath(final int index)
394 {
395 return this.paths.get(index);
396 }
397
398
399 @Override
400 public void constructModel(final SimulatorInterface<Abs<TimeUnit>, Rel<TimeUnit>, OTSSimTimeDouble> theSimulator)
401 throws SimRuntimeException, RemoteException
402 {
403 final int laneCount = 2;
404 for (int laneIndex = 0; laneIndex < laneCount; laneIndex++)
405 {
406 this.paths.add(new ArrayList<Lane>());
407 }
408 this.simulator = (OTSDEVSSimulatorInterface) theSimulator;
409 double radius = 6000 / 2 / Math.PI;
410 double headway = 40;
411 double headwayVariability = 0;
412 try
413 {
414 String carFollowingModelName = null;
415 CompoundProperty propertyContainer = new CompoundProperty("", "", this.properties, false, 0);
416 AbstractProperty<?> cfmp = propertyContainer.findByShortName("Car following model");
417 if (null == cfmp)
418 {
419 throw new Error("Cannot find \"Car following model\" property");
420 }
421 if (cfmp instanceof SelectionProperty)
422 {
423 carFollowingModelName = ((SelectionProperty) cfmp).getValue();
424 }
425 else
426 {
427 throw new Error("\"Car following model\" property has wrong type");
428 }
429 Iterator<AbstractProperty<ArrayList<AbstractProperty<?>>>> iterator =
430 new CompoundProperty("", "", this.properties, false, 0).iterator();
431 while (iterator.hasNext())
432 {
433 AbstractProperty<?> ap = iterator.next();
434 if (ap instanceof SelectionProperty)
435 {
436 SelectionProperty sp = (SelectionProperty) ap;
437 if ("Car following model".equals(sp.getShortName()))
438 {
439 carFollowingModelName = sp.getValue();
440 }
441 else if ("Lane changing".equals(sp.getShortName()))
442 {
443 String strategyName = sp.getValue();
444 if ("Egoistic".equals(strategyName))
445 {
446 this.laneChangeModel = new Egoistic();
447 }
448 else if ("Altruistic".equals(strategyName))
449 {
450 this.laneChangeModel = new Altruistic();
451 }
452 else
453 {
454 throw new Error("Lane changing " + strategyName + " not implemented");
455 }
456 }
457 else if ("Tactical planner".equals(sp.getShortName()))
458 {
459 String tacticalPlannerName = sp.getValue();
460 if ("MOBIL".equals(tacticalPlannerName))
461 {
462 this.tacticalPlanner = new LaneBasedCFLCTacticalPlanner();
463 }
464 else if ("Verbraeck".equals(tacticalPlannerName))
465 {
466 this.tacticalPlanner = new LaneBasedGTUFollowingLaneChangeTacticalPlanner();
467 }
468 else if ("Verbraeck0".equals(tacticalPlannerName))
469 {
470 this.tacticalPlanner = new LaneBasedGTUFollowingChange0TacticalPlanner();
471 }
472 else
473 {
474 throw new Error("Don't know how to create a " + tacticalPlannerName + " tactical planner");
475 }
476 }
477 }
478 else if (ap instanceof ProbabilityDistributionProperty)
479 {
480 ProbabilityDistributionProperty pdp = (ProbabilityDistributionProperty) ap;
481 if (ap.getShortName().equals("Traffic composition"))
482 {
483 this.carProbability = pdp.getValue()[0];
484 }
485 }
486 else if (ap instanceof IntegerProperty)
487 {
488 IntegerProperty ip = (IntegerProperty) ap;
489 if ("Track length".equals(ip.getShortName()))
490 {
491 radius = ip.getValue() / 2 / Math.PI;
492 }
493 }
494 else if (ap instanceof ContinuousProperty)
495 {
496 ContinuousProperty cp = (ContinuousProperty) ap;
497 if (cp.getShortName().equals("Mean density"))
498 {
499 headway = 1000 / cp.getValue();
500 }
501 if (cp.getShortName().equals("Density variability"))
502 {
503 headwayVariability = cp.getValue();
504 }
505 }
506 else if (ap instanceof CompoundProperty)
507 {
508 CompoundProperty cp = (CompoundProperty) ap;
509 if (ap.getShortName().equals("Output graphs"))
510 {
511 continue;
512 }
513 if (ap.getShortName().contains("IDM"))
514 {
515
516 Acceleration a = IDMPropertySet.getA(cp);
517 Acceleration b = IDMPropertySet.getB(cp);
518 Length.Rel s0 = IDMPropertySet.getS0(cp);
519 Time.Rel tSafe = IDMPropertySet.getTSafe(cp);
520 GTUFollowingModelOld gtuFollowingModel = null;
521 if (carFollowingModelName.equals("IDM"))
522 {
523 gtuFollowingModel = new IDMOld(a, b, s0, tSafe, 1.0);
524 }
525 else if (carFollowingModelName.equals("IDM+"))
526 {
527 gtuFollowingModel = new IDMPlusOld(a, b, s0, tSafe, 1.0);
528 }
529 else
530 {
531 throw new Error("Unknown gtu following model: " + carFollowingModelName);
532 }
533 if (ap.getShortName().contains(" Car "))
534 {
535 this.carFollowingModelCars = gtuFollowingModel;
536 }
537 else if (ap.getShortName().contains(" Truck "))
538 {
539 this.carFollowingModelTrucks = gtuFollowingModel;
540 }
541 else
542 {
543 throw new Error("Cannot determine gtu type for " + ap.getShortName());
544 }
545 }
546 }
547 }
548 GTUType gtuType = GTUType.makeGTUType("car");
549 LaneType laneType = new LaneType("CarLane");
550 laneType.addCompatibility(gtuType);
551 OTSNode start = new OTSNode("Start", new OTSPoint3D(radius, 0, 0));
552 OTSNode halfway = new OTSNode("Halfway", new OTSPoint3D(-radius, 0, 0));
553
554 OTSPoint3D[] coordsHalf1 = new OTSPoint3D[127];
555 for (int i = 0; i < coordsHalf1.length; i++)
556 {
557 double angle = Math.PI * (1 + i) / (1 + coordsHalf1.length);
558 coordsHalf1[i] = new OTSPoint3D(radius * Math.cos(angle), radius * Math.sin(angle), 0);
559 }
560 Lane[] lanes1 =
561 LaneFactory.makeMultiLane("FirstHalf", start, halfway, coordsHalf1, laneCount, laneType, this.speedLimit,
562 this.simulator, LongitudinalDirectionality.DIR_PLUS);
563 OTSPoint3D[] coordsHalf2 = new OTSPoint3D[127];
564 for (int i = 0; i < coordsHalf2.length; i++)
565 {
566 double angle = Math.PI + Math.PI * (1 + i) / (1 + coordsHalf2.length);
567 coordsHalf2[i] = new OTSPoint3D(radius * Math.cos(angle), radius * Math.sin(angle), 0);
568 }
569 Lane[] lanes2 =
570 LaneFactory.makeMultiLane("SecondHalf", halfway, start, coordsHalf2, laneCount, laneType, this.speedLimit,
571 this.simulator, LongitudinalDirectionality.DIR_PLUS);
572 for (int laneIndex = 0; laneIndex < laneCount; laneIndex++)
573 {
574 this.paths.get(laneIndex).add(lanes1[laneIndex]);
575 this.paths.get(laneIndex).add(lanes2[laneIndex]);
576 }
577
578 double variability = (headway - 20) * headwayVariability;
579 System.out.println("headway is " + headway + " variability limit is " + variability);
580 Random random = new Random(12345);
581 for (int laneIndex = 0; laneIndex < laneCount; laneIndex++)
582 {
583 double lane1Length = lanes1[laneIndex].getLength().getSI();
584 double trackLength = lane1Length + lanes2[laneIndex].getLength().getSI();
585 for (double pos = 0; pos <= trackLength - headway - variability;)
586 {
587 Lane lane = pos >= lane1Length ? lanes2[laneIndex] : lanes1[laneIndex];
588
589 double laneRelativePos = pos > lane1Length ? pos - lane1Length : pos;
590 double actualHeadway = headway + (random.nextDouble() * 2 - 1) * variability;
591
592 generateCar(new Length.Rel(laneRelativePos, METER), lane, gtuType);
593 pos += actualHeadway;
594 }
595 }
596
597 this.simulator.scheduleEventAbs(new DoubleScalar.Abs<TimeUnit>(9.999, SECOND), this, this, "drawGraphs", null);
598 }
599 catch (SimRuntimeException | NamingException | NetworkException | GTUException | OTSGeometryException exception)
600 {
601 exception.printStackTrace();
602 }
603 }
604
605
606
607
608 protected final void drawGraphs()
609 {
610 for (LaneBasedGTUSampler plot : this.plots)
611 {
612 plot.reGraph();
613 }
614
615 try
616 {
617 this.simulator.scheduleEventAbs(new Time.Abs(this.simulator.getSimulatorTime().get().getSI() + 10, SECOND), this,
618 this, "drawGraphs", null);
619 }
620 catch (SimRuntimeException exception)
621 {
622 exception.printStackTrace();
623 }
624
625 }
626
627
628
629
630
631
632
633
634
635
636
637
638 protected final void generateCar(final Length.Rel initialPosition, final Lane lane, final GTUType gtuType)
639 throws NamingException, NetworkException, SimRuntimeException, GTUException, OTSGeometryException
640 {
641 boolean generateTruck = this.randomGenerator.nextDouble() > this.carProbability;
642 Speed initialSpeed = new Speed(0, KM_PER_HOUR);
643 Set<DirectedLanePosition> initialPositions = new LinkedHashSet<>(1);
644 initialPositions.add(new DirectedLanePosition(lane, initialPosition, GTUDirectionality.DIR_PLUS));
645 Length.Rel vehicleLength = new Length.Rel(generateTruck ? 15 : 4, METER);
646 LaneBasedBehavioralCharacteristics drivingCharacteristics =
647 new LaneBasedBehavioralCharacteristics(generateTruck ? this.carFollowingModelTrucks : this.carFollowingModelCars,
648 this.laneChangeModel);
649 LaneBasedStrategicalPlanner strategicalPlanner = new LaneBasedStrategicalRoutePlanner(drivingCharacteristics,
650 this.tacticalPlanner);
651 new LaneBasedIndividualGTU("" + (++this.carsCreated), gtuType, initialPositions, initialSpeed, vehicleLength,
652 new Length.Rel(1.8, METER), new Speed(200, KM_PER_HOUR), this.simulator, strategicalPlanner,
653 new LanePerceptionFull(), DefaultCarAnimation.class, this.gtuColorer, this.network);
654 }
655
656
657 @Override
658 public SimulatorInterface<Abs<TimeUnit>, Rel<TimeUnit>, OTSSimTimeDouble> getSimulator() throws RemoteException
659 {
660 return this.simulator;
661 }
662
663
664
665
666 public final ArrayList<LaneBasedGTUSampler> getPlots()
667 {
668 return this.plots;
669 }
670
671
672
673
674 public final Length.Rel getMinimumDistance()
675 {
676 return this.minimumDistance;
677 }
678
679
680
681
682
683
684 public void stopSimulator(final OTSDEVSSimulatorInterface theSimulator, final String errorMessage)
685 {
686 System.out.println("Error: " + errorMessage);
687 try
688 {
689 if (theSimulator.isRunning())
690 {
691 theSimulator.stop();
692 }
693 }
694 catch (SimRuntimeException exception)
695 {
696 exception.printStackTrace();
697 }
698 throw new Error(errorMessage);
699 }
700
701 }