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.net.URL;
9   import java.nio.charset.StandardCharsets;
10  import java.rmi.RemoteException;
11  import java.util.Scanner;
12  
13  import javax.naming.NamingException;
14  import javax.swing.JPanel;
15  import javax.swing.JScrollPane;
16  
17  import org.djunits.value.vdouble.scalar.Duration;
18  import org.djunits.value.vdouble.scalar.Time;
19  import org.djutils.event.Event;
20  import org.djutils.event.EventListener;
21  import org.djutils.event.EventType;
22  import org.djutils.immutablecollections.ImmutableMap;
23  import org.djutils.io.URLResource;
24  import org.djutils.logger.CategoryLogger;
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.object.NonLocatedObject;
29  import org.opentrafficsim.demo.trafficcontrol.TrafCodDemo2.TrafCodModel;
30  import org.opentrafficsim.draw.OtsDrawingException;
31  import org.opentrafficsim.road.network.RoadNetwork;
32  import org.opentrafficsim.road.network.factory.xml.parser.XmlParser;
33  import org.opentrafficsim.swing.gui.OtsAnimationPanel;
34  import org.opentrafficsim.swing.gui.OtsSimulationApplication;
35  import org.opentrafficsim.trafficcontrol.TrafficController;
36  import org.opentrafficsim.trafficcontrol.trafcod.TrafCod;
37  
38  import nl.tudelft.simulation.dsol.SimRuntimeException;
39  import nl.tudelft.simulation.dsol.swing.gui.TabbedContentPane;
40  import nl.tudelft.simulation.language.DsolException;
41  
42  /**
43   * <p>
44   * Copyright (c) 2013-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
45   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
46   * </p>
47   * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
48   * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
49   * @author <a href="https://github.com/wjschakel">Wouter Schakel</a>
50   */
51  public class TrafCodDemo2 extends OtsSimulationApplication<TrafCodModel>
52  {
53      /** */
54      private static final long serialVersionUID = 20161118L;
55  
56      /**
57       * Create a Trafcod demo.
58       * @param title String; the title of the Frame
59       * @param panel OtsAnimationPanel; the tabbed panel to display
60       * @param model TrafCODModel; the model
61       * @throws OtsDrawingException on animation error
62       */
63      public TrafCodDemo2(final String title, final OtsAnimationPanel panel, final TrafCodModel model) throws OtsDrawingException
64      {
65          super(model, panel);
66      }
67  
68      /**
69       * Main program.
70       * @param args String[]; the command line arguments (not used)
71       * @throws IOException ...
72       */
73      public static void main(final String[] args) throws IOException
74      {
75          demo(true);
76      }
77  
78      /**
79       * Open an URL, read it and store the contents in a string. Adapted from
80       * https://stackoverflow.com/questions/4328711/read-url-to-string-in-few-lines-of-java-code
81       * @param url URL; the URL
82       * @return String
83       * @throws IOException when reading the file fails
84       */
85      public static String readStringFromURL(final URL url) throws IOException
86      {
87          try (Scanner scanner = new Scanner(url.openStream(), StandardCharsets.UTF_8.toString()))
88          {
89              scanner.useDelimiter("\\A");
90              return scanner.hasNext() ? scanner.next() : "";
91          }
92      }
93  
94      /**
95       * Start the demo.
96       * @param exitOnClose boolean; when running stand-alone: true; when running as part of a demo: false
97       * @throws IOException when reading the file fails
98       */
99      public static void demo(final boolean exitOnClose) throws IOException
100     {
101         try
102         {
103             OtsAnimator simulator = new OtsAnimator("TrafCODDemo2");
104             URL url = URLResource.getResource("/resources/TrafCODDemo2/TrafCODDemo2.xml");
105             System.out.println("url is " + url);
106             String xml = readStringFromURL(url);
107             final TrafCodModel trafcodModel = new TrafCodModel(simulator, "TrafCODModel", "TrafCOD demonstration Model", xml);
108             simulator.initialize(Time.ZERO, Duration.ZERO, Duration.instantiateSI(3600.0), trafcodModel);
109             OtsAnimationPanel animationPanel = new OtsAnimationPanel(trafcodModel.getNetwork().getExtent(),
110                     new Dimension(800, 600), simulator, trafcodModel, DEFAULT_COLORER, trafcodModel.getNetwork());
111             TrafCodDemo2 app = new TrafCodDemo2("TrafCOD demo complex crossing", animationPanel, trafcodModel);
112             app.setExitOnClose(exitOnClose);
113             animationPanel.enableSimulationControlButtons();
114         }
115         catch (SimRuntimeException | NamingException | RemoteException | OtsDrawingException | DsolException exception)
116         {
117             exception.printStackTrace();
118         }
119     }
120 
121     /**
122      * Add tabs with trafCOD status display.
123      */
124     @Override
125     protected final void addTabs()
126     {
127         OtsAnimationPanel animationPanel = getAnimationPanel();
128         if (null == animationPanel)
129         {
130             return;
131         }
132         ImmutableMap<String, NonLocatedObject> nonLocatedObjectMap = getModel().getNetwork().getNonLocatedObjectMap();
133         for (NonLocatedObject ioi : nonLocatedObjectMap.values())
134         {
135             if (ioi instanceof TrafCod)
136             {
137                 TrafCod trafCOD = (TrafCod) ioi;
138                 Container controllerDisplayPanel = trafCOD.getDisplayContainer();
139                 if (null != controllerDisplayPanel)
140                 {
141                     JPanel wrapper = new JPanel(new BorderLayout());
142                     wrapper.add(new JScrollPane(controllerDisplayPanel));
143                     TabbedContentPane tabbedPane = animationPanel.getTabbedPane();
144                     tabbedPane.addTab(tabbedPane.getTabCount() - 1, trafCOD.getId(), wrapper);
145                 }
146                 // trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONTROLLER_EVALUATING);
147                 trafCOD.addListener(getModel(), TrafficController.TRAFFICCONTROL_CONTROLLER_WARNING);
148                 trafCOD.addListener(getModel(), TrafficController.TRAFFICCONTROL_CONFLICT_GROUP_CHANGED);
149                 trafCOD.addListener(getModel(), TrafficController.TRAFFICCONTROL_STATE_CHANGED);
150                 trafCOD.addListener(getModel(), TrafficController.TRAFFICCONTROL_VARIABLE_CREATED);
151                 trafCOD.addListener(getModel(), TrafficController.TRAFFICCONTROL_TRACED_VARIABLE_UPDATED);
152 
153             }
154         }
155     }
156 
157     /**
158      * The simulation model.
159      */
160     public static class TrafCodModel extends AbstractOtsModel implements EventListener
161     {
162         /** */
163         private static final long serialVersionUID = 20161020L;
164 
165         /** The network. */
166         private RoadNetwork network;
167 
168         /** The XML. */
169         private final String xml;
170 
171         /**
172          * @param simulator OtsSimulatorInterface; the simulator
173          * @param shortName String; name of the model
174          * @param description String; description of the model
175          * @param xml String; the XML string
176          */
177         public TrafCodModel(final OtsSimulatorInterface simulator, final String shortName, final String description,
178                 final String xml)
179         {
180             super(simulator, shortName, description);
181             this.xml = xml;
182         }
183 
184         /** {@inheritDoc} */
185         @Override
186         public void constructModel() throws SimRuntimeException
187         {
188             try
189             {
190                 this.network = new RoadNetwork(getShortName(), getSimulator());
191                 new XmlParser(this.network).setStream(new ByteArrayInputStream(this.xml.getBytes(StandardCharsets.UTF_8)))
192                         .build();
193             }
194             catch (Exception exception)
195             {
196                 exception.printStackTrace();
197             }
198         }
199 
200         /** {@inheritDoc} */
201         @Override
202         public final RoadNetwork getNetwork()
203         {
204             return this.network;
205         }
206 
207         /** {@inheritDoc} */
208         @Override
209         public void notify(final Event event) throws RemoteException
210         {
211             EventType type = event.getType();
212             Object[] payload = (Object[]) event.getContent();
213             if (TrafficController.TRAFFICCONTROL_CONTROLLER_EVALUATING.equals(type))
214             {
215                 // System.out.println("Evaluation starts at " + getSimulator().getSimulatorTime());
216                 return;
217             }
218             else if (TrafficController.TRAFFICCONTROL_CONFLICT_GROUP_CHANGED.equals(type))
219             {
220                 CategoryLogger.always().info("Conflict group changed from {} to {}", (String) payload[1], (String) payload[2]);
221             }
222             else if (TrafficController.TRAFFICCONTROL_TRACED_VARIABLE_UPDATED.equals(type))
223             {
224                 CategoryLogger.always().info("Variable changed %s <- %d   %s", payload[1], payload[4], payload[5]);
225             }
226             else if (TrafficController.TRAFFICCONTROL_CONTROLLER_WARNING.equals(type))
227             {
228                 CategoryLogger.always().info("Warning " + payload[1]);
229             }
230             else
231             {
232                 StringBuilder stringBuilder = new StringBuilder();
233                 stringBuilder.append("TrafCODDemo received event of type " + event.getType() + ", payload [");
234                 String separator = "";
235                 for (Object o : payload)
236                 {
237                     stringBuilder.append(separator + o);
238                     separator = ",";
239                 }
240                 stringBuilder.append("]");
241                 CategoryLogger.always().info(stringBuilder.toString());
242             }
243         }
244 
245         /** {@inheritDoc} */
246         @Override
247         public String toString()
248         {
249             return "TrafCODModel [network=" + this.network.getId() + "]";
250         }
251 
252     }
253 
254 }