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