View Javadoc
1   package org.opentrafficsim.demo;
2   
3   import java.awt.Dimension;
4   import java.rmi.RemoteException;
5   import java.util.LinkedHashSet;
6   import java.util.Set;
7   
8   import javax.naming.NamingException;
9   
10  import org.djunits.unit.LengthUnit;
11  import org.djunits.unit.TimeUnit;
12  import org.djunits.unit.util.UNITS;
13  import org.djunits.value.vdouble.scalar.Acceleration;
14  import org.djunits.value.vdouble.scalar.Direction;
15  import org.djunits.value.vdouble.scalar.Duration;
16  import org.djunits.value.vdouble.scalar.Length;
17  import org.djunits.value.vdouble.scalar.Speed;
18  import org.djunits.value.vdouble.scalar.Time;
19  import org.djutils.exceptions.Try;
20  import org.opentrafficsim.base.parameters.ParameterException;
21  import org.opentrafficsim.base.parameters.Parameters;
22  import org.opentrafficsim.core.compatibility.Compatible;
23  import org.opentrafficsim.core.dsol.AbstractOTSModel;
24  import org.opentrafficsim.core.dsol.OTSAnimator;
25  import org.opentrafficsim.core.dsol.OTSSimulationException;
26  import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
27  import org.opentrafficsim.core.geometry.OTSGeometryException;
28  import org.opentrafficsim.core.geometry.OTSPoint3D;
29  import org.opentrafficsim.core.gtu.GTUDirectionality;
30  import org.opentrafficsim.core.gtu.GTUException;
31  import org.opentrafficsim.core.gtu.GTUType;
32  import org.opentrafficsim.core.network.NetworkException;
33  import org.opentrafficsim.demo.FundamentalDiagrams.FundamentalDiagramPlotsModel;
34  import org.opentrafficsim.draw.core.OTSDrawingException;
35  import org.opentrafficsim.draw.graphs.FundamentalDiagram;
36  import org.opentrafficsim.draw.graphs.FundamentalDiagram.Quantity;
37  import org.opentrafficsim.draw.graphs.road.GraphLaneUtil;
38  import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
39  import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusFactory;
40  import org.opentrafficsim.road.gtu.lane.tactical.lmrs.DefaultLMRSPerceptionFactory;
41  import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRSFactory;
42  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
43  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
44  import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
45  import org.opentrafficsim.road.network.OTSRoadNetwork;
46  import org.opentrafficsim.road.network.factory.LaneFactory;
47  import org.opentrafficsim.road.network.lane.CrossSectionLink;
48  import org.opentrafficsim.road.network.lane.DirectedLanePosition;
49  import org.opentrafficsim.road.network.lane.Lane;
50  import org.opentrafficsim.road.network.lane.LaneType;
51  import org.opentrafficsim.road.network.lane.OTSRoadNode;
52  import org.opentrafficsim.road.network.lane.object.sensor.SinkSensor;
53  import org.opentrafficsim.road.network.lane.object.trafficlight.SimpleTrafficLight;
54  import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLightColor;
55  import org.opentrafficsim.road.network.sampling.RoadSampler;
56  import org.opentrafficsim.swing.graphs.SwingFundamentalDiagram;
57  import org.opentrafficsim.swing.gui.OTSAnimationPanel;
58  import org.opentrafficsim.swing.gui.OTSSimulationApplication;
59  
60  import nl.tudelft.simulation.dsol.SimRuntimeException;
61  import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterException;
62  import nl.tudelft.simulation.dsol.swing.gui.TablePanel;
63  import nl.tudelft.simulation.dsol.swing.gui.inputparameters.TabbedParameterDialog;
64  import nl.tudelft.simulation.jstats.streams.MersenneTwister;
65  import nl.tudelft.simulation.jstats.streams.StreamInterface;
66  
67  /**
68   * Demonstrate the FundamentalDiagram plot.
69   * <p>
70   * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
71   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
72   * <p>
73   * $LastChangedDate: 2020-01-23 11:14:19 +0100 (Thu, 23 Jan 2020) $, @version $Revision: 6010 $, by $Author: averbraeck $,
74   * initial version 17 dec. 2014 <br>
75   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
76   */
77  public class FundamentalDiagrams extends OTSSimulationApplication<FundamentalDiagramPlotsModel> implements UNITS
78  {
79      /** */
80      private static final long serialVersionUID = 1L;
81  
82      /**
83       * Create a Straight Swing application.
84       * @param title String; the title of the Frame
85       * @param panel OTSAnimationPanel; the tabbed panel to display
86       * @param model FundamentalDiagramPlotsModel; the model
87       * @throws OTSDrawingException on animation error
88       * @throws OTSSimulationException on graph error
89       */
90      public FundamentalDiagrams(final String title, final OTSAnimationPanel panel, final FundamentalDiagramPlotsModel model)
91              throws OTSDrawingException, OTSSimulationException
92      {
93          super(model, panel);
94          OTSRoadNetwork network = model.getNetwork();
95          System.out.println(network.getLinkMap());
96      }
97  
98      /** {@inheritDoc} */
99      @Override
100     protected void addTabs()
101     {
102         Try.execute(() -> addStatisticsTabs(getModel().getSimulator()), RuntimeException.class,
103                 "Exception while setting up the statistics tabs.");
104     }
105 
106     /**
107      * Main program.
108      * @param args String[]; the command line arguments (not used)
109      */
110     public static void main(final String[] args)
111     {
112         demo(true);
113     }
114 
115     /**
116      * Start the demo.
117      * @param exitOnClose boolean; when running stand-alone: true; when running as part of a demo: false
118      */
119     public static void demo(final boolean exitOnClose)
120     {
121         try
122         {
123             OTSAnimator simulator = new OTSAnimator();
124             final FundamentalDiagramPlotsModel otsModel = new FundamentalDiagramPlotsModel(simulator);
125             if (TabbedParameterDialog.process(otsModel.getInputParameterMap()))
126             {
127                 simulator.initialize(Time.ZERO, Duration.ZERO, Duration.instantiateSI(3600.0), otsModel);
128                 OTSAnimationPanel animationPanel = new OTSAnimationPanel(otsModel.getNetwork().getExtent(),
129                         new Dimension(800, 600), simulator, otsModel, DEFAULT_COLORER, otsModel.getNetwork());
130                 FundamentalDiagramsms.html#FundamentalDiagrams">FundamentalDiagrams app = new FundamentalDiagrams("FundamentalDiagrams", animationPanel, otsModel);
131                 app.setExitOnClose(exitOnClose);
132             }
133             else
134             {
135                 if (exitOnClose)
136                 {
137                     System.exit(0);
138                 }
139             }
140         }
141         catch (SimRuntimeException | NamingException | RemoteException | OTSDrawingException | OTSSimulationException exception)
142         {
143             exception.printStackTrace();
144         }
145     }
146 
147     /**
148      * Add the statistics tabs.
149      * @param simulator OTSSimulatorInterface; the simulator on which sampling can be scheduled
150      * @throws OTSSimulationException on error
151      */
152     protected final void addStatisticsTabs(final OTSSimulatorInterface simulator) throws OTSSimulationException
153     {
154         final int panelsPerRow = 3;
155         TablePanel charts = new TablePanel(4, panelsPerRow);
156         RoadSampler sampler = new RoadSampler(simulator);
157         for (int plotNumber = 0; plotNumber < 10; plotNumber++)
158         {
159             Length detectorLocation = new Length(400 + 500 * plotNumber, METER);
160             String name = "Fundamental Diagram at " + detectorLocation.getSI() + "m";
161             SwingFundamentalDiagram graph;
162             try
163             {
164                 graph = new SwingFundamentalDiagram(new FundamentalDiagram(name, Quantity.DENSITY, Quantity.FLOW, simulator,
165                         sampler,
166                         GraphLaneUtil.createCrossSection(name,
167                                 new DirectedLanePosition(getModel().getLane(), detectorLocation, GTUDirectionality.DIR_PLUS)),
168                         false, Duration.instantiateSI(60.0), false));
169             }
170             catch (NetworkException | GTUException exception)
171             {
172                 throw new OTSSimulationException(exception);
173             }
174             charts.setCell(graph.getContentPane(), plotNumber / panelsPerRow, plotNumber % panelsPerRow);
175         }
176         getAnimationPanel().getTabbedPane().addTab(getAnimationPanel().getTabbedPane().getTabCount(), "statistics ", charts);
177     }
178 
179     /**
180      * Simulate a single lane road of 5 km length. Vehicles are generated at a constant rate of 1500 veh/hour. At time 300s a
181      * blockade is inserted at position 4 km; this blockade is removed at time 500s. The used car following algorithm is IDM+
182      * <a href="http://opentrafficsim.org/downloads/MOTUS%20reference.pdf"><i>Integrated Lane Change Model with Relaxation and
183      * Synchronization</i>, by Wouter J. Schakel, Victor L. Knoop and Bart van Arem, 2012</a>. <br>
184      * Output is a set of FundamentalDiagram plots for various point along the lane.
185      * <p>
186      * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
187      * <br>
188      * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
189      * <p>
190      * $LastChangedDate: 2020-01-23 11:14:19 +0100 (Thu, 23 Jan 2020) $, @version $Revision: 6010 $, by $Author: averbraeck $,
191      * initial version ug 1, 2014 <br>
192      * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
193      */
194     static class FundamentalDiagramPlotsModel extends AbstractOTSModel implements UNITS
195     {
196         /** */
197         private static final long serialVersionUID = 20140820L;
198 
199         /** The network. */
200         private OTSRoadNetwork network = new OTSRoadNetwork("network", true);
201 
202         /** The headway (inter-vehicle time). */
203         private Duration headway;
204 
205         /** Number of cars created. */
206         private int carsCreated = 0;
207 
208         /** Strategical planner generator for cars. */
209         private LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerGeneratorCars = null;
210 
211         /** Strategical planner generator for trucks. */
212         private LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerGeneratorTrucks = null;
213 
214         /** Car parameters. */
215         private Parameters parametersCar;
216 
217         /** Truck parameters. */
218         private Parameters parametersTruck;
219 
220         /** The probability that the next generated GTU is a passenger car. */
221         private double carProbability;
222 
223         /** The blocking, implemented as a traffic light. */
224         private SimpleTrafficLight block = null;
225 
226         /** Minimum distance. */
227         private Length minimumDistance = new Length(0, METER);
228 
229         /** Maximum distance. */
230         private Length maximumDistance = new Length(5000, METER);
231 
232         /** The Lane containing the simulated Cars. */
233         private Lane lane;
234 
235         /** The speed limit. */
236         private Speed speedLimit = new Speed(100, KM_PER_HOUR);
237 
238         /** The random number generator used to decide what kind of GTU to generate. */
239         private StreamInterface stream = new MersenneTwister(12345);
240 
241         /**
242          * @param simulator OTSSimulatorInterface; the simulator for this model
243          */
244         FundamentalDiagramPlotsModel(final OTSSimulatorInterface simulator)
245         {
246             super(simulator);
247             InputParameterHelper.makeInputParameterMapCarTruck(this.inputParameterMap, 1.0);
248         }
249 
250         /** {@inheritDoc} */
251         @Override
252         public final void constructModel() throws SimRuntimeException
253         {
254             try
255             {
256                 OTSRoadNode from = new OTSRoadNode(this.network, "From", new OTSPoint3D(getMinimumDistance().getSI(), 0, 0),
257                         Direction.ZERO);
258                 OTSRoadNode to =
259                         new OTSRoadNode(this.network, "To", new OTSPoint3D(getMaximumDistance().getSI(), 0, 0), Direction.ZERO);
260                 OTSRoadNode end = new OTSRoadNode(this.network, "End",
261                         new OTSPoint3D(getMaximumDistance().getSI() + 50.0, 0, 0), Direction.ZERO);
262                 LaneType laneType = this.network.getLaneType(LaneType.DEFAULTS.TWO_WAY_LANE);
263                 this.lane =
264                         LaneFactory.makeLane(this.network, "Lane", from, to, null, laneType, this.speedLimit, this.simulator);
265                 CrossSectionLink endLink = LaneFactory.makeLink(this.network, "endLink", to, end, null, this.simulator);
266                 // No overtaking, single lane
267                 Lane sinkLane = new Lane(endLink, "sinkLane", this.lane.getLateralCenterPosition(1.0),
268                         this.lane.getLateralCenterPosition(1.0), this.lane.getWidth(1.0), this.lane.getWidth(1.0), laneType,
269                         this.speedLimit);
270                 new SinkSensor(sinkLane, new Length(10.0, METER), Compatible.EVERYTHING, this.simulator);
271 
272                 this.carProbability = (double) getInputParameter("generic.carProbability");
273                 this.parametersCar = InputParameterHelper.getParametersCar(getInputParameterMap());
274                 this.parametersTruck = InputParameterHelper.getParametersTruck(getInputParameterMap());
275 
276                 this.strategicalPlannerGeneratorCars = new LaneBasedStrategicalRoutePlannerFactory(
277                         new LMRSFactory(new IDMPlusFactory(this.stream), new DefaultLMRSPerceptionFactory()));
278                 this.strategicalPlannerGeneratorTrucks = new LaneBasedStrategicalRoutePlannerFactory(
279                         new LMRSFactory(new IDMPlusFactory(this.stream), new DefaultLMRSPerceptionFactory()));
280 
281                 // 1500 [veh / hour] == 2.4s headway
282                 this.headway = new Duration(3600.0 / 1500.0, SECOND);
283 
284                 // Schedule creation of the first car (this will re-schedule itself one headway later, etc.).
285                 this.simulator.scheduleEventAbs(Time.ZERO, this, this, "generateCar", null);
286 
287                 this.block = new SimpleTrafficLight(this.lane.getId() + "_TL", this.lane,
288                         new Length(new Length(4000.0, LengthUnit.METER)), this.simulator);
289                 this.block.setTrafficLightColor(TrafficLightColor.GREEN);
290 
291                 // Create a block at t = 5 minutes
292                 this.simulator.scheduleEventAbs(new Time(300, TimeUnit.BASE_SECOND), this, this, "createBlock", null);
293                 // Remove the block at t = 7 minutes
294                 this.simulator.scheduleEventAbs(new Time(420, TimeUnit.BASE_SECOND), this, this, "removeBlock", null);
295             }
296             catch (SimRuntimeException | NetworkException | GTUException | OTSGeometryException | ParameterException
297                     | InputParameterException exception)
298             {
299                 exception.printStackTrace();
300             }
301         }
302 
303         /**
304          * Set up the block.
305          */
306         protected final void createBlock()
307         {
308             this.block.setTrafficLightColor(TrafficLightColor.RED);
309         }
310 
311         /**
312          * Remove the block.
313          */
314         protected final void removeBlock()
315         {
316             this.block.setTrafficLightColor(TrafficLightColor.GREEN);
317         }
318 
319         /**
320          * Generate cars at a fixed rate (implemented by re-scheduling this method).
321          */
322         protected final void generateCar()
323         {
324             try
325             {
326                 boolean generateTruck = this.stream.nextDouble() > this.carProbability;
327                 Length vehicleLength = new Length(generateTruck ? 15 : 4, METER);
328                 LaneBasedIndividualGTU gtu = new LaneBasedIndividualGTU("" + (++this.carsCreated),
329                         this.network.getGtuType(GTUType.DEFAULTS.CAR), vehicleLength, new Length(1.8, METER),
330                         new Speed(200, KM_PER_HOUR), vehicleLength.times(0.5), this.simulator, this.network);
331                 gtu.setParameters(generateTruck ? this.parametersTruck : this.parametersCar);
332                 gtu.setNoLaneChangeDistance(Length.ZERO);
333                 gtu.setMaximumAcceleration(Acceleration.instantiateSI(3.0));
334                 gtu.setMaximumDeceleration(Acceleration.instantiateSI(-8.0));
335 
336                 // strategical planner
337                 LaneBasedStrategicalPlanner strategicalPlanner =
338                         generateTruck ? this.strategicalPlannerGeneratorTrucks.create(gtu, null, null, null)
339                                 : this.strategicalPlannerGeneratorCars.create(gtu, null, null, null);
340 
341                 Set<DirectedLanePosition> initialPositions = new LinkedHashSet<>(1);
342                 Length initialPosition = new Length(20, METER);
343                 initialPositions.add(new DirectedLanePosition(this.lane, initialPosition, GTUDirectionality.DIR_PLUS));
344                 Speed initialSpeed = new Speed(100.0, KM_PER_HOUR);
345                 gtu.init(strategicalPlanner, initialPositions, initialSpeed);
346                 this.simulator.scheduleEventRel(this.headway, this, this, "generateCar", null);
347             }
348             catch (SimRuntimeException | NetworkException | GTUException | OTSGeometryException exception)
349             {
350                 exception.printStackTrace();
351             }
352         }
353 
354         /** {@inheritDoc} */
355         @Override
356         public OTSRoadNetwork getNetwork()
357         {
358             return this.network;
359         }
360 
361         /**
362          * @return minimumDistance
363          */
364         public final Length getMinimumDistance()
365         {
366             return this.minimumDistance;
367         }
368 
369         /**
370          * @return maximumDistance
371          */
372         public final Length getMaximumDistance()
373         {
374             return this.maximumDistance;
375         }
376 
377         /**
378          * @return lane.
379          */
380         public Lane getLane()
381         {
382             return this.lane;
383         }
384     }
385 
386     /** {@inheritDoc} */
387     @Override
388     public final String toString()
389     {
390         return "FundamentalDiagrams [model=" + getModel() + "]";
391     }
392 
393 }