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