-Client optimizations
-Implemented comprehensize logging system
git-svn-id: https://robotics.mvla.net/svn/frc971/2013/trunk/src@4143 f308d9b7-e957-4cde-b6ac-9a88185e7312
diff --git a/971CV/src/org/frc971/DebugServerRun.java b/971CV/src/org/frc971/DebugServerRun.java
new file mode 100644
index 0000000..14b5239
--- /dev/null
+++ b/971CV/src/org/frc971/DebugServerRun.java
@@ -0,0 +1,25 @@
+package org.frc971;
+
+import java.io.IOException;
+import java.nio.channels.SocketChannel;
+import java.net.InetSocketAddress;
+
+import aos.DebugServer;
+import aos.ChannelImageGetter;
+
+public class DebugServerRun {
+ public static void main(final String args[]) {
+ try {
+ DebugServer server = new DebugServer(9714);
+ System.out.println("Debug Server running on port 9714.");
+ SocketChannel client_sock = SocketChannel.open();
+ client_sock.connect(new InetSocketAddress("192.168.0.137", 9714));
+ ChannelImageGetter client = new ChannelImageGetter(client_sock);
+ client.getJPEG();
+ System.out.println(client.getTimestamp());
+ }
+ catch (IOException e) {
+ System.out.println(e.getMessage());
+ }
+ }
+}
diff --git a/971CV/src/org/frc971/HTTPClient.java b/971CV/src/org/frc971/HTTPClient.java
index 4e42553..e5ea204 100644
--- a/971CV/src/org/frc971/HTTPClient.java
+++ b/971CV/src/org/frc971/HTTPClient.java
@@ -6,13 +6,16 @@
import java.net.*;
import java.awt.image.BufferedImage;
-import javax.imageio.ImageIO;
-
-import aos.ChannelImageGetter;
import java.nio.channels.SocketChannel;
import java.nio.ByteBuffer;
+import java.util.logging.Logger;
+
+import javax.imageio.ImageIO;
+
+import aos.ChannelImageGetter;
+
import edu.wpi.first.wpijavacv.WPIColorImage;
public class HTTPClient {
@@ -29,10 +32,14 @@
private final String ATOM_IP = "10.9.71.6";
+ private ChannelImageGetter cgetter;
+
+ private final static Logger LOG = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
+
private void WriteDebug(String message) {
//small helper function to write debug messages
if (LOCAL_DEBUG)
- System.out.println(message);
+ LOG.info("LOCAL_DEBUG: " + message);
}
private String ReadtoBoundary(String boundary) {
//reads from socket until it encounters a specific character combination
@@ -43,7 +50,7 @@
core_sock.setSoTimeout(10000);
}
catch (SocketException e) {
- System.err.println("Warning: Could not set socket timeout.");
+ LOG.warning("Could not set socket timeout.");
}
try {
int ret;
@@ -67,11 +74,11 @@
}
}
catch (InterruptedIOException e) {
- System.err.println("Warning: Image receive timed out.");
+ LOG.warning("Image receive timed out.");
return null;
}
catch (IOException e) {
- System.err.println("Error: Socket read failed.");
+ LOG.severe("Socket read failed.");
return null;
}
return message;
@@ -81,7 +88,7 @@
try {
sock = SocketChannel.open();
core_sock = sock.socket();
- WriteDebug("Connecting to server...");
+ WriteDebug("Connecting to server at " + ATOM_IP);
sock.connect(new InetSocketAddress(ATOM_IP, 9714));
sock_in = new BufferedReader(new InputStreamReader(core_sock.getInputStream()));
sock_out = new PrintWriter(core_sock.getOutputStream(), true);
@@ -93,13 +100,14 @@
WriteDebug("Reading headers...");
ReadtoBoundary("donotcross\r\n");
WriteDebug("Now receiving data.");
+ cgetter = new ChannelImageGetter(sock);
}
catch (UnknownHostException e) {
- System.err.println("Error: Invalid host.");
+ LOG.severe("Invalid host.");
System.exit(1);
}
catch (IOException e) {
- System.err.println("Error: Socket IO failed.");
+ LOG.severe("Socket IO failed.");
System.exit(2);
}
@@ -107,26 +115,18 @@
public ImageWithTimestamp GetFrame() {
//Use Brian's code to extract an image and timestamp from raw server data.
ImageWithTimestamp final_image = new ImageWithTimestamp();
+ ByteBuffer binary_image = cgetter.getJPEG();
+ //Decode ByteBuffer into an IplImage
+ InputStream in = new ByteArrayInputStream(binary_image.array());
try {
- ChannelImageGetter cgetter = new ChannelImageGetter(sock);
- ByteBuffer binary_image = cgetter.getJPEG();
- //Decode ByteBuffer into an IplImage
- InputStream in = new ByteArrayInputStream(binary_image.array());
- try {
- BufferedImage bImageFromConvert = ImageIO.read(in);
- final_image.image = new WPIColorImage(bImageFromConvert);
- final_image.timestamp = cgetter.getTimestamp();
- WriteDebug("Image processing successful.");
- return final_image;
- }
- catch (IOException e) {
- System.err.println(e.getMessage());
- return null;
- }
-
+ BufferedImage bImageFromConvert = ImageIO.read(in);
+ final_image.image = new WPIColorImage(bImageFromConvert);
+ final_image.timestamp = cgetter.getTimestamp();
+ WriteDebug("Image processing successful.");
+ return final_image;
}
catch (IOException e) {
- WriteDebug("Error: Failed to initialize ChannelImageGetter.");
+ LOG.warning("Image processing failed.");
return null;
}
}
diff --git a/971CV/src/org/frc971/LogHandler.java b/971CV/src/org/frc971/LogHandler.java
new file mode 100644
index 0000000..59f74a9
--- /dev/null
+++ b/971CV/src/org/frc971/LogHandler.java
@@ -0,0 +1,51 @@
+/**
+ *
+ */
+package org.frc971;
+
+import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
+import java.io.PrintWriter;
+
+import java.util.logging.Handler;
+import java.util.logging.LogRecord;
+
+/**
+ * @author daniel
+ * logs data to custom files, using specific formatting.
+ */
+public class LogHandler extends Handler {
+
+ private FileOutputStream ofstream;
+ PrintWriter writer;
+
+ public LogHandler (String filename) throws FileNotFoundException {
+ super();
+
+ if (filename == null || filename == "") {
+ filename = "logfile.log";
+ }
+
+ //check if file exists, and if not, create it
+ ofstream = new FileOutputStream(filename);
+ writer = new PrintWriter(ofstream);
+ setFormatter(new TimeFormatter());
+ }
+
+ /*Required methods*/
+
+ public void publish(LogRecord message) {
+ //record a message
+ if (!isLoggable(message)) {
+ //ensure that this message should be logged by this handler
+ return;
+ }
+ writer.print(getFormatter().format(message)); //Formatter adds trailing \n
+ }
+ public void flush() {
+ writer.flush();
+ }
+ public void close() throws SecurityException {
+ writer.close();
+ }
+}
diff --git a/971CV/src/org/frc971/Recognizer2013.java b/971CV/src/org/frc971/Recognizer2013.java
index 115af27..7fbf28e 100644
--- a/971CV/src/org/frc971/Recognizer2013.java
+++ b/971CV/src/org/frc971/Recognizer2013.java
@@ -1,6 +1,7 @@
package org.frc971;
import java.util.ArrayList;
+import java.util.logging.Logger;
import com.googlecode.javacv.cpp.opencv_core;
import com.googlecode.javacv.cpp.opencv_core.CvSize;
@@ -24,6 +25,8 @@
* @author jerry
*/
public class Recognizer2013 implements Recognizer {
+
+ private final static Logger LOG = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
// --- Tunable recognizer constants.
static final double kRoughlyHorizontalSlope = Math.tan(Math.toRadians(30));
@@ -240,7 +243,7 @@
rawImage.drawPolygon(bestTarget, targetColor, 2);
measureTarget(bestTarget);
} else {
- System.out.println("No target found");
+ LOG.fine("No target found");
}
// Draw a crosshair
@@ -271,12 +274,10 @@
double elevationCam = Math.atan2(yc * 2 * kTanVFOV2, vh);
double rangeIn = kTargetWidthIn * vw / (w * 2 * kTanHFOV2);
- System.out.format("Best target at (%.2f, %.2f) %.2f x %.2f"
- + ", shot azimuth=%.2f elevation=%.2f range=%.2f'%n",
- x, y, w, h,
- Math.toDegrees(azimuthCam) - kShooterOffsetDeg,
- Math.toDegrees(elevationCam) + kCameraPitchDeg,
- rangeIn / 12);
+ LOG.fine("Best target at (" + x + ", " + y + ") " + w +" x " + h
+ + ", shot azimuth=" + (Math.toDegrees(azimuthCam) - kShooterOffsetDeg) +
+ " elevation=" + (Math.toDegrees(elevationCam) + kCameraPitchDeg) +
+ " range=" + (rangeIn / 12));
}
}
diff --git a/971CV/src/org/frc971/TestImageGetter.java b/971CV/src/org/frc971/TestImageGetter.java
index 1f80520..b0cf9b0 100644
--- a/971CV/src/org/frc971/TestImageGetter.java
+++ b/971CV/src/org/frc971/TestImageGetter.java
@@ -10,15 +10,21 @@
//get debug images for Java camera processor
+import java.io.File;
+import java.io.IOException;
+
+import java.util.logging.Logger;
+
import javax.imageio.ImageIO;
import edu.wpi.first.wpijavacv.WPIColorImage;
-import java.io.File;
-import java.io.IOException;
-
public class TestImageGetter {
+
private String path_to_images;
+
+ private final static Logger LOG = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
+
final static String[] images = {"45in_DoubleGreen.jpg",
"57inLargeTarget_DoubleGreenBK.jpg",
"FullField_DoubleGreenBK3.jpg",
@@ -61,7 +67,7 @@
return current_image;
}
catch (IOException e) {
- System.err.println("Could not open file.");
+ LOG.warning("Could not open file.");
return null;
}
}
@@ -78,7 +84,7 @@
return current_image;
}
catch (IOException e) {
- System.err.println("Could not open file.");
+ LOG.warning("Could not open file.");
return null;
}
}
diff --git a/971CV/src/org/frc971/TimeFormatter.java b/971CV/src/org/frc971/TimeFormatter.java
new file mode 100644
index 0000000..9f46bd4
--- /dev/null
+++ b/971CV/src/org/frc971/TimeFormatter.java
@@ -0,0 +1,37 @@
+/**
+ *
+ */
+package org.frc971;
+
+import java.util.logging.Formatter;
+import java.util.logging.LogRecord;
+import java.util.Date;
+
+/**
+ * @author daniel
+ * Formats log messages with adequate timestamp
+ */
+public class TimeFormatter extends Formatter{
+ public TimeFormatter() {
+ super();
+ }
+ public String format(LogRecord message) {
+ //we need to include the date and time in our message
+ StringBuffer out = new StringBuffer();
+ out.append("@");
+ Date date = new Date(message.getMillis());
+ out.append(date.toString());
+ out.append(" in [");
+ //add our logger's name
+ out.append(message.getLoggerName());
+ out.append("]: (");
+ //add message level
+ out.append(message.getLevel().getName());
+ out.append(") ");
+ //add actual message
+ out.append(formatMessage(message));
+ out.append("\n");
+ return out.toString();
+ }
+
+}
diff --git a/971CV/src/org/frc971/VisionTuner.java b/971CV/src/org/frc971/VisionTuner.java
index c664391..4d062dc 100644
--- a/971CV/src/org/frc971/VisionTuner.java
+++ b/971CV/src/org/frc971/VisionTuner.java
@@ -3,7 +3,12 @@
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
+
import java.util.Arrays;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import java.io.FileNotFoundException;
import javax.swing.JPanel;
import javax.swing.JSlider;
@@ -41,6 +46,8 @@
public class VisionTuner {
private Recognizer recognizer = new Recognizer2013();
+ private final static Logger LOG = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
+
private final CanvasFrame cameraFrame = new CanvasFrame("Camera");
private final JPanel panel = new JPanel();
private final JSlider hueMinSlider = new JSlider();
@@ -56,6 +63,18 @@
private TestImageGetter getter;
public VisionTuner() {
+ //set logger to log everything
+ LOG.setLevel(Level.ALL);
+ try {
+ LogHandler handler = new LogHandler("../src/org/frc971/ds_vision.log");
+ TimeFormatter formatter = new TimeFormatter();
+ handler.setFormatter(formatter);
+ LOG.addHandler(handler);
+ }
+ catch (FileNotFoundException e) {
+ System.err.println("Warning: Logging initialization failed.");
+ }
+
cameraFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
recognizer.showIntermediateStages(true);
@@ -66,7 +85,7 @@
ChangeListener sliderListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
- System.out.println("New HSV range ["
+ LOG.fine("New HSV range ["
+ hueMinSlider.getValue() + " .. "
+ hueMaxSlider.getValue() + "] "
+ satMinSlider.getValue() + "+ "
@@ -99,7 +118,7 @@
valMinSlider.setValue(recognizer.getValMin());
panel.add(valMinSlider);
- System.out.println("Initial HSV range ["
+ LOG.fine("Initial HSV range ["
+ hueMinSlider.getValue() + " .. "
+ hueMaxSlider.getValue() + "] "
+ satMinSlider.getValue() + "+ "
@@ -117,7 +136,7 @@
*/
private void processImage(WPIColorImage cameraImage) {
- cameraFrame.setTitle("Test Images:");
+ cameraFrame.setTitle("Input:");
long startTime = System.nanoTime();
WPIImage processedImage = recognizer.processImage(cameraImage);
@@ -130,9 +149,8 @@
totalMsec += milliseconds;
minMsec = Math.min(minMsec, milliseconds);
maxMsec = Math.max(maxMsec, milliseconds);
- System.out.format("The recognizer took %.2f ms, %.2f fps, %.2f avg%n",
- milliseconds, 1000 / milliseconds,
- 1000 * totalFrames / totalMsec);
+ LOG.fine("The recognizer took " + milliseconds + " ms, " +
+ (1000 * totalFrames / totalMsec) + " fps, %.2f avg");
}
}
@@ -159,11 +177,8 @@
nextImage();
break;
case KeyEvent.VK_Q: // Q: print time measurements then quit
- System.out.format("The recognizer took %.2f ms avg, %.2f min,"
- + " %.2f max, %.2f fps avg%n",
- totalMsec / totalFrames,
- minMsec, maxMsec,
- 1000 * totalFrames / totalMsec);
+ LOG.fine("The recognizer took " + (totalMsec / totalFrames) + "ms avg, " + minMsec +" min,"
+ + maxMsec + " max, " + (1000 * totalFrames / totalMsec) + " fps avg");
System.exit(0);
}
}
@@ -174,13 +189,14 @@
//debug mode has been requested
tuner.getter = new TestImageGetter(".");
WPIColorImage to_process = tuner.getter.GetNext();
- if (to_process != null)
+ if (to_process != null) {
tuner.processImage(to_process);
+ for (;;) {
+ tuner.processEvents();
+ }
+ }
else
- System.err.println("Cannot find test images.");
- for (;;) {
- tuner.processEvents();
- }
+ LOG.severe("Cannot find test images.");
}
else {
HTTPClient client = new HTTPClient();
@@ -188,7 +204,7 @@
ImageWithTimestamp to_process = client.GetFrame();
if (to_process.image != null) {
tuner.processImage(to_process.image);
- System.out.println("Captured time: " + Double.toString(to_process.timestamp));
+ LOG.fine("Captured time: " + Double.toString(to_process.timestamp));
}
}
}