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
55
56
57
58
59
60
61
62
63 public class TrafCODDemo2 extends AbstractWrappableAnimation
64 {
65
66
67 private static final long serialVersionUID = 20161118L;
68
69
70
71
72
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
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
97 private JPanel controllerDisplayPanel = new JPanel(new BorderLayout());
98
99
100 private TrafCOD trafCOD;
101
102
103 @Override
104 public final String shortName()
105 {
106 return "TrafCOD demonstration 2";
107 }
108
109
110 @Override
111 public final String description()
112 {
113 return "TrafCOD demonstration";
114 }
115
116
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
127 @Override
128 protected final OTSModelInterface makeModel(final GTUColorer colorer) throws OTSSimulationException
129 {
130 return new TrafCODModel();
131 }
132
133
134 @Override
135 protected final void addAnimationToggles()
136 {
137 AnimationToggles.setTextAnimationTogglesStandard(this);
138 }
139
140
141 @Override
142 protected final Double makeAnimationRectangle()
143 {
144 return new Rectangle2D.Double(-200, -200, 400, 400);
145 }
146
147
148
149
150 class TrafCODModel extends EventProducer implements OTSModelInterface, EventListenerInterface
151 {
152
153 private static final long serialVersionUID = 20161020L;
154
155
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
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
208 addListener(TrafCODDemo2.this.trafCOD, TrafficController.TRAFFICCONTROL_SET_TRACING);
209
210
211
212
213
214
215
216
217
218
219
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
235 @Override
236 public final OTSNetwork getNetwork()
237 {
238 return this.network;
239 }
240
241
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
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 }