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 nl.tudelft.simulation.dsol.SimRuntimeException;
18  import nl.tudelft.simulation.dsol.simulators.DEVSSimulator;
19  import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
20  import nl.tudelft.simulation.event.EventInterface;
21  import nl.tudelft.simulation.event.EventListenerInterface;
22  import nl.tudelft.simulation.event.EventProducer;
23  import nl.tudelft.simulation.event.EventType;
24  import nl.tudelft.simulation.language.io.URLResource;
25  
26  import org.djunits.unit.LengthUnit;
27  import org.djunits.unit.TimeUnit;
28  import org.djunits.value.vdouble.scalar.Duration;
29  import org.djunits.value.vdouble.scalar.Length;
30  import org.djunits.value.vdouble.scalar.Time;
31  import org.opentrafficsim.base.modelproperties.Property;
32  import org.opentrafficsim.base.modelproperties.PropertyException;
33  import org.opentrafficsim.core.dsol.OTSDEVSSimulatorInterface;
34  import org.opentrafficsim.core.dsol.OTSModelInterface;
35  import org.opentrafficsim.core.dsol.OTSSimTimeDouble;
36  import org.opentrafficsim.core.gtu.RelativePosition;
37  import org.opentrafficsim.core.gtu.animation.GTUColorer;
38  import org.opentrafficsim.core.network.OTSNetwork;
39  import org.opentrafficsim.road.animation.AnimationToggles;
40  import org.opentrafficsim.road.network.factory.xml.XmlNetworkLaneParser;
41  import org.opentrafficsim.road.network.lane.CrossSectionLink;
42  import org.opentrafficsim.road.network.lane.Lane;
43  import org.opentrafficsim.road.network.lane.object.sensor.TrafficLightSensor;
44  import org.opentrafficsim.road.network.lane.object.trafficlight.SimpleTrafficLight;
45  import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLight;
46  import org.opentrafficsim.simulationengine.AbstractWrappableAnimation;
47  import org.opentrafficsim.simulationengine.OTSSimulationException;
48  import org.opentrafficsim.simulationengine.SimpleSimulatorInterface;
49  import org.opentrafficsim.trafficcontrol.TrafficController;
50  import org.opentrafficsim.trafficcontrol.trafcod.TrafCOD;
51  
52  /**
53   * <p>
54   * Copyright (c) 2013-2016 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(new Time(0.0, TimeUnit.SECOND), new Duration(0.0, TimeUnit.SECOND), new Duration(60.0,
85                              TimeUnit.MINUTE), 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(final GTUColorer colorer) 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, OTSSimTimeDouble> theSimulator)
160                 throws SimRuntimeException, RemoteException
161         {
162             try
163             {
164                 URL url = URLResource.getResource("/TrafCODDemo2/Network.xml");
165                 XmlNetworkLaneParser nlp = new XmlNetworkLaneParser((OTSDEVSSimulatorInterface) theSimulator);
166                 this.network = nlp.build(url);
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 =
182                                 (Lane) ((CrossSectionLink) this.network.getLink(direction, direction + "C"))
183                                         .getCrossSectionElement("FORWARD" + laneNumber);
184                         trafficLights.add(new SimpleTrafficLight(String.format("TL%02d", stream), lane, lane.getLength().minus(
185                                 stopLineMargin), (OTSDEVSSimulatorInterface) theSimulator));
186                         sensors.add(new TrafficLightSensor(String.format("D%02d1", stream), lane, lane.getLength().minus(
187                                 headDetectorMargin), lane, lane.getLength().minus(headDetectorMargin).plus(headDetectorLength),
188                                 null, RelativePosition.FRONT, RelativePosition.REAR, (OTSDEVSSimulatorInterface) theSimulator));
189                         sensors.add(new TrafficLightSensor(String.format("D%02d2", stream), lane, lane.getLength().minus(
190                                 longDetectorMargin), lane, lane.getLength().minus(longDetectorMargin).plus(longDetectorLength),
191                                 null, RelativePosition.FRONT, RelativePosition.REAR, (OTSDEVSSimulatorInterface) theSimulator));
192                         stream++;
193                     }
194                 }
195                 String controllerName = "Not so simple TrafCOD controller";
196                 TrafCODDemo2.this.trafCOD =
197                         new TrafCOD(controllerName, URLResource.getResource("/TrafCODDemo2/Intersection12Dir.tfc"),
198                                 trafficLights, sensors, (DEVSSimulator<Time, Duration, OTSSimTimeDouble>) theSimulator,
199                                 TrafCODDemo2.this.controllerDisplayPanel);
200                 TrafCODDemo2.this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONTROLLER_EVALUATING);
201                 TrafCODDemo2.this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONTROLLER_WARNING);
202                 TrafCODDemo2.this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONFLICT_GROUP_CHANGED);
203                 TrafCODDemo2.this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_STATE_CHANGED);
204                 TrafCODDemo2.this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_VARIABLE_CREATED);
205                 TrafCODDemo2.this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_TRACED_VARIABLE_UPDATED);
206                 // Subscribe the TrafCOD machine to trace command events that we emit
207                 addListener(TrafCODDemo2.this.trafCOD, TrafficController.TRAFFICCONTROL_SET_TRACING);
208                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new Object[] {controllerName, "TGX", 8, true});
209                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new Object[] {controllerName, "XR1", 11, true});
210                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new Object[] {controllerName, "TD1", 11, true});
211                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new Object[] {controllerName, "TGX", 11, true});
212                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new Object[] {controllerName, "TL", 11, true});
213                 // System.out.println("demo: emitting a SET TRACING event for all variables related to stream 11");
214                 // fireEvent(TrafficController.TRAFFICCONTROL_SET_TRACING, new Object[] { controllerName, "", 11, true });
215 
216                 // TrafCODDemo2.this.trafCOD.traceVariablesOfStream(TrafficController.NO_STREAM, true);
217                 // TrafCODDemo2.this.trafCOD.traceVariablesOfStream(11, true);
218                 // TrafCODDemo2.this.trafCOD.traceVariable("MRV", 11, true);
219             }
220             catch (Exception exception)
221             {
222                 exception.printStackTrace();
223             }
224         }
225 
226         @SuppressWarnings("synthetic-access")
227         @Override
228         public SimulatorInterface<Time, Duration, OTSSimTimeDouble> getSimulator() throws RemoteException
229         {
230             return TrafCODDemo2.this.trafCOD.getSimulator();
231         }
232 
233         /** {@inheritDoc} */
234         @Override
235         public final OTSNetwork getNetwork()
236         {
237             return this.network;
238         }
239 
240         /** {@inheritDoc} */
241         @Override
242         public void notify(final EventInterface event) throws RemoteException
243         {
244             EventType type = event.getType();
245             Object[] payload = (Object[]) event.getContent();
246             if (TrafficController.TRAFFICCONTROL_CONTROLLER_EVALUATING.equals(type))
247             {
248                 // System.out.println("Evaluation starts at " + getSimulator().getSimulatorTime().getTime());
249                 return;
250             }
251             else if (TrafficController.TRAFFICCONTROL_CONFLICT_GROUP_CHANGED.equals(type))
252             {
253                 System.out.println("Conflict group changed from " + ((String) payload[1]) + " to " + ((String) payload[2]));
254             }
255             else if (TrafficController.TRAFFICCONTROL_TRACED_VARIABLE_UPDATED.equals(type))
256             {
257                 System.out.println(String.format("Variable changed %s <- %d   %s", payload[1], payload[4], payload[5]));
258             }
259             else if (TrafficController.TRAFFICCONTROL_CONTROLLER_WARNING.equals(type))
260             {
261                 System.out.println("Warning " + payload[1]);
262             }
263             else
264             {
265                 System.out.print("TrafCODDemo received event of type " + event.getType() + ", payload [");
266                 String separator = "";
267                 for (Object o : payload)
268                 {
269                     System.out.print(separator + o);
270                     separator = ",";
271                 }
272                 System.out.println("]");
273             }
274         }
275 
276     }
277 
278 }