View Javadoc
1   package org.opentrafficsim.simulationengine;
2   
3   import java.awt.Dimension;
4   import java.awt.geom.Rectangle2D;
5   import java.rmi.RemoteException;
6   
7   import nl.tudelft.simulation.dsol.SimRuntimeException;
8   import nl.tudelft.simulation.dsol.animation.D2.AnimationPanel;
9   import nl.tudelft.simulation.dsol.experiment.ReplicationMode;
10  import nl.tudelft.simulation.dsol.formalisms.eventscheduling.SimEvent;
11  import nl.tudelft.simulation.dsol.formalisms.eventscheduling.SimEventInterface;
12  import nl.tudelft.simulation.dsol.gui.swing.DSOLPanel;
13  import nl.tudelft.simulation.dsol.simulators.DEVSSimulator;
14  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
15  import nl.tudelft.simulation.event.Event;
16  
17  import org.opentrafficsim.core.dsol.OTSDEVSAnimator;
18  import org.opentrafficsim.core.dsol.OTSDEVSSimulator;
19  import org.opentrafficsim.core.dsol.OTSModelInterface;
20  import org.opentrafficsim.core.dsol.OTSReplication;
21  import org.opentrafficsim.core.dsol.OTSSimTimeDouble;
22  import org.opentrafficsim.core.unit.TimeUnit;
23  import org.opentrafficsim.core.value.vdouble.scalar.DoubleScalar;
24  
25  /**
26   * <p>
27   * Copyright (c) 2013-2014 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights
28   * reserved. <br>
29   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
30   * <p>
31   * @version 12 nov. 2014 <br>
32   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
33   */
34  public class SimpleSimulator
35  {
36      /** Counter for replication. */
37      private int lastReplication = 0;
38  
39      /** The JPanel that contains the simulator controls, a status bar and a JTabbedPane with switchable sub panels. */
40      private final DSOLPanel<DoubleScalar.Abs<TimeUnit>, DoubleScalar.Rel<TimeUnit>, OTSSimTimeDouble> panel;
41  
42      /** The simulator engine. */
43      private final DEVSSimulator<DoubleScalar.Abs<TimeUnit>, DoubleScalar.Rel<TimeUnit>, OTSSimTimeDouble> simulator;
44  
45      /**
46       * Create a simulation engine without animation; the easy way. PauseOnError is set to true;
47       * @param startTime OTSSimTimeDouble; the start time of the simulation
48       * @param warmupPeriod DoubleScalar.Rel&lt;TimeUnit&gt;; the warm up period of the simulation (use new
49       *            DoubleScalar.Rel&ltTimeUnit&gt;(0, TimeUnit.SECOND) if you don't know what this is)
50       * @param runLength DoubleScalar.Rel&lt;TimeUnit&gt;; the duration of the simulation
51       * @param model OTSModelInterface; the simulation to execute
52       * @throws RemoteException on communications failure
53       * @throws SimRuntimeException on ???
54       */
55      public SimpleSimulator(final DoubleScalar.Abs<TimeUnit> startTime, final DoubleScalar.Rel<TimeUnit> warmupPeriod,
56              final DoubleScalar.Rel<TimeUnit> runLength, final OTSModelInterface model) throws RemoteException,
57              SimRuntimeException
58      {
59          this.simulator = new OTSDEVSSimulator();
60          this.simulator.setPauseOnError(true);
61          this.simulator.initialize(new OTSReplication("rep" + ++this.lastReplication, new OTSSimTimeDouble(startTime),
62                  warmupPeriod, runLength, model), ReplicationMode.TERMINATING);
63          this.panel =
64                  new DSOLPanel<DoubleScalar.Abs<TimeUnit>, DoubleScalar.Rel<TimeUnit>, OTSSimTimeDouble>(model,
65                          this.simulator);
66      }
67  
68      /**
69       * Create a simulation engine with animation; the easy way. PauseOnError is set to true;
70       * @param startTime DoubleScalar.Abs&lt;TimeUnit&gt;; the start time of the simulation
71       * @param warmupPeriod DoubleScalar.Rel&lt;TimeUnit&gt;; the warm up period of the simulation (use new
72       *            DoubleScalar.Rel&ltTimeUnit&gt;(0, TimeUnit.SECOND) if you don't know what this is)
73       * @param runLength DoubleScalar.Rel&lt;TimeUnit&gt;; the duration of the simulation
74       * @param model OTSModelInterface; the simulation to execute
75       * @param extent Rectangle2D; bottom left corner, length and width of the area (world) to animate.
76       * @throws RemoteException on communications failure
77       * @throws SimRuntimeException on ???
78       */
79      public SimpleSimulator(final DoubleScalar.Abs<TimeUnit> startTime, final DoubleScalar.Rel<TimeUnit> warmupPeriod,
80              final DoubleScalar.Rel<TimeUnit> runLength, final OTSModelInterface model, final Rectangle2D extent)
81              throws RemoteException, SimRuntimeException
82      {
83          this.simulator = new OTSDEVSAnimator();
84          this.simulator.setPauseOnError(true);
85          this.simulator.initialize(new OTSReplication("rep" + ++this.lastReplication, new OTSSimTimeDouble(startTime),
86                  warmupPeriod, runLength, model), ReplicationMode.TERMINATING);
87          this.panel =
88                  new DSOLPanel<DoubleScalar.Abs<TimeUnit>, DoubleScalar.Rel<TimeUnit>, OTSSimTimeDouble>(model,
89                          this.simulator);
90          Dimension size = new Dimension(1024, 768);
91          AnimationPanel animationPanel = new AnimationPanel(extent, size, this.simulator);
92          this.panel.getTabbedPane().addTab(0, "animation", animationPanel);
93          animationPanel.notify(new Event(SimulatorInterface.START_REPLICATION_EVENT, this.simulator, null));
94          this.panel.getTabbedPane().setSelectedIndex(0); // Select the animation panel
95      }
96  
97      /**
98       * To use in a Swing application add the DSOLPanel to a JFrame.
99       * @return the simulation panel (extends JPanel).
100      */
101     public final DSOLPanel<DoubleScalar.Abs<TimeUnit>, DoubleScalar.Rel<TimeUnit>, OTSSimTimeDouble> getPanel()
102     {
103         return this.panel;
104     }
105 
106     /**
107      * Access to the simulator is needed to create simulated objects.
108      * @return simulator.
109      */
110     public final DEVSSimulator<DoubleScalar.Abs<TimeUnit>, DoubleScalar.Rel<TimeUnit>, OTSSimTimeDouble> getSimulator()
111     {
112         return this.simulator;
113     }
114 
115     /** The stop simulation event that is used to run the simulator up to a specified time. */
116     private SimEvent<OTSSimTimeDouble> stopAtEvent = null;
117 
118     /**
119      * Run the simulation up to the specified time.
120      * @param when DoubleScalar.Abs&lt;TimeUnit&gt;; the stop time.
121      * @throws SimRuntimeException when the specified time lies in the past
122      */
123     public final void runUpTo(final DoubleScalar.Abs<TimeUnit> when) throws SimRuntimeException
124     {
125         this.stopAtEvent =
126                 new SimEvent<OTSSimTimeDouble>(new OTSSimTimeDouble(new DoubleScalar.Abs<TimeUnit>(when.getSI(),
127                         TimeUnit.SECOND)), SimEventInterface.MAX_PRIORITY, this, this, "autoPauseSimulator", null);
128         this.simulator.scheduleEvent(this.stopAtEvent);
129         while (this.simulator.getSimulatorTime().get().getSI() < when.getSI())
130         {
131             this.simulator.step();
132         }
133     }
134 
135     /**
136      * Pause the simulator.
137      */
138     @SuppressWarnings("unused")
139     private void autoPauseSimulator()
140     {
141         if (this.simulator.isRunning())
142         {
143             this.simulator.stop();
144         }
145     }
146 
147 }