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