1 package org.opentrafficsim.demo.trafficcontrol;
2
3 import java.awt.BorderLayout;
4 import java.awt.Dimension;
5 import java.io.ByteArrayInputStream;
6 import java.io.IOException;
7 import java.io.Serializable;
8 import java.net.URL;
9 import java.nio.charset.StandardCharsets;
10 import java.rmi.RemoteException;
11 import java.util.List;
12 import java.util.Scanner;
13
14 import javax.naming.NamingException;
15 import javax.swing.JPanel;
16 import javax.swing.JScrollPane;
17
18 import org.djunits.value.vdouble.scalar.Duration;
19 import org.djunits.value.vdouble.scalar.Time;
20 import org.djutils.event.EventInterface;
21 import org.djutils.event.EventListenerInterface;
22 import org.djutils.event.EventTypeInterface;
23 import org.djutils.exceptions.Throw;
24 import org.djutils.io.URLResource;
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.network.NetworkException;
29 import org.opentrafficsim.core.object.InvisibleObjectInterface;
30 import org.opentrafficsim.demo.trafficcontrol.TrafCODDemo1.TrafCODModel;
31 import org.opentrafficsim.draw.core.OTSDrawingException;
32 import org.opentrafficsim.road.network.OTSRoadNetwork;
33 import org.opentrafficsim.road.network.factory.xml.parser.XmlNetworkLaneParser;
34 import org.opentrafficsim.swing.gui.OTSAnimationPanel;
35 import org.opentrafficsim.swing.gui.OTSSimulationApplication;
36 import org.opentrafficsim.trafficcontrol.TrafficController;
37 import org.opentrafficsim.trafficcontrol.trafcod.TrafCOD;
38 import org.opentrafficsim.xml.generated.CONTROL;
39 import org.opentrafficsim.xml.generated.OTS;
40
41 import nl.tudelft.simulation.dsol.SimRuntimeException;
42 import nl.tudelft.simulation.language.DSOLException;
43
44
45
46
47
48
49
50
51
52
53
54 public class TrafCODDemo1 extends OTSSimulationApplication<TrafCODModel>
55 {
56
57 private static final long serialVersionUID = 20161118L;
58
59
60
61
62
63
64
65
66 public TrafCODDemo1(final String title, final OTSAnimationPanel panel, final TrafCODModel model) throws OTSDrawingException
67 {
68 super(model, panel);
69 }
70
71
72
73
74
75
76 public static void main(final String[] args) throws IOException
77 {
78 demo(true);
79 }
80
81
82
83
84
85
86
87
88 public static String readStringFromURL(final URL url) throws IOException
89 {
90 try (Scanner scanner = new Scanner(url.openStream(), StandardCharsets.UTF_8.toString()))
91 {
92 scanner.useDelimiter("\\A");
93 return scanner.hasNext() ? scanner.next() : "";
94 }
95 }
96
97
98
99
100
101
102 public static void demo(final boolean exitOnClose) throws IOException
103 {
104 try
105 {
106 OTSAnimator simulator = new OTSAnimator("TrafCODDemo1");
107 URL url = URLResource.getResource("/TrafCODDemo1/TrafCODDemo1.xml");
108 String xml = readStringFromURL(url);
109 final TrafCODModel trafcodModel = new TrafCODModel(simulator, "TrafCODModel", "TrafCOD demonstration Model", xml);
110 simulator.initialize(Time.ZERO, Duration.ZERO, Duration.instantiateSI(3600.0), trafcodModel);
111 OTSAnimationPanel animationPanel = new OTSAnimationPanel(trafcodModel.getNetwork().getExtent(),
112 new Dimension(800, 600), simulator, trafcodModel, DEFAULT_COLORER, trafcodModel.getNetwork());
113 TrafCODDemo1control/TrafCODDemo1.html#TrafCODDemo1">TrafCODDemo1 app = new TrafCODDemo1("TrafCOD demo simple crossing", animationPanel, trafcodModel);
114 app.setExitOnClose(exitOnClose);
115 }
116 catch (SimRuntimeException | NamingException | RemoteException | OTSDrawingException | DSOLException exception)
117 {
118 exception.printStackTrace();
119 }
120 }
121
122
123
124
125 @Override
126 protected final void addTabs()
127 {
128 JScrollPane scrollPane = new JScrollPane(getModel().getTrafCOD().getDisplayContainer());
129 JPanel wrapper = new JPanel(new BorderLayout());
130 wrapper.add(scrollPane);
131 getAnimationPanel().getTabbedPane().addTab(getAnimationPanel().getTabbedPane().getTabCount() - 1,
132 getModel().getTrafCOD().getId(), wrapper);
133 }
134
135
136
137
138 public static class TrafCODModel extends AbstractOTSModel implements EventListenerInterface
139 {
140
141 private static final long serialVersionUID = 20161020L;
142
143
144 private OTSRoadNetwork network;
145
146
147 private TrafCOD trafCOD;
148
149
150 private final String xml;
151
152
153
154
155
156
157
158 public TrafCODModel(final OTSSimulatorInterface simulator, final String shortName, final String description,
159 final String xml)
160 {
161 super(simulator);
162 this.xml = xml;
163 }
164
165
166 @Override
167 public void constructModel() throws SimRuntimeException
168 {
169 try
170 {
171 this.network = new OTSRoadNetwork(getShortName(), true, getSimulator());
172 OTS ots = XmlNetworkLaneParser.parseXML(new ByteArrayInputStream(this.xml.getBytes(StandardCharsets.UTF_8)));
173 XmlNetworkLaneParser.build(ots, this.network, false);
174
175
176 List<CONTROL> trafficControllerList = ots.getCONTROL();
177 Throw.when(trafficControllerList.size() != 1, NetworkException.class,
178 "OTS contains wrong number of traffic controllers (should be 1, got %1)", trafficControllerList.size());
179 for (InvisibleObjectInterface ioi : this.network.getInvisibleObjectMap().values())
180 {
181 if (ioi instanceof TrafCOD)
182 {
183 if (null != this.trafCOD)
184 {
185 throw new NetworkException("More than one TrafCOD controller found in network");
186 }
187 this.trafCOD = (TrafCOD) ioi;
188 }
189 }
190 if (null == this.trafCOD)
191 {
192 throw new NetworkException("No TrafCOD controller found in network");
193 }
194 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONTROLLER_EVALUATING);
195 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONTROLLER_WARNING);
196 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_CONFLICT_GROUP_CHANGED);
197 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_STATE_CHANGED);
198 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_VARIABLE_CREATED);
199 this.trafCOD.addListener(this, TrafficController.TRAFFICCONTROL_TRACED_VARIABLE_UPDATED);
200
201 addListener(this.trafCOD, TrafficController.TRAFFICCONTROL_SET_TRACING);
202
203
204
205
206
207
208
209
210
211
212
213 }
214 catch (Exception exception)
215 {
216 exception.printStackTrace();
217 }
218 }
219
220
221 @Override
222 public final OTSRoadNetwork getNetwork()
223 {
224 return this.network;
225 }
226
227
228
229
230 public final TrafCOD getTrafCOD()
231 {
232 return this.trafCOD;
233 }
234
235
236 @Override
237 public void notify(final EventInterface event) throws RemoteException
238 {
239 EventTypeInterface type = event.getType();
240 Object[] payload = (Object[]) event.getContent();
241 if (TrafficController.TRAFFICCONTROL_CONTROLLER_EVALUATING.equals(type))
242 {
243
244 return;
245 }
246 else if (TrafficController.TRAFFICCONTROL_CONFLICT_GROUP_CHANGED.equals(type))
247 {
248 System.out.println("Conflict group changed from " + ((String) payload[1]) + " to " + ((String) payload[2]));
249 }
250 else if (TrafficController.TRAFFICCONTROL_TRACED_VARIABLE_UPDATED.equals(type))
251 {
252 System.out.println(String.format("Variable changed %s <- %d %s", payload[1], payload[4], payload[5]));
253 }
254 else if (TrafficController.TRAFFICCONTROL_CONTROLLER_WARNING.equals(type))
255 {
256 System.out.println("Warning " + payload[1]);
257 }
258 else
259 {
260 System.out.print("TrafCODDemo received event of type " + event.getType() + ", payload [");
261 String separator = "";
262 for (Object o : payload)
263 {
264 System.out.print(separator + o);
265 separator = ",";
266 }
267 System.out.println("]");
268 }
269 }
270
271
272 @Override
273 public Serializable getSourceId()
274 {
275 return "TrafCODModel";
276 }
277
278 }
279
280 }