1   package org.opentrafficsim.demo.conflictAndControl;
2   
3   import java.awt.BorderLayout;
4   import java.awt.Dimension;
5   import java.net.URL;
6   import java.rmi.RemoteException;
7   import java.util.LinkedHashSet;
8   import java.util.Set;
9   
10  import javax.naming.NamingException;
11  import javax.swing.JPanel;
12  import javax.swing.JScrollPane;
13  
14  import org.djunits.unit.LengthUnit;
15  import org.djunits.value.vdouble.scalar.Duration;
16  import org.djunits.value.vdouble.scalar.Length;
17  import org.djunits.value.vdouble.scalar.Time;
18  import org.djutils.io.URLResource;
19  import org.opentrafficsim.core.animation.gtu.colorer.DefaultSwitchableGTUColorer;
20  import org.opentrafficsim.core.compatibility.Compatible;
21  import org.opentrafficsim.core.dsol.AbstractOTSModel;
22  import org.opentrafficsim.core.dsol.OTSAnimator;
23  import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
24  import org.opentrafficsim.core.gtu.GTUType;
25  import org.opentrafficsim.core.gtu.RelativePosition;
26  import org.opentrafficsim.core.network.NetworkException;
27  import org.opentrafficsim.demo.conflictAndControl.DemoTrafcodAndTurbo.TrafCODModel;
28  import org.opentrafficsim.draw.core.OTSDrawingException;
29  import org.opentrafficsim.draw.road.TrafficLightAnimation;
30  import org.opentrafficsim.road.network.OTSRoadNetwork;
31  import org.opentrafficsim.road.network.factory.xml.parser.XmlNetworkLaneParser;
32  import org.opentrafficsim.road.network.lane.CrossSectionLink;
33  import org.opentrafficsim.road.network.lane.CrossSectionLink.Priority;
34  import org.opentrafficsim.road.network.lane.Lane;
35  import org.opentrafficsim.road.network.lane.conflict.ConflictBuilder;
36  import org.opentrafficsim.road.network.lane.object.sensor.TrafficLightSensor;
37  import org.opentrafficsim.road.network.lane.object.trafficlight.SimpleTrafficLight;
38  import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLight;
39  import org.opentrafficsim.swing.gui.OTSAnimationPanel;
40  import org.opentrafficsim.swing.gui.OTSSimulationApplication;
41  import org.opentrafficsim.trafficcontrol.TrafficController;
42  import org.opentrafficsim.trafficcontrol.trafcod.TrafCOD;
43  
44  import nl.tudelft.simulation.dsol.SimRuntimeException;
45  import nl.tudelft.simulation.event.EventInterface;
46  import nl.tudelft.simulation.event.EventListenerInterface;
47  import nl.tudelft.simulation.event.EventType;
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  public class DemoTrafcodAndTurbo extends OTSSimulationApplication<TrafCODModel>
61  {
62      
63      private static final long serialVersionUID = 20161118L;
64  
65      
66  
67  
68  
69  
70  
71  
72      public DemoTrafcodAndTurbo(final String title, final OTSAnimationPanel panel, final TrafCODModel model)
73              throws OTSDrawingException
74      {
75          super(model, panel);
76      }
77  
78      
79  
80  
81  
82      public static void main(final String[] args)
83      {
84          demo(true);
85      }
86  
87      
88  
89  
90  
91      public static void demo(final boolean exitOnClose)
92      {
93          try
94          {
95              OTSAnimator simulator = new OTSAnimator();
96              final TrafCODModel junctionModel = new TrafCODModel(simulator);
97              simulator.initialize(Time.ZERO, Duration.ZERO, Duration.instantiateSI(3600.0), junctionModel);
98              OTSAnimationPanel animationPanel =
99                      new OTSAnimationPanel(junctionModel.getNetwork().getExtent(), new Dimension(800, 600), simulator,
100                             junctionModel, new DefaultSwitchableGTUColorer(), junctionModel.getNetwork());
101             DemoTrafcodAndTurbotrol/DemoTrafcodAndTurbo.html#DemoTrafcodAndTurbo">DemoTrafcodAndTurbo app = new DemoTrafcodAndTurbo("TrafCOD Turbo demo", animationPanel, junctionModel);
102             app.setExitOnClose(exitOnClose);
103         }
104         catch (SimRuntimeException | NamingException | RemoteException | OTSDrawingException exception)
105         {
106             exception.printStackTrace();
107         }
108     }
109 
110     
111 
112 
113     @Override
114     protected void addTabs()
115     {
116         JScrollPane scrollPane = new JScrollPane(getModel().getControllerDisplayPanel());
117         JPanel wrapper = new JPanel(new BorderLayout());
118         wrapper.add(scrollPane);
119         getAnimationPanel().getTabbedPane().addTab(getAnimationPanel().getTabbedPane().getTabCount() - 1,
120                 getModel().getTrafCOD().getId(), wrapper);
121     }
122 
123     
124 
125 
126     static class TrafCODModel extends AbstractOTSModel implements EventListenerInterface
127     {
128         
129         private static final long serialVersionUID = 20161020L;
130 
131         
132         private OTSRoadNetwork network;
133 
134         
135         private TrafCOD trafCOD;
136 
137         
138         private JPanel controllerDisplayPanel = new JPanel(new BorderLayout());
139 
140         
141 
142 
143         TrafCODModel(final OTSSimulatorInterface simulator)
144         {
145             super(simulator);
146         }
147 
148         
149         @Override
150         public void constructModel() throws SimRuntimeException
151         {
152             try
153             {
154                 URL xmlURL = URLResource.getResource("/conflictAndControl/TurboRoundaboutAndSignal.xml");
155                 this.network = new OTSRoadNetwork("TurboRoundaboutAndSignal", true);
156                 XmlNetworkLaneParser.build(xmlURL, this.network, getSimulator(), false);
157 
158                 
159                 ((CrossSectionLink) this.network.getLink("EBNA")).setPriority(Priority.PRIORITY);
160                 ((CrossSectionLink) this.network.getLink("NBWA")).setPriority(Priority.PRIORITY);
161                 ((CrossSectionLink) this.network.getLink("WBSA")).setPriority(Priority.PRIORITY);
162                 ((CrossSectionLink) this.network.getLink("SBEA")).setPriority(Priority.PRIORITY);
163                 ConflictBuilder.buildConflicts(this.network, this.network.getGtuType(GTUType.DEFAULTS.VEHICLE), this.simulator,
164                         new ConflictBuilder.FixedWidthGenerator(new Length(2.0, LengthUnit.SI)));
165 
166                 
167                 
168                 
169                 
170                 
171                 
172 
173                 String[] directions = {"E", "S", "W", "N"};
174                 
175                 Set<TrafficLight> trafficLights = new LinkedHashSet<>();
176                 Set<TrafficLightSensor> sensors = new LinkedHashSet<>();
177                 Length stopLineMargin = new Length(0.1, LengthUnit.METER);
178                 Length headDetectorLength = new Length(1, LengthUnit.METER);
179                 Length headDetectorMargin = stopLineMargin.plus(headDetectorLength).plus(new Length(3, LengthUnit.METER));
180                 Length longDetectorLength = new Length(30, LengthUnit.METER);
181                 Length longDetectorMargin = stopLineMargin.plus(longDetectorLength).plus(new Length(10, LengthUnit.METER));
182                 int stream = 1;
183                 for (String direction : directions)
184                 {
185                     for (int laneNumber = 3; laneNumber >= 1; laneNumber--)
186                     {
187                         Lane lane = (Lane) ((CrossSectionLink) this.network.getLink(direction + "S", direction + "C"))
188                                 .getCrossSectionElement("FORWARD" + laneNumber);
189                         if (lane != null)
190                         {
191                             if (stream != 7)
192                             {
193                                 TrafficLight tl = new SimpleTrafficLight(String.format("%02d", stream), lane,
194                                         lane.getLength().minus(stopLineMargin), this.simulator);
195                                 trafficLights.add(tl);
196 
197                                 try
198                                 {
199                                     new TrafficLightAnimation(tl, this.simulator);
200                                 }
201                                 catch (RemoteException | NamingException exception)
202                                 {
203                                     throw new NetworkException(exception);
204                                 }
205 
206                                 sensors.add(new TrafficLightSensor(String.format("D%02d1", stream), lane,
207                                         lane.getLength().minus(headDetectorMargin), lane,
208                                         lane.getLength().minus(headDetectorMargin).plus(headDetectorLength), null,
209                                         RelativePosition.FRONT, RelativePosition.REAR, this.simulator, Compatible.EVERYTHING));
210                                 sensors.add(new TrafficLightSensor(String.format("D%02d2", stream), lane,
211                                         lane.getLength().minus(longDetectorMargin), lane,
212                                         lane.getLength().minus(longDetectorMargin).plus(longDetectorLength), null,
213                                         RelativePosition.FRONT, RelativePosition.REAR, this.simulator, Compatible.EVERYTHING));
214                             }
215                             else
216                             {
217                                 lane = (Lane) ((CrossSectionLink) this.network.getLink("ESS1", "ESS"))
218                                         .getCrossSectionElement("FORWARD");
219                                 TrafficLight tl = new SimpleTrafficLight(String.format("%02d", stream), lane,
220                                         lane.getLength().minus(stopLineMargin), this.simulator);
221                                 trafficLights.add(tl);
222 
223                                 try
224                                 {
225                                     new TrafficLightAnimation(tl, this.simulator);
226                                 }
227                                 catch (RemoteException | NamingException exception)
228                                 {
229                                     throw new NetworkException(exception);
230                                 }
231 
232                                 sensors.add(new TrafficLightSensor(String.format("D%02d1", stream), lane,
233                                         lane.getLength().minus(headDetectorMargin), lane,
234                                         lane.getLength().minus(headDetectorMargin).plus(headDetectorLength), null,
235                                         RelativePosition.FRONT, RelativePosition.REAR, this.simulator, Compatible.EVERYTHING));
236                                 sensors.add(new TrafficLightSensor(String.format("D%02d2", stream), lane,
237                                         lane.getLength().minus(longDetectorMargin), lane,
238                                         lane.getLength().minus(longDetectorMargin).plus(longDetectorLength), null,
239                                         RelativePosition.FRONT, RelativePosition.REAR, this.simulator, Compatible.EVERYTHING));
240 
241                             }
242 
243                         }
244                         stream++;
245                     }
246                 }
247                 String controllerName = "Not so simple TrafCOD controller";
248                 this.trafCOD = new TrafCOD(controllerName, URLResource.getResource("/conflictAndControl/Intersection12Dir.tfc"),
249                         this.simulator, this.controllerDisplayPanel, null, null);
250                 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONTROLLER_EVALUATING);
251                 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONTROLLER_WARNING);
252                 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONFLICT_GROUP_CHANGED);
253                 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_STATE_CHANGED);
254                 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_VARIABLE_CREATED);
255                 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_TRACED_VARIABLE_UPDATED);
256                 
257                 
258                 addListener(this.trafCOD, TrafficController.TRAFFICCONTROL_SET_TRACING);
259                 
260                 
261                 
262                 
263                 
264                 
265                 
266                 
267                 
268                 
269                 
270                 
271                 
272                 
273 
274                 
275                 
276                 
277                 
278             }
279             catch (Exception exception)
280             {
281                 exception.printStackTrace();
282             }
283         }
284 
285         
286         @Override
287         public final OTSRoadNetwork getNetwork()
288         {
289             return this.network;
290         }
291 
292         
293 
294 
295         public final TrafCOD getTrafCOD()
296         {
297             return this.trafCOD;
298         }
299 
300         
301 
302 
303         public final JPanel getControllerDisplayPanel()
304         {
305             return this.controllerDisplayPanel;
306         }
307 
308         
309         @Override
310         public void notify(final EventInterface event) throws RemoteException
311         {
312             EventType type = event.getType();
313             Object[] payload = (Object[]) event.getContent();
314             if (TrafficController.TRAFFICCONTROL_CONTROLLER_EVALUATING.equals(type))
315             {
316                 
317                 
318                 return;
319             }
320             else if (TrafficController.TRAFFICCONTROL_CONFLICT_GROUP_CHANGED.equals(type))
321             {
322                 System.out.println("Conflict group changed from " + ((String) payload[1]) + " to " + ((String) payload[2]));
323             }
324             else if (TrafficController.TRAFFICCONTROL_TRACED_VARIABLE_UPDATED.equals(type))
325             {
326                 System.out.println(String.format("Variable changed %s <- %d   %s", payload[1], payload[4], payload[5]));
327             }
328             else if (TrafficController.TRAFFICCONTROL_CONTROLLER_WARNING.equals(type))
329             {
330                 System.out.println("Warning " + payload[1]);
331             }
332             else
333             {
334                 System.out.print("TrafCODDemo received event of type " + event.getType() + ", payload [");
335                 String separator = "";
336                 for (Object o : payload)
337                 {
338                     System.out.print(separator + o);
339                     separator = ",";
340                 }
341                 System.out.println("]");
342             }
343         }
344     }
345 }