1 package org.opentrafficsim.demo;
2
3 import java.io.BufferedReader;
4 import java.io.ByteArrayOutputStream;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.io.InputStreamReader;
8 import java.io.OutputStream;
9 import java.net.Socket;
10 import java.net.URL;
11 import java.net.URLConnection;
12 import java.nio.charset.StandardCharsets;
13 import java.util.stream.Collectors;
14
15 import org.opentrafficsim.aimsun.proto.AimsunControlProtoBuf;
16
17 import com.google.protobuf.CodedOutputStream;
18
19 import nl.tudelft.simulation.language.io.URLResource;
20
21
22
23
24
25
26
27
28
29
30
31
32 public final class TestController
33 {
34
35
36
37 private TestController()
38 {
39
40 }
41
42
43
44
45
46
47
48
49
50
51
52
53
54 public static void main(final String[] args) throws IOException
55 {
56 String ip = null;
57 Integer port = null;
58
59 for (String arg : args)
60 {
61 int equalsPos = arg.indexOf("=");
62 if (equalsPos < 0)
63 {
64 System.err.println("Unhandled argument \"" + arg + "\"");
65 }
66 String key = arg.substring(0, equalsPos);
67 String value = arg.substring(equalsPos + 1);
68 switch (key.toUpperCase())
69 {
70 case "IP":
71 ip = value;
72 break;
73 case "PORT":
74 try
75 {
76 port = Integer.parseInt(value);
77 }
78 catch (NumberFormatException exception)
79 {
80 System.err.println("Bad port number \"" + value + "\"");
81 System.exit(1);
82 }
83 break;
84 default:
85 System.err.println("Unhandled argument \"" + arg + "\"");
86 }
87 }
88 if (null == ip || null == port)
89 {
90 System.err.println("Missing required argument(s) ip=<ip-number_or_hostname> port=<port-number>");
91 System.exit(1);
92 }
93
94 AimsunControlProtoBuf.CreateSimulation.Builder createSimulationBuilder =
95 AimsunControlProtoBuf.CreateSimulation.newBuilder();
96 createSimulationBuilder.setRunTime(3600d);
97 createSimulationBuilder.setWarmUpTime(0d);
98
99 String networkResource = "/aimsun/singleRoad.xml";
100 String network = null;
101 URL networkURL = URLResource.getResource(networkResource);
102 if (null == networkURL)
103 {
104 throw new Error("Could not load network from resource " + networkResource);
105 }
106 URLConnection conn = networkURL.openConnection();
107 try (BufferedReader reader =
108 new BufferedReader(new InputStreamReader(conn.getInputStream(), StandardCharsets.UTF_8)))
109 {
110 network = reader.lines().collect(Collectors.joining("\n"));
111 }
112
113
114 System.out.println("Connecting to server...");
115 Socket socket = new Socket(ip, port);
116 System.out.println("Connected");
117 OutputStream outputStream = socket.getOutputStream();
118 InputStream inputStream = socket.getInputStream();
119
120 createSimulationBuilder.setNetworkXML(network);
121 System.out.println("Sending CREATESIMULATION message");
122 sendProtoMessage(outputStream,
123 AimsunControlProtoBuf.OTSMessage.newBuilder().setCreateSimulation(createSimulationBuilder.build()).build());
124
125 for (int step = 0; step <= 20; step++)
126 {
127 AimsunControlProtoBuf.SimulateUntil simulateUntil =
128 AimsunControlProtoBuf.SimulateUntil.newBuilder().setTime(0.5d * step).build();
129 System.out.println("Sending simulate up to step " + step + " command");
130 sendProtoMessage(outputStream, AimsunControlProtoBuf.OTSMessage.newBuilder().setSimulateUntil(simulateUntil)
131 .build());
132 System.out.println("Receive reply");
133 AimsunControlProtoBuf.OTSMessage reply = receiveProtoMessage(inputStream);
134 System.out.println("Received " + reply);
135 }
136 try
137 {
138 Thread.sleep(5000);
139 }
140 catch (InterruptedException exception)
141 {
142 exception.printStackTrace();
143 }
144 socket.close();
145 }
146
147
148
149
150
151
152
153 public static void sendProtoMessage(final OutputStream outputStream, final AimsunControlProtoBuf.OTSMessage message)
154 throws IOException
155 {
156 int size = message.getSerializedSize();
157
158 byte[] sizeBytes = new byte[4];
159 sizeBytes[0] = (byte) ((size >> 24) & 0xff);
160 sizeBytes[1] = (byte) ((size >> 16) & 0xff);
161 sizeBytes[2] = (byte) ((size >> 8) & 0xff);
162 sizeBytes[3] = (byte) (size & 0xff);
163 outputStream.write(sizeBytes);
164 ByteArrayOutputStream baos = new ByteArrayOutputStream();
165 message.writeTo(CodedOutputStream.newInstance(baos));
166
167
168 outputStream.write(baos.toByteArray());
169
170 }
171
172
173
174
175
176
177
178 public static AimsunControlProtoBuf.OTSMessage receiveProtoMessage(final InputStream inputStream) throws IOException
179 {
180 byte[] sizeBytes = receiveBytes(inputStream, 4);
181
182
183
184
185 int size =
186 ((sizeBytes[0] & 0xff) << 24) + ((sizeBytes[1] & 0xff) << 16) + ((sizeBytes[2] & 0xff) << 8)
187 + (sizeBytes[3] & 0xff);
188
189 byte[] messageBytes = receiveBytes(inputStream, size);
190 return AimsunControlProtoBuf.OTSMessage.parseFrom(messageBytes);
191 }
192
193
194
195
196
197
198
199
200 public static byte[] receiveBytes(final InputStream inputStream, final int size) throws IOException
201 {
202 System.out.print("Need to read " + size + " bytes ... ");
203 int offset = 0;
204 byte[] buffer = new byte[size];
205 while (true)
206 {
207 int bytesRead = inputStream.read(buffer, offset, buffer.length - offset);
208 if (-1 == bytesRead)
209 {
210 break;
211 }
212 offset += bytesRead;
213 if (buffer.length == offset)
214 {
215 System.out.println("Got all " + buffer.length + " requested bytes");
216 break;
217 }
218 if (buffer.length < offset)
219 {
220 System.out.println("Oops: Got more than " + buffer.length + " requested bytes");
221 break;
222 }
223 System.out.print("Now got " + offset + " bytes; need to read " + (buffer.length - offset) + " more bytes ");
224 }
225 if (offset != buffer.length)
226 {
227 throw new IOException("Got only " + offset + " of expected " + buffer.length + " bytes");
228 }
229 return buffer;
230 }
231
232 }