blob: 37d6214e6cf3dd7bb81b8673faf546877bef188c [file] [log] [blame]
danielp502ec002013-02-19 23:54:14 +00001package org.frc971;
2
3//Author: Daniel Petti
4
5import java.io.*;
6import java.net.*;
7
8import java.awt.image.BufferedImage;
9import javax.imageio.ImageIO;
10
11import com.googlecode.javacv.cpp.opencv_core.IplImage;
12
13public class HTTPClient {
14 //Connects to HTTP Server on robot and receives images
15
16 private final static boolean LOCAL_DEBUG = true;
17
18 private Socket sock;
19 private BufferedReader sock_in;
20 private PrintWriter sock_out;
21
22 private String LastBoundary = "";
23
24 private void WriteDebug(String message) {
25 //small helper function to write debug messages
26 if (LOCAL_DEBUG)
27 System.out.println(message);
28 }
29 private String ReadtoBoundary(String boundary) {
30 //reads from socket until it encounters a specific character combination
31 //if boundary is null, it reads until it runs out of data
32 StringBuilder recvd = new StringBuilder();
33 String message = "";
34 try {
35 sock.setSoTimeout(5000);
36 }
37 catch (SocketException e) {
38 System.err.println("Warning: Could not set socket timeout.");
39 }
40 try {
41 int ret;
42 while ((ret = sock_in.read()) != -1) {
43 if (ret == 0) {
44 //finished receiving
45 message += recvd.toString();
46 recvd.setLength(0);
47 if (boundary == null)
48 break;
49 }
50 else {
51 recvd.append((char)ret);
52 if (boundary != null) {
53 if (message.contains(boundary))
54 break;
55 else
56 continue;
57 }
58 }
59 }
60 }
61 catch (InterruptedIOException e) {
62 System.err.println("Warning: Image receive timed out.");
63 return null;
64 }
65 catch (IOException e) {
66 System.err.println("Error: Socket read failed.");
67 return null;
68 }
69 return message;
70 }
71 public HTTPClient() {
72 //Initialize socket connection to robot
73 try {
74 WriteDebug("Connecting to server...");
75 sock = new Socket("192.168.0.178", 9714);
76 sock_in = new BufferedReader(new InputStreamReader(sock.getInputStream()));
77 sock_out = new PrintWriter(sock.getOutputStream(), true);
78 //Write headers
79 //HTTPStreamer does not actually use the headers, so we can just write terminating chars.
80 WriteDebug("Writing headers...");
81 sock_out.println("\r\n\r\n");
82 //Receive headers
83 WriteDebug("Reading headers...");
84 ReadtoBoundary("cross\r\n");
85 WriteDebug("Now receiving data.");
86 }
87 catch (UnknownHostException e) {
88 System.err.println("Error: Invalid host.");
89 System.exit(1);
90 }
91 catch (IOException e) {
92 System.err.println("Error: Socket IO failed.");
93 System.exit(2);
94 }
95
96 }
97 public ImageWithTimestamp GetFrame() {
98 //read all current data from socket, in case of processing bottleneck
99 WriteDebug("Emptying TCP stack...");
100 String message = ReadtoBoundary(null);
101 //we must end with a boundary
102 int len = message.length();
103 if (message.substring(len - 4, len - 1) != "\r\n\r\n") {
104 WriteDebug("Boundary was not found. Waiting for boundary...");
105 message += ReadtoBoundary("\r\n\r\n");
106 }
107 //Add the last boundary we cut off to the beginning of our message
108 message = LastBoundary + message;
109 //Divide our large message into string separated by boundary beginnings
110 String[] cut = message.split("\r\n--");
111 len = cut.length;
112 //Save the newest boundary, so we can use it later.
113 LastBoundary = cut[len - 1];
114 //Keep only our penultimate boundary and the image after it
115 //NOTE that message is missing its preceding \r\n--
116 message = cut[len - 2];
117 cut = message.split("\r\n\r\n");
118 //NOTE that boundary is now missing its trailing \r\n\r\n
119 String boundary = cut[0];
120 String JPEGImage = cut[1];
121 //extract timestamp in seconds
122 cut = boundary.split("X-Timestamp: ");
123 String time_data = cut[1];
124 boundary = cut[0];
125 float timestamp = Float.parseFloat(time_data);
126 //extract size so we can make sure our image data is not corrupted
127 cut = boundary.split("Content-Length: ");
128 String size_data = cut[1];
129 float size = Float.parseFloat(size_data);
danielp305cb512013-02-20 01:37:07 +0000130 assert (size == JPEGImage.length()) : ("Fatal mismatch between actual and expected image size. Check regular expressions.");
danielp502ec002013-02-19 23:54:14 +0000131 byte[] ImageArray = JPEGImage.getBytes();
132 InputStream in = new ByteArrayInputStream(ImageArray);
133 try {
134 BufferedImage bImageFromConvert = ImageIO.read(in);
135 ImageWithTimestamp to_return = new ImageWithTimestamp();
136 to_return.image = IplImage.createFrom(bImageFromConvert);
137 to_return.timestamp = timestamp;
138 WriteDebug("Image processing successful.");
139 return to_return;
140 }
141 catch (IOException e) {
142 System.err.println(e.getMessage());
143 return null;
144 }
145 }
146}