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