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