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