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