View Javadoc
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.Iterator;
11  import java.util.LinkedHashMap;
12  import java.util.List;
13  import java.util.Map;
14  import java.util.Random;
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 nl.tudelft.simulation.dsol.SimRuntimeException;
23  import nl.tudelft.simulation.dsol.gui.swing.HTMLPanel;
24  import nl.tudelft.simulation.dsol.gui.swing.TablePanel;
25  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
26  
27  import org.djunits.unit.TimeUnit;
28  import org.djunits.value.vdouble.scalar.DoubleScalar;
29  import org.djunits.value.vdouble.scalar.DoubleScalar.Abs;
30  import org.djunits.value.vdouble.scalar.DoubleScalar.Rel;
31  import org.opentrafficsim.core.OTS_SCALAR;
32  import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
33  import org.opentrafficsim.core.dsol.OTSModelInterface;
34  import org.opentrafficsim.core.dsol.OTSSimTimeDouble;
35  import org.opentrafficsim.core.geometry.OTSGeometryException;
36  import org.opentrafficsim.core.geometry.OTSPoint3D;
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.network.NetworkException;
41  import org.opentrafficsim.core.network.OTSNode;
42  import org.opentrafficsim.core.network.route.CompleteRoute;
43  import org.opentrafficsim.graphs.AccelerationContourPlot;
44  import org.opentrafficsim.graphs.ContourPlot;
45  import org.opentrafficsim.graphs.DensityContourPlot;
46  import org.opentrafficsim.graphs.FlowContourPlot;
47  import org.opentrafficsim.graphs.LaneBasedGTUSampler;
48  import org.opentrafficsim.graphs.SpeedContourPlot;
49  import org.opentrafficsim.graphs.TrajectoryPlot;
50  import org.opentrafficsim.road.car.LaneBasedIndividualCar;
51  import org.opentrafficsim.road.gtu.animation.DefaultCarAnimation;
52  import org.opentrafficsim.road.gtu.following.GTUFollowingModel;
53  import org.opentrafficsim.road.gtu.following.IDM;
54  import org.opentrafficsim.road.gtu.following.IDMPlus;
55  import org.opentrafficsim.road.gtu.lane.changing.AbstractLaneChangeModel;
56  import org.opentrafficsim.road.gtu.lane.changing.Egoistic;
57  import org.opentrafficsim.road.network.factory.LaneFactory;
58  import org.opentrafficsim.road.network.lane.CrossSectionLink;
59  import org.opentrafficsim.road.network.lane.Lane;
60  import org.opentrafficsim.road.network.lane.LaneType;
61  import org.opentrafficsim.road.network.lane.Sensor;
62  import org.opentrafficsim.road.network.lane.SinkSensor;
63  import org.opentrafficsim.road.network.route.CompleteLaneBasedRouteNavigator;
64  import org.opentrafficsim.simulationengine.AbstractWrappableAnimation;
65  import org.opentrafficsim.simulationengine.properties.AbstractProperty;
66  import org.opentrafficsim.simulationengine.properties.BooleanProperty;
67  import org.opentrafficsim.simulationengine.properties.CompoundProperty;
68  import org.opentrafficsim.simulationengine.properties.IDMPropertySet;
69  import org.opentrafficsim.simulationengine.properties.ProbabilityDistributionProperty;
70  import org.opentrafficsim.simulationengine.properties.PropertyException;
71  import org.opentrafficsim.simulationengine.properties.SelectionProperty;
72  
73  /**
74   * Single lane road consisting of three consecutive links.<br>
75   * Tests that GTUs correctly transfer themselves onto the next lane and that the graph samplers handle this situation.
76   * <p>
77   * Copyright (c) 2013-2015 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
78   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
79   * <p>
80   * $LastChangedDate: 2015-09-24 19:14:49 +0200 (Thu, 24 Sep 2015) $, @version $Revision: 1430 $, by $Author: averbraeck $,
81   * initial version 30 jan. 2015 <br>
82   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
83   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
84   */
85  public class SequentialLanes extends AbstractWrappableAnimation
86  {
87      /** the model. */
88      private SequentialModel model;
89  
90      /** Create a SequentialLanes simulation. */
91      public SequentialLanes()
92      {
93          ArrayList<AbstractProperty<?>> outputProperties = new ArrayList<AbstractProperty<?>>();
94          outputProperties.add(new BooleanProperty("Density", "Density contour plot", true, false, 0));
95          outputProperties.add(new BooleanProperty("Flow", "Flow contour plot", true, false, 1));
96          outputProperties.add(new BooleanProperty("Speed", "Speed contour plot", true, false, 2));
97          outputProperties.add(new BooleanProperty("Acceleration", "Acceleration contour plot", true, false, 3));
98          outputProperties.add(new BooleanProperty("Trajectories", "Trajectory (time/distance) diagram", true, false, 4));
99          this.properties.add(new CompoundProperty("Output graphs", "Select the graphical output", outputProperties, true,
100             1000));
101     }
102 
103     /** {@inheritDoc} */
104     @Override
105     public final void stopTimersThreads()
106     {
107         super.stopTimersThreads();
108         this.model = null;
109     }
110 
111     /**
112      * Main program.
113      * @param args String[]; the command line arguments (not used)
114      * @throws SimRuntimeException when simulation cannot be created with given parameters
115      */
116     public static void main(final String[] args) throws SimRuntimeException
117     {
118         SwingUtilities.invokeLater(new Runnable()
119         {
120             @Override
121             public void run()
122             {
123                 try
124                 {
125                     SequentialLanes sequential = new SequentialLanes();
126                     ArrayList<AbstractProperty<?>> localProperties = sequential.getProperties();
127                     try
128                     {
129                         localProperties.add(new ProbabilityDistributionProperty("Traffic composition",
130                             "<html>Mix of passenger cars and trucks</html>", new String[]{"passenger car", "truck"},
131                             new Double[]{0.8, 0.2}, false, 10));
132                     }
133                     catch (PropertyException exception)
134                     {
135                         exception.printStackTrace();
136                     }
137                     localProperties.add(new SelectionProperty("Car following model",
138                         "<html>The car following model determines "
139                             + "the acceleration that a vehicle will make taking into account "
140                             + "nearby vehicles, infrastructural restrictions (e.g. speed limit, "
141                             + "curvature of the road) capabilities of the vehicle and personality "
142                             + "of the driver.</html>", new String[]{"IDM", "IDM+"}, 1, false, 1));
143                     localProperties.add(IDMPropertySet.makeIDMPropertySet("Car", new Acceleration.Abs(1.0,
144                         METER_PER_SECOND_2), new Acceleration.Abs(1.5, METER_PER_SECOND_2), new Length.Rel(2.0, METER),
145                         new Time.Rel(1.0, SECOND), 2));
146                     localProperties.add(IDMPropertySet.makeIDMPropertySet("Truck", new Acceleration.Abs(0.5,
147                         METER_PER_SECOND_2), new Acceleration.Abs(1.25, METER_PER_SECOND_2), new Length.Rel(2.0, METER),
148                         new Time.Rel(1.0, SECOND), 3));
149                     sequential.buildAnimator(new Time.Abs(0.0, SECOND), new Time.Rel(0.0, SECOND), new Time.Rel(3600.0,
150                         SECOND), localProperties, null, true);
151                     sequential.panel.getTabbedPane().addTab("info", sequential.makeInfoPane());
152                 }
153                 catch (SimRuntimeException | NamingException exception)
154                 {
155                     exception.printStackTrace();
156                 }
157             }
158         });
159     }
160 
161     /** {@inheritDoc} */
162     @Override
163     protected final Rectangle2D.Double makeAnimationRectangle()
164     {
165         return new Rectangle2D.Double(0, -100, 2010, 200);
166     }
167 
168     /** {@inheritDoc} */
169     @Override
170     protected final OTSModelInterface makeModel(final GTUColorer colorer)
171     {
172         this.model = new SequentialModel(this.savedUserModifiedProperties, colorer);
173         return this.model;
174     }
175 
176     /**
177      * @return an info pane to be added to the tabbed pane.
178      */
179     protected final JComponent makeInfoPane()
180     {
181         // Make the info tab
182         String helpSource = "/" + StraightModel.class.getPackage().getName().replace('.', '/') + "/IDMPlus.html";
183         URL page = StraightModel.class.getResource(helpSource);
184         if (page != null)
185         {
186             try
187             {
188                 HTMLPanel htmlPanel = new HTMLPanel(page);
189                 return new JScrollPane(htmlPanel);
190             }
191             catch (IOException exception)
192             {
193                 exception.printStackTrace();
194             }
195         }
196         return new JPanel();
197     }
198 
199     /** {@inheritDoc} */
200     @Override
201     protected final JPanel makeCharts()
202     {
203         // Make the tab with the plots
204         AbstractProperty<?> output =
205             new CompoundProperty("", "", this.properties, false, 0).findByShortName("Output graphs");
206         if (null == output)
207         {
208             throw new Error("Cannot find output properties");
209         }
210         ArrayList<BooleanProperty> graphs = new ArrayList<BooleanProperty>();
211         if (output instanceof CompoundProperty)
212         {
213             CompoundProperty outputProperties = (CompoundProperty) output;
214             for (AbstractProperty<?> ap : outputProperties.getValue())
215             {
216                 if (ap instanceof BooleanProperty)
217                 {
218                     BooleanProperty bp = (BooleanProperty) ap;
219                     if (bp.getValue())
220                     {
221                         graphs.add(bp);
222                     }
223                 }
224             }
225         }
226         else
227         {
228             throw new Error("output properties should be compound");
229         }
230         int graphCount = graphs.size();
231         int columns = (int) Math.ceil(Math.sqrt(graphCount));
232         int rows = 0 == columns ? 0 : (int) Math.ceil(graphCount * 1.0 / columns);
233         TablePanel charts = new TablePanel(columns, rows);
234 
235         for (int i = 0; i < graphCount; i++)
236         {
237             String graphName = graphs.get(i).getShortName();
238             Container container = null;
239             LaneBasedGTUSampler graph;
240             if (graphName.contains("Trajectories"))
241             {
242                 TrajectoryPlot tp = new TrajectoryPlot("TrajectoryPlot", new Time.Rel(0.5, SECOND), this.model.getPath());
243                 tp.setTitle("Trajectory Graph");
244                 tp.setExtendedState(Frame.MAXIMIZED_BOTH);
245                 graph = tp;
246                 container = tp.getContentPane();
247             }
248             else
249             {
250                 ContourPlot cp;
251                 if (graphName.contains("Density"))
252                 {
253                     cp = new DensityContourPlot("DensityPlot", this.model.getPath());
254                     cp.setTitle("Density Contour Graph");
255                 }
256                 else if (graphName.contains("Speed"))
257                 {
258                     cp = new SpeedContourPlot("SpeedPlot", this.model.getPath());
259                     cp.setTitle("Speed Contour Graph");
260                 }
261                 else if (graphName.contains("Flow"))
262                 {
263                     cp = new FlowContourPlot("FlowPlot", this.model.getPath());
264                     cp.setTitle("Flow Contour Graph");
265                 }
266                 else if (graphName.contains("Acceleration"))
267                 {
268                     cp = new AccelerationContourPlot("AccelerationPlot", this.model.getPath());
269                     cp.setTitle("Acceleration Contour Graph");
270                 }
271                 else
272                 {
273                     continue;
274                     // throw new Error("Unhandled type of contourplot: " + graphName);
275                 }
276                 graph = cp;
277                 container = cp.getContentPane();
278             }
279             // Add the container to the matrix
280             charts.setCell(container, i % columns, i / columns);
281             this.model.getPlots().add(graph);
282         }
283         return charts;
284     }
285 
286     /** {@inheritDoc} */
287     @Override
288     public final String shortName()
289     {
290         return "Sequential Lanes";
291     }
292 
293     /** {@inheritDoc} */
294     @Override
295     public final String description()
296     {
297         return "<html><h1>Simulation of a straight one-lane road consisting of three consecutive Links</H1>"
298             + "Simulation of a single lane road consisting of two 1 km stretches with a 1m stretch in between. "
299             + "This will test transition of a GTU from one lane section onto the next.<br />"
300             + "Vehicles are generated at a constant rate of 1500 veh/hour.<br />"
301             + "Selected trajectory and contour plots are generated during the simulation.</html>";
302     }
303 
304 }
305 
306 /**
307  * Build the sequential model.
308  * <p>
309  * Copyright (c) 2013-2015 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
310  * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
311  * <p>
312  * $LastChangedDate: 2015-09-24 19:14:49 +0200 (Thu, 24 Sep 2015) $, @version $Revision: 1430 $, by $Author: averbraeck $,
313  * initial version 0 jan. 2015 <br>
314  * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
315  */
316 class SequentialModel implements OTSModelInterface, OTS_SCALAR
317 {
318     /** */
319     private static final long serialVersionUID = 20150130L;
320 
321     /** the simulator. */
322     private OTSDEVSSimulatorInterface simulator;
323 
324     /** The nodes of our network in the order that all GTUs will visit them. */
325     private ArrayList<OTSNode> nodes = new ArrayList<OTSNode>();
326 
327     /** the car following model, e.g. IDM Plus for cars. */
328     private GTUFollowingModel carFollowingModelCars;
329 
330     /** the car following model, e.g. IDM Plus for trucks. */
331     private GTUFollowingModel carFollowingModelTrucks;
332 
333     /** The probability that the next generated GTU is a passenger car. */
334     private double carProbability;
335 
336     /** The lane change model. */
337     private AbstractLaneChangeModel laneChangeModel = new Egoistic();
338 
339     /** the headway (inter-vehicle time). */
340     private Time.Rel headway;
341 
342     /** number of cars created. */
343     private int carsCreated = 0;
344 
345     /** Type of all GTUs. */
346     private GTUType gtuType = GTUType.makeGTUType("Car");
347 
348     /** minimum distance. */
349     private Length.Rel minimumDistance = new Length.Rel(0, METER);
350 
351     /** The Lane where newly created Cars initially placed on. */
352     private Lane initialLane;
353 
354     /** maximum distance. */
355     private Length.Rel maximumDistance = new Length.Rel(2001, METER);
356 
357     /** the contour plots. */
358     private ArrayList<LaneBasedGTUSampler> plots = new ArrayList<LaneBasedGTUSampler>();
359 
360     /** The random number generator used to decide what kind of GTU to generate. */
361     private Random randomGenerator = new Random(12345);
362 
363     /** User settable properties. */
364     private ArrayList<AbstractProperty<?>> properties = null;
365 
366     /** The sequence of Lanes that all vehicles will follow. */
367     private List<Lane> path = new ArrayList<Lane>();
368 
369     /** The speedLimit on all Lanes. */
370     private Speed.Abs speedLimit;
371 
372     /** The GTUColorer for the generated vehicles. */
373     private final GTUColorer gtuColorer;
374 
375     /**
376      * @param properties the user settable properties
377      * @param gtuColorer the default and initial GTUColorer, e.g. a DefaultSwitchableTUColorer.
378      */
379     public SequentialModel(final ArrayList<AbstractProperty<?>> properties, final GTUColorer gtuColorer)
380     {
381         this.properties = properties;
382         this.gtuColorer = gtuColorer;
383     }
384 
385     /**
386      * @return a newly created path (which all GTUs in this simulation will follow).
387      */
388     public List<Lane> getPath()
389     {
390         return new ArrayList<Lane>(this.path);
391     }
392 
393     /** {@inheritDoc} */
394     @Override
395     public final void constructModel(final SimulatorInterface<Abs<TimeUnit>, Rel<TimeUnit>, OTSSimTimeDouble> theSimulator)
396         throws SimRuntimeException, RemoteException
397     {
398         this.simulator = (OTSDEVSSimulatorInterface) theSimulator;
399         this.speedLimit = new Speed.Abs(100, KM_PER_HOUR);
400         this.nodes = new ArrayList<OTSNode>();
401         // TODO use: int[] linkBoundaries = {0, 1000, 1001, 2001, 2200};
402         int[] linkBoundaries = {0, 1000, 2001, 2200};
403         for (int xPos : linkBoundaries)
404         {
405             this.nodes.add(new OTSNode("Node at " + xPos, new OTSPoint3D(xPos, xPos > 1001 ? 200 : -10, 0)));
406         }
407         LaneType laneType = new LaneType("CarLane");
408         laneType.addCompatibility(this.gtuType);
409         // Now we can build a series of Links with one Lane on them
410         ArrayList<CrossSectionLink> links = new ArrayList<CrossSectionLink>();
411         for (int i = 1; i < this.nodes.size(); i++)
412         {
413             OTSNode fromNode = this.nodes.get(i - 1);
414             OTSNode toNode = this.nodes.get(i);
415             String linkName = fromNode.getId() + "-" + toNode.getId();
416             try
417             {
418                 Lane[] lanes =
419                     LaneFactory
420                         .makeMultiLane(linkName, fromNode, toNode, null, 1, laneType, this.speedLimit, this.simulator);
421                 if (i == this.nodes.size() - 1)
422                 {
423                     Sensor sensor = new SinkSensor(lanes[0], new Length.Rel(10.0, METER), this.simulator);
424                     lanes[0].addSensor(sensor, GTUType.ALL);
425                 }
426                 this.path.add(lanes[0]);
427                 links.add(lanes[0].getParentLink());
428                 if (1 == i)
429                 {
430                     this.initialLane = lanes[0];
431                 }
432             }
433             catch (NamingException | NetworkException | OTSGeometryException exception)
434             {
435                 exception.printStackTrace();
436             }
437         }
438 
439         // 1500 [veh / hour] == 2.4s headway
440         this.headway = new Time.Rel(3600.0 / 1500.0, SECOND);
441         // Schedule creation of the first car (it will re-schedule itself one headway later, etc.).
442         this.simulator.scheduleEventAbs(new DoubleScalar.Abs<TimeUnit>(0.0, SECOND), this, this, "generateCar", null);
443         // Schedule regular updates of the graphs
444         for (int t = 1; t <= 1800; t++)
445         {
446             this.simulator.scheduleEventAbs(new DoubleScalar.Abs<TimeUnit>(t - 0.001, SECOND), this, this, "drawGraphs",
447                 null);
448         }
449         try
450         {
451             String carFollowingModelName = null;
452             CompoundProperty propertyContainer = new CompoundProperty("", "", this.properties, false, 0);
453             AbstractProperty<?> cfmp = propertyContainer.findByShortName("Car following model");
454             if (null == cfmp)
455             {
456                 throw new Error("Cannot find \"Car following model\" property");
457             }
458             if (cfmp instanceof SelectionProperty)
459             {
460                 carFollowingModelName = ((SelectionProperty) cfmp).getValue();
461             }
462             else
463             {
464                 throw new Error("\"Car following model\" property has wrong type");
465             }
466             Iterator<AbstractProperty<ArrayList<AbstractProperty<?>>>> iterator =
467                 new CompoundProperty("", "", this.properties, false, 0).iterator();
468             while (iterator.hasNext())
469             {
470                 AbstractProperty<?> ap = iterator.next();
471                 if (ap instanceof SelectionProperty)
472                 {
473                     SelectionProperty sp = (SelectionProperty) ap;
474                     if ("Car following model".equals(sp.getShortName()))
475                     {
476                         carFollowingModelName = sp.getValue();
477                     }
478                 }
479                 else if (ap instanceof ProbabilityDistributionProperty)
480                 {
481                     ProbabilityDistributionProperty pdp = (ProbabilityDistributionProperty) ap;
482                     if (ap.getShortName().equals("Traffic composition"))
483                     {
484                         this.carProbability = pdp.getValue()[0];
485                     }
486                 }
487                 else if (ap instanceof CompoundProperty)
488                 {
489                     CompoundProperty cp = (CompoundProperty) ap;
490                     if (ap.getShortName().equals("Output graphs"))
491                     {
492                         continue; // Output settings are handled elsewhere
493                     }
494                     if (ap.getShortName().contains("IDM"))
495                     {
496                         // System.out.println("Car following model name appears to be " + ap.getShortName());
497                         Acceleration.Abs a = IDMPropertySet.getA(cp);
498                         Acceleration.Abs b = IDMPropertySet.getB(cp);
499                         Length.Rel s0 = IDMPropertySet.getS0(cp);
500                         Time.Rel tSafe = IDMPropertySet.getTSafe(cp);
501                         GTUFollowingModel gtuFollowingModel = null;
502                         if (carFollowingModelName.equals("IDM"))
503                         {
504                             gtuFollowingModel = new IDM(a, b, s0, tSafe, 1.0);
505                         }
506                         else if (carFollowingModelName.equals("IDM+"))
507                         {
508                             gtuFollowingModel = new IDMPlus(a, b, s0, tSafe, 1.0);
509                         }
510                         else
511                         {
512                             throw new Error("Unknown gtu following model: " + carFollowingModelName);
513                         }
514                         if (ap.getShortName().contains(" Car "))
515                         {
516                             this.carFollowingModelCars = gtuFollowingModel;
517                         }
518                         else if (ap.getShortName().contains(" Truck "))
519                         {
520                             this.carFollowingModelTrucks = gtuFollowingModel;
521                         }
522                         else
523                         {
524                             throw new Error("Cannot determine gtu type for " + ap.getShortName());
525                         }
526                     }
527                 }
528             }
529         }
530         catch (Exception e)
531         {
532             System.out.println("Caught exception " + e);
533         }
534     }
535 
536     /** {@inheritDoc} */
537     @Override
538     public SimulatorInterface<Abs<TimeUnit>, Rel<TimeUnit>, OTSSimTimeDouble> getSimulator() throws RemoteException
539     {
540         return this.simulator;
541     }
542 
543     /**
544      * @return contourPlots
545      */
546     public final ArrayList<LaneBasedGTUSampler> getPlots()
547     {
548         return this.plots;
549     }
550 
551     /**
552      * @return minimumDistance
553      */
554     public final Length.Rel getMinimumDistance()
555     {
556         return this.minimumDistance;
557     }
558 
559     /**
560      * @return maximumDistance
561      */
562     public final Length.Rel getMaximumDistance()
563     {
564         return this.maximumDistance;
565     }
566 
567     /**
568      * Notify the contour plots that the underlying data has changed.
569      */
570     protected final void drawGraphs()
571     {
572         for (LaneBasedGTUSampler plot : this.plots)
573         {
574             plot.reGraph();
575         }
576     }
577 
578     /**
579      * Generate cars at a fixed rate (implemented by re-scheduling this method).
580      */
581     protected final void generateCar()
582     {
583         boolean generateTruck = this.randomGenerator.nextDouble() > this.carProbability;
584         Length.Rel initialPosition = new Length.Rel(0, METER);
585         Speed.Abs initialSpeed = new Speed.Abs(100, KM_PER_HOUR);
586         Map<Lane, Length.Rel> initialPositions = new LinkedHashMap<Lane, Length.Rel>();
587         initialPositions.put(this.initialLane, initialPosition);
588         try
589         {
590             Length.Rel vehicleLength = new Length.Rel(generateTruck ? 15 : 4, METER);
591             GTUFollowingModel gtuFollowingModel = generateTruck ? this.carFollowingModelTrucks : this.carFollowingModelCars;
592             if (null == gtuFollowingModel)
593             {
594                 throw new Error("gtuFollowingModel is null");
595             }
596             new LaneBasedIndividualCar("" + (++this.carsCreated), this.gtuType, generateTruck ? this.carFollowingModelTrucks
597                 : this.carFollowingModelCars, this.laneChangeModel, initialPositions, initialSpeed, vehicleLength,
598                 new Length.Rel(1.8, METER), new Speed.Abs(200, KM_PER_HOUR), new CompleteLaneBasedRouteNavigator(
599                     new CompleteRoute("")), this.simulator, DefaultCarAnimation.class, this.gtuColorer);
600             this.simulator.scheduleEventRel(this.headway, this, this, "generateCar", null);
601         }
602         catch (SimRuntimeException | NamingException | NetworkException | GTUException exception)
603         {
604             exception.printStackTrace();
605         }
606     }
607 
608 }