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 }