From bff2c2d8e05830742d4dc31be7200c484f2dec7d Mon Sep 17 00:00:00 2001 From: Banks Troutman Date: Sat, 2 Nov 2019 03:34:51 -0400 Subject: [PATCH] reworked driverMode, fixed streamDivisor --- .../chameleonvision/vision/camera/Camera.java | 112 +++++++++++------- .../vision/camera/CameraDeserializer.java | 20 +++- .../vision/camera/CameraSerializer.java | 4 +- .../vision/process/VisionProcess.java | 10 +- .../chameleonvision/web/ServerHandler.java | 27 ++++- 5 files changed, 117 insertions(+), 56 deletions(-) diff --git a/Main/src/main/java/com/chameleonvision/vision/camera/Camera.java b/Main/src/main/java/com/chameleonvision/vision/camera/Camera.java index 2e21f64b1..c36d5cc1b 100644 --- a/Main/src/main/java/com/chameleonvision/vision/camera/Camera.java +++ b/Main/src/main/java/com/chameleonvision/vision/camera/Camera.java @@ -1,10 +1,7 @@ package com.chameleonvision.vision.camera; -import com.chameleonvision.Main; import com.chameleonvision.settings.Platform; -import com.chameleonvision.settings.SettingsManager; import com.chameleonvision.vision.Pipeline; -import com.chameleonvision.web.Server; import com.chameleonvision.web.ServerHandler; import edu.wpi.cscore.*; import edu.wpi.first.cameraserver.CameraServer; @@ -12,7 +9,6 @@ import edu.wpi.first.networktables.NetworkTable; import edu.wpi.first.networktables.NetworkTableInstance; import org.opencv.core.Mat; -import java.nio.channels.Pipe; import java.util.*; import java.util.stream.Collectors; import java.util.stream.IntStream; @@ -21,15 +17,14 @@ public class Camera { private static final double DEFAULT_FOV = 60.8; private static final StreamDivisor DEFAULT_STREAMDIVISOR = StreamDivisor.none; - private static final int DEFAULT_EXPOSURE = 50; - private static final int DEFAULT_BRIGHTNESS = 50; + public static final int DEFAULT_EXPOSURE = 50; + public static final int DEFAULT_BRIGHTNESS = 50; private static final int MINIMUM_FPS = 30; private static final int MINIMUM_WIDTH = 320; private static final int MINIMUM_HEIGHT = 200; private static final int MAX_INIT_MS = 1500; private static final List ALLOWED_PIXEL_FORMATS = Arrays.asList(VideoMode.PixelFormat.kYUYV, VideoMode.PixelFormat.kMJPEG); - public final String name; public final String path; @@ -50,9 +45,9 @@ public class Camera { private List pipelines; //Driver mode camera settings - public int driverExposure; - public int driverBrightness; - public boolean isDriver; + private int driverExposure; + private int driverBrightness; + private boolean isDriver; public Camera(String cameraName) { this(cameraName, DEFAULT_FOV); @@ -67,18 +62,18 @@ public class Camera { } public Camera(String cameraName, UsbCameraInfo usbCamInfo, double fov, StreamDivisor divisor) { - this(cameraName, usbCamInfo, fov, new ArrayList<>(), 0, divisor, DEFAULT_EXPOSURE, DEFAULT_BRIGHTNESS,false); + this(cameraName, usbCamInfo, fov, new ArrayList<>(), 0, divisor, false); } - public Camera(String cameraName, double fov, List pipelines, int videoModeIndex, StreamDivisor divisor, int driverExposure, int driverBrightness,boolean isDriver) { - this(cameraName, CameraManager.AllUsbCameraInfosByName.get(cameraName), fov, pipelines, videoModeIndex, divisor, driverExposure, driverBrightness, isDriver); + public Camera(String cameraName, double fov, List pipelines, int videoModeIndex, StreamDivisor divisor, boolean isDriver) { + this(cameraName, CameraManager.AllUsbCameraInfosByName.get(cameraName), fov, pipelines, videoModeIndex, divisor, isDriver); } - public Camera(String cameraName, double fov, int videoModeIndex, StreamDivisor divisor, int driverExposure, int driverBrightness,boolean isDriver) { - this(cameraName, fov, new ArrayList<>(), videoModeIndex, divisor, driverExposure, driverBrightness,isDriver); + public Camera(String cameraName, double fov, int videoModeIndex, StreamDivisor divisor, boolean isDriver) { + this(cameraName, fov, new ArrayList<>(), videoModeIndex, divisor, isDriver); } - public Camera(String cameraName, UsbCameraInfo usbCamInfo, double fov, List pipelines, int videoModeIndex, StreamDivisor divisor, int driverExposure, int driverBrightness,boolean isDriver) { + public Camera(String cameraName, UsbCameraInfo usbCamInfo, double fov, List pipelines, int videoModeIndex, StreamDivisor divisor, boolean isDriver) { FOV = fov; name = cameraName; @@ -121,11 +116,6 @@ public class Camera { cvSink = cs.getVideo(UsbCam); cvSource = cs.putVideo(name, camVals.ImageWidth / streamDivisor.value , camVals.ImageHeight / streamDivisor.value); - - //Driver mode settings - this.isDriver = isDriver; - this.driverBrightness=driverBrightness; - this.driverExposure=driverExposure; } VideoMode[] getAvailableVideoModes() { @@ -144,18 +134,28 @@ public class Camera { private void setCamVideoMode(CamVideoMode newVideoMode, boolean updateCvSource) { var prevVideoMode = this.camVideoMode; this.camVideoMode = newVideoMode; - UsbCam.setVideoMode(newVideoMode.getActualPixelFormat(), newVideoMode.width, newVideoMode.height, newVideoMode.fps); // update camera values camVals = new CameraValues(this); - if (prevVideoMode != null && !prevVideoMode.equals(newVideoMode) && updateCvSource) { // if resolution changed - synchronized (cvSourceLock) { - cvSource = cs.putVideo(name, newVideoMode.width, newVideoMode.height); + + if (prevVideoMode != null && !prevVideoMode.equals(newVideoMode)) { // if resolution changed + UsbCam.setVideoMode(newVideoMode.getActualPixelFormat(), newVideoMode.width, newVideoMode.height, newVideoMode.fps); + if (updateCvSource) { + updateCvSource(); } - ServerHandler.sendFullSettings(); } } + private void updateCvSource() { + synchronized (cvSourceLock) { + var newWidth = camVideoMode.width / streamDivisor.value; + var newHeight = camVideoMode.height / streamDivisor.value; + cvSource = cs.putVideo(name, newWidth, newHeight); + } + CameraManager.getVisionProcessByCameraName(name).cameraProcess.updateFrameSize(); + ServerHandler.sendFullSettings(); + } + public void addPipeline() { Pipeline p = new Pipeline(); p.nickname = "New pipeline " + pipelines.size(); @@ -195,8 +195,11 @@ public class Camera { return streamDivisor; } - public void setStreamDivisor(int divisor) { + public void setStreamDivisor(int divisor, boolean updateCvSource) { streamDivisor = StreamDivisor.values()[divisor]; + if (updateCvSource) { + updateCvSource(); + } } public List getPipelines() { @@ -230,15 +233,11 @@ public class Camera { public void setDriverMode(boolean state) { - isDriver=state; - if(isDriver){ - UsbCam.setBrightness(driverBrightness);//We call setBrightness because it updates after 2 calls - UsbCam.setBrightness(driverBrightness);//Check it after we update to 2020 libraries - try{UsbCam.setExposureManual(driverExposure);} - catch (VideoException e) - { - System.out.println("Exposure change isn't supported"); - } + isDriver = state; + if( isDriver ) { + setBrightness(driverBrightness); //We call setBrightness because it updates after 2 calls + setBrightness(driverBrightness); //Check it after we update to 2020 libraries + setExposure(driverExposure); } else{ UsbCam.setBrightness(getCurrentPipeline().brightness); @@ -263,18 +262,24 @@ public class Camera { public void setBrightness(int brightness) { - if (isDriver) - driverBrightness=brightness; - else + if (isDriver) { + driverBrightness = brightness; + UsbCam.setBrightness(brightness); // set twice to reduce timeout + } + else { getCurrentPipeline().brightness = brightness; + } UsbCam.setBrightness(brightness); } public void setExposure(int exposure) { - if (isDriver) - driverExposure=exposure; - else + if (isDriver) { + driverExposure = exposure; + } + else { getCurrentPipeline().exposure = exposure; + } + try { UsbCam.setExposureManual(exposure); } catch (VideoException e) { @@ -316,4 +321,27 @@ public class Camera { return nickname == null ? name : nickname; } + public void setDriverExposure(int exposure) { + driverExposure = exposure; + + if (isDriver) { + setExposure(exposure); + } + } + + public void setDriverBrightness(int brightness) { + driverBrightness = brightness; + + if (isDriver) { + setBrightness(brightness); + } + } + + public int getDriverExposure() { + return driverExposure; + } + + public int getDriverBrightness() { + return driverBrightness; + } } diff --git a/Main/src/main/java/com/chameleonvision/vision/camera/CameraDeserializer.java b/Main/src/main/java/com/chameleonvision/vision/camera/CameraDeserializer.java index 6148c5b61..88152ca3e 100644 --- a/Main/src/main/java/com/chameleonvision/vision/camera/CameraDeserializer.java +++ b/Main/src/main/java/com/chameleonvision/vision/camera/CameraDeserializer.java @@ -23,10 +23,18 @@ public class CameraDeserializer implements JsonDeserializer { var camName = jsonObj.get("name").getAsString(); var camNickname = jsonObj.get("nickname").getAsString(); var videoModeIndex = jsonObj.get("resolution").getAsInt(); - var isDriver = jsonObj.get("isDriver").getAsBoolean(); - var driverExposure = jsonObj.get("driverExposure").getAsInt(); - var driverBrightness = jsonObj.get("driverBrightness").getAsInt(); - var divisor = StreamDivisor.values()[jsonObj.get("streamDivisor").getAsInt()]; + + // new for 2.0 + var isDriverObj = jsonObj.get("isDriver"); + var driverExposureObj = jsonObj.get("driverExposure"); + var driverBrightnessObj = jsonObj.get("driverBrightness"); + var divisorObj = jsonObj.get("streamDivisor"); + + // always null-check new features + boolean isDriver = isDriverObj != null && isDriverObj.getAsBoolean(); + int driverExposure = driverExposureObj == null ? Camera.DEFAULT_EXPOSURE : driverExposureObj.getAsInt(); + int driverBrightness = driverBrightnessObj == null ? Camera.DEFAULT_BRIGHTNESS : driverBrightnessObj.getAsInt(); + StreamDivisor divisor = divisorObj == null ? StreamDivisor.none : StreamDivisor.values()[divisorObj.getAsInt()]; var pipelines = jsonObj.get("pipelines"); List actualPipelines = new ArrayList<>(); @@ -39,8 +47,10 @@ public class CameraDeserializer implements JsonDeserializer { e.printStackTrace(); } - var newCamera = actualPipelines != null ? new Camera(camName, camFOV, actualPipelines, videoModeIndex, divisor, driverExposure, driverBrightness,isDriver) : new Camera(camName, camFOV, videoModeIndex, divisor, driverExposure, driverBrightness,isDriver); + var newCamera = actualPipelines != null ? new Camera(camName, camFOV, actualPipelines, videoModeIndex, divisor, isDriver) : new Camera(camName, camFOV, videoModeIndex, divisor, isDriver); newCamera.setNickname(camNickname != null ? camNickname : ""); + newCamera.setDriverExposure(driverExposure); + newCamera.setDriverBrightness(driverBrightness); return newCamera; } catch (NullPointerException e) diff --git a/Main/src/main/java/com/chameleonvision/vision/camera/CameraSerializer.java b/Main/src/main/java/com/chameleonvision/vision/camera/CameraSerializer.java index 443db9ee1..313959ddb 100644 --- a/Main/src/main/java/com/chameleonvision/vision/camera/CameraSerializer.java +++ b/Main/src/main/java/com/chameleonvision/vision/camera/CameraSerializer.java @@ -17,8 +17,8 @@ public class CameraSerializer implements JsonSerializer { obj.addProperty("resolution", camera.getVideoModeIndex()); obj.add("camVideoMode", context.serialize(camera.getVideoMode())); obj.add("isDriver",context.serialize(camera.getDriverMode())); - obj.add("driverExposure",context.serialize(camera.driverExposure)); - obj.add("driverBrightness",context.serialize(camera.driverBrightness)); + obj.add("driverExposure",context.serialize(camera.getDriverExposure())); + obj.add("driverBrightness",context.serialize(camera.getDriverBrightness())); return obj; } } diff --git a/Main/src/main/java/com/chameleonvision/vision/process/VisionProcess.java b/Main/src/main/java/com/chameleonvision/vision/process/VisionProcess.java index fe2e8581f..6e00b6477 100644 --- a/Main/src/main/java/com/chameleonvision/vision/process/VisionProcess.java +++ b/Main/src/main/java/com/chameleonvision/vision/process/VisionProcess.java @@ -19,7 +19,7 @@ public class VisionProcess implements Runnable { private final Camera camera; private final String cameraName; - private final CameraProcess cameraProcess; + public final CameraProcess cameraProcess; // NetworkTables public NetworkTableEntry ntPipelineEntry; public NetworkTableEntry ntDriverModeEntry; @@ -165,6 +165,14 @@ public class VisionProcess implements Runnable { pipelineResult.CalibratedY = (finalRect.center.x * currentPipeline.m) + currentPipeline.b; break; } +// var camVals = camera.getCamVals(); +// if (currentPipeline.isCalibrated) { +// pipelineResult.CalibratedX = (finalRect.center.y - currentPipeline.b) / currentPipeline.m; +// pipelineResult.CalibratedY = (finalRect.center.x * currentPipeline.m) + currentPipeline.b; +// } else { +// pipelineResult.CalibratedX = camVals.CenterX; +// pipelineResult.CalibratedY = camVals.CenterY; +// } pipelineResult.Pitch = camera.getCamVals().CalculatePitch(finalRect.center.y, pipelineResult.CalibratedY); pipelineResult.Yaw = camera.getCamVals().CalculateYaw(finalRect.center.x, pipelineResult.CalibratedX); pipelineResult.Area = finalRect.size.area(); diff --git a/Main/src/main/java/com/chameleonvision/web/ServerHandler.java b/Main/src/main/java/com/chameleonvision/web/ServerHandler.java index ea8cae077..8192e613f 100644 --- a/Main/src/main/java/com/chameleonvision/web/ServerHandler.java +++ b/Main/src/main/java/com/chameleonvision/web/ServerHandler.java @@ -65,10 +65,25 @@ public class ServerHandler { } case "cameraSettings": { HashMap camSettings = (HashMap) entry.getValue(); - CameraManager.getCurrentCamera().setFOV((Number) camSettings.get("fov")); - CameraManager.getCurrentCamera().setStreamDivisor((Integer) camSettings.get("streamDivisor")); - CameraManager.getCurrentCamera().setCamVideoMode((Integer) camSettings.get("resolution"), true); - SettingsManager.saveSettings(); + var curCam = CameraManager.getCurrentCamera(); + + Number newFOV = (Number) camSettings.get("fov"); + Integer newStreamDivisor = (Integer) camSettings.get("streamDivisor"); + Integer newResolution = (Integer) camSettings.get("resolution"); + + curCam.setFOV(newFOV); + + var currentStreamDivisorOrdinal = curCam.getStreamDivisor().ordinal(); + if (currentStreamDivisorOrdinal != newStreamDivisor) { + curCam.setStreamDivisor(newStreamDivisor, true); + } + + var currentResolutionIndex = curCam.getVideoModeIndex(); + if (currentResolutionIndex != newResolution) { + curCam.setCamVideoMode(newResolution, true); + } + + CameraManager.saveCameras(); sendFullSettings(); break; } @@ -238,8 +253,8 @@ public class ServerHandler { try { var currentCamera = CameraManager.getCurrentCamera(); tmp.put("isDriver", currentCamera.getDriverMode()); - tmp.put("driverBrightness", currentCamera.driverBrightness); - tmp.put("driverExposure", currentCamera.driverExposure); + tmp.put("driverBrightness", currentCamera.getDriverBrightness()); + tmp.put("driverExposure", currentCamera.getDriverExposure()); } catch (CameraException e) { e.printStackTrace(); }