1 package org.opentrafficsim.demo;
2
3 import java.awt.Dimension;
4 import java.io.Serializable;
5 import java.rmi.RemoteException;
6 import java.util.ArrayList;
7 import java.util.Arrays;
8 import java.util.LinkedHashSet;
9 import java.util.List;
10 import java.util.Set;
11
12 import javax.naming.NamingException;
13
14 import org.djunits.unit.util.UNITS;
15 import org.djunits.value.vdouble.scalar.Acceleration;
16 import org.djunits.value.vdouble.scalar.Direction;
17 import org.djunits.value.vdouble.scalar.Duration;
18 import org.djunits.value.vdouble.scalar.Length;
19 import org.djunits.value.vdouble.scalar.Speed;
20 import org.djunits.value.vdouble.scalar.Time;
21 import org.opentrafficsim.base.parameters.ParameterException;
22 import org.opentrafficsim.base.parameters.Parameters;
23 import org.opentrafficsim.core.compatibility.Compatible;
24 import org.opentrafficsim.core.dsol.AbstractOTSModel;
25 import org.opentrafficsim.core.dsol.OTSAnimator;
26 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
27 import org.opentrafficsim.core.geometry.OTSGeometryException;
28 import org.opentrafficsim.core.geometry.OTSLine3D;
29 import org.opentrafficsim.core.geometry.OTSPoint3D;
30 import org.opentrafficsim.core.gtu.GTUDirectionality;
31 import org.opentrafficsim.core.gtu.GTUException;
32 import org.opentrafficsim.core.gtu.GTUType;
33 import org.opentrafficsim.core.network.NetworkException;
34 import org.opentrafficsim.demo.SequentialLanes.SequentialModel;
35 import org.opentrafficsim.draw.core.OTSDrawingException;
36 import org.opentrafficsim.draw.graphs.ContourDataSource;
37 import org.opentrafficsim.draw.graphs.ContourPlotAcceleration;
38 import org.opentrafficsim.draw.graphs.ContourPlotDensity;
39 import org.opentrafficsim.draw.graphs.ContourPlotFlow;
40 import org.opentrafficsim.draw.graphs.ContourPlotSpeed;
41 import org.opentrafficsim.draw.graphs.GraphPath;
42 import org.opentrafficsim.draw.graphs.TrajectoryPlot;
43 import org.opentrafficsim.draw.graphs.road.GraphLaneUtil;
44 import org.opentrafficsim.kpi.sampling.KpiLaneDirection;
45 import org.opentrafficsim.road.gtu.lane.LaneBasedIndividualGTU;
46 import org.opentrafficsim.road.gtu.lane.tactical.following.IDMPlusFactory;
47 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.DefaultLMRSPerceptionFactory;
48 import org.opentrafficsim.road.gtu.lane.tactical.lmrs.LMRSFactory;
49 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlanner;
50 import org.opentrafficsim.road.gtu.strategical.LaneBasedStrategicalPlannerFactory;
51 import org.opentrafficsim.road.gtu.strategical.route.LaneBasedStrategicalRoutePlannerFactory;
52 import org.opentrafficsim.road.network.OTSRoadNetwork;
53 import org.opentrafficsim.road.network.factory.LaneFactory;
54 import org.opentrafficsim.road.network.lane.CrossSectionLink;
55 import org.opentrafficsim.road.network.lane.DirectedLanePosition;
56 import org.opentrafficsim.road.network.lane.Lane;
57 import org.opentrafficsim.road.network.lane.LaneDirection;
58 import org.opentrafficsim.road.network.lane.LaneType;
59 import org.opentrafficsim.road.network.lane.OTSRoadNode;
60 import org.opentrafficsim.road.network.lane.object.sensor.SinkSensor;
61 import org.opentrafficsim.road.network.sampling.RoadSampler;
62 import org.opentrafficsim.swing.graphs.SwingContourPlot;
63 import org.opentrafficsim.swing.graphs.SwingPlot;
64 import org.opentrafficsim.swing.graphs.SwingTrajectoryPlot;
65 import org.opentrafficsim.swing.gui.OTSAnimationPanel;
66 import org.opentrafficsim.swing.gui.OTSSimulationApplication;
67
68 import nl.tudelft.simulation.dsol.SimRuntimeException;
69 import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterException;
70 import nl.tudelft.simulation.dsol.swing.gui.TablePanel;
71 import nl.tudelft.simulation.dsol.swing.gui.inputparameters.TabbedParameterDialog;
72 import nl.tudelft.simulation.jstats.streams.MersenneTwister;
73 import nl.tudelft.simulation.jstats.streams.StreamInterface;
74 import nl.tudelft.simulation.language.DSOLException;
75
76
77
78
79
80
81
82
83
84
85
86
87
88 public class SequentialLanes extends OTSSimulationApplication<SequentialModel> implements UNITS
89 {
90
91 private static final long serialVersionUID = 1L;
92
93
94
95
96
97
98
99
100 public SequentialLanes(final String title, final OTSAnimationPanel panel, final SequentialModel model)
101 throws OTSDrawingException
102 {
103 super(model, panel);
104 OTSRoadNetwork network = model.getNetwork();
105 System.out.println(network.getLinkMap());
106 }
107
108
109 @Override
110 protected void addTabs()
111 {
112 addStatisticsTabs(getModel().getSimulator());
113 }
114
115
116
117
118
119 public static void main(final String[] args)
120 {
121 demo(true);
122 }
123
124
125
126
127
128 public static void demo(final boolean exitOnClose)
129 {
130 try
131 {
132 OTSAnimator simulator = new OTSAnimator("SequentialLanes");
133 final SequentialModel otsModel = new SequentialModel(simulator);
134 if (TabbedParameterDialog.process(otsModel.getInputParameterMap()))
135 {
136 simulator.initialize(Time.ZERO, Duration.ZERO, Duration.instantiateSI(3600.0), otsModel);
137 OTSAnimationPanel animationPanel = new OTSAnimationPanel(otsModel.getNetwork().getExtent(), new Dimension(800,
138 600), simulator, otsModel, DEFAULT_COLORER, otsModel.getNetwork());
139 SequentialLanes app = new SequentialLanes("SequentialLanes", animationPanel, otsModel);
140 app.setExitOnClose(exitOnClose);
141 animationPanel.enableSimulationControlButtons();
142 }
143 else
144 {
145 if (exitOnClose)
146 {
147 System.exit(0);
148 }
149 }
150 }
151 catch (SimRuntimeException | NamingException | RemoteException | OTSDrawingException | DSOLException exception)
152 {
153 exception.printStackTrace();
154 }
155 }
156
157
158
159
160
161 protected final void addStatisticsTabs(final OTSSimulatorInterface simulator)
162 {
163 GraphPath<KpiLaneDirection> path;
164 try
165 {
166 path = GraphLaneUtil.createPath("Lane", new LaneDirection(getModel().getPath().get(0), GTUDirectionality.DIR_PLUS));
167 }
168 catch (NetworkException exception)
169 {
170 throw new RuntimeException("Could not create a path as a lane has no set speed limit.", exception);
171 }
172
173 RoadSampler sampler = new RoadSampler(getModel().getNetwork());
174 GraphPath.initRecording(sampler, path);
175 ContourDataSource<?> dataPool = new ContourDataSource<>(sampler.getSamplerData(), path);
176 TablePanel charts = new TablePanel(3, 2);
177 SwingPlot plot = null;
178
179 plot = new SwingTrajectoryPlot(new TrajectoryPlot("TrajectoryPlot", Duration.instantiateSI(10.0), simulator, sampler
180 .getSamplerData(), path));
181 charts.setCell(plot.getContentPane(), 0, 0);
182
183 plot = new SwingContourPlot(new ContourPlotDensity("DensityPlot", simulator, dataPool));
184 charts.setCell(plot.getContentPane(), 1, 0);
185
186 plot = new SwingContourPlot(new ContourPlotSpeed("SpeedPlot", simulator, dataPool));
187 charts.setCell(plot.getContentPane(), 2, 0);
188
189 plot = new SwingContourPlot(new ContourPlotFlow("FlowPlot", simulator, dataPool));
190 charts.setCell(plot.getContentPane(), 1, 1);
191
192 plot = new SwingContourPlot(new ContourPlotAcceleration("AccelerationPlot", simulator, dataPool));
193 charts.setCell(plot.getContentPane(), 2, 1);
194
195 getAnimationPanel().getTabbedPane().addTab(getAnimationPanel().getTabbedPane().getTabCount(), "statistics ", charts);
196 }
197
198
199
200
201
202
203
204
205
206
207
208
209 static class SequentialModel extends AbstractOTSModel implements UNITS
210 {
211
212 private static final long serialVersionUID = 20150130L;
213
214
215 private final OTSRoadNetwork network = new OTSRoadNetwork("network", true, getSimulator());
216
217
218 private List<OTSRoadNode> nodes = new ArrayList<>();
219
220
221 private LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerGeneratorCars = null;
222
223
224 private LaneBasedStrategicalPlannerFactory<LaneBasedStrategicalPlanner> strategicalPlannerGeneratorTrucks = null;
225
226
227 private Parameters parametersCar;
228
229
230 private Parameters parametersTruck;
231
232
233 private double carProbability;
234
235
236 private Duration headway;
237
238
239 private int carsCreated = 0;
240
241
242 private Length minimumDistance = new Length(0, METER);
243
244
245 private Lane initialLane;
246
247
248 private Length maximumDistance = new Length(2001, METER);
249
250
251 private StreamInterface stream = new MersenneTwister(12345);
252
253
254 private List<Lane> path = new ArrayList<>();
255
256
257 private Speed speedLimit;
258
259
260
261
262 SequentialModel(final OTSSimulatorInterface simulator)
263 {
264 super(simulator);
265 InputParameterHelper.makeInputParameterMapCarTruck(this.inputParameterMap, 1.0);
266 }
267
268
269
270
271 public List<Lane> getPath()
272 {
273 return new ArrayList<>(this.path);
274 }
275
276
277 @Override
278 public final void constructModel() throws SimRuntimeException
279 {
280 this.speedLimit = new Speed(100, KM_PER_HOUR);
281
282
283 boolean minus = false;
284
285 this.nodes = new ArrayList<>();
286 try
287 {
288 OTSPoint3D p2 = new OTSPoint3D(1020, 3);
289 OTSPoint3D p3 = new OTSPoint3D(2000, 197);
290 Direction dir23 = p2.horizontalDirection(p3);
291 OTSRoadNode n0 = new OTSRoadNode(this.network, "Node-0-(0,0)", new OTSPoint3D(0, 0), Direction.ZERO);
292 OTSRoadNode n1 = new OTSRoadNode(this.network, "Node-1-(1000,0)", new OTSPoint3D(1000, 0), Direction.ZERO);
293 OTSRoadNode n2 = new OTSRoadNode(this.network, "Node-2-(1020,3)", p2, dir23);
294 OTSRoadNode n3 = new OTSRoadNode(this.network, "Node-3-(2000,197)", p3, dir23);
295 OTSRoadNode n4 = new OTSRoadNode(this.network, "Node-4-(2020,200)", new OTSPoint3D(2020, 200), Direction.ZERO);
296 OTSRoadNode n5 = new OTSRoadNode(this.network, "Node-5-(2200,200)", new OTSPoint3D(2200, 200), Direction.ZERO);
297 this.nodes.addAll(Arrays.asList(new OTSRoadNode[] {n0, n1, n2, n3, n4, n5}));
298
299 LaneType laneType = this.network.getLaneType(LaneType.DEFAULTS.TWO_WAY_LANE);
300
301
302 ArrayList<CrossSectionLink> links = new ArrayList<>();
303 OTSLine3D l01 = new OTSLine3D(n0.getPoint(), n1.getPoint());
304 OTSLine3D l12 = LaneFactory.makeBezier(n0, n1, n2, n3);
305 OTSLine3D l23 = minus ? new OTSLine3D(n3.getPoint(), n2.getPoint()) : new OTSLine3D(n2.getPoint(), n3
306 .getPoint());
307 OTSLine3D l34 = LaneFactory.makeBezier(n2, n3, n4, n5);
308 OTSLine3D l45 = new OTSLine3D(n4.getPoint(), n5.getPoint());
309 OTSLine3D[] lines = new OTSLine3D[] {l01, l12, l23, l34, l45};
310
311 for (int i = 1; i < this.nodes.size(); i++)
312 {
313 OTSRoadNode fromNode = this.nodes.get(i - 1);
314 OTSRoadNode toNode = this.nodes.get(i);
315 OTSLine3D line = lines[i - 1];
316 String linkName = fromNode.getId() + "-" + toNode.getId();
317
318
319 Lane[] lanes = LaneFactory.makeMultiLane(this.network, linkName, fromNode, toNode, line.getPoints(), 1,
320 laneType, this.speedLimit, this.simulator);
321 if (i == this.nodes.size() - 1)
322 {
323 new SinkSensor(lanes[0], new Length(100.0, METER), Compatible.EVERYTHING, this.simulator);
324 }
325 this.path.add(lanes[0]);
326 links.add(lanes[0].getParentLink());
327 if (1 == i)
328 {
329 this.initialLane = lanes[0];
330 }
331 }
332
333 this.carProbability = (double) getInputParameter("generic.carProbability");
334 this.parametersCar = InputParameterHelper.getParametersCar(getInputParameterMap());
335 this.parametersTruck = InputParameterHelper.getParametersTruck(getInputParameterMap());
336
337 this.strategicalPlannerGeneratorCars = new LaneBasedStrategicalRoutePlannerFactory(new LMRSFactory(
338 new IDMPlusFactory(this.stream), new DefaultLMRSPerceptionFactory()));
339 this.strategicalPlannerGeneratorTrucks = new LaneBasedStrategicalRoutePlannerFactory(new LMRSFactory(
340 new IDMPlusFactory(this.stream), new DefaultLMRSPerceptionFactory()));
341
342
343 this.headway = new Duration(3600.0 / 1500.0, SECOND);
344
345
346 this.simulator.scheduleEventAbsTime(Time.ZERO, this, this, "generateCar", null);
347 }
348 catch (NamingException | NetworkException | OTSGeometryException | ParameterException | InputParameterException
349 | GTUException exception)
350 {
351 exception.printStackTrace();
352 }
353 }
354
355
356 @Override
357 public OTSRoadNetwork getNetwork()
358 {
359 return this.network;
360 }
361
362
363
364
365 public final Length getMinimumDistance()
366 {
367 return this.minimumDistance;
368 }
369
370
371
372
373 public final Length getMaximumDistance()
374 {
375 return this.maximumDistance;
376 }
377
378
379
380
381 protected final void generateCar()
382 {
383 try
384 {
385 boolean generateTruck = this.stream.nextDouble() > this.carProbability;
386 Length vehicleLength = new Length(generateTruck ? 15 : 4, METER);
387 LaneBasedIndividualGTU gtu = new LaneBasedIndividualGTU("" + (++this.carsCreated), this.network.getGtuType(
388 GTUType.DEFAULTS.CAR), vehicleLength, new Length(1.8, METER), new Speed(200, KM_PER_HOUR), vehicleLength
389 .times(0.5), this.simulator, this.network);
390 gtu.setParameters(generateTruck ? this.parametersTruck : this.parametersCar);
391 gtu.setNoLaneChangeDistance(Length.ZERO);
392 gtu.setMaximumAcceleration(Acceleration.instantiateSI(3.0));
393 gtu.setMaximumDeceleration(Acceleration.instantiateSI(-8.0));
394
395
396 LaneBasedStrategicalPlanner strategicalPlanner = generateTruck ? this.strategicalPlannerGeneratorTrucks.create(
397 gtu, null, null, null) : this.strategicalPlannerGeneratorCars.create(gtu, null, null, null);
398
399 Set<DirectedLanePosition> initialPositions = new LinkedHashSet<>(1);
400 Length initialPosition = new Length(20, METER);
401 initialPositions.add(new DirectedLanePosition(this.initialLane, initialPosition, GTUDirectionality.DIR_PLUS));
402 Speed initialSpeed = new Speed(100.0, KM_PER_HOUR);
403 gtu.init(strategicalPlanner, initialPositions, initialSpeed);
404 this.simulator.scheduleEventRel(this.headway, this, this, "generateCar", null);
405 }
406 catch (SimRuntimeException | NetworkException | GTUException | OTSGeometryException exception)
407 {
408 exception.printStackTrace();
409 }
410 }
411
412
413 @Override
414 public Serializable getSourceId()
415 {
416 return "SequentialModel";
417 }
418
419 }
420 }