1 package org.opentrafficsim.trafficcontrol.ccol;
2
3 import java.awt.Container;
4 import java.io.BufferedReader;
5 import java.io.IOException;
6 import java.io.InputStreamReader;
7 import java.io.PrintWriter;
8 import java.io.Serializable;
9 import java.net.ServerSocket;
10 import java.net.Socket;
11 import java.rmi.RemoteException;
12 import java.util.Set;
13
14 import org.djunits.unit.DurationUnit;
15 import org.djunits.value.vdouble.scalar.Duration;
16 import org.djunits.value.vdouble.scalar.Time;
17 import org.djutils.event.EventInterface;
18 import org.djutils.event.EventProducer;
19 import org.djutils.event.EventTypeInterface;
20 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
21 import org.opentrafficsim.core.network.Network;
22 import org.opentrafficsim.core.network.NetworkException;
23 import org.opentrafficsim.core.object.InvisibleObjectInterface;
24 import org.opentrafficsim.road.network.lane.object.sensor.TrafficLightSensor;
25 import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLight;
26 import org.opentrafficsim.trafficcontrol.ActuatedTrafficController;
27 import org.opentrafficsim.trafficcontrol.TrafficControlException;
28
29 import nl.tudelft.simulation.dsol.SimRuntimeException;
30 import nl.tudelft.simulation.dsol.experiment.Replication;
31 import nl.tudelft.simulation.dsol.simtime.SimTimeDoubleUnit;
32 import nl.tudelft.simulation.dsol.simulators.DEVSSimulator;
33
34
35
36
37
38
39
40
41
42
43
44
45 public class CCOL extends EventProducer implements ActuatedTrafficController
46 {
47
48 private static final long serialVersionUID = 20170126L;
49
50
51 private final String id;
52
53
54 private final DEVSSimulator<Time, Duration, SimTimeDoubleUnit> simulator;
55
56
57 private static int port = 4321;
58
59
60 static final Duration EVALUATION_INTERVAL = new Duration(0.1, DurationUnit.SECOND);
61
62
63 private ServerSocket serverSocket;
64
65
66 private Socket clientSocket = null;
67
68
69 private BufferedReader ccolReader = null;
70
71
72 private PrintWriter ccolWriter = null;
73
74
75 private Thread acceptThread;
76
77
78
79
80
81
82
83
84
85
86
87
88
89 public CCOL(final String id, final String controlProgram, final Set<TrafficLight> trafficLights,
90 final Set<TrafficLightSensor> sensors, final DEVSSimulator<Time, Duration, SimTimeDoubleUnit> simulator)
91 throws TrafficControlException, SimRuntimeException
92 {
93 this.id = id;
94 this.simulator = simulator;
95 try
96 {
97
98 this.serverSocket = new ServerSocket(port);
99 Runnable acceptTask = new Runnable()
100 {
101 @Override
102 public void run()
103 {
104 try
105 {
106 setClientSocket(CCOL.this.serverSocket.accept());
107 }
108 catch (IOException exception)
109 {
110 exception.printStackTrace();
111 }
112 }
113 };
114 this.acceptThread = new Thread(acceptTask);
115 this.acceptThread.start();
116
117 Runtime.getRuntime().exec(controlProgram + " localhost:" + this.serverSocket.getLocalPort());
118 }
119 catch (IOException e)
120 {
121 e.printStackTrace();
122 }
123 this.simulator.scheduleEventRel(Duration.ZERO, this, this, "step", null);
124 this.simulator.addListener(this, Replication.END_REPLICATION_EVENT);
125 }
126
127
128
129
130
131 void setClientSocket(final Socket socket)
132 {
133 if (null != this.clientSocket)
134 {
135 System.err.println("clientSocket already set");
136 return;
137 }
138 this.clientSocket = socket;
139 try
140 {
141 this.ccolReader = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
142 this.ccolWriter = new PrintWriter(this.clientSocket.getOutputStream());
143 }
144 catch (IOException exception)
145 {
146 exception.printStackTrace();
147 }
148
149 try
150 {
151 this.serverSocket.close();
152 }
153 catch (IOException exception)
154 {
155 exception.printStackTrace();
156 }
157 }
158
159
160
161
162
163 Socket getClientSocket()
164 {
165 return this.clientSocket;
166 }
167
168
169
170
171
172
173 @SuppressWarnings("unused")
174 private void step() throws TrafficControlException, SimRuntimeException
175 {
176
177 String message = String.format("STEP %s", this.simulator.getSimulatorTime());
178 this.ccolWriter.print(message);
179 try
180 {
181 String result = this.ccolReader.readLine();
182
183
184 }
185 catch (IOException exception)
186 {
187 exception.printStackTrace();
188 }
189
190 this.simulator.scheduleEventRel(EVALUATION_INTERVAL, this, this, "step", null);
191 }
192
193
194 @Override
195 public void notify(final EventInterface event) throws RemoteException
196 {
197 EventTypeInterface eventType = event.getType();
198 if (eventType.equals(Replication.END_REPLICATION_EVENT))
199 {
200 if (null != this.serverSocket)
201 {
202 try
203 {
204 this.serverSocket.close();
205 }
206 catch (IOException exception)
207 {
208 exception.printStackTrace();
209 }
210 this.serverSocket = null;
211 }
212 if (null != this.clientSocket)
213 {
214 try
215 {
216 this.clientSocket.close();
217 }
218 catch (IOException exception)
219 {
220 exception.printStackTrace();
221 }
222 this.clientSocket = null;
223 }
224 }
225
226 }
227
228
229 @Override
230 public String getId()
231 {
232 return this.id;
233 }
234
235
236 @Override
237 public String getFullId()
238 {
239 return this.id;
240 }
241
242
243 @Override
244 public void updateDetector(final String detectorId, final boolean detectingGTU)
245 {
246
247 String message = String.format("DET %s %s", detectorId, detectingGTU);
248 this.ccolWriter.print(message);
249 }
250
251
252 @Override
253 public InvisibleObjectInterface clone(final OTSSimulatorInterface newSimulator, final Network newNetwork)
254 throws NetworkException
255 {
256
257 return null;
258 }
259
260
261 @Override
262 public Serializable getSourceId()
263 {
264 return "CCOL";
265 }
266
267
268 @Override
269 public Container getDisplayContainer()
270 {
271 return null;
272 }
273
274 }