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
54
55
56
57
58
59
60
61
62
63 public class DemoTrafcodAndTurbo extends OTSSimulationApplication<TrafCODModel>
64 {
65
66 private static final long serialVersionUID = 20161118L;
67
68
69
70
71
72
73
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
83
84
85 public static void main(final String[] args)
86 {
87 demo(true);
88 }
89
90
91
92
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
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
129
130 static class TrafCODModel extends AbstractOTSModel implements EventListenerInterface
131 {
132
133 private static final long serialVersionUID = 20161020L;
134
135
136 private OTSRoadNetwork network;
137
138
139 private TrafCOD trafCOD;
140
141
142 private JPanel controllerDisplayPanel = new JPanel(new BorderLayout());
143
144
145
146
147 TrafCODModel(final OTSSimulatorInterface simulator)
148 {
149 super(simulator);
150 }
151
152
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
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
171
172
173
174
175
176
177 String[] directions = {"E", "S", "W", "N"};
178
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
261
262 addListener(this.trafCOD, TrafficController.TRAFFICCONTROL_SET_TRACING);
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282 }
283 catch (Exception exception)
284 {
285 exception.printStackTrace();
286 }
287 }
288
289
290 @Override
291 public final OTSRoadNetwork getNetwork()
292 {
293 return this.network;
294 }
295
296
297
298
299 public final TrafCOD getTrafCOD()
300 {
301 return this.trafCOD;
302 }
303
304
305
306
307 public final JPanel getControllerDisplayPanel()
308 {
309 return this.controllerDisplayPanel;
310 }
311
312
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
321
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
350 @Override
351 public Serializable getSourceId()
352 {
353 return "TrafCODModel";
354 }
355 }
356 }