View Javadoc
1   package org.opentrafficsim.demo.conflictAndControl;
2   
3   import java.awt.BorderLayout;
4   import java.awt.Dimension;
5   import java.io.Serializable;
6   import java.net.URL;
7   import java.rmi.RemoteException;
8   import java.util.LinkedHashSet;
9   import java.util.Set;
10  
11  import javax.naming.NamingException;
12  import javax.swing.JPanel;
13  import javax.swing.JScrollPane;
14  
15  import org.djunits.unit.LengthUnit;
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.event.EventInterface;
20  import org.djutils.event.EventListenerInterface;
21  import org.djutils.event.EventTypeInterface;
22  import org.djutils.io.URLResource;
23  import org.opentrafficsim.core.animation.gtu.colorer.DefaultSwitchableGTUColorer;
24  import org.opentrafficsim.core.compatibility.Compatible;
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.gtu.GTUType;
29  import org.opentrafficsim.core.gtu.RelativePosition;
30  import org.opentrafficsim.core.network.NetworkException;
31  import org.opentrafficsim.demo.conflictAndControl.DemoTrafcodAndTurbo.TrafCODModel;
32  import org.opentrafficsim.draw.core.OTSDrawingException;
33  import org.opentrafficsim.draw.road.TrafficLightAnimation;
34  import org.opentrafficsim.road.network.OTSRoadNetwork;
35  import org.opentrafficsim.road.network.factory.xml.parser.XmlNetworkLaneParser;
36  import org.opentrafficsim.road.network.lane.CrossSectionLink;
37  import org.opentrafficsim.road.network.lane.CrossSectionLink.Priority;
38  import org.opentrafficsim.road.network.lane.Lane;
39  import org.opentrafficsim.road.network.lane.conflict.ConflictBuilder;
40  import org.opentrafficsim.road.network.lane.object.sensor.TrafficLightSensor;
41  import org.opentrafficsim.road.network.lane.object.trafficlight.SimpleTrafficLight;
42  import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLight;
43  import org.opentrafficsim.swing.gui.OTSAnimationPanel;
44  import org.opentrafficsim.swing.gui.OTSSimulationApplication;
45  import org.opentrafficsim.trafficcontrol.TrafficController;
46  import org.opentrafficsim.trafficcontrol.trafcod.TrafCOD;
47  
48  import nl.tudelft.simulation.dsol.SimRuntimeException;
49  import nl.tudelft.simulation.language.DSOLException;
50  
51  
52  /**
53   * <p>
54   * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
55   * BSD-style license. See <a href="http://opentrafficsim.org/node/13">OpenTrafficSim License</a>.
56   * <p>
57   * @version $Revision: 6688 $, $LastChangedDate: 2020-09-03 11:54:19 +0200 (Thu, 03 Sep 2020) $, by $Author: averbraeck $,
58   *          initial version Dec 06, 2016 <br>
59   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
60   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
61   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
62   */
63  public class DemoTrafcodAndTurbo extends OTSSimulationApplication<TrafCODModel>
64  {
65      /** */
66      private static final long serialVersionUID = 20161118L;
67  
68      /**
69       * Create a TrafcodAndTurbo demo.
70       * @param title String; the title of the Frame
71       * @param panel OTSAnimationPanel; the tabbed panel to display
72       * @param model TrafCODModel; the model
73       * @throws OTSDrawingException on animation error
74       */
75      public DemoTrafcodAndTurbo(final String title, final OTSAnimationPanel panel, final TrafCODModel model)
76              throws OTSDrawingException
77      {
78          super(model, panel);
79      }
80  
81      /**
82       * Main program.
83       * @param args String[]; the command line arguments (not used)
84       */
85      public static void main(final String[] args)
86      {
87          demo(true);
88      }
89  
90      /**
91       * Start the demo.
92       * @param exitOnClose boolean; when running stand-alone: true; when running as part of a demo: false
93       */
94      public static void demo(final boolean exitOnClose)
95      {
96          try
97          {
98              OTSAnimator simulator = new OTSAnimator("DemoTrafcodAndTurbo");
99              final TrafCODModel junctionModel = new TrafCODModel(simulator);
100             simulator.initialize(Time.ZERO, Duration.ZERO, Duration.instantiateSI(3600.0), junctionModel);
101             OTSAnimationPanel animationPanel =
102                     new OTSAnimationPanel(junctionModel.getNetwork().getExtent(), new Dimension(800, 600), simulator,
103                             junctionModel, new DefaultSwitchableGTUColorer(), junctionModel.getNetwork());
104             DemoTrafcodAndTurbotrol/DemoTrafcodAndTurbo.html#DemoTrafcodAndTurbo">DemoTrafcodAndTurbo app = new DemoTrafcodAndTurbo("TrafCOD Turbo demo", animationPanel, junctionModel);
105             app.setExitOnClose(exitOnClose);
106             animationPanel.enableSimulationControlButtons();
107         }
108         catch (SimRuntimeException | NamingException | RemoteException | OTSDrawingException | DSOLException exception)
109         {
110             exception.printStackTrace();
111         }
112     }
113 
114     /**
115      * Add tab with trafCOD status.
116      */
117     @Override
118     protected void addTabs()
119     {
120         JScrollPane scrollPane = new JScrollPane(getModel().getControllerDisplayPanel());
121         JPanel wrapper = new JPanel(new BorderLayout());
122         wrapper.add(scrollPane);
123         getAnimationPanel().getTabbedPane().addTab(getAnimationPanel().getTabbedPane().getTabCount() - 1,
124                 getModel().getTrafCOD().getId(), wrapper);
125     }
126 
127     /**
128      * The simulation model.
129      */
130     static class TrafCODModel extends AbstractOTSModel implements EventListenerInterface
131     {
132         /** */
133         private static final long serialVersionUID = 20161020L;
134 
135         /** The network. */
136         private OTSRoadNetwork network;
137 
138         /** The TrafCOD controller. */
139         private TrafCOD trafCOD;
140 
141         /** TrafCOD controller display. */
142         private JPanel controllerDisplayPanel = new JPanel(new BorderLayout());
143 
144         /**
145          * @param simulator OTSSimulatorInterface; the simulator for this model
146          */
147         TrafCODModel(final OTSSimulatorInterface simulator)
148         {
149             super(simulator);
150         }
151 
152         /** {@inheritDoc} */
153         @Override
154         public void constructModel() throws SimRuntimeException
155         {
156             try
157             {
158                 URL xmlURL = URLResource.getResource("/conflictAndControl/TurboRoundaboutAndSignal.xml");
159                 this.network = new OTSRoadNetwork("TurboRoundaboutAndSignal", true, getSimulator());
160                 XmlNetworkLaneParser.build(xmlURL, this.network, false);
161 
162                 // add conflicts
163                 ((CrossSectionLink) this.network.getLink("EBNA")).setPriority(Priority.PRIORITY);
164                 ((CrossSectionLink) this.network.getLink("NBWA")).setPriority(Priority.PRIORITY);
165                 ((CrossSectionLink) this.network.getLink("WBSA")).setPriority(Priority.PRIORITY);
166                 ((CrossSectionLink) this.network.getLink("SBEA")).setPriority(Priority.PRIORITY);
167                 ConflictBuilder.buildConflicts(this.network, this.network.getGtuType(GTUType.DEFAULTS.VEHICLE), this.simulator,
168                         new ConflictBuilder.FixedWidthGenerator(new Length(2.0, LengthUnit.SI)));
169 
170                 // CrossSectionLink csLink = ((CrossSectionLink)
171                 // this.network.getLink("WWW"));
172                 // Lane lane = (Lane) csLink.getCrossSectionElement("RIGHT");
173                 // GTUColorer gtuColorer = null;
174                 // setupBlock(lane, (DEVSSimulatorInterface.TimeDoubleUnit) this.simulator,
175                 // gtuColorer );
176 
177                 String[] directions = {"E", "S", "W", "N"};
178                 // Add the traffic lights and the detectors
179                 Set<TrafficLight> trafficLights = new LinkedHashSet<>();
180                 Set<TrafficLightSensor> sensors = new LinkedHashSet<>();
181                 Length stopLineMargin = new Length(0.1, LengthUnit.METER);
182                 Length headDetectorLength = new Length(1, LengthUnit.METER);
183                 Length headDetectorMargin = stopLineMargin.plus(headDetectorLength).plus(new Length(3, LengthUnit.METER));
184                 Length longDetectorLength = new Length(30, LengthUnit.METER);
185                 Length longDetectorMargin = stopLineMargin.plus(longDetectorLength).plus(new Length(10, LengthUnit.METER));
186                 int stream = 1;
187                 for (String direction : directions)
188                 {
189                     for (int laneNumber = 3; laneNumber >= 1; laneNumber--)
190                     {
191                         Lane lane = (Lane) ((CrossSectionLink) this.network.getLink(direction + "S", direction + "C"))
192                                 .getCrossSectionElement("FORWARD" + laneNumber);
193                         if (lane != null)
194                         {
195                             if (stream != 7)
196                             {
197                                 TrafficLight tl = new SimpleTrafficLight(String.format("%02d", stream), lane,
198                                         lane.getLength().minus(stopLineMargin), this.simulator);
199                                 trafficLights.add(tl);
200 
201                                 try
202                                 {
203                                     new TrafficLightAnimation(tl, this.simulator);
204                                 }
205                                 catch (RemoteException | NamingException exception)
206                                 {
207                                     throw new NetworkException(exception);
208                                 }
209 
210                                 sensors.add(new TrafficLightSensor(String.format("D%02d1", stream), lane,
211                                         lane.getLength().minus(headDetectorMargin), lane,
212                                         lane.getLength().minus(headDetectorMargin).plus(headDetectorLength), null,
213                                         RelativePosition.FRONT, RelativePosition.REAR, this.simulator, Compatible.EVERYTHING));
214                                 sensors.add(new TrafficLightSensor(String.format("D%02d2", stream), lane,
215                                         lane.getLength().minus(longDetectorMargin), lane,
216                                         lane.getLength().minus(longDetectorMargin).plus(longDetectorLength), null,
217                                         RelativePosition.FRONT, RelativePosition.REAR, this.simulator, Compatible.EVERYTHING));
218                             }
219                             else
220                             {
221                                 lane = (Lane) ((CrossSectionLink) this.network.getLink("ESS1", "ESS"))
222                                         .getCrossSectionElement("FORWARD");
223                                 TrafficLight tl = new SimpleTrafficLight(String.format("%02d", stream), lane,
224                                         lane.getLength().minus(stopLineMargin), this.simulator);
225                                 trafficLights.add(tl);
226 
227                                 try
228                                 {
229                                     new TrafficLightAnimation(tl, this.simulator);
230                                 }
231                                 catch (RemoteException | NamingException exception)
232                                 {
233                                     throw new NetworkException(exception);
234                                 }
235 
236                                 sensors.add(new TrafficLightSensor(String.format("D%02d1", stream), lane,
237                                         lane.getLength().minus(headDetectorMargin), lane,
238                                         lane.getLength().minus(headDetectorMargin).plus(headDetectorLength), null,
239                                         RelativePosition.FRONT, RelativePosition.REAR, this.simulator, Compatible.EVERYTHING));
240                                 sensors.add(new TrafficLightSensor(String.format("D%02d2", stream), lane,
241                                         lane.getLength().minus(longDetectorMargin), lane,
242                                         lane.getLength().minus(longDetectorMargin).plus(longDetectorLength), null,
243                                         RelativePosition.FRONT, RelativePosition.REAR, this.simulator, Compatible.EVERYTHING));
244 
245                             }
246 
247                         }
248                         stream++;
249                     }
250                 }
251                 String controllerName = "Not so simple TrafCOD controller";
252                 this.trafCOD = new TrafCOD(controllerName, URLResource.getResource("/conflictAndControl/Intersection12Dir.tfc"),
253                         this.simulator, this.controllerDisplayPanel, null, null);
254                 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONTROLLER_EVALUATING);
255                 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONTROLLER_WARNING);
256                 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONFLICT_GROUP_CHANGED);
257                 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_STATE_CHANGED);
258                 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_VARIABLE_CREATED);
259                 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_TRACED_VARIABLE_UPDATED);
260                 // Subscribe the TrafCOD machine to trace command events that we
261                 // emit
262                 addListener(this.trafCOD, TrafficController.TRAFFICCONTROL_SET_TRACING);
263                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new
264                 // Object[] {controllerName, "TGX", 8, true});
265                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new
266                 // Object[] {controllerName, "XR1", 11, true});
267                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new
268                 // Object[] {controllerName, "TD1", 11, true});
269                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new
270                 // Object[] {controllerName, "TGX", 11, true});
271                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new
272                 // Object[] {controllerName, "TL", 11, true});
273                 // System.out.println("demo: emitting a SET TRACING event for
274                 // all variables related to stream 11");
275                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new
276                 // Object[] { controllerName, "", 11, true });
277 
278                 // TrafCODDemo2.this.trafCOD.traceVariablesOfStream(TrafficController.NO_STREAM,
279                 // true);
280                 // TrafCODDemo2.this.trafCOD.traceVariablesOfStream(11, true);
281                 // TrafCODDemo2.this.trafCOD.traceVariable("MRV", 11, true);
282             }
283             catch (Exception exception)
284             {
285                 exception.printStackTrace();
286             }
287         }
288 
289         /** {@inheritDoc} */
290         @Override
291         public final OTSRoadNetwork getNetwork()
292         {
293             return this.network;
294         }
295 
296         /**
297          * @return trafCOD
298          */
299         public final TrafCOD getTrafCOD()
300         {
301             return this.trafCOD;
302         }
303 
304         /**
305          * @return controllerDisplayPanel
306          */
307         public final JPanel getControllerDisplayPanel()
308         {
309             return this.controllerDisplayPanel;
310         }
311 
312         /** {@inheritDoc} */
313         @Override
314         public void notify(final EventInterface event) throws RemoteException
315         {
316             EventTypeInterface type = event.getType();
317             Object[] payload = (Object[]) event.getContent();
318             if (TrafficController.TRAFFICCONTROL_CONTROLLER_EVALUATING.equals(type))
319             {
320                 // System.out.println("Evaluation starts at " +
321                 // getSimulator().getSimulatorTime());
322                 return;
323             }
324             else if (TrafficController.TRAFFICCONTROL_CONFLICT_GROUP_CHANGED.equals(type))
325             {
326                 System.out.println("Conflict group changed from " + ((String) payload[1]) + " to " + ((String) payload[2]));
327             }
328             else if (TrafficController.TRAFFICCONTROL_TRACED_VARIABLE_UPDATED.equals(type))
329             {
330                 System.out.println(String.format("Variable changed %s <- %d   %s", payload[1], payload[4], payload[5]));
331             }
332             else if (TrafficController.TRAFFICCONTROL_CONTROLLER_WARNING.equals(type))
333             {
334                 System.out.println("Warning " + payload[1]);
335             }
336             else
337             {
338                 System.out.print("TrafCODDemo received event of type " + event.getType() + ", payload [");
339                 String separator = "";
340                 for (Object o : payload)
341                 {
342                     System.out.print(separator + o);
343                     separator = ",";
344                 }
345                 System.out.println("]");
346             }
347         }
348 
349         /** {@inheritDoc} */
350         @Override
351         public Serializable getSourceId()
352         {
353             return "TrafCODModel";
354         }
355     }
356 }