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