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