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