View Javadoc
1   package org.opentrafficsim.demo.trafficcontrol;
2   
3   import java.awt.BorderLayout;
4   import java.awt.Dimension;
5   import java.io.ByteArrayInputStream;
6   import java.io.IOException;
7   import java.io.Serializable;
8   import java.net.URL;
9   import java.nio.charset.StandardCharsets;
10  import java.rmi.RemoteException;
11  import java.util.List;
12  import java.util.Scanner;
13  
14  import javax.naming.NamingException;
15  import javax.swing.JPanel;
16  import javax.swing.JScrollPane;
17  
18  import org.djunits.value.vdouble.scalar.Duration;
19  import org.djunits.value.vdouble.scalar.Time;
20  import org.djutils.event.EventInterface;
21  import org.djutils.event.EventListenerInterface;
22  import org.djutils.event.EventTypeInterface;
23  import org.djutils.exceptions.Throw;
24  import org.djutils.io.URLResource;
25  import org.opentrafficsim.core.dsol.AbstractOTSModel;
26  import org.opentrafficsim.core.dsol.OTSAnimator;
27  import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
28  import org.opentrafficsim.core.network.NetworkException;
29  import org.opentrafficsim.core.object.InvisibleObjectInterface;
30  import org.opentrafficsim.demo.trafficcontrol.TrafCODDemo1.TrafCODModel;
31  import org.opentrafficsim.draw.core.OTSDrawingException;
32  import org.opentrafficsim.road.network.OTSRoadNetwork;
33  import org.opentrafficsim.road.network.factory.xml.parser.XmlNetworkLaneParser;
34  import org.opentrafficsim.swing.gui.OTSAnimationPanel;
35  import org.opentrafficsim.swing.gui.OTSSimulationApplication;
36  import org.opentrafficsim.trafficcontrol.TrafficController;
37  import org.opentrafficsim.trafficcontrol.trafcod.TrafCOD;
38  import org.opentrafficsim.xml.generated.CONTROL;
39  import org.opentrafficsim.xml.generated.OTS;
40  
41  import nl.tudelft.simulation.dsol.SimRuntimeException;
42  import nl.tudelft.simulation.language.DSOLException;
43  
44  /**
45   * <p>
46   * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
47   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
48   * <p>
49   * @version $Revision$, $LastChangedDate$, by $Author$, initial version Nov 18, 2016 <br>
50   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
51   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
52   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
53   */
54  public class TrafCODDemo1 extends OTSSimulationApplication<TrafCODModel>
55  {
56      /** */
57      private static final long serialVersionUID = 20161118L;
58  
59      /**
60       * Create a Trafcod demo.
61       * @param title String; the title of the Frame
62       * @param panel OTSAnimationPanel; the tabbed panel to display
63       * @param model TrafCODModel; the model
64       * @throws OTSDrawingException on animation error
65       */
66      public TrafCODDemo1(final String title, final OTSAnimationPanel panel, final TrafCODModel model) throws OTSDrawingException
67      {
68          super(model, panel);
69      }
70  
71      /**
72       * Main program.
73       * @param args String[]; the command line arguments (not used)
74       * @throws IOException ...
75       */
76      public static void main(final String[] args) throws IOException
77      {
78          demo(true);
79      }
80  
81      /**
82       * Open an URL, read it and store the contents in a string. Adapted from
83       * https://stackoverflow.com/questions/4328711/read-url-to-string-in-few-lines-of-java-code
84       * @param url URL; the URL
85       * @return String
86       * @throws IOException when reading the file fails
87       */
88      public static String readStringFromURL(final URL url) throws IOException
89      {
90          try (Scanner scanner = new Scanner(url.openStream(), StandardCharsets.UTF_8.toString()))
91          {
92              scanner.useDelimiter("\\A");
93              return scanner.hasNext() ? scanner.next() : "";
94          }
95      }
96  
97      /**
98       * Start the demo.
99       * @param exitOnClose boolean; when running stand-alone: true; when running as part of a demo: false
100      * @throws IOException when reading the file fails
101      */
102     public static void demo(final boolean exitOnClose) throws IOException
103     {
104         try
105         {
106             OTSAnimator simulator = new OTSAnimator("TrafCODDemo1");
107             URL url = URLResource.getResource("/TrafCODDemo1/TrafCODDemo1.xml");
108             String xml = readStringFromURL(url);
109             final TrafCODModel trafcodModel = new TrafCODModel(simulator, "TrafCODModel", "TrafCOD demonstration Model", xml);
110             simulator.initialize(Time.ZERO, Duration.ZERO, Duration.instantiateSI(3600.0), trafcodModel);
111             OTSAnimationPanel animationPanel = new OTSAnimationPanel(trafcodModel.getNetwork().getExtent(),
112                     new Dimension(800, 600), simulator, trafcodModel, DEFAULT_COLORER, trafcodModel.getNetwork());
113             TrafCODDemo1control/TrafCODDemo1.html#TrafCODDemo1">TrafCODDemo1 app = new TrafCODDemo1("TrafCOD demo simple crossing", animationPanel, trafcodModel);
114             app.setExitOnClose(exitOnClose);
115         }
116         catch (SimRuntimeException | NamingException | RemoteException | OTSDrawingException | DSOLException exception)
117         {
118             exception.printStackTrace();
119         }
120     }
121 
122     /**
123      * Add tab with trafCOD status.
124      */
125     @Override
126     protected final void addTabs()
127     {
128         JScrollPane scrollPane = new JScrollPane(getModel().getTrafCOD().getDisplayContainer());
129         JPanel wrapper = new JPanel(new BorderLayout());
130         wrapper.add(scrollPane);
131         getAnimationPanel().getTabbedPane().addTab(getAnimationPanel().getTabbedPane().getTabCount() - 1,
132                 getModel().getTrafCOD().getId(), wrapper);
133     }
134 
135     /**
136      * The simulation model.
137      */
138     public static class TrafCODModel extends AbstractOTSModel implements EventListenerInterface
139     {
140         /** */
141         private static final long serialVersionUID = 20161020L;
142 
143         /** The network. */
144         private OTSRoadNetwork network;
145 
146         /** The TrafCOD controller. */
147         private TrafCOD trafCOD;
148 
149         /** The XML. */
150         private final String xml;
151 
152         /**
153          * @param simulator OTSSimulatorInterface; the simulator
154          * @param shortName String; name of the model
155          * @param description String; description of the model
156          * @param xml String; the XML string
157          */
158         public TrafCODModel(final OTSSimulatorInterface simulator, final String shortName, final String description,
159                 final String xml)
160         {
161             super(simulator);
162             this.xml = xml;
163         }
164 
165         /** {@inheritDoc} */
166         @Override
167         public void constructModel() throws SimRuntimeException
168         {
169             try
170             {
171                 this.network = new OTSRoadNetwork(getShortName(), true, getSimulator());
172                 OTS ots = XmlNetworkLaneParser.parseXML(new ByteArrayInputStream(this.xml.getBytes(StandardCharsets.UTF_8)));
173                 XmlNetworkLaneParser.build(ots, this.network, false);
174 
175                 //String controllerName = "TrafCOD_simple";
176                 List<CONTROL> trafficControllerList = ots.getCONTROL();
177                 Throw.when(trafficControllerList.size() != 1, NetworkException.class,
178                         "OTS contains wrong number of traffic controllers (should be 1, got %1)", trafficControllerList.size());
179                 for (InvisibleObjectInterface ioi : this.network.getInvisibleObjectMap().values())
180                 {
181                     if (ioi instanceof TrafCOD)
182                     {
183                         if (null != this.trafCOD)
184                         {
185                             throw new NetworkException("More than one TrafCOD controller found in network");
186                         }
187                         this.trafCOD = (TrafCOD) ioi;
188                     }
189                 }
190                 if (null == this.trafCOD)
191                 {
192                     throw new NetworkException("No TrafCOD controller found in network");
193                 }
194                 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONTROLLER_EVALUATING);
195                 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONTROLLER_WARNING);
196                 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONFLICT_GROUP_CHANGED);
197                 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_STATE_CHANGED);
198                 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_VARIABLE_CREATED);
199                 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_TRACED_VARIABLE_UPDATED);
200                 // Subscribe the TrafCOD machine to trace command events that we emit
201                 addListener(this.trafCOD, TrafficController.TRAFFICCONTROL_SET_TRACING);
202                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new Object[] {controllerName, "TGX", 8, true});
203                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new Object[] {controllerName, "XR1", 11, true});
204                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new Object[] {controllerName, "TD1", 11, true});
205                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new Object[] {controllerName, "TGX", 11, true});
206                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new Object[] {controllerName, "TL", 11, true});
207                 // System.out.println("demo: emitting a SET TRACING event for all variables related to stream 11");
208                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new Object[] { controllerName, "", 11, true });
209 
210                 // this.trafCOD.traceVariablesOfStream(TrafficController.NO_STREAM, true);
211                 // this.trafCOD.traceVariablesOfStream(11, true);
212                 // this.trafCOD.traceVariable("MRV", 11, true);
213             }
214             catch (Exception exception)
215             {
216                 exception.printStackTrace();
217             }
218         }
219 
220         /** {@inheritDoc} */
221         @Override
222         public final OTSRoadNetwork getNetwork()
223         {
224             return this.network;
225         }
226 
227         /**
228          * @return trafCOD
229          */
230         public final TrafCOD getTrafCOD()
231         {
232             return this.trafCOD;
233         }
234 
235         /** {@inheritDoc} */
236         @Override
237         public void notify(final EventInterface event) throws RemoteException
238         {
239             EventTypeInterface type = event.getType();
240             Object[] payload = (Object[]) event.getContent();
241             if (TrafficController.TRAFFICCONTROL_CONTROLLER_EVALUATING.equals(type))
242             {
243                 // System.out.println("Evalution starts at " + getSimulator().getSimulatorTime());
244                 return;
245             }
246             else if (TrafficController.TRAFFICCONTROL_CONFLICT_GROUP_CHANGED.equals(type))
247             {
248                 System.out.println("Conflict group changed from " + ((String) payload[1]) + " to " + ((String) payload[2]));
249             }
250             else if (TrafficController.TRAFFICCONTROL_TRACED_VARIABLE_UPDATED.equals(type))
251             {
252                 System.out.println(String.format("Variable changed %s <- %d   %s", payload[1], payload[4], payload[5]));
253             }
254             else if (TrafficController.TRAFFICCONTROL_CONTROLLER_WARNING.equals(type))
255             {
256                 System.out.println("Warning " + payload[1]);
257             }
258             else
259             {
260                 System.out.print("TrafCODDemo received event of type " + event.getType() + ", payload [");
261                 String separator = "";
262                 for (Object o : payload)
263                 {
264                     System.out.print(separator + o);
265                     separator = ",";
266                 }
267                 System.out.println("]");
268             }
269         }
270 
271         /** {@inheritDoc} */
272         @Override
273         public Serializable getSourceId()
274         {
275             return "TrafCODModel";
276         }
277 
278     }
279 
280 }