1 package org.opentrafficsim.swing.script;
2
3 import java.awt.Dimension;
4 import java.rmi.RemoteException;
5 import java.util.HashMap;
6 import java.util.List;
7 import java.util.Map;
8
9 import org.djunits.value.vdouble.scalar.Duration;
10 import org.djunits.value.vdouble.scalar.Time;
11 import org.djutils.exceptions.Throw;
12 import org.djutils.exceptions.Try;
13 import org.opentrafficsim.core.animation.gtu.colorer.GTUColorer;
14 import org.opentrafficsim.core.dsol.OTSAnimator;
15 import org.opentrafficsim.core.dsol.OTSModelInterface;
16 import org.opentrafficsim.core.dsol.OTSSimulator;
17 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
18 import org.opentrafficsim.core.network.OTSLink;
19 import org.opentrafficsim.core.network.OTSNetwork;
20 import org.opentrafficsim.core.network.OTSNode;
21 import org.opentrafficsim.draw.core.OTSDrawingException;
22 import org.opentrafficsim.draw.factory.DefaultAnimationFactory;
23 import org.opentrafficsim.road.gtu.generator.GtuGeneratorQueue;
24 import org.opentrafficsim.road.network.OTSRoadNetwork;
25 import org.opentrafficsim.road.network.lane.object.SpeedSign;
26 import org.opentrafficsim.swing.gui.AnimationToggles;
27 import org.opentrafficsim.swing.gui.OTSAnimationPanel;
28 import org.opentrafficsim.swing.gui.OTSSimulationApplication;
29 import org.opentrafficsim.swing.gui.OTSSwingApplication;
30
31 import nl.tudelft.simulation.dsol.SimRuntimeException;
32 import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterMap;
33 import nl.tudelft.simulation.dsol.model.outputstatistics.OutputStatistic;
34 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
35 import nl.tudelft.simulation.event.EventInterface;
36 import nl.tudelft.simulation.event.EventListenerInterface;
37 import nl.tudelft.simulation.jstats.streams.MersenneTwister;
38 import nl.tudelft.simulation.jstats.streams.StreamInterface;
39
40
41
42
43
44
45
46
47
48
49
50
51 public abstract class AbstractSimulationScript implements EventListenerInterface
52 {
53
54 final String name;
55
56
57 final String description;
58
59
60 OTSSimulatorInterface simulator;
61
62
63 private OTSRoadNetwork network;
64
65
66 private final Map<String, String> props = new HashMap<>();
67
68
69 private GTUColorer gtuColorer = OTSSwingApplication.DEFAULT_COLORER;
70
71
72
73
74
75
76
77 protected AbstractSimulationScript(final String name, final String description, final String[] properties)
78 {
79 this.name = name;
80 this.description = description;
81 this.props.put("seed", "1");
82 this.props.put("startTime", "0");
83 this.props.put("warmupTime", "0");
84 this.props.put("simulationTime", "3600");
85 this.props.put("autorun", "false");
86 setDefaultProperties();
87 for (int i = 0; i < properties.length; i += 2)
88 {
89 System.out.println("Adding argument " + properties[i] + " with argument " + properties[i + 1]);
90 this.props.put(properties[i], properties[i + 1]);
91 }
92 }
93
94
95
96
97
98
99 public final void setProperty(final String propertyName, final Object propertyValue)
100 {
101 this.props.put(propertyName, propertyValue.toString());
102 }
103
104
105
106
107
108
109 public final String getProperty(final String propertyName)
110 {
111 String p = this.props.get(propertyName);
112 Throw.when(p == null, IllegalStateException.class, "Property %s is not given.", propertyName);
113 return p;
114 }
115
116
117
118
119
120
121 public final double getDoubleProperty(final String propertyName)
122 {
123 return Double.parseDouble(getProperty(propertyName));
124 }
125
126
127
128
129
130
131 public final boolean getBooleanProperty(final String propertyName)
132 {
133 return Boolean.parseBoolean(getProperty(propertyName));
134 }
135
136
137
138
139
140
141 public final int getIntegerProperty(final String propertyName)
142 {
143 return Integer.parseInt(getProperty(propertyName));
144 }
145
146
147
148
149
150
151 public final long getLongProperty(final String propertyName)
152 {
153 return Long.parseLong(getProperty(propertyName));
154 }
155
156
157
158
159
160
161 public final Duration getDurationProperty(final String propertyName)
162 {
163 return Duration.createSI(getDoubleProperty(propertyName));
164 }
165
166
167
168
169
170
171 public final Time getTimeProperty(final String propertyName)
172 {
173 return Time.createSI(getDoubleProperty(propertyName));
174 }
175
176
177
178
179
180 public final void setGtuColorer(final GTUColorer colorer)
181 {
182 this.gtuColorer = colorer;
183 }
184
185
186
187
188
189 public final GTUColorer getGtuColorer()
190 {
191 return this.gtuColorer;
192 }
193
194
195
196
197
198 public final void start() throws Exception
199 {
200 Time startTime = getTimeProperty("startTime");
201 Duration warmupTime = getDurationProperty("warmupTime");
202 Duration simulationTime = getDurationProperty("simulationTime");
203 if (getBooleanProperty("autorun"))
204 {
205 this.simulator = new OTSSimulator();
206 final ScriptModel scriptModel = new ScriptModel(this.simulator);
207 this.simulator.initialize(startTime, warmupTime, simulationTime, scriptModel);
208 this.simulator.addListener(this, SimulatorInterface.END_REPLICATION_EVENT);
209 double tReport = 60.0;
210 Time t = this.simulator.getSimulatorTime();
211 while (t.si < simulationTime.si)
212 {
213 this.simulator.step();
214 t = this.simulator.getSimulatorTime();
215 if (t.si >= tReport)
216 {
217 System.out.println("Simulation time is " + t);
218 tReport += 60.0;
219 }
220 }
221
222 onSimulationEnd();
223 System.exit(0);
224 }
225 else
226 {
227 this.simulator = new OTSAnimator();
228 final ScriptModel scriptModel = new ScriptModel(this.simulator);
229 this.simulator.initialize(startTime, warmupTime, simulationTime, scriptModel);
230 OTSAnimationPanel animationPanel =
231 new OTSAnimationPanel(scriptModel.getNetwork().getExtent(), new Dimension(800, 600),
232 (OTSAnimator) this.simulator, scriptModel, getGtuColorer(), scriptModel.getNetwork());
233 setAnimationToggles(animationPanel);
234 animateNetwork(scriptModel.getNetwork());
235 setupDemo(animationPanel, scriptModel.getNetwork());
236 OTSSimulationApplication<ScriptModel> app = new OTSSimulationApplication<ScriptModel>(scriptModel, animationPanel)
237 {
238
239 private static final long serialVersionUID = 20190130L;
240
241
242 @Override
243 protected void animateNetwork() throws OTSDrawingException
244 {
245
246 }
247
248
249 @Override
250 protected void setAnimationToggles()
251 {
252
253 }
254 };
255 addTabs(this.simulator, app);
256 app.setExitOnClose(true);
257 }
258 }
259
260
261 @Override
262 public final void notify(final EventInterface event) throws RemoteException
263 {
264 if (event.getType().equals(SimulatorInterface.END_REPLICATION_EVENT))
265 {
266 onSimulationEnd();
267
268 AbstractSimulationScript.this.simulator.removeListener(AbstractSimulationScript.this,
269 SimulatorInterface.END_REPLICATION_EVENT);
270 }
271 }
272
273
274
275
276
277 public final OTSSimulatorInterface getSimulator()
278 {
279 return AbstractSimulationScript.this.simulator;
280 }
281
282
283
284
285
286 public final OTSRoadNetwork getNetwork()
287 {
288 return AbstractSimulationScript.this.network;
289 }
290
291
292
293
294
295
296
297 protected void animateNetwork(final OTSNetwork net)
298 {
299 try
300 {
301 DefaultAnimationFactory.animateNetwork(net, getSimulator(), getGtuColorer());
302 }
303 catch (OTSDrawingException exception)
304 {
305 throw new RuntimeException("Exception while creating network animation.", exception);
306 }
307 }
308
309
310
311
312
313
314 protected void addTabs(final OTSSimulatorInterface sim, final OTSSimulationApplication<?> animation)
315 {
316
317 }
318
319
320
321
322 protected void setDefaultProperties()
323 {
324
325 }
326
327
328
329
330 protected void onSimulationEnd()
331 {
332
333 }
334
335
336
337
338
339
340 protected void setupDemo(final OTSAnimationPanel animationPanel, final OTSRoadNetwork net)
341 {
342
343 }
344
345
346
347
348
349 protected void setAnimationToggles(final OTSAnimationPanel animation)
350 {
351 AnimationToggles.setIconAnimationTogglesFull(animation);
352 animation.getAnimationPanel().toggleClass(OTSLink.class);
353 animation.getAnimationPanel().toggleClass(OTSNode.class);
354 animation.getAnimationPanel().toggleClass(GtuGeneratorQueue.class);
355 animation.getAnimationPanel().showClass(SpeedSign.class);
356 }
357
358
359
360
361
362
363
364
365
366
367 protected abstract OTSRoadNetwork setupSimulation(OTSSimulatorInterface sim) throws Exception;
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383 private class ScriptModel implements OTSModelInterface
384 {
385
386 private static final long serialVersionUID = 20180409L;
387
388
389
390
391 ScriptModel(final OTSSimulatorInterface simulator)
392 {
393 AbstractSimulationScript.this.simulator = simulator;
394 }
395
396
397 @SuppressWarnings("synthetic-access")
398 @Override
399 public void constructModel() throws SimRuntimeException
400 {
401 Map<String, StreamInterface> streams = new HashMap<>();
402 long seed = getLongProperty("seed");
403 StreamInterface stream = new MersenneTwister(seed);
404 streams.put("generation", stream);
405 stream = new MersenneTwister(seed + 1);
406 streams.put("default", stream);
407 AbstractSimulationScript.this.simulator.getReplication().setStreams(streams);
408 AbstractSimulationScript.this.network =
409 Try.assign(() -> AbstractSimulationScript.this.setupSimulation(AbstractSimulationScript.this.simulator),
410 RuntimeException.class, "Exception while setting up simulation.");
411 try
412 {
413 AbstractSimulationScript.this.simulator.addListener(AbstractSimulationScript.this,
414 SimulatorInterface.END_REPLICATION_EVENT);
415 }
416 catch (RemoteException exception)
417 {
418 throw new SimRuntimeException(exception);
419 }
420 }
421
422
423 @Override
424 public OTSSimulatorInterface getSimulator()
425 {
426 return AbstractSimulationScript.this.simulator;
427 }
428
429
430 @SuppressWarnings("synthetic-access")
431 @Override
432 public OTSRoadNetwork getNetwork()
433 {
434 return AbstractSimulationScript.this.network;
435 }
436
437
438 @Override
439 public InputParameterMap getInputParameterMap()
440 {
441 return null;
442 }
443
444
445 @Override
446 public List<OutputStatistic<?>> getOutputStatistics()
447 {
448 return null;
449 }
450
451
452 @Override
453 public String getShortName()
454 {
455 return AbstractSimulationScript.this.name;
456 }
457
458
459 @Override
460 public String getDescription()
461 {
462 return AbstractSimulationScript.this.description;
463 }
464 }
465
466 }