blob: cccf2411faa03a944196e404131789f4533524dc [file] [log] [blame]
danielp54e997e2013-02-21 01:54:23 +00001package org.frc971;
2
danielpb3d24ee2013-02-22 19:47:11 +00003import java.io.BufferedInputStream;
danielpb3d24ee2013-02-22 19:47:11 +00004import java.io.File;
5import java.io.FileInputStream;
6import java.io.FileNotFoundException;
danielp54e997e2013-02-21 01:54:23 +00007import java.io.IOException;
danielpb3d24ee2013-02-22 19:47:11 +00008import java.io.InputStream;
danielp54e997e2013-02-21 01:54:23 +00009
danielpb3d24ee2013-02-22 19:47:11 +000010import java.net.InetSocketAddress;
danielpb3d24ee2013-02-22 19:47:11 +000011import java.nio.ByteBuffer;
danielpb3d24ee2013-02-22 19:47:11 +000012import java.nio.channels.ServerSocketChannel;
13import java.nio.channels.SocketChannel;
14
danielp3c598e52013-02-24 06:12:54 +000015import java.util.Arrays;
danielpb3d24ee2013-02-22 19:47:11 +000016import java.util.logging.Level;
17import java.util.logging.Logger;
18
19import com.googlecode.javacv.OpenCVFrameGrabber;
20import com.googlecode.javacv.cpp.opencv_core.*;
21import static com.googlecode.javacv.cpp.opencv_highgui.*;
danielp54e997e2013-02-21 01:54:23 +000022
23public class DebugServerRun {
danielpb3d24ee2013-02-22 19:47:11 +000024
25 private final static Logger LOG = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
26
27 final OpenCVFrameGrabber grabber = new OpenCVFrameGrabber(-1);
28
29 private ServerSocketChannel sock;
30 private SocketChannel client;
danielpb3d24ee2013-02-22 19:47:11 +000031
danielp64c4e052013-02-23 07:21:41 +000032 /** Constructs a formatted boundary header from a timestamp and content length. */
danielpb3d24ee2013-02-22 19:47:11 +000033 private ByteBuffer CreateTransmission(long content_length, double timestamp) {
34 StringBuilder ret = new StringBuilder();
35 ret.append("\r\n--boundarydonotcross\r\n");
36 ret.append("Content-Type: image/jpeg\r\n");
37 ret.append("Content-Length: ");
38 ret.append(content_length);
39 ret.append("\r\n");
40 ret.append("X-Timestamp: ");
41 ret.append(timestamp);
42 ret.append("\r\n\r\n");
43 return ByteBuffer.wrap(ret.toString().getBytes());
44 }
danielp64c4e052013-02-23 07:21:41 +000045
46 /** Loop that pushes a data stream to the client. */
danielpb3d24ee2013-02-22 19:47:11 +000047 private void push() {
danielp54e997e2013-02-21 01:54:23 +000048 try {
danielpb3d24ee2013-02-22 19:47:11 +000049 grabber.start();
danielp54e997e2013-02-21 01:54:23 +000050 }
danielpb3d24ee2013-02-22 19:47:11 +000051 catch (Exception e) {
52 LOG.severe("Could not start frame grabber.");
53 return;
danielp54e997e2013-02-21 01:54:23 +000054 }
danielpb3d24ee2013-02-22 19:47:11 +000055 IplImage img;
56 long content_size;
57 File buff_file;
58 InputStream input;
59 double timestamp;
60 while (true) {
61 //get some image data
62 try {
63 img = grabber.grab();
64 timestamp = System.currentTimeMillis();
danielp64c4e052013-02-23 07:21:41 +000065 /*We buffer through /dev/shm, just to make the conversion process easier.
66 * I know this is really ugly, but it works a lot better than what
67 * I was doing before, which segfaulted.
68 */
danielpb3d24ee2013-02-22 19:47:11 +000069 cvSaveImage("/dev/shm/DebugServerBuffer.jpg", img);
70 buff_file = new File("/dev/shm/DebugServerBuffer.jpg");
71 content_size = buff_file.length();
72 int totalBytesRead = 0;
73 input = new BufferedInputStream(new FileInputStream(buff_file));
74 byte[] result = new byte[(int)content_size];
75 while(totalBytesRead < result.length){
76 int bytesRemaining = result.length - totalBytesRead;
77 //input.read() returns -1, 0, or more :
78 int bytesRead = input.read(result, totalBytesRead, bytesRemaining);
79 if (bytesRead > 0){
80 totalBytesRead = totalBytesRead + bytesRead;
81 }
82 }
83 ByteBuffer header = CreateTransmission(content_size, timestamp);
84 ByteBuffer bbuf = ByteBuffer.wrap(result);
85 ByteBuffer to_send = ByteBuffer.allocate(header.capacity() + bbuf.capacity());
86 to_send.put(header);
87 to_send.put(bbuf);
88 to_send.rewind();
danielp64c4e052013-02-23 07:21:41 +000089 SocketCommon.sendAll(client, to_send);
danielpb3d24ee2013-02-22 19:47:11 +000090 }
91 catch (Exception e) {
92 LOG.warning("Could not grab frame.");
93 continue;
94 }
95 }
96 }
danielp3c598e52013-02-24 06:12:54 +000097
danielp64c4e052013-02-23 07:21:41 +000098 /** Constructor to start the server and bind it to a port. */
danielpb3d24ee2013-02-22 19:47:11 +000099 public DebugServerRun(final int port) throws IOException {
100 sock = ServerSocketChannel.open();
101 sock.socket().bind(new InetSocketAddress(9714));
danielp64c4e052013-02-23 07:21:41 +0000102 client = sock.accept();
103 client.configureBlocking(false);
104 //we are now connected to our client. Wait for them to send us a header.
105 LOG.info("Reading headers...");
106 SocketCommon.readtoBoundary(client, "\r\n\r\n");
107 //send one back
108 LOG.info("Writing headers...");
109 SocketCommon.sendAll(client, "donotcross\r\n");
danielpb3d24ee2013-02-22 19:47:11 +0000110 }
danielp3c598e52013-02-24 06:12:54 +0000111
danielp64c4e052013-02-23 07:21:41 +0000112 /** Runs the server, and concurrently starts the vision processor with -vision flag. */
113 public static void main(final String args[]) throws IOException {
danielpb3d24ee2013-02-22 19:47:11 +0000114 //main function for server
danielp3c598e52013-02-24 06:12:54 +0000115
116 String atomIP = null;
117 try {
118 atomIP = args[0];
119 }
120 catch (ArrayIndexOutOfBoundsException e) {
121 System.out.println("Usage: VisionTuner [atom ip]");
122 System.exit(0);
123 }
124
danielpb3d24ee2013-02-22 19:47:11 +0000125 //set logger to log everything
126 LOG.setLevel(Level.ALL);
127 try {
danielp64c4e052013-02-23 07:21:41 +0000128 LogHandler handler = new LogHandler("ds_vision.log");
danielpb3d24ee2013-02-22 19:47:11 +0000129 TimeFormatter formatter = new TimeFormatter();
130 handler.setFormatter(formatter);
131 LOG.addHandler(handler);
132 }
133 catch (FileNotFoundException e) {
134 System.err.println("Warning: Logging initialization failed.");
135 }
136
danielp3c598e52013-02-24 06:12:54 +0000137 if (Arrays.asList(args).contains("-vision")) {
danielp64c4e052013-02-23 07:21:41 +0000138 LOG.info("Starting vision processor.");
danielp3c598e52013-02-24 06:12:54 +0000139 new TestClient(atomIP);
danielp64c4e052013-02-23 07:21:41 +0000140 }
141
danielpb3d24ee2013-02-22 19:47:11 +0000142 DebugServerRun server = new DebugServerRun(9714);
danielpb3d24ee2013-02-22 19:47:11 +0000143 server.push();
danielp54e997e2013-02-21 01:54:23 +0000144 }
145}