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.net.ServerSocket;
8 import java.net.Socket;
9 import java.rmi.RemoteException;
10 import java.util.Set;
11
12 import org.djunits.unit.DurationUnit;
13 import org.djunits.value.vdouble.scalar.Duration;
14 import org.djunits.value.vdouble.scalar.Time;
15 import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
16 import org.opentrafficsim.core.network.Network;
17 import org.opentrafficsim.core.network.NetworkException;
18 import org.opentrafficsim.core.object.InvisibleObjectInterface;
19 import org.opentrafficsim.road.network.lane.object.sensor.TrafficLightSensor;
20 import org.opentrafficsim.road.network.lane.object.trafficlight.TrafficLight;
21 import org.opentrafficsim.trafficcontrol.TrafficControlException;
22 import org.opentrafficsim.trafficcontrol.TrafficController;
23
24 import nl.tudelft.simulation.dsol.SimRuntimeException;
25 import nl.tudelft.simulation.dsol.simtime.SimTimeDoubleUnit;
26 import nl.tudelft.simulation.dsol.simulators.DEVSSimulator;
27 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
28 import nl.tudelft.simulation.event.EventInterface;
29 import nl.tudelft.simulation.event.EventProducer;
30 import nl.tudelft.simulation.event.EventType;
31
32
33
34
35
36
37
38
39
40
41
42
43 public class CCOL extends EventProducer implements TrafficController
44 {
45
46 private static final long serialVersionUID = 20170126L;
47
48
49 final String id;
50
51
52 final DEVSSimulator<Time, Duration, SimTimeDoubleUnit> simulator;
53
54
55 static int PORT = 4321;
56
57
58 final static Duration EVALUATION_INTERVAL = new Duration(0.1, DurationUnit.SECOND);
59
60
61 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 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 DEVSSimulator<Time, Duration, SimTimeDoubleUnit> 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, SimulatorInterface.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(EventInterface event) throws RemoteException
194 {
195 EventType eventType = event.getType();
196 if (eventType.equals(SimulatorInterface.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(OTSSimulatorInterface newSimulator, Network newNetwork) throws NetworkException
252 {
253
254 return null;
255 }
256
257 }