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
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 OTSRoadNetwork 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.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
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 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
181
182
183
184
185
186
187
188
189
190
191
192
193
194 static class FundamentalDiagramPlotsModel extends AbstractOTSModel implements UNITS
195 {
196
197 private static final long serialVersionUID = 20140820L;
198
199
200 private OTSRoadNetwork network = new OTSRoadNetwork("network", true);
201
202
203 private Duration headway;
204
205
206 private int carsCreated = 0;
207
208
209 private LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerGeneratorCars = null;
210
211
212 private LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerGeneratorTrucks = null;
213
214
215 private Parameters parametersCar;
216
217
218 private Parameters parametersTruck;
219
220
221 private double carProbability;
222
223
224 private SimpleTrafficLight block = null;
225
226
227 private Length minimumDistance = new Length(0, METER);
228
229
230 private Length maximumDistance = new Length(5000, METER);
231
232
233 private Lane lane;
234
235
236 private Speed speedLimit = new Speed(100, KM_PER_HOUR);
237
238
239 private StreamInterface stream = new MersenneTwister(12345);
240
241
242
243
244 FundamentalDiagramPlotsModel(final OTSSimulatorInterface simulator)
245 {
246 super(simulator);
247 InputParameterHelper.makeInputParameterMapCarTruck(this.inputParameterMap, 1.0);
248 }
249
250
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
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
282 this.headway = new Duration(3600.0 / 1500.0, SECOND);
283
284
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
292 this.simulator.scheduleEventAbs(new Time(300, TimeUnit.BASE_SECOND), this, this, "createBlock", null);
293
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
305
306 protected final void createBlock()
307 {
308 this.block.setTrafficLightColor(TrafficLightColor.RED);
309 }
310
311
312
313
314 protected final void removeBlock()
315 {
316 this.block.setTrafficLightColor(TrafficLightColor.GREEN);
317 }
318
319
320
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
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
355 @Override
356 public OTSRoadNetwork getNetwork()
357 {
358 return this.network;
359 }
360
361
362
363
364 public final Length getMinimumDistance()
365 {
366 return this.minimumDistance;
367 }
368
369
370
371
372 public final Length getMaximumDistance()
373 {
374 return this.maximumDistance;
375 }
376
377
378
379
380 public Lane getLane()
381 {
382 return this.lane;
383 }
384 }
385
386
387 @Override
388 public final String toString()
389 {
390 return "FundamentalDiagrams [model=" + getModel() + "]";
391 }
392
393 }