View Javadoc
1   package org.opentrafficsim.demo.trafficcontrol;
2   
3   import java.awt.BorderLayout;
4   import java.awt.Container;
5   import java.awt.Dimension;
6   import java.io.ByteArrayInputStream;
7   import java.io.IOException;
8   import java.io.Serializable;
9   import java.net.URL;
10  import java.nio.charset.StandardCharsets;
11  import java.rmi.RemoteException;
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.immutablecollections.ImmutableMap;
24  import org.djutils.io.URLResource;
25  import org.djutils.logger.CategoryLogger;
26  import org.opentrafficsim.core.dsol.AbstractOTSModel;
27  import org.opentrafficsim.core.dsol.OTSAnimator;
28  import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
29  import org.opentrafficsim.core.object.InvisibleObjectInterface;
30  import org.opentrafficsim.demo.trafficcontrol.TrafCODDemo2.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.OTS;
39  
40  import nl.tudelft.simulation.dsol.SimRuntimeException;
41  import nl.tudelft.simulation.dsol.swing.gui.TabbedContentPane;
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 Dec 06, 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 TrafCODDemo2 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 TrafCODDemo2(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("TrafCODDemo2");
107             URL url = URLResource.getResource("/TrafCODDemo2/TrafCODDemo2.xml");
108             System.out.println("url is " + url);
109             String xml = readStringFromURL(url);
110             final TrafCODModel trafcodModel = new TrafCODModel(simulator, "TrafCODModel", "TrafCOD demonstration Model", xml);
111             simulator.initialize(Time.ZERO, Duration.ZERO, Duration.instantiateSI(3600.0), trafcodModel);
112             OTSAnimationPanel animationPanel = new OTSAnimationPanel(trafcodModel.getNetwork().getExtent(),
113                     new Dimension(800, 600), simulator, trafcodModel, DEFAULT_COLORER, trafcodModel.getNetwork());
114             TrafCODDemo2control/TrafCODDemo2.html#TrafCODDemo2">TrafCODDemo2 app = new TrafCODDemo2("TrafCOD demo complex crossing", animationPanel, trafcodModel);
115             app.setExitOnClose(exitOnClose);
116             animationPanel.enableSimulationControlButtons();
117         }
118         catch (SimRuntimeException | NamingException | RemoteException | OTSDrawingException | DSOLException exception)
119         {
120             exception.printStackTrace();
121         }
122     }
123 
124     /**
125      * Add tabs with trafCOD status display.
126      */
127     @Override
128     protected final void addTabs()
129     {
130         OTSAnimationPanel animationPanel = getAnimationPanel();
131         if (null == animationPanel)
132         {
133             return;
134         }
135         ImmutableMap<String, InvisibleObjectInterface> invisibleObjectMap = getModel().getNetwork().getInvisibleObjectMap();
136         for (InvisibleObjectInterface ioi : invisibleObjectMap.values())
137         {
138             if (ioi instanceof TrafCOD)
139             {
140                 TrafCOD trafCOD = (TrafCOD) ioi;
141                 Container controllerDisplayPanel = trafCOD.getDisplayContainer();
142                 if (null != controllerDisplayPanel)
143                 {
144                     JPanel wrapper = new JPanel(new BorderLayout());
145                     wrapper.add(new JScrollPane(controllerDisplayPanel));
146                     TabbedContentPane tabbedPane = animationPanel.getTabbedPane();
147                     tabbedPane.addTab(tabbedPane.getTabCount() - 1, trafCOD.getId(), wrapper);
148                 }
149                 // trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONTROLLER_EVALUATING);
150                 trafCOD.addListener(getModel(), TrafficController.TRAFFICCONTROL_CONTROLLER_WARNING);
151                 trafCOD.addListener(getModel(), TrafficController.TRAFFICCONTROL_CONFLICT_GROUP_CHANGED);
152                 trafCOD.addListener(getModel(), TrafficController.TRAFFICCONTROL_STATE_CHANGED);
153                 trafCOD.addListener(getModel(), TrafficController.TRAFFICCONTROL_VARIABLE_CREATED);
154                 trafCOD.addListener(getModel(), TrafficController.TRAFFICCONTROL_TRACED_VARIABLE_UPDATED);
155 
156             }
157         }
158     }
159 
160     /**
161      * The simulation model.
162      */
163     public static class TrafCODModel extends AbstractOTSModel implements EventListenerInterface
164     {
165         /** */
166         private static final long serialVersionUID = 20161020L;
167 
168         /** The network. */
169         private OTSRoadNetwork network;
170 
171         /** The XML. */
172         private final String xml;
173 
174         /**
175          * @param simulator OTSSimulatorInterface; the simulator
176          * @param shortName String; name of the model
177          * @param description String; description of the model
178          * @param xml String; the XML string
179          */
180         public TrafCODModel(final OTSSimulatorInterface simulator, final String shortName, final String description,
181                 final String xml)
182         {
183             super(simulator, shortName, description);
184             this.xml = xml;
185         }
186 
187         /** {@inheritDoc} */
188         @Override
189         public void constructModel() throws SimRuntimeException
190         {
191             try
192             {
193                 this.network = new OTSRoadNetwork(getShortName(), true, getSimulator());
194                 OTS ots = XmlNetworkLaneParser.parseXML(new ByteArrayInputStream(this.xml.getBytes(StandardCharsets.UTF_8)));
195                 XmlNetworkLaneParser.build(ots, this.network, false);
196             }
197             catch (Exception exception)
198             {
199                 exception.printStackTrace();
200             }
201         }
202 
203         /** {@inheritDoc} */
204         @Override
205         public final OTSRoadNetwork getNetwork()
206         {
207             return this.network;
208         }
209 
210         /** {@inheritDoc} */
211         @Override
212         public void notify(final EventInterface event) throws RemoteException
213         {
214             EventTypeInterface type = event.getType();
215             Object[] payload = (Object[]) event.getContent();
216             if (TrafficController.TRAFFICCONTROL_CONTROLLER_EVALUATING.equals(type))
217             {
218                 // System.out.println("Evaluation starts at " + getSimulator().getSimulatorTime());
219                 return;
220             }
221             else if (TrafficController.TRAFFICCONTROL_CONFLICT_GROUP_CHANGED.equals(type))
222             {
223                 CategoryLogger.always().info("Conflict group changed from {} to {}", (String) payload[1], (String) payload[2]);
224             }
225             else if (TrafficController.TRAFFICCONTROL_TRACED_VARIABLE_UPDATED.equals(type))
226             {
227                 CategoryLogger.always().info("Variable changed %s <- %d   %s", payload[1], payload[4], payload[5]);
228             }
229             else if (TrafficController.TRAFFICCONTROL_CONTROLLER_WARNING.equals(type))
230             {
231                 CategoryLogger.always().info("Warning " + payload[1]);
232             }
233             else
234             {
235                 StringBuilder stringBuilder = new StringBuilder();
236                 stringBuilder.append("TrafCODDemo received event of type " + event.getType() + ", payload [");
237                 String separator = "";
238                 for (Object o : payload)
239                 {
240                     stringBuilder.append(separator + o);
241                     separator = ",";
242                 }
243                 stringBuilder.append("]");
244                 CategoryLogger.always().info(stringBuilder.toString());
245             }
246         }
247 
248         /** {@inheritDoc} */
249         @Override
250         public Serializable getSourceId()
251         {
252             return "TrafCODModel";
253         }
254 
255         /** {@inheritDoc} */
256         @Override
257         public String toString()
258         {
259             return "TrafCODModel [network=" + network.getId() + "]";
260         }
261 
262     }
263 
264 }