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