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