summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@sbcglobal.net>2016-03-09 15:03:22 -0500
committerLuke Shumaker <lukeshu@sbcglobal.net>2016-03-09 15:03:22 -0500
commit96dc00ca38368b528e7a2dfa0962e124e885c73f (patch)
tree39efb6841f4c5aa2702f427d7a011b70565e8d7c
parentf834bb57f9fcbf4c8a4631f8053f1395587c0445 (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.java5
-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.java212
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);
+ }
+ }
+}