blob: e5ea2040f8e287483f8d481ce308ff18a236ae79 [file] [log] [blame]
danielp502ec002013-02-19 23:54:14 +00001package org.frc971;
2
danielp4a35a7a2013-02-20 20:45:39 +00003//@author: daniel
danielp502ec002013-02-19 23:54:14 +00004
5import java.io.*;
6import java.net.*;
7
8import java.awt.image.BufferedImage;
danielp6eb01d12013-02-20 05:36:09 +00009
10import java.nio.channels.SocketChannel;
11import java.nio.ByteBuffer;
12
danielp54e997e2013-02-21 01:54:23 +000013import java.util.logging.Logger;
14
15import javax.imageio.ImageIO;
16
17import aos.ChannelImageGetter;
18
danielp4a35a7a2013-02-20 20:45:39 +000019import edu.wpi.first.wpijavacv.WPIColorImage;
20
danielp502ec002013-02-19 23:54:14 +000021public class HTTPClient {
22 //Connects to HTTP Server on robot and receives images
23
24 private final static boolean LOCAL_DEBUG = true;
25
danielp4a35a7a2013-02-20 20:45:39 +000026 private SocketChannel sock;
27 private Socket core_sock;
danielp502ec002013-02-19 23:54:14 +000028
danielp502ec002013-02-19 23:54:14 +000029
danielp6eb01d12013-02-20 05:36:09 +000030 private BufferedReader sock_in;
31 private PrintWriter sock_out;
32
danielp4a35a7a2013-02-20 20:45:39 +000033 private final String ATOM_IP = "10.9.71.6";
34
danielp54e997e2013-02-21 01:54:23 +000035 private ChannelImageGetter cgetter;
36
37 private final static Logger LOG = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
38
danielp502ec002013-02-19 23:54:14 +000039 private void WriteDebug(String message) {
40 //small helper function to write debug messages
41 if (LOCAL_DEBUG)
danielp54e997e2013-02-21 01:54:23 +000042 LOG.info("LOCAL_DEBUG: " + message);
danielp502ec002013-02-19 23:54:14 +000043 }
44 private String ReadtoBoundary(String boundary) {
45 //reads from socket until it encounters a specific character combination
46 //if boundary is null, it reads until it runs out of data
47 StringBuilder recvd = new StringBuilder();
48 String message = "";
49 try {
danielp6eb01d12013-02-20 05:36:09 +000050 core_sock.setSoTimeout(10000);
danielp502ec002013-02-19 23:54:14 +000051 }
52 catch (SocketException e) {
danielp54e997e2013-02-21 01:54:23 +000053 LOG.warning("Could not set socket timeout.");
danielp502ec002013-02-19 23:54:14 +000054 }
55 try {
56 int ret;
57 while ((ret = sock_in.read()) != -1) {
58 if (ret == 0) {
59 //finished receiving
60 message += recvd.toString();
61 recvd.setLength(0);
62 if (boundary == null)
63 break;
64 }
65 else {
66 recvd.append((char)ret);
67 if (boundary != null) {
68 if (message.contains(boundary))
69 break;
70 else
71 continue;
72 }
73 }
74 }
75 }
76 catch (InterruptedIOException e) {
danielp54e997e2013-02-21 01:54:23 +000077 LOG.warning("Image receive timed out.");
danielp502ec002013-02-19 23:54:14 +000078 return null;
79 }
80 catch (IOException e) {
danielp54e997e2013-02-21 01:54:23 +000081 LOG.severe("Socket read failed.");
danielp502ec002013-02-19 23:54:14 +000082 return null;
83 }
84 return message;
85 }
86 public HTTPClient() {
87 //Initialize socket connection to robot
88 try {
danielp4a35a7a2013-02-20 20:45:39 +000089 sock = SocketChannel.open();
90 core_sock = sock.socket();
danielp54e997e2013-02-21 01:54:23 +000091 WriteDebug("Connecting to server at " + ATOM_IP);
danielp4a35a7a2013-02-20 20:45:39 +000092 sock.connect(new InetSocketAddress(ATOM_IP, 9714));
danielp6eb01d12013-02-20 05:36:09 +000093 sock_in = new BufferedReader(new InputStreamReader(core_sock.getInputStream()));
94 sock_out = new PrintWriter(core_sock.getOutputStream(), true);
danielp502ec002013-02-19 23:54:14 +000095 //Write headers
96 //HTTPStreamer does not actually use the headers, so we can just write terminating chars.
97 WriteDebug("Writing headers...");
98 sock_out.println("\r\n\r\n");
99 //Receive headers
100 WriteDebug("Reading headers...");
danielp6eb01d12013-02-20 05:36:09 +0000101 ReadtoBoundary("donotcross\r\n");
danielp502ec002013-02-19 23:54:14 +0000102 WriteDebug("Now receiving data.");
danielp54e997e2013-02-21 01:54:23 +0000103 cgetter = new ChannelImageGetter(sock);
danielp502ec002013-02-19 23:54:14 +0000104 }
105 catch (UnknownHostException e) {
danielp54e997e2013-02-21 01:54:23 +0000106 LOG.severe("Invalid host.");
danielp502ec002013-02-19 23:54:14 +0000107 System.exit(1);
108 }
109 catch (IOException e) {
danielp54e997e2013-02-21 01:54:23 +0000110 LOG.severe("Socket IO failed.");
danielp502ec002013-02-19 23:54:14 +0000111 System.exit(2);
112 }
113
114 }
115 public ImageWithTimestamp GetFrame() {
danielp6eb01d12013-02-20 05:36:09 +0000116 //Use Brian's code to extract an image and timestamp from raw server data.
117 ImageWithTimestamp final_image = new ImageWithTimestamp();
danielp54e997e2013-02-21 01:54:23 +0000118 ByteBuffer binary_image = cgetter.getJPEG();
119 //Decode ByteBuffer into an IplImage
120 InputStream in = new ByteArrayInputStream(binary_image.array());
danielp6eb01d12013-02-20 05:36:09 +0000121 try {
danielp54e997e2013-02-21 01:54:23 +0000122 BufferedImage bImageFromConvert = ImageIO.read(in);
123 final_image.image = new WPIColorImage(bImageFromConvert);
124 final_image.timestamp = cgetter.getTimestamp();
125 WriteDebug("Image processing successful.");
126 return final_image;
danielp6eb01d12013-02-20 05:36:09 +0000127 }
128 catch (IOException e) {
danielp54e997e2013-02-21 01:54:23 +0000129 LOG.warning("Image processing failed.");
danielp6eb01d12013-02-20 05:36:09 +0000130 return null;
131 }
danielp502ec002013-02-19 23:54:14 +0000132 }
133}