1   package org.opentrafficsim.demo;
2   
3   import static org.opentrafficsim.core.gtu.GTUType.CAR;
4   
5   import java.awt.Dimension;
6   import java.rmi.RemoteException;
7   import java.util.LinkedHashSet;
8   import java.util.Set;
9   
10  import javax.naming.NamingException;
11  
12  import org.djunits.unit.LengthUnit;
13  import org.djunits.unit.TimeUnit;
14  import org.djunits.unit.UNITS;
15  import org.djunits.value.vdouble.scalar.Acceleration;
16  import org.djunits.value.vdouble.scalar.Duration;
17  import org.djunits.value.vdouble.scalar.Length;
18  import org.djunits.value.vdouble.scalar.Speed;
19  import org.djunits.value.vdouble.scalar.Time;
20  import org.djutils.exceptions.Try;
21  import org.opentrafficsim.base.parameters.ParameterException;
22  import org.opentrafficsim.base.parameters.Parameters;
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.core.network.OTSNetwork;
34  import org.opentrafficsim.core.network.OTSNode;
35  import org.opentrafficsim.demo.FundamentalDiagrams.FundamentalDiagramPlotsModel;
36  import org.opentrafficsim.draw.core.OTSDrawingException;
37  import org.opentrafficsim.draw.graphs.FundamentalDiagram;
38  import org.opentrafficsim.draw.graphs.FundamentalDiagram.Quantity;
39  import org.opentrafficsim.draw.graphs.road.GraphLaneUtil;
40  import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
41  import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusFactory;
42  import org.opentrafficsim.road.gtu.lane.tactical.lmrs.DefaultLMRSPerceptionFactory;
43  import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRSFactory;
44  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
45  import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
46  import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
47  import org.opentrafficsim.road.network.factory.LaneFactory;
48  import org.opentrafficsim.road.network.lane.CrossSectionLink;
49  import org.opentrafficsim.road.network.lane.DirectedLanePosition;
50  import org.opentrafficsim.road.network.lane.Lane;
51  import org.opentrafficsim.road.network.lane.LaneType;
52  import org.opentrafficsim.road.network.lane.changing.OvertakingConditions;
53  import org.opentrafficsim.road.network.lane.object.sensor.SinkSensor;
54  import org.opentrafficsim.road.network.lane.object.trafficlight.SimpleTrafficLight;
55  import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLightColor;
56  import org.opentrafficsim.road.network.sampling.RoadSampler;
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  
69  
70  
71  
72  
73  
74  
75  
76  
77  public class FundamentalDiagrams extends OTSSimulationApplication<FundamentalDiagramPlotsModel> implements UNITS
78  {
79      
80      private static final long serialVersionUID = 1L;
81  
82      
83  
84  
85  
86  
87  
88  
89  
90      public FundamentalDiagrams(final String title, final OTSAnimationPanel panel, final FundamentalDiagramPlotsModel model)
91              throws OTSDrawingException, OTSSimulationException
92      {
93          super(model, panel);
94          OTSNetwork network = model.getNetwork();
95          System.out.println(network.getLinkMap());
96      }
97  
98      
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 
108 
109 
110     public static void main(final String[] args)
111     {
112         demo(true);
113     }
114 
115     
116 
117 
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.createSI(3600.0), otsModel);
128                 OTSAnimationPanel animationPanel = new OTSAnimationPanel(otsModel.getNetwork().getExtent(),
129                         new Dimension(800, 600), simulator, otsModel, DEFAULT_COLORER, otsModel.getNetwork());
130                 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 
149 
150 
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             FundamentalDiagram graph;
162             try
163             {
164                 graph = new FundamentalDiagram(name, Quantity.DENSITY, Quantity.FLOW, simulator, sampler,
165                         GraphLaneUtil.createCrossSection(name,
166                                 new DirectedLanePosition(getModel().getLane(), detectorLocation, GTUDirectionality.DIR_PLUS)),
167                         false, Duration.createSI(60.0), false);
168             }
169             catch (NetworkException | GTUException exception)
170             {
171                 throw new OTSSimulationException(exception);
172             }
173             charts.setCell(graph.getContentPane(), plotNumber / panelsPerRow, plotNumber % panelsPerRow);
174         }
175         getAnimationPanel().getTabbedPane().addTab(getAnimationPanel().getTabbedPane().getTabCount(), "statistics ", charts);
176     }
177 
178     
179 
180 
181 
182 
183 
184 
185 
186 
187 
188 
189 
190 
191 
192 
193     static class FundamentalDiagramPlotsModel extends AbstractOTSModel implements UNITS
194     {
195         
196         private static final long serialVersionUID = 20140820L;
197 
198         
199         private OTSNetwork network = new OTSNetwork("network");
200 
201         
202         private Duration headway;
203 
204         
205         private int carsCreated = 0;
206 
207         
208         private GTUType gtuType = CAR;
209 
210         
211         private LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerGeneratorCars = null;
212 
213         
214         private LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerGeneratorTrucks = null;
215 
216         
217         private Parameters parametersCar;
218 
219         
220         private Parameters parametersTruck;
221 
222         
223         private double carProbability;
224 
225         
226         private SimpleTrafficLight block = null;
227 
228         
229         private Length minimumDistance = new Length(0, METER);
230 
231         
232         private Length maximumDistance = new Length(5000, METER);
233 
234         
235         private Lane lane;
236 
237         
238         private Speed speedLimit = new Speed(100, KM_PER_HOUR);
239 
240         
241         private StreamInterface stream = new MersenneTwister(12345);
242 
243         
244 
245 
246         FundamentalDiagramPlotsModel(final OTSSimulatorInterface simulator)
247         {
248             super(simulator);
249             InputParameterHelper.makeInputParameterMapCarTruck(this.inputParameterMap, 1.0);
250         }
251 
252         
253         @Override
254         public final void constructModel() throws SimRuntimeException
255         {
256             try
257             {
258                 OTSNode from = new OTSNode(this.network, "From", new OTSPoint3D(getMinimumDistance().getSI(), 0, 0));
259                 OTSNode to = new OTSNode(this.network, "To", new OTSPoint3D(getMaximumDistance().getSI(), 0, 0));
260                 OTSNode end = new OTSNode(this.network, "End", new OTSPoint3D(getMaximumDistance().getSI() + 50.0, 0, 0));
261                 LaneType laneType = LaneType.TWO_WAY_LANE;
262                 this.lane =
263                         LaneFactory.makeLane(this.network, "Lane", from, to, null, laneType, this.speedLimit, this.simulator);
264                 CrossSectionLink endLink = LaneFactory.makeLink(this.network, "endLink", to, end, null, this.simulator);
265                 
266                 Lane sinkLane = new Lane(endLink, "sinkLane", this.lane.getLateralCenterPosition(1.0),
267                         this.lane.getLateralCenterPosition(1.0), this.lane.getWidth(1.0), this.lane.getWidth(1.0), laneType,
268                         this.speedLimit, new OvertakingConditions.None());
269                 new SinkSensor(sinkLane, new Length(10.0, METER), this.simulator);
270 
271                 this.carProbability = (double) getInputParameter("generic.carProbability");
272                 this.parametersCar = InputParameterHelper.getParametersCar(getInputParameterMap());
273                 this.parametersTruck = InputParameterHelper.getParametersTruck(getInputParameterMap());
274 
275                 this.strategicalPlannerGeneratorCars = new LaneBasedStrategicalRoutePlannerFactory(
276                         new LMRSFactory(new IDMPlusFactory(this.stream), new DefaultLMRSPerceptionFactory()));
277                 this.strategicalPlannerGeneratorTrucks = new LaneBasedStrategicalRoutePlannerFactory(
278                         new LMRSFactory(new IDMPlusFactory(this.stream), new DefaultLMRSPerceptionFactory()));
279 
280                 
281                 this.headway = new Duration(3600.0 / 1500.0, SECOND);
282 
283                 
284                 this.simulator.scheduleEventAbs(Time.ZERO, this, this, "generateCar", null);
285 
286                 this.block = new SimpleTrafficLight(this.lane.getId() + "_TL", this.lane,
287                         new Length(new Length(4000.0, LengthUnit.METER)), this.simulator);
288                 this.block.setTrafficLightColor(TrafficLightColor.GREEN);
289 
290                 
291                 this.simulator.scheduleEventAbs(new Time(300, TimeUnit.BASE_SECOND), this, this, "createBlock", null);
292                 
293                 this.simulator.scheduleEventAbs(new Time(420, TimeUnit.BASE_SECOND), this, this, "removeBlock", null);
294             }
295             catch (SimRuntimeException | NetworkException | GTUException | OTSGeometryException | ParameterException
296                     | InputParameterException exception)
297             {
298                 exception.printStackTrace();
299             }
300         }
301 
302         
303 
304 
305         protected final void createBlock()
306         {
307             this.block.setTrafficLightColor(TrafficLightColor.RED);
308         }
309 
310         
311 
312 
313         protected final void removeBlock()
314         {
315             this.block.setTrafficLightColor(TrafficLightColor.GREEN);
316         }
317 
318         
319 
320 
321         protected final void generateCar()
322         {
323             try
324             {
325                 boolean generateTruck = this.stream.nextDouble() > this.carProbability;
326                 Length vehicleLength = new Length(generateTruck ? 15 : 4, METER);
327                 LaneBasedIndividualGTU gtu = new LaneBasedIndividualGTU("" + (++this.carsCreated), this.gtuType, vehicleLength,
328                         new Length(1.8, METER), new Speed(200, KM_PER_HOUR), vehicleLength.multiplyBy(0.5), this.simulator,
329                         this.network);
330                 gtu.setParameters(generateTruck ? this.parametersTruck : this.parametersCar);
331                 gtu.setNoLaneChangeDistance(Length.ZERO);
332                 gtu.setMaximumAcceleration(Acceleration.createSI(3.0));
333                 gtu.setMaximumDeceleration(Acceleration.createSI(-8.0));
334 
335                 
336                 LaneBasedStrategicalPlanner strategicalPlanner =
337                         generateTruck ? this.strategicalPlannerGeneratorTrucks.create(gtu, null, null, null)
338                                 : this.strategicalPlannerGeneratorCars.create(gtu, null, null, null);
339 
340                 Set<DirectedLanePosition> initialPositions = new LinkedHashSet<>(1);
341                 Length initialPosition = new Length(20, METER);
342                 initialPositions.add(new DirectedLanePosition(this.lane, initialPosition, GTUDirectionality.DIR_PLUS));
343                 Speed initialSpeed = new Speed(100.0, KM_PER_HOUR);
344                 gtu.init(strategicalPlanner, initialPositions, initialSpeed);
345                 this.simulator.scheduleEventRel(this.headway, this, this, "generateCar", null);
346             }
347             catch (SimRuntimeException | NetworkException | GTUException | OTSGeometryException exception)
348             {
349                 exception.printStackTrace();
350             }
351         }
352 
353         
354         @Override
355         public OTSNetwork getNetwork()
356         {
357             return this.network;
358         }
359 
360         
361 
362 
363         public final Length getMinimumDistance()
364         {
365             return this.minimumDistance;
366         }
367 
368         
369 
370 
371         public final Length getMaximumDistance()
372         {
373             return this.maximumDistance;
374         }
375 
376         
377 
378 
379         public Lane getLane()
380         {
381             return this.lane;
382         }
383     }
384 
385     
386     @Override
387     public final String toString()
388     {
389         return "FundamentalDiagrams [model=" + getModel() + "]";
390     }
391 
392 }