diff options
author | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-03-09 15:03:22 -0500 |
---|---|---|
committer | Luke Shumaker <lukeshu@sbcglobal.net> | 2016-03-09 15:03:22 -0500 |
commit | 96dc00ca38368b528e7a2dfa0962e124e885c73f (patch) | |
tree | 39efb6841f4c5aa2702f427d7a011b70565e8d7c | |
parent | f834bb57f9fcbf4c8a4631f8053f1395587c0445 (diff) |
stuffcleanup
-rw-r--r-- | smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/AxisCameraExtension.java (renamed from smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/VideoStreamViewerExtension.java) | 13 | ||||
-rw-r--r-- | smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/DefaultDisplayElementRegistrar.java | 5 | ||||
-rw-r--r-- | smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/RoboRIOCameraExtension.java (renamed from smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/WebcamViewerExtension.java) | 8 | ||||
-rw-r--r-- | smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/VideoURLExtension.java | 212 |
4 files changed, 227 insertions, 11 deletions
diff --git a/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/VideoStreamViewerExtension.java b/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/AxisCameraExtension.java index 2e9a65e..02005d3 100644 --- a/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/VideoStreamViewerExtension.java +++ b/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/AxisCameraExtension.java @@ -24,9 +24,9 @@ import javax.imageio.ImageIO; * * @author Greg Granito */ -public class VideoStreamViewerExtension extends StaticWidget { - - public static final String NAME = "Simple Camera Viewer"; +public class AxisCameraExtension extends StaticWidget { + public static final String NAME = "Axis Camera"; + protected static final long errorBackoff = 500; private static final int[] START_BYTES = new int[]{0xFF, 0xD8}; @@ -43,7 +43,7 @@ public class VideoStreamViewerExtension extends StaticWidget { boolean destroyed = false; public BGThread() { - super("Camera Viewer Background"); + super(NAME+" Background"); } long lastRepaint = 0; @@ -110,8 +110,9 @@ public class VideoStreamViewerExtension extends StaticWidget { if(!ipChanged){ try { - Thread.sleep(500); - } catch (InterruptedException ex) {} + Thread.sleep(errorBackoff); + } catch (InterruptedException ex) { + } } } diff --git a/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/DefaultDisplayElementRegistrar.java b/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/DefaultDisplayElementRegistrar.java index ce680a6..4ee1c16 100644 --- a/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/DefaultDisplayElementRegistrar.java +++ b/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/DefaultDisplayElementRegistrar.java @@ -29,8 +29,9 @@ public class DefaultDisplayElementRegistrar { DisplayElementRegistry.registerStaticWidget(ConnectionIndicator.class); DisplayElementRegistry.registerStaticWidget(Label.class); DisplayElementRegistry.registerStaticWidget(RobotPreferences.class); - DisplayElementRegistry.registerStaticWidget(VideoStreamViewerExtension.class); - DisplayElementRegistry.registerStaticWidget(WebcamViewerExtension.class); + DisplayElementRegistry.registerStaticWidget(AxisCameraExtension.class); + DisplayElementRegistry.registerStaticWidget(RoboRIOCameraExtension.class); + DisplayElementRegistry.registerStaticWidget(VideoURLExtension.class); } } diff --git a/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/WebcamViewerExtension.java b/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/RoboRIOCameraExtension.java index f9ba47d..00a0dcb 100644 --- a/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/WebcamViewerExtension.java +++ b/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/RoboRIOCameraExtension.java @@ -22,12 +22,14 @@ import java.util.Arrays; * program. This is mostly compatible with the LabVIEW dashboard in * "HW Compression" mode. * + * @see edu.wpi.first.wpilibj.CameraServer + * * @author Tom Clark * @author Ryan Cahoon */ -public class WebcamViewerExtension extends StaticWidget implements Runnable { +public class RoboRIOCameraExtension extends StaticWidget implements Runnable { - public static final String NAME = "USB Webcam Viewer"; + public static final String NAME = "roboRIO Camera Viewer"; public final IntegerProperty fpsProperty = new IntegerProperty(this, "FPS", 30); public final MultiProperty sizeProperty; @@ -46,7 +48,7 @@ public class WebcamViewerExtension extends StaticWidget implements Runnable { private Socket socket; private Thread thread; - public WebcamViewerExtension() { + public RoboRIOCameraExtension() { super(); sizeProperty = new MultiProperty(this, "Size"); sizeProperty.add("640x480", SIZE_640x480); diff --git a/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/VideoURLExtension.java b/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/VideoURLExtension.java new file mode 100644 index 0000000..ccac096 --- /dev/null +++ b/smartdashboard/src/edu/wpi/first/smartdashboard/gui/elements/VideoURLExtension.java @@ -0,0 +1,212 @@ +package edu.wpi.first.smartdashboard.gui.elements; + +import edu.wpi.first.smartdashboard.gui.DashboardPrefs; +import edu.wpi.first.smartdashboard.gui.StaticWidget; +import edu.wpi.first.smartdashboard.properties.IntegerProperty; +import edu.wpi.first.smartdashboard.properties.Property; +import edu.wpi.first.smartdashboard.properties.StringProperty; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; + +import javax.imageio.ImageIO; + +/** + * + * @author Greg Granito + */ +public class VideoURLExtension extends StaticWidget { + public static final String NAME = "Video URL"; + protected static final long errorBackoff = 500; + + + private static final int[] START_BYTES = new int[]{0xFF, 0xD8}; + private static final int[] END_BYTES = new int[]{0xFF, 0xD9}; + + private boolean urlChanged = true; + private String urlString = null; + private double rotateAngleRad = 0; + private long lastFPSCheck = 0; + private int lastFPS = 0; + private int fpsCounter = 0; + public class BGThread extends Thread { + + boolean destroyed = false; + + public BGThread() { + super(NAME+" Background"); + } + + long lastRepaint = 0; + @Override + public void run() { + URLConnection connection = null; + InputStream stream = null; + ByteArrayOutputStream imageBuffer = new ByteArrayOutputStream(); + while (!destroyed) { + try{ + System.out.println("Connecting to camera"); + urlChanged = false; + URL url = new URL(urlString); + connection = url.openConnection(); + connection.setReadTimeout(250); + stream = connection.getInputStream(); + + while(!destroyed && !urlChanged){ + while(System.currentTimeMillis()-lastRepaint<10){ + stream.skip(stream.available()); + Thread.sleep(1); + } + stream.skip(stream.available()); + + imageBuffer.reset(); + for(int i = 0; i<START_BYTES.length;){ + int b = stream.read(); + if(b==START_BYTES[i]) + i++; + else + i = 0; + } + for(int i = 0; i<START_BYTES.length;++i) + imageBuffer.write(START_BYTES[i]); + + for(int i = 0; i<END_BYTES.length;){ + int b = stream.read(); + imageBuffer.write(b); + if(b==END_BYTES[i]) + i++; + else + i = 0; + } + + fpsCounter++; + if(System.currentTimeMillis()-lastFPSCheck>500){ + lastFPSCheck = System.currentTimeMillis(); + lastFPS = fpsCounter*2; + fpsCounter = 0; + } + + lastRepaint = System.currentTimeMillis(); + ByteArrayInputStream tmpStream = new ByteArrayInputStream(imageBuffer.toByteArray()); + imageToDraw = ImageIO.read(tmpStream); + System.out.println(System.currentTimeMillis()-lastRepaint); + repaint(); + } + + } catch(Exception e){ + imageToDraw = null; + repaint(); + e.printStackTrace(); + } + + if(!urlChanged){ + try { + Thread.sleep(errorBackoff); + } catch (InterruptedException ex) { + } + } + } + + } + + @Override + public void destroy() { + destroyed = true; + } + } + private BufferedImage imageToDraw; + private BGThread bgThread = new BGThread(); + public final StringProperty urlProperty = new StringProperty(this, "Video Path", "http://alarmpi:8090/kinect-video.mjpg"); + public final IntegerProperty rotateProperty = new IntegerProperty(this, "Degrees Rotation", 0); + + @Override + public void init() { + setPreferredSize(new Dimension(100, 100)); + urlString = urlProperty.getSaveValue(); + rotateAngleRad = Math.toRadians(rotateProperty.getValue()); + bgThread.start(); + revalidate(); + repaint(); + } + + @Override + public void propertyChanged(Property property) { + if (property == urlProperty) { + urlString = urlProperty.getSaveValue(); + urlChanged = true; + } + if (property == rotateProperty) { + rotateAngleRad = Math.toRadians(rotateProperty.getValue()); + } + + } + + @Override + public void disconnect() { + bgThread.destroy(); + super.disconnect(); + } + + @Override + protected void paintComponent(Graphics g) { + BufferedImage drawnImage = imageToDraw; + + if (drawnImage != null) { + // cast the Graphics context into a Graphics2D + Graphics2D g2d = (Graphics2D)g; + + // get the existing Graphics transform and copy it so that we can perform scaling and rotation + AffineTransform origXform = g2d.getTransform(); + AffineTransform newXform = (AffineTransform)(origXform.clone()); + + // find the center of the original image + int origImageWidth = drawnImage.getWidth(); + int origImageHeight = drawnImage.getHeight(); + int imageCenterX = origImageWidth/2; + int imageCenterY = origImageHeight/2; + + // perform the desired scaling + double panelWidth = getBounds().width; + double panelHeight = getBounds().height; + double panelCenterX = panelWidth/2.0; + double panelCenterY = panelHeight/2.0; + double rotatedImageWidth = origImageWidth * Math.abs(Math.cos(rotateAngleRad)) + origImageHeight * Math.abs(Math.sin(rotateAngleRad)); + double rotatedImageHeight = origImageWidth * Math.abs(Math.sin(rotateAngleRad)) + origImageHeight * Math.abs(Math.cos(rotateAngleRad)); + + // compute scaling needed + double scale = Math.min(panelWidth / rotatedImageWidth, panelHeight / rotatedImageHeight); + + // set the transform before drawing the image + // 1 - translate the origin to the center of the panel + // 2 - perform the desired rotation (rotation will be about origin) + // 3 - perform the desired scaling (will scale centered about origin) + newXform.translate(panelCenterX, panelCenterY); + newXform.rotate(rotateAngleRad); + newXform.scale(scale, scale); + g2d.setTransform(newXform); + + // draw image so that the center of the image is at the "origin"; the transform will take care of the rotation and scaling + g2d.drawImage(drawnImage, -imageCenterX, -imageCenterY, null); + + // restore the original transform + g2d.setTransform(origXform); + + g.setColor(Color.PINK); + g.drawString("FPS: "+lastFPS, 10, 10); + } else { + g.setColor(Color.PINK); + g.fillRect(0, 0, getBounds().width, getBounds().height); + g.setColor(Color.BLACK); + g.drawString("NO CONNECTION", 10, 10); + } + } +} |