View Javadoc
1   package org.opentrafficsim.demo.trafficcontrol;
2   
3   import java.awt.BorderLayout;
4   import java.awt.geom.Rectangle2D;
5   import java.awt.geom.Rectangle2D.Double;
6   import java.net.URL;
7   import java.rmi.RemoteException;
8   import java.util.ArrayList;
9   import java.util.HashSet;
10  import java.util.Set;
11  
12  import javax.naming.NamingException;
13  import javax.swing.JPanel;
14  import javax.swing.JScrollPane;
15  import javax.swing.SwingUtilities;
16  
17  import org.djunits.unit.DurationUnit;
18  import org.djunits.unit.LengthUnit;
19  import org.djunits.value.vdouble.scalar.Duration;
20  import org.djunits.value.vdouble.scalar.Length;
21  import org.djunits.value.vdouble.scalar.Time;
22  import org.opentrafficsim.base.modelproperties.Property;
23  import org.opentrafficsim.base.modelproperties.PropertyException;
24  import org.opentrafficsim.core.compatibility.Compatible;
25  import org.opentrafficsim.core.dsol.OTSModelInterface;
26  import org.opentrafficsim.core.gtu.RelativePosition;
27  import org.opentrafficsim.core.network.OTSNetwork;
28  import org.opentrafficsim.road.animation.AnimationToggles;
29  import org.opentrafficsim.road.network.factory.xml.XmlNetworkLaneParser;
30  import org.opentrafficsim.road.network.lane.CrossSectionLink;
31  import org.opentrafficsim.road.network.lane.Lane;
32  import org.opentrafficsim.road.network.lane.object.sensor.TrafficLightSensor;
33  import org.opentrafficsim.road.network.lane.object.trafficlight.SimpleTrafficLight;
34  import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLight;
35  import org.opentrafficsim.simulationengine.AbstractWrappableAnimation;
36  import org.opentrafficsim.simulationengine.OTSSimulationException;
37  import org.opentrafficsim.simulationengine.SimpleSimulatorInterface;
38  import org.opentrafficsim.trafficcontrol.TrafficController;
39  import org.opentrafficsim.trafficcontrol.trafcod.TrafCOD;
40  
41  import nl.tudelft.simulation.dsol.SimRuntimeException;
42  import nl.tudelft.simulation.dsol.simtime.SimTimeDoubleUnit;
43  import nl.tudelft.simulation.dsol.simulators.DEVSSimulator;
44  import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
45  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
46  import nl.tudelft.simulation.event.EventInterface;
47  import nl.tudelft.simulation.event.EventListenerInterface;
48  import nl.tudelft.simulation.event.EventProducer;
49  import nl.tudelft.simulation.event.EventType;
50  import nl.tudelft.simulation.language.io.URLResource;
51  
52  /**
53   * <p>
54   * Copyright (c) 2013-2018 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$, $LastChangedDate$, by $Author$, initial version Dec 06, 2016 <br>
58   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
59   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
60   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
61   */
62  public class TrafCODDemo2 extends AbstractWrappableAnimation
63  {
64  
65      /** */
66      private static final long serialVersionUID = 20161118L;
67  
68      /**
69       * Main program.
70       * @param args String[]; the command line arguments (not used)
71       * @throws SimRuntimeException should never happen
72       */
73      public static void main(final String[] args) throws SimRuntimeException
74      {
75          SwingUtilities.invokeLater(new Runnable()
76          {
77              @Override
78              public void run()
79              {
80                  try
81                  {
82                      TrafCODDemo2 model = new TrafCODDemo2();
83                      // 1 hour simulation run for testing
84                      model.buildAnimator(Time.ZERO, Duration.ZERO, new Duration(60.0, DurationUnit.MINUTE),
85                              new ArrayList<Property<?>>(), null, true);
86                  }
87                  catch (SimRuntimeException | NamingException | OTSSimulationException | PropertyException exception)
88                  {
89                      exception.printStackTrace();
90                  }
91              }
92          });
93      }
94  
95      /** TrafCOD controller display. */
96      private JPanel controllerDisplayPanel = new JPanel(new BorderLayout());
97  
98      /** The TrafCOD controller. */
99      private TrafCOD trafCOD;
100 
101     /** {@inheritDoc} */
102     @Override
103     public final String shortName()
104     {
105         return "TrafCOD demonstration 2";
106     }
107 
108     /** {@inheritDoc} */
109     @Override
110     public final String description()
111     {
112         return "TrafCOD demonstration";
113     }
114 
115     /** {@inheritDoc} */
116     @Override
117     protected final void addTabs(final SimpleSimulatorInterface simulator) throws OTSSimulationException, PropertyException
118     {
119         JScrollPane scrollPane = new JScrollPane(TrafCODDemo2.this.controllerDisplayPanel);
120         JPanel wrapper = new JPanel(new BorderLayout());
121         wrapper.add(scrollPane);
122         addTab(getTabCount() - 1, this.trafCOD.getId(), wrapper);
123     }
124 
125     /** {@inheritDoc} */
126     @Override
127     protected final OTSModelInterface makeModel() throws OTSSimulationException
128     {
129         return new TrafCODModel();
130     }
131 
132     /** {@inheritDoc} */
133     @Override
134     protected final void addAnimationToggles()
135     {
136         AnimationToggles.setTextAnimationTogglesStandard(this);
137     }
138 
139     /** {@inheritDoc} */
140     @Override
141     protected final Double makeAnimationRectangle()
142     {
143         return new Rectangle2D.Double(-200, -200, 400, 400);
144     }
145 
146     /**
147      * The simulation model.
148      */
149     class TrafCODModel extends EventProducer implements OTSModelInterface, EventListenerInterface
150     {
151         /** */
152         private static final long serialVersionUID = 20161020L;
153 
154         /** The network. */
155         private OTSNetwork network;
156 
157         @SuppressWarnings("synthetic-access")
158         @Override
159         public void constructModel(final SimulatorInterface<Time, Duration, SimTimeDoubleUnit> theSimulator)
160                 throws SimRuntimeException
161         {
162             try
163             {
164                 URL url = URLResource.getResource("/TrafCODDemo2/Network.xml");
165                 XmlNetworkLaneParser nlp = new XmlNetworkLaneParser((DEVSSimulatorInterface.TimeDoubleUnit) theSimulator);
166                 this.network = nlp.build(url, true);
167                 String[] directions = { "E", "S", "W", "N" };
168                 // Add the traffic lights and the detectors
169                 Set<TrafficLight> trafficLights = new HashSet<>();
170                 Set<TrafficLightSensor> sensors = new HashSet<>();
171                 Length stopLineMargin = new Length(0.1, LengthUnit.METER);
172                 Length headDetectorLength = new Length(1, LengthUnit.METER);
173                 Length headDetectorMargin = stopLineMargin.plus(headDetectorLength).plus(new Length(3, LengthUnit.METER));
174                 Length longDetectorLength = new Length(30, LengthUnit.METER);
175                 Length longDetectorMargin = stopLineMargin.plus(longDetectorLength).plus(new Length(10, LengthUnit.METER));
176                 int stream = 1;
177                 for (String direction : directions)
178                 {
179                     for (int laneNumber = 3; laneNumber >= 1; laneNumber--)
180                     {
181                         Lane lane = (Lane) ((CrossSectionLink) this.network.getLink(direction, direction + "C"))
182                                 .getCrossSectionElement("FORWARD" + laneNumber);
183                         trafficLights.add(new SimpleTrafficLight(String.format("TL%02d", stream), lane,
184                                 lane.getLength().minus(stopLineMargin), (DEVSSimulatorInterface.TimeDoubleUnit) theSimulator));
185                         sensors.add(new TrafficLightSensor(String.format("D%02d1", stream), lane,
186                                 lane.getLength().minus(headDetectorMargin), lane,
187                                 lane.getLength().minus(headDetectorMargin).plus(headDetectorLength), null,
188                                 RelativePosition.FRONT, RelativePosition.REAR, (DEVSSimulatorInterface.TimeDoubleUnit) theSimulator,
189                                 Compatible.EVERYTHING));
190                         sensors.add(new TrafficLightSensor(String.format("D%02d2", stream), lane,
191                                 lane.getLength().minus(longDetectorMargin), lane,
192                                 lane.getLength().minus(longDetectorMargin).plus(longDetectorLength), null,
193                                 RelativePosition.FRONT, RelativePosition.REAR, (DEVSSimulatorInterface.TimeDoubleUnit) theSimulator,
194                                 Compatible.EVERYTHING));
195                         stream++;
196                     }
197                 }
198                 String controllerName = "Not so simple TrafCOD controller";
199                 TrafCODDemo2.this.trafCOD =
200                         new TrafCOD(controllerName, URLResource.getResource("/TrafCODDemo2/Intersection12Dir.tfc"),
201                                 trafficLights, sensors, (DEVSSimulator<Time, Duration, SimTimeDoubleUnit>) theSimulator,
202                                 TrafCODDemo2.this.controllerDisplayPanel);
203                 TrafCODDemo2.this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONTROLLER_EVALUATING);
204                 TrafCODDemo2.this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONTROLLER_WARNING);
205                 TrafCODDemo2.this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONFLICT_GROUP_CHANGED);
206                 TrafCODDemo2.this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_STATE_CHANGED);
207                 TrafCODDemo2.this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_VARIABLE_CREATED);
208                 TrafCODDemo2.this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_TRACED_VARIABLE_UPDATED);
209                 // Subscribe the TrafCOD machine to trace command events that we emit
210                 addListener(TrafCODDemo2.this.trafCOD, TrafficController.TRAFFICCONTROL_SET_TRACING);
211                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new Object[] {controllerName, "TGX", 8, true});
212                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new Object[] {controllerName, "XR1", 11, true});
213                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new Object[] {controllerName, "TD1", 11, true});
214                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new Object[] {controllerName, "TGX", 11, true});
215                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new Object[] {controllerName, "TL", 11, true});
216                 // System.out.println("demo: emitting a SET TRACING event for all variables related to stream 11");
217                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new Object[] { controllerName, "", 11, true });
218 
219                 // TrafCODDemo2.this.trafCOD.traceVariablesOfStream(TrafficController.NO_STREAM, true);
220                 // TrafCODDemo2.this.trafCOD.traceVariablesOfStream(11, true);
221                 // TrafCODDemo2.this.trafCOD.traceVariable("MRV", 11, true);
222             }
223             catch (Exception exception)
224             {
225                 exception.printStackTrace();
226             }
227         }
228 
229         @SuppressWarnings("synthetic-access")
230         @Override
231         public SimulatorInterface<Time, Duration, SimTimeDoubleUnit> getSimulator()
232         {
233             return TrafCODDemo2.this.trafCOD.getSimulator();
234         }
235 
236         /** {@inheritDoc} */
237         @Override
238         public final OTSNetwork getNetwork()
239         {
240             return this.network;
241         }
242 
243         /** {@inheritDoc} */
244         @Override
245         public void notify(final EventInterface event) throws RemoteException
246         {
247             EventType type = event.getType();
248             Object[] payload = (Object[]) event.getContent();
249             if (TrafficController.TRAFFICCONTROL_CONTROLLER_EVALUATING.equals(type))
250             {
251                 // System.out.println("Evaluation starts at " + getSimulator().getSimulatorTime());
252                 return;
253             }
254             else if (TrafficController.TRAFFICCONTROL_CONFLICT_GROUP_CHANGED.equals(type))
255             {
256                 System.out.println("Conflict group changed from " + ((String) payload[1]) + " to " + ((String) payload[2]));
257             }
258             else if (TrafficController.TRAFFICCONTROL_TRACED_VARIABLE_UPDATED.equals(type))
259             {
260                 System.out.println(String.format("Variable changed %s <- %d   %s", payload[1], payload[4], payload[5]));
261             }
262             else if (TrafficController.TRAFFICCONTROL_CONTROLLER_WARNING.equals(type))
263             {
264                 System.out.println("Warning " + payload[1]);
265             }
266             else
267             {
268                 System.out.print("TrafCODDemo received event of type " + event.getType() + ", payload [");
269                 String separator = "";
270                 for (Object o : payload)
271                 {
272                     System.out.print(separator + o);
273                     separator = ",";
274                 }
275                 System.out.println("]");
276             }
277         }
278 
279     }
280 
281 }