mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-21 01:01:41 +00:00
Continue plumbing ServerHandler
This commit is contained in:
@@ -115,7 +115,6 @@ public class Main {
|
||||
|
||||
if (!CurrentPlatform.isRoot()) {
|
||||
if (ignoreRoot) {
|
||||
// TODO: should we do this?
|
||||
// manageNetwork = false;
|
||||
System.out.println("Ignoring root, network will not be managed!");
|
||||
} else {
|
||||
|
||||
@@ -1,29 +1,27 @@
|
||||
package com.chameleonvision.classabstraction;
|
||||
|
||||
import com.chameleonvision.classabstraction.camera.CameraProcess;
|
||||
import com.chameleonvision.classabstraction.camera.USBCameraProcess;
|
||||
import com.chameleonvision.classabstraction.config.CameraConfig;
|
||||
import com.chameleonvision.classabstraction.config.ConfigManager;
|
||||
import com.chameleonvision.settings.Platform;
|
||||
import com.chameleonvision.settings.SettingsManager;
|
||||
import com.chameleonvision.util.FileHelper;
|
||||
import com.chameleonvision.vision.camera.CameraException;
|
||||
import com.chameleonvision.vision.camera.USBCamera;
|
||||
import edu.wpi.cscore.UsbCamera;
|
||||
import edu.wpi.cscore.UsbCameraInfo;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.opencv.videoio.VideoCapture;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class VisionManager {
|
||||
|
||||
private VisionManager() {}
|
||||
|
||||
private static final Path CamConfigPath = Paths.get(SettingsManager.SettingsPath.toString(), "cameras");
|
||||
|
||||
public static final LinkedHashMap<String, UsbCameraInfo> UsbCameraInfosByCameraName = new LinkedHashMap<>();
|
||||
private static final LinkedHashMap<String, UsbCameraInfo> UsbCameraInfosByCameraName = new LinkedHashMap<>();
|
||||
private static final LinkedList<CameraConfig> LoadedCameraConfigs = new LinkedList<>();
|
||||
public static final LinkedHashMap<String, VisionProcess> VisionProcessesByCameraName = new LinkedHashMap<>();
|
||||
private static final LinkedHashMap<Integer, Pair<VisionProcess, String>> VisionProcessesByIndex = new LinkedHashMap<>();
|
||||
|
||||
private static VisionProcess currentUIVisionProcess;
|
||||
|
||||
public static boolean initializeSources() {
|
||||
int suffix = 0;
|
||||
@@ -44,8 +42,6 @@ public class VisionManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
FileHelper.CheckPath(CamConfigPath);
|
||||
|
||||
// load the config
|
||||
List<CameraConfig> preliminaryConfigs = new ArrayList<>();
|
||||
|
||||
@@ -62,6 +58,8 @@ public class VisionManager {
|
||||
});
|
||||
|
||||
LoadedCameraConfigs.addAll(ConfigManager.initializeCameraConfig(preliminaryConfigs));
|
||||
|
||||
// TODO: (HIGH) Load pipelines from json
|
||||
// UsbCameraInfosByCameraName.forEach((cameraName, cameraInfo) -> {
|
||||
// Path cameraConfigFolder = Paths.get(CamConfigPath.toString(), String.format("%s\\", cameraName));
|
||||
// Path cameraConfigPath = Paths.get(cameraConfigFolder.toString(), String.format("%s.json", cameraName));
|
||||
@@ -72,23 +70,43 @@ public class VisionManager {
|
||||
}
|
||||
|
||||
public static boolean initializeProcesses() {
|
||||
LoadedCameraConfigs.forEach(config -> {
|
||||
var camera = new USBCameraProcess(config);
|
||||
VisionProcessesByCameraName.put(config.name, new VisionProcess(camera, config.name));
|
||||
});
|
||||
for (int i = 0; i < LoadedCameraConfigs.size(); i++) {
|
||||
CameraConfig config = LoadedCameraConfigs.get(i);
|
||||
CameraProcess camera = new USBCameraProcess(config);
|
||||
VisionProcess process = new VisionProcess(camera, config.name);
|
||||
VisionProcessesByIndex.put(i, Pair.of(process, config.name));
|
||||
}
|
||||
currentUIVisionProcess = VisionProcessesByIndex.get(0).getLeft();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void startProcesses() {
|
||||
VisionProcessesByCameraName.forEach((name, process) -> {
|
||||
process.start();
|
||||
VisionProcessesByIndex.forEach((index, processNamePair) -> {
|
||||
processNamePair.getLeft().start();
|
||||
});
|
||||
}
|
||||
|
||||
public static VisionProcess getCurrentCamera() throws CameraException {
|
||||
if (VisionProcessesByCameraName.size() == 0) throw new CameraException(CameraException.CameraExceptionType.NO_CAMERA);
|
||||
var curCam = VisionProcessesByCameraName.get(SettingsManager.generalSettings.currentCamera);
|
||||
if (curCam == null) throw new CameraException(CameraException.CameraExceptionType.BAD_CAMERA);
|
||||
return curCam;
|
||||
public static VisionProcess getCurrentUIVisionProcess() {
|
||||
return currentUIVisionProcess;
|
||||
}
|
||||
|
||||
public static void setCurrentProcessByIndex(int processIndex) {
|
||||
if (processIndex > VisionProcessesByIndex.size() - 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
currentUIVisionProcess = VisionProcessesByIndex.get(processIndex).getLeft();
|
||||
}
|
||||
|
||||
public static VisionProcess getVisionProcessByIndex(int processIndex) {
|
||||
if (processIndex > VisionProcessesByIndex.size() - 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return VisionProcessesByIndex.get(0).getLeft();
|
||||
}
|
||||
|
||||
public static List<String> getAllCameraNicknames() {
|
||||
return VisionProcessesByIndex.values().stream().map(processNamePair -> processNamePair.getLeft().getCamera().getProperties().getNickname()).collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import com.chameleonvision.classabstraction.camera.CameraStreamer;
|
||||
import com.chameleonvision.classabstraction.config.ConfigManager;
|
||||
import com.chameleonvision.classabstraction.pipeline.*;
|
||||
import com.chameleonvision.classabstraction.util.LoopingRunnable;
|
||||
import com.chameleonvision.vision.Pipeline;
|
||||
import com.chameleonvision.web.ServerHandler;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
@@ -26,11 +27,13 @@ public class VisionProcess {
|
||||
private final CameraFrameRunnable cameraRunnable;
|
||||
private final CameraStreamerRunnable streamRunnable;
|
||||
private final VisionProcessRunnable visionRunnable;
|
||||
private final CameraStreamer cameraStreamer;
|
||||
public final CameraStreamer cameraStreamer;
|
||||
|
||||
private CVPipeline currentPipeline;
|
||||
private int currentPipelineIndex = 0;
|
||||
|
||||
private final CVPipelineSettings driverVisionSettings = new CVPipelineSettings();
|
||||
private final CVPipelineSettings driverModeSettings = new CVPipelineSettings();
|
||||
private CVPipeline driverModePipeline = new DriverVisionPipeline(driverModeSettings);
|
||||
|
||||
// shitty stuff
|
||||
private volatile Mat lastCameraFrame = new Mat();
|
||||
@@ -38,27 +41,27 @@ public class VisionProcess {
|
||||
private volatile CVPipelineResult lastPipelineResult;
|
||||
|
||||
// network table stuff
|
||||
public NetworkTableEntry ntPipelineEntry;
|
||||
public NetworkTableEntry ntDriverModeEntry;
|
||||
private NetworkTableEntry ntPipelineEntry;
|
||||
private NetworkTableEntry ntDriverModeEntry;
|
||||
private int ntDriveModeListenerID;
|
||||
private int ntPipelineListenerID;
|
||||
private NetworkTableEntry ntYawEntry;
|
||||
private NetworkTableEntry ntPitchEntry;
|
||||
private NetworkTableEntry ntAuxListEntry;
|
||||
private NetworkTableEntry ntDistanceEntry;
|
||||
private NetworkTableEntry ntAreaEntry;
|
||||
private NetworkTableEntry ntTimeStampEntry;
|
||||
private NetworkTableEntry ntValidEntry;
|
||||
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
private Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
|
||||
public VisionProcess(CameraProcess cameraProcess, String name) {
|
||||
VisionProcess(CameraProcess cameraProcess, String name) {
|
||||
this.cameraProcess = cameraProcess;
|
||||
|
||||
pipelines.add(new DriverVisionPipeline(() -> driverVisionSettings));
|
||||
pipelines.add(new CVPipeline2d("New Pipeline"));
|
||||
setPipeline(0);
|
||||
|
||||
// Thread to grab frames from the camera
|
||||
// TODO: fix video modes!!!
|
||||
// TODO: FIX FPS!!!!!!!
|
||||
// TODO: (HIGH) fix video modes!!!
|
||||
// TODO: (HIGH) FIX FPS!!!!!!!
|
||||
this.cameraRunnable = new CameraFrameRunnable(cameraProcess.getProperties().videoModes.get(0).fps);
|
||||
|
||||
lastPipelineResult = new DriverVisionPipeline.DriverPipelineResult(
|
||||
@@ -106,7 +109,7 @@ public class VisionProcess {
|
||||
ntDriverModeEntry = newTable.getEntry("driver_mode");
|
||||
ntPitchEntry = newTable.getEntry("pitch");
|
||||
ntYawEntry = newTable.getEntry("yaw");
|
||||
ntDistanceEntry = newTable.getEntry("distance");
|
||||
ntAreaEntry = newTable.getEntry("area");
|
||||
ntTimeStampEntry = newTable.getEntry("timestamp");
|
||||
ntValidEntry = newTable.getEntry("is_valid");
|
||||
ntDriveModeListenerID = ntDriverModeEntry.addListener(this::setDriverMode, EntryListenerFlags.kUpdate);
|
||||
@@ -115,8 +118,16 @@ public class VisionProcess {
|
||||
ntPipelineEntry.setNumber(0);
|
||||
}
|
||||
|
||||
private void setDriverMode(EntryNotification ignored) {
|
||||
setPipeline(0);
|
||||
private void setDriverMode(EntryNotification driverModeEntryNotification) {
|
||||
setDriverMode(driverModeEntryNotification.value.getBoolean());
|
||||
}
|
||||
|
||||
public void setDriverMode(boolean driverMode) {
|
||||
if (driverMode) {
|
||||
setPipelineInternal(driverModePipeline);
|
||||
} else {
|
||||
setPipeline(currentPipelineIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,25 +146,23 @@ public class VisionProcess {
|
||||
}
|
||||
|
||||
public void setPipeline(int pipelineIndex) {
|
||||
|
||||
CVPipeline newPipeline = pipelines.get(pipelineIndex);
|
||||
if (newPipeline != null) {
|
||||
setPipelineInternal(newPipeline);
|
||||
}
|
||||
currentPipelineIndex = pipelineIndex;
|
||||
|
||||
// update the configManager
|
||||
if(ConfigManager.settings.currentCamera.equals(cameraProcess.getProperties().name)) {
|
||||
ConfigManager.settings.currentPipeline = pipelineIndex;
|
||||
HashMap<String, Object> pipeChange = new HashMap<>();
|
||||
pipeChange.put("currentPipeline", pipelineIndex);
|
||||
ServerHandler.broadcastMessage(pipeChange);
|
||||
ServerHandler.sendFullSettings();
|
||||
// update the configManager
|
||||
if(ConfigManager.settings.currentCamera.equals(cameraProcess.getProperties().name)) {
|
||||
ConfigManager.settings.currentPipeline = pipelineIndex;
|
||||
HashMap<String, Object> pipeChange = new HashMap<>();
|
||||
pipeChange.put("currentPipeline", pipelineIndex);
|
||||
ServerHandler.broadcastMessage(pipeChange);
|
||||
ServerHandler.sendFullSettings();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setPipelineInternal(CVPipeline pipeline) {
|
||||
pipelines.add(pipeline);
|
||||
currentPipeline = pipeline;
|
||||
currentPipeline.initPipeline(cameraProcess);
|
||||
}
|
||||
@@ -165,14 +174,15 @@ public class VisionProcess {
|
||||
HashMap<String, Object> calculated = new HashMap<>();
|
||||
List<Double> center = new ArrayList<>();
|
||||
if (data.hasTarget) {
|
||||
|
||||
if(data instanceof CVPipeline2d.CVPipeline2dResult) {
|
||||
CVPipeline2d.CVPipeline2dResult result = (CVPipeline2d.CVPipeline2dResult) data;
|
||||
CVPipeline2d.Target bestTarget = result.targets.get(0);
|
||||
CVPipeline2d.Target2d bestTarget = result.targets.get(0);
|
||||
center.add(bestTarget.rawPoint.center.x);
|
||||
center.add(bestTarget.rawPoint.center.y);
|
||||
calculated.put("pitch", bestTarget.pitch);
|
||||
calculated.put("yaw", bestTarget.yaw);
|
||||
} else if (data instanceof CVPipeline3d.CVPipeline3dResult) {
|
||||
// TODO: (2.1) 3d stuff in UI
|
||||
} else {
|
||||
center.add(0.0);
|
||||
center.add(0.0);
|
||||
@@ -200,19 +210,19 @@ public class VisionProcess {
|
||||
ntTimeStampEntry.setDouble(data.processTime);
|
||||
|
||||
//noinspection unchecked
|
||||
List<CVPipeline2d.Target> targets = (List<CVPipeline2d.Target>) data.targets;
|
||||
List<CVPipeline2d.Target2d> targets = (List<CVPipeline2d.Target2d>) data.targets;
|
||||
ntPitchEntry.setDouble(targets.get(0).pitch);
|
||||
ntYawEntry.setDouble(targets.get(0).yaw);
|
||||
ntDistanceEntry.setDouble(targets.get(0).area);
|
||||
ntAreaEntry.setDouble(targets.get(0).area);
|
||||
ntAuxListEntry.setString(gson.toJson(targets));
|
||||
|
||||
} else if(data instanceof CVPipeline3d.CVPipeline3dResult) {
|
||||
// TODO implement
|
||||
} else if (data instanceof CVPipeline3d.CVPipeline3dResult) {
|
||||
// TODO: (2.1) 3d stuff...
|
||||
}
|
||||
} else {
|
||||
ntPitchEntry.setDouble(0.0);
|
||||
ntYawEntry.setDouble(0.0);
|
||||
ntDistanceEntry.setDouble(0.0);
|
||||
ntAreaEntry.setDouble(0.0);
|
||||
ntTimeStampEntry.setDouble(0.0);
|
||||
}
|
||||
}
|
||||
@@ -222,10 +232,43 @@ public class VisionProcess {
|
||||
cameraStreamer.setNewVideoMode(newMode);
|
||||
}
|
||||
|
||||
public List<CVPipeline> getPipelines() {
|
||||
return pipelines;
|
||||
}
|
||||
|
||||
public CVPipeline getCurrentPipeline() {
|
||||
return currentPipeline;
|
||||
}
|
||||
|
||||
public int getCurrentPipelineIndex() {
|
||||
return currentPipelineIndex;
|
||||
}
|
||||
|
||||
public void addPipeline() {
|
||||
// TODO: (2.1) add to UI option between 2d and 3d pipeline
|
||||
pipelines.add(new CVPipeline2d());
|
||||
}
|
||||
|
||||
public void addPipeline(CVPipeline pipeline) {
|
||||
pipelines.add(pipeline);
|
||||
}
|
||||
|
||||
public CameraProcess getCamera() {
|
||||
return cameraProcess;
|
||||
}
|
||||
|
||||
public boolean getDriverMode() {
|
||||
return (currentPipeline == driverModePipeline);
|
||||
}
|
||||
|
||||
public CVPipelineSettings getDriverModeSettings() {
|
||||
return driverModePipeline.settings;
|
||||
}
|
||||
|
||||
public CVPipeline getPipelineByIndex(int pipelineIndex) {
|
||||
return pipelines.get(pipelineIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* CameraFrameRunnable grabs images from the cameraProcess
|
||||
* at a specified loopTime
|
||||
@@ -243,7 +286,7 @@ public class VisionProcess {
|
||||
*/
|
||||
CameraFrameRunnable(int cameraFPS) {
|
||||
// add 2 FPS to allow for a bit of overhead
|
||||
// TODO: test the affect of this
|
||||
// TODO: (low) test the effect of this
|
||||
super(1000L/(cameraFPS + 2));
|
||||
}
|
||||
|
||||
@@ -281,7 +324,7 @@ public class VisionProcess {
|
||||
*/
|
||||
private class VisionProcessRunnable implements Runnable {
|
||||
|
||||
public Double fps = 0.0; // TODO update or average or something
|
||||
public Double fps = 0.0; // TODO: (HIGH) update or average or something
|
||||
private CVPipelineResult result;
|
||||
private Mat streamBuffer = new Mat();
|
||||
|
||||
@@ -311,19 +354,19 @@ public class VisionProcess {
|
||||
} else {
|
||||
// System.err.println("Bad streambuffer mat");
|
||||
}
|
||||
// TODO do something with the result
|
||||
// TODO: (HIGH) do something with the result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class CameraStreamerRunnable extends LoopingRunnable {
|
||||
|
||||
private final CameraStreamer streamer;
|
||||
public final CameraStreamer streamer;
|
||||
private Mat streamBuffer = new Mat();
|
||||
|
||||
private CameraStreamerRunnable(int cameraFPS, CameraStreamer streamer) {
|
||||
// add 2 FPS to allow for a bit of overhead
|
||||
// TODO: test the affect of this
|
||||
// TODO: (low) test the effect of this
|
||||
super(1000L/(cameraFPS + 2));
|
||||
this.streamer = streamer;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.opencv.core.Mat;
|
||||
|
||||
public interface CameraProcess {
|
||||
CameraProperties getProperties();
|
||||
USBCameraProperties getProperties();
|
||||
|
||||
/**
|
||||
* Get the next camera frame
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.chameleonvision.classabstraction.camera;
|
||||
|
||||
import com.chameleonvision.vision.camera.StreamDivisor;
|
||||
import com.chameleonvision.web.ServerHandler;
|
||||
import edu.wpi.cscore.CvSource;
|
||||
import edu.wpi.cscore.VideoMode;
|
||||
import edu.wpi.first.cameraserver.CameraServer;
|
||||
@@ -35,7 +36,11 @@ public class CameraStreamer {
|
||||
cameraProcess.getProperties().staticProperties.imageWidth / divisor.value,
|
||||
cameraProcess.getProperties().staticProperties.imageHeight / divisor.value);
|
||||
}
|
||||
// ServerHandler.sendFullSettings();
|
||||
ServerHandler.sendFullSettings();
|
||||
}
|
||||
|
||||
public StreamDivisor getDivisor() {
|
||||
return divisor;
|
||||
}
|
||||
|
||||
public void setNewVideoMode(VideoMode newVideoMode) {
|
||||
@@ -57,5 +62,4 @@ public class CameraStreamer {
|
||||
// }
|
||||
cvSource.putFrame(streamBuffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,18 +13,18 @@ public class USBCameraProcess implements CameraProcess {
|
||||
private final UsbCamera baseCamera;
|
||||
private final CvSink cvSink;
|
||||
private Mat imageBuffer = new Mat();
|
||||
private CameraProperties properties;
|
||||
private USBCameraProperties properties;
|
||||
|
||||
public USBCameraProcess(CameraConfig config) {
|
||||
baseCamera = new UsbCamera(config.name, config.path);
|
||||
cvSink = CameraServer.getInstance().getVideo(baseCamera);
|
||||
properties = new CameraProperties(baseCamera, config);
|
||||
properties = new USBCameraProperties(baseCamera, config);
|
||||
|
||||
setVideoMode(properties.videoModes.get(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public CameraProperties getProperties() {
|
||||
public USBCameraProperties getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,101 +1,101 @@
|
||||
package com.chameleonvision.classabstraction.camera;
|
||||
|
||||
import com.chameleonvision.classabstraction.config.CameraConfig;
|
||||
import com.chameleonvision.settings.Platform;
|
||||
import edu.wpi.cscore.UsbCamera;
|
||||
import edu.wpi.cscore.VideoMode;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class CameraProperties {
|
||||
public static final double DEFAULT_FOV = 70;
|
||||
private static final int DEFAULT_EXPOSURE = 50;
|
||||
private 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<VideoMode.PixelFormat> ALLOWED_PIXEL_FORMATS = Arrays.asList(VideoMode.PixelFormat.kYUYV, VideoMode.PixelFormat.kMJPEG);
|
||||
|
||||
private static final Predicate<VideoMode> kMinFPSPredicate = (videoMode -> videoMode.fps >= MINIMUM_FPS);
|
||||
private static final Predicate<VideoMode> kMinSizePredicate = (videoMode -> videoMode.width >= MINIMUM_WIDTH && videoMode.height >= MINIMUM_HEIGHT);
|
||||
private static final Predicate<VideoMode> kPixelFormatPredicate = (videoMode -> ALLOWED_PIXEL_FORMATS.contains(videoMode.pixelFormat));
|
||||
|
||||
public CameraStaticProperties staticProperties;
|
||||
public final String name;
|
||||
public final String path;
|
||||
public final double FOV;
|
||||
public final List<VideoMode> videoModes;
|
||||
|
||||
private final UsbCamera baseCamera;
|
||||
|
||||
private String nickname;
|
||||
|
||||
public final boolean hasGain;
|
||||
|
||||
public CameraProperties(UsbCamera baseCamera, CameraConfig config) {
|
||||
FOV = config.fov;
|
||||
name = config.name;
|
||||
path = config.path;
|
||||
nickname = config.nickname;
|
||||
this.baseCamera = baseCamera;
|
||||
|
||||
// wait for camera USB init on Windows, Windows USB is slow...
|
||||
if (Platform.CurrentPlatform == Platform.WINDOWS_64 && !baseCamera.isConnected()) {
|
||||
System.out.print("Waiting on camera... ");
|
||||
long initTimeout = System.nanoTime();
|
||||
while (!baseCamera.isConnected()) {
|
||||
if (((System.nanoTime() - initTimeout) / 1e6) >= MAX_INIT_MS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
var initTimeMs = (System.nanoTime() - initTimeout) / 1e6;
|
||||
System.out.printf("USBCameraProcess initialized in %.2fms\n", initTimeMs);
|
||||
}
|
||||
|
||||
// TODO: find way to determine if camera is a PS3Eye
|
||||
hasGain = false;
|
||||
// var props = baseCamera.enumerateProperties();
|
||||
// for (var prop : props) {
|
||||
// var name = prop.getName();
|
||||
// var min = prop.getMin();
|
||||
// var max = prop.getMax();
|
||||
// var _default = prop.getDefault();
|
||||
// var kind = prop.getKind();
|
||||
// }
|
||||
|
||||
videoModes = filterVideoModes(baseCamera.enumerateVideoModes());
|
||||
}
|
||||
|
||||
public void setNickname(String nickname) {
|
||||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
public String getNickname() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
private List<VideoMode> filterVideoModes(VideoMode[] videoModes) {
|
||||
Predicate<VideoMode> fullPredicate = kMinFPSPredicate.and(kMinSizePredicate).and(kPixelFormatPredicate);
|
||||
Stream<VideoMode> validModes = Arrays.stream(videoModes).filter(fullPredicate);
|
||||
return validModes.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void updateVideoMode(VideoMode videoMode) {
|
||||
staticProperties = new CameraStaticProperties(videoMode.width, videoMode.height, FOV);
|
||||
}
|
||||
|
||||
public double calculatePitch(double PixelY, double centerY) {
|
||||
double pitch = FastMath.toDegrees(FastMath.atan((PixelY - centerY) / staticProperties.verticalFocalLength));
|
||||
return (pitch * -1);
|
||||
}
|
||||
|
||||
public double calculateYaw(double PixelX, double centerX) {
|
||||
return FastMath.toDegrees(FastMath.atan((PixelX - centerX) / staticProperties.horizontalFocalLength));
|
||||
}
|
||||
}
|
||||
package com.chameleonvision.classabstraction.camera;
|
||||
|
||||
import com.chameleonvision.classabstraction.config.CameraConfig;
|
||||
import com.chameleonvision.settings.Platform;
|
||||
import edu.wpi.cscore.UsbCamera;
|
||||
import edu.wpi.cscore.VideoMode;
|
||||
import org.apache.commons.math3.util.FastMath;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class USBCameraProperties {
|
||||
public static final double DEFAULT_FOV = 70;
|
||||
private static final int DEFAULT_EXPOSURE = 50;
|
||||
private 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<VideoMode.PixelFormat> ALLOWED_PIXEL_FORMATS = Arrays.asList(VideoMode.PixelFormat.kYUYV, VideoMode.PixelFormat.kMJPEG);
|
||||
|
||||
private static final Predicate<VideoMode> kMinFPSPredicate = (videoMode -> videoMode.fps >= MINIMUM_FPS);
|
||||
private static final Predicate<VideoMode> kMinSizePredicate = (videoMode -> videoMode.width >= MINIMUM_WIDTH && videoMode.height >= MINIMUM_HEIGHT);
|
||||
private static final Predicate<VideoMode> kPixelFormatPredicate = (videoMode -> ALLOWED_PIXEL_FORMATS.contains(videoMode.pixelFormat));
|
||||
|
||||
public CameraStaticProperties staticProperties;
|
||||
public final String name;
|
||||
public final String path;
|
||||
public final List<VideoMode> videoModes;
|
||||
|
||||
private final UsbCamera baseCamera;
|
||||
|
||||
private String nickname;
|
||||
public double FOV;
|
||||
|
||||
public final boolean hasGain;
|
||||
|
||||
public USBCameraProperties(UsbCamera baseCamera, CameraConfig config) {
|
||||
FOV = config.fov;
|
||||
name = config.name;
|
||||
path = config.path;
|
||||
nickname = config.nickname;
|
||||
this.baseCamera = baseCamera;
|
||||
|
||||
// wait for camera USB init on Windows, Windows USB is slow...
|
||||
if (Platform.CurrentPlatform == Platform.WINDOWS_64 && !baseCamera.isConnected()) {
|
||||
System.out.print("Waiting on camera... ");
|
||||
long initTimeout = System.nanoTime();
|
||||
while (!baseCamera.isConnected()) {
|
||||
if (((System.nanoTime() - initTimeout) / 1e6) >= MAX_INIT_MS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
var initTimeMs = (System.nanoTime() - initTimeout) / 1e6;
|
||||
System.out.printf("USBCameraProcess initialized in %.2fms\n", initTimeMs);
|
||||
}
|
||||
|
||||
// TODO: (low) find way to determine if camera is a PS3Eye
|
||||
hasGain = false;
|
||||
// var props = baseCamera.enumerateProperties();
|
||||
// for (var prop : props) {
|
||||
// var name = prop.getName();
|
||||
// var min = prop.getMin();
|
||||
// var max = prop.getMax();
|
||||
// var _default = prop.getDefault();
|
||||
// var kind = prop.getKind();
|
||||
// }
|
||||
|
||||
videoModes = filterVideoModes(baseCamera.enumerateVideoModes());
|
||||
}
|
||||
|
||||
public void setNickname(String nickname) {
|
||||
this.nickname = nickname;
|
||||
}
|
||||
|
||||
public String getNickname() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
private List<VideoMode> filterVideoModes(VideoMode[] videoModes) {
|
||||
Predicate<VideoMode> fullPredicate = kMinFPSPredicate.and(kMinSizePredicate).and(kPixelFormatPredicate);
|
||||
Stream<VideoMode> validModes = Arrays.stream(videoModes).filter(fullPredicate);
|
||||
return validModes.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public void updateVideoMode(VideoMode videoMode) {
|
||||
staticProperties = new CameraStaticProperties(videoMode.width, videoMode.height, FOV);
|
||||
}
|
||||
|
||||
public double calculatePitch(double PixelY, double centerY) {
|
||||
double pitch = FastMath.toDegrees(FastMath.atan((PixelY - centerY) / staticProperties.verticalFocalLength));
|
||||
return (pitch * -1);
|
||||
}
|
||||
|
||||
public double calculateYaw(double PixelX, double centerX) {
|
||||
return FastMath.toDegrees(FastMath.atan((PixelX - centerX) / staticProperties.horizontalFocalLength));
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.chameleonvision.classabstraction.config;
|
||||
|
||||
import com.chameleonvision.classabstraction.camera.CameraProperties;
|
||||
import com.chameleonvision.classabstraction.camera.USBCameraProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
@@ -23,7 +23,7 @@ public class CameraConfig {
|
||||
}
|
||||
|
||||
public CameraConfig(String path, String name) {
|
||||
this.fov = CameraProperties.DEFAULT_FOV;
|
||||
this.fov = USBCameraProperties.DEFAULT_FOV;
|
||||
this.path = path;
|
||||
this.name = name;
|
||||
this.nickname = name;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.chameleonvision.classabstraction.config;
|
||||
|
||||
import com.chameleonvision.classabstraction.camera.CameraProperties;
|
||||
import com.chameleonvision.classabstraction.camera.USBCameraProperties;
|
||||
import com.chameleonvision.classabstraction.camera.USBCameraProcess;
|
||||
import com.fasterxml.jackson.core.JsonGenerator;
|
||||
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||
@@ -16,7 +16,7 @@ public class CameraSerializer extends StdSerializer<USBCameraProcess> {
|
||||
@Override
|
||||
public void serialize(USBCameraProcess value, JsonGenerator gen, SerializerProvider provider) throws IOException {
|
||||
gen.writeStartObject();
|
||||
CameraProperties camProps = value.getProperties();
|
||||
USBCameraProperties camProps = value.getProperties();
|
||||
gen.writeNumberField("FOV", camProps.FOV);
|
||||
gen.writeStringField("Name", camProps.name);
|
||||
gen.writeStringField("Path", camProps.path);
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
package com.chameleonvision.classabstraction.config;
|
||||
|
||||
import com.chameleonvision.classabstraction.pipeline.PipelineType;
|
||||
|
||||
public class PipelineConfig {
|
||||
public PipelineType type;
|
||||
// TODO: config stuff
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package com.chameleonvision.classabstraction.pipeline;
|
||||
import com.chameleonvision.classabstraction.camera.CameraProcess;
|
||||
import org.opencv.core.Mat;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
@@ -12,20 +13,21 @@ import java.util.function.Supplier;
|
||||
public abstract class CVPipeline<R extends CVPipelineResult, S extends CVPipelineSettings> {
|
||||
protected Mat outputMat = new Mat();
|
||||
CameraProcess cameraProcess;
|
||||
final Supplier<S> settingsSupplier;
|
||||
public final S settings;
|
||||
|
||||
public CVPipeline(Supplier<S> settingsSupplier) {
|
||||
this.settingsSupplier = settingsSupplier;
|
||||
protected CVPipeline(S settings) {
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public S getSettings() {
|
||||
return settingsSupplier.get();
|
||||
protected CVPipeline(String pipelineName, S settings) {
|
||||
this.settings = settings;
|
||||
settings.nickname = pipelineName;
|
||||
}
|
||||
|
||||
public void initPipeline(CameraProcess camera) {
|
||||
cameraProcess = camera;
|
||||
cameraProcess.setExposure((int) getSettings().exposure);
|
||||
cameraProcess.setBrightness((int) getSettings().brightness);
|
||||
cameraProcess.setExposure((int) settings.exposure);
|
||||
cameraProcess.setBrightness((int) settings.brightness);
|
||||
}
|
||||
abstract public R runPipeline(Mat inputMat);
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import org.opencv.core.*;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static com.chameleonvision.classabstraction.pipeline.CVPipeline2d.*;
|
||||
|
||||
@@ -18,8 +17,16 @@ public class CVPipeline2d extends CVPipeline<CVPipeline2dResult, CVPipeline2dSet
|
||||
private Mat rawCameraMat = new Mat();
|
||||
private Mat hsvOutputMat = new Mat();
|
||||
|
||||
public CVPipeline2d(Supplier<CVPipeline2dSettings> settingsSupplier) {
|
||||
super(settingsSupplier);
|
||||
public CVPipeline2d() {
|
||||
super(new CVPipeline2dSettings());
|
||||
}
|
||||
|
||||
public CVPipeline2d(String name) {
|
||||
super(name, new CVPipeline2dSettings());
|
||||
}
|
||||
|
||||
public CVPipeline2d(CVPipeline2dSettings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -32,7 +39,6 @@ public class CVPipeline2d extends CVPipeline<CVPipeline2dResult, CVPipeline2dSet
|
||||
long totalProcessTimeNanos = 0;
|
||||
StringBuilder procTimeStringBuilder = new StringBuilder();
|
||||
|
||||
var settings = settingsSupplier.get();
|
||||
CameraStaticProperties camProps = cameraProcess.getProperties().staticProperties;
|
||||
|
||||
rawCameraMat = inputMat;
|
||||
@@ -104,7 +110,7 @@ public class CVPipeline2d extends CVPipeline<CVPipeline2dResult, CVPipeline2dSet
|
||||
totalProcessTimeNanos += sortContoursResult.getRight();
|
||||
procTimeStringBuilder.append(String.format("SortContours: %.2fms, ", sortContoursResult.getRight() / 1000.0));
|
||||
|
||||
Pair<List<Target>, Long> collect2dTargetsResult = collect2dTargetsPipe.run(sortContoursResult.getLeft());
|
||||
Pair<List<Target2d>, Long> collect2dTargetsResult = collect2dTargetsPipe.run(sortContoursResult.getLeft());
|
||||
totalProcessTimeNanos += collect2dTargetsResult.getRight();
|
||||
procTimeStringBuilder.append(String.format("SortContours: %.2fms, ", sortContoursResult.getRight() / 1000.0));
|
||||
|
||||
@@ -124,13 +130,13 @@ public class CVPipeline2d extends CVPipeline<CVPipeline2dResult, CVPipeline2dSet
|
||||
return new CVPipeline2dResult(collect2dTargetsResult.getLeft(), draw2dContoursResult.getLeft(), totalProcessTimeNanos / 1000);
|
||||
}
|
||||
|
||||
public static class CVPipeline2dResult extends CVPipelineResult<Target> {
|
||||
public CVPipeline2dResult(List<Target> targets, Mat outputMat, long processTime) {
|
||||
public static class CVPipeline2dResult extends CVPipelineResult<Target2d> {
|
||||
public CVPipeline2dResult(List<Target2d> targets, Mat outputMat, long processTime) {
|
||||
super(targets, outputMat, processTime);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Target {
|
||||
public static class Target2d {
|
||||
public double calibratedX = 0.0;
|
||||
public double calibratedY = 0.0;
|
||||
public double pitch = 0.0;
|
||||
|
||||
@@ -10,8 +10,9 @@ import static com.chameleonvision.classabstraction.pipeline.CVPipeline3d.*;
|
||||
|
||||
public class CVPipeline3d extends CVPipeline<CVPipeline3dResult, CVPipeline3dSettings> {
|
||||
|
||||
public CVPipeline3d(Supplier<CVPipeline3dSettings> settingsSupplier) {
|
||||
super(settingsSupplier);
|
||||
|
||||
protected CVPipeline3d(CVPipeline3dSettings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -27,7 +28,6 @@ public class CVPipeline3d extends CVPipeline<CVPipeline3dResult, CVPipeline3dSet
|
||||
}
|
||||
|
||||
public static class Target3d {
|
||||
// TODO: Define 3d-specific target data
|
||||
// TODO: (2.1) Define 3d-specific target data
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
package com.chameleonvision.classabstraction.pipeline;
|
||||
|
||||
public class CVPipeline3dSettings extends CVPipeline2dSettings {
|
||||
// TODO:
|
||||
// TODO: (2.1) define 3d-specific pipeline settings
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import com.chameleonvision.vision.*;
|
||||
@SuppressWarnings("ALL")
|
||||
public class CVPipelineSettings {
|
||||
public ImageFlipMode flipMode = ImageFlipMode.NONE;
|
||||
public String nickname = "";
|
||||
public String nickname = "New Pipeline";
|
||||
public double exposure = 50.0;
|
||||
public double brightness = 50.0;
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ import static com.chameleonvision.classabstraction.pipeline.DriverVisionPipeline
|
||||
|
||||
public class DriverVisionPipeline extends CVPipeline<DriverPipelineResult, CVPipelineSettings> {
|
||||
|
||||
public DriverVisionPipeline(Supplier<CVPipelineSettings> settingsSupplier) {
|
||||
super(settingsSupplier);
|
||||
public DriverVisionPipeline(CVPipelineSettings settings) {
|
||||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,14 +10,14 @@ import org.opencv.core.RotatedRect;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class Collect2dTargetsPipe implements Pipe<List<RotatedRect>, List<CVPipeline2d.Target>> {
|
||||
public class Collect2dTargetsPipe implements Pipe<List<RotatedRect>, List<CVPipeline2d.Target2d>> {
|
||||
|
||||
private final CalibrationMode calibrationMode;
|
||||
private final CameraStaticProperties camProps;
|
||||
private final List<Number> calibrationPoint;
|
||||
private final double calibrationM, calibrationB;
|
||||
|
||||
private List<CVPipeline2d.Target> targets = new ArrayList<>();
|
||||
private List<CVPipeline2d.Target2d> targets = new ArrayList<>();
|
||||
|
||||
public Collect2dTargetsPipe(CalibrationMode calibrationMode, List<Number> calibrationPoint, double calibrationM, double calibrationB, CameraStaticProperties camProps) {
|
||||
this.calibrationMode = calibrationMode;
|
||||
@@ -28,11 +28,11 @@ public class Collect2dTargetsPipe implements Pipe<List<RotatedRect>, List<CVPipe
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<List<CVPipeline2d.Target>, Long> run(List<RotatedRect> input) {
|
||||
public Pair<List<CVPipeline2d.Target2d>, Long> run(List<RotatedRect> input) {
|
||||
long processStartNanos = System.nanoTime();
|
||||
|
||||
input.forEach(r -> {
|
||||
CVPipeline2d.Target t = new CVPipeline2d.Target();
|
||||
CVPipeline2d.Target2d t = new CVPipeline2d.Target2d();
|
||||
t.rawPoint = r;
|
||||
switch (calibrationMode) {
|
||||
case None:
|
||||
|
||||
@@ -19,7 +19,7 @@ public class NetworkInterface {
|
||||
IPAddress = inetAddress.getHostAddress();
|
||||
Netmask = getIPv4LocalNetMask(ifaceAddress);
|
||||
|
||||
// TODO: hack to "get" gateway, this is gross and bad, pls fix
|
||||
// TODO: (low) hack to "get" gateway, this is gross and bad, pls fix
|
||||
var splitIPAddr = IPAddress.split("\\.");
|
||||
splitIPAddr[3] = "1";
|
||||
Gateway = String.join(".", splitIPAddr);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package com.chameleonvision.vision;
|
||||
|
||||
public enum Orientation {
|
||||
Normal,Inverted//TODO add 90 and 270 deg rotation?
|
||||
//TODO: (low) add 90 and 270 deg rotation?
|
||||
Normal,
|
||||
Inverted;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.chameleonvision.classabstraction.pipeline.CVPipeline2d;
|
||||
import com.chameleonvision.classabstraction.pipeline.CVPipeline2dSettings;
|
||||
import com.chameleonvision.classabstraction.pipeline.DriverVisionPipeline;
|
||||
import com.chameleonvision.settings.SettingsManager;
|
||||
import com.chameleonvision.vision.Orientation;
|
||||
import com.chameleonvision.vision.Pipeline;
|
||||
import com.chameleonvision.web.ServerHandler;
|
||||
import edu.wpi.cscore.VideoException;
|
||||
@@ -131,7 +130,7 @@ public class VisionProcess implements Runnable {
|
||||
private PipelineResult runVisionProcess(Mat inputImage, Mat outputImage) {
|
||||
|
||||
if (cvPipeline2d == null) {
|
||||
cvPipeline2d = new CVPipeline2d(() -> pipelineTo2dSettings(currentPipeline));
|
||||
cvPipeline2d = new CVPipeline2d(pipelineTo2dSettings(currentPipeline));
|
||||
}
|
||||
CVPipeline2dResult result = cvPipeline2d.runPipeline(inputImage);
|
||||
result.outputMat.copyTo(outputImage);
|
||||
@@ -145,7 +144,7 @@ public class VisionProcess implements Runnable {
|
||||
pipeResult.Yaw = 0;
|
||||
pipeResult.Area = 0;
|
||||
} else {
|
||||
Target t = result.targets.get(0);
|
||||
Target2d t = result.targets.get(0);
|
||||
pipeResult.CalibratedX = t.calibratedX;
|
||||
pipeResult.CalibratedY = t.calibratedY;
|
||||
pipeResult.Pitch = t.pitch;
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
package com.chameleonvision.web;
|
||||
|
||||
import com.chameleonvision.classabstraction.VisionManager;
|
||||
import com.chameleonvision.classabstraction.VisionProcess;
|
||||
import com.chameleonvision.classabstraction.camera.CameraProcess;
|
||||
import com.chameleonvision.classabstraction.config.ConfigManager;
|
||||
import com.chameleonvision.classabstraction.pipeline.CVPipeline;
|
||||
import com.chameleonvision.classabstraction.pipeline.CVPipelineSettings;
|
||||
import com.chameleonvision.vision.*;
|
||||
import com.chameleonvision.vision.camera.StreamDivisor;
|
||||
import com.chameleonvision.vision.camera.USBCamera;
|
||||
import com.chameleonvision.vision.camera.CameraException;
|
||||
import com.chameleonvision.settings.SettingsManager;
|
||||
@@ -43,9 +48,14 @@ public class ServerHandler {
|
||||
});
|
||||
for (Map.Entry<String, Object> entry : deserialized.entrySet()) {
|
||||
try {
|
||||
var data = (HashMap<String, Object>) entry.getValue();
|
||||
VisionProcess currentProcess = VisionManager.getCurrentUIVisionProcess();
|
||||
CameraProcess currentCamera = currentProcess.getCamera();
|
||||
CVPipeline currentPipeline = currentProcess.getCurrentPipeline();
|
||||
|
||||
switch (entry.getKey()) {
|
||||
case "generalSettings": {
|
||||
for (HashMap.Entry<String, Object> e : ((HashMap<String, Object>) entry.getValue()).entrySet()) {
|
||||
for (HashMap.Entry<String, Object> e : data.entrySet()) {
|
||||
setField(ConfigManager.settings, e.getKey(), e.getValue());
|
||||
}
|
||||
SettingsManager.saveSettings();
|
||||
@@ -53,45 +63,47 @@ public class ServerHandler {
|
||||
break;
|
||||
}
|
||||
case "driverMode": {
|
||||
for (HashMap.Entry<String, Object> e : ((HashMap<String, Object>) entry.getValue()).entrySet()) {
|
||||
setField(VisionManager.getCurrentCamera(), e.getKey(), e.getValue());
|
||||
for (HashMap.Entry<String, Object> e : data.entrySet()) {
|
||||
setField(VisionManager.getCurrentUIVisionProcess(), e.getKey(), e.getValue());
|
||||
}
|
||||
VisionManager.getCurrentCamera().setDriverMode((Boolean) ((HashMap<String, Object>) entry.getValue()).get("isDriver"));
|
||||
VisionManager.saveCameras();
|
||||
VisionManager.getCurrentUIVisionProcess().setDriverMode((Boolean) data.get("isDriver"));
|
||||
|
||||
// TODO: (HIGH) create saveCameras() function in VisionManager
|
||||
// VisionManager.saveCameras();
|
||||
break;
|
||||
}
|
||||
case "cameraSettings": {
|
||||
HashMap camSettings = (HashMap) entry.getValue();
|
||||
var curCam = VisionManager.getCurrentCamera();
|
||||
|
||||
Number newFOV = (Number) camSettings.get("fov");
|
||||
Integer newStreamDivisor = (Integer) camSettings.get("streamDivisor");
|
||||
StreamDivisor newStreamDivisor = StreamDivisor.values()[(Integer) camSettings.get("streamDivisor")];
|
||||
Integer newResolution = (Integer) camSettings.get("resolution");
|
||||
|
||||
curCam.setFOV(newFOV);
|
||||
currentCamera.getProperties().FOV = (double) newFOV;
|
||||
|
||||
var currentStreamDivisorOrdinal = curCam.getStreamDivisor().ordinal();
|
||||
if (currentStreamDivisorOrdinal != newStreamDivisor) {
|
||||
curCam.setStreamDivisor(newStreamDivisor, true);
|
||||
if (currentProcess.cameraStreamer.getDivisor() != newStreamDivisor) {
|
||||
currentProcess.cameraStreamer.setDivisor(newStreamDivisor);
|
||||
}
|
||||
|
||||
var currentResolutionIndex = curCam.getVideoModeIndex();
|
||||
if (currentResolutionIndex != newResolution) {
|
||||
curCam.setCamVideoMode(newResolution, true);
|
||||
}
|
||||
// TODO (HIGH) get and set video modes!
|
||||
// var currentResolutionIndex = currentPipeline.getVideoModeIndex();
|
||||
// if (currentResolutionIndex != newResolution) {
|
||||
// currentCamera.getProperties().setCamVideoMode(newResolution, true);
|
||||
// }
|
||||
|
||||
VisionManager.saveCameras();
|
||||
// TODO: (HIGH) create saveCameras() function in VisionManager
|
||||
// VisionManager.saveCameras();
|
||||
sendFullSettings();
|
||||
break;
|
||||
}
|
||||
case "changeCameraName": {
|
||||
VisionManager.getCurrentCamera().setNickname((String) entry.getValue());
|
||||
currentCamera.getProperties().setNickname((String) entry.getValue());
|
||||
sendFullSettings();
|
||||
SettingsManager.saveSettings();
|
||||
break;
|
||||
}
|
||||
case "changePipelineName": {
|
||||
VisionManager.getCurrentPipeline().nickname = (String) entry.getValue();
|
||||
currentPipeline.settings.nickname = ((String) entry.getValue());
|
||||
sendFullSettings();
|
||||
SettingsManager.saveSettings();
|
||||
break;
|
||||
@@ -101,38 +113,44 @@ public class ServerHandler {
|
||||
int pipelineIndex = (int) pipelineVals.get("pipeline");
|
||||
int cameraIndex = (int) pipelineVals.get("camera");
|
||||
|
||||
Pipeline origPipeline = VisionManager.getCurrentCamera().getPipelineByIndex(pipelineIndex);
|
||||
CVPipeline origPipeline = currentProcess.getPipelineByIndex(pipelineIndex);
|
||||
|
||||
if (cameraIndex != -1) {
|
||||
VisionManager.getCameraByIndex(cameraIndex).addPipeline(origPipeline);
|
||||
VisionProcess newProcess = VisionManager.getVisionProcessByIndex(cameraIndex);
|
||||
if(newProcess != null) {
|
||||
newProcess.addPipeline(origPipeline);
|
||||
}
|
||||
} else {
|
||||
VisionManager.getCurrentCamera().addPipeline(origPipeline);
|
||||
currentProcess.addPipeline(origPipeline);
|
||||
}
|
||||
// TODO: (HIGH) switch to ConfigManager
|
||||
SettingsManager.saveSettings();
|
||||
break;
|
||||
}
|
||||
case "command": {
|
||||
var cam = VisionManager.getCurrentCamera();
|
||||
switch ((String) entry.getValue()) {
|
||||
case "addNewPipeline":
|
||||
cam.addPipeline();
|
||||
currentProcess.addPipeline();
|
||||
sendFullSettings();
|
||||
// TODO: (HIGH) switch to ConfigManager
|
||||
SettingsManager.saveSettings();
|
||||
break;
|
||||
// TODO: (HIGH) this never worked before, re-visit now that VisionProcess is written sanely
|
||||
case "deleteCurrentPipeline":
|
||||
int currentIndex = cam.getCurrentPipelineIndex();
|
||||
int nextIndex;
|
||||
if (currentIndex == cam.getPipelines().size() - 1) {
|
||||
nextIndex = currentIndex - 1;
|
||||
} else {
|
||||
nextIndex = currentIndex;
|
||||
}
|
||||
cam.deletePipeline();
|
||||
cam.setCurrentPipelineIndex(nextIndex);
|
||||
sendFullSettings();
|
||||
SettingsManager.saveSettings();
|
||||
// int currentIndex = currentProcess.getCurrentPipelineIndex();
|
||||
// int nextIndex;
|
||||
// if (currentIndex == currentProcess.getPipelines().size() - 1) {
|
||||
// nextIndex = currentIndex - 1;
|
||||
// } else {
|
||||
// nextIndex = currentIndex;
|
||||
// }
|
||||
// cam.deletePipeline();
|
||||
// cam.setCurrentPipelineIndex(nextIndex);
|
||||
// sendFullSettings();
|
||||
// SettingsManager.saveSettings();
|
||||
break;
|
||||
case "save":
|
||||
// TODO: (HIGH) switch to ConfigManager
|
||||
SettingsManager.saveSettings();
|
||||
System.out.println("saved Settings");
|
||||
break;
|
||||
@@ -141,30 +159,31 @@ public class ServerHandler {
|
||||
break;
|
||||
}
|
||||
case "currentCamera": {
|
||||
VisionManager.setCurrentCamera((Integer) entry.getValue());
|
||||
// TODO: (HIGH) find way to map cameras to indexes
|
||||
VisionManager.setCurrentProcessByIndex((Integer) entry.getValue());
|
||||
sendFullSettings();
|
||||
break;
|
||||
}
|
||||
case "currentPipeline": {
|
||||
var cam = VisionManager.getCurrentCamera();
|
||||
cam.setCurrentPipelineIndex((Integer) entry.getValue());
|
||||
currentProcess.setPipeline((Integer) entry.getValue());
|
||||
sendFullSettings();
|
||||
try {
|
||||
cam.setBrightness(cam.getCurrentPipeline().brightness);
|
||||
cam.setExposure(cam.getCurrentPipeline().exposure);
|
||||
currentCamera.setBrightness((int) currentPipeline.settings.brightness);
|
||||
currentCamera.setExposure((int) currentPipeline.settings.exposure);
|
||||
} catch (Exception e) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
setField(VisionManager.getCurrentCamera().getCurrentPipeline(), entry.getKey(), entry.getValue());
|
||||
setField(currentPipeline.settings, entry.getKey(), entry.getValue());
|
||||
|
||||
switch (entry.getKey()) {
|
||||
case "exposure": {
|
||||
VisionManager.getCurrentCamera().setExposure((Integer) entry.getValue());
|
||||
currentCamera.setExposure((Integer) entry.getValue());
|
||||
}
|
||||
case "brightness": {
|
||||
VisionManager.getCurrentCamera().setBrightness((Integer) entry.getValue());
|
||||
currentCamera.setBrightness((Integer) entry.getValue());
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -180,7 +199,9 @@ public class ServerHandler {
|
||||
private void setField(Object obj, String fieldName, Object value) {
|
||||
try {
|
||||
if (obj instanceof USBCamera) {
|
||||
var cam = (USBCamera)obj;
|
||||
// TODO: (HIGH) FIXXX!!!! this won't work anymore
|
||||
// the UI should instead understand that DriverMode is a pipeline (?)
|
||||
USBCamera cam = (USBCamera)obj;
|
||||
if (fieldName.equals("driverBrightness")) {
|
||||
cam.setDriverBrightness((Integer)value);
|
||||
} else if (fieldName.equals("driverExposure")) {
|
||||
@@ -199,7 +220,7 @@ public class ServerHandler {
|
||||
|
||||
private static void broadcastMessage(Object obj, WsContext userToSkip) {
|
||||
if (users != null)
|
||||
for (var user : users) {
|
||||
for (WsContext user : users) {
|
||||
if (userToSkip != null && user.getSessionId().equals(userToSkip.getSessionId())) {
|
||||
continue;
|
||||
}
|
||||
@@ -220,9 +241,9 @@ public class ServerHandler {
|
||||
HashMap<String, Object> tmp = new HashMap<>();
|
||||
for (Field f : Pipeline.class.getFields()) {
|
||||
if (!f.getType().isEnum()) {
|
||||
tmp.put(f.getName(), f.get(VisionManager.getCurrentCamera().getCurrentPipeline()));
|
||||
tmp.put(f.getName(), f.get(VisionManager.getCurrentUIVisionProcess().getCurrentPipeline()));
|
||||
} else {
|
||||
var i = (Enum) f.get(VisionManager.getCurrentCamera().getCurrentPipeline());
|
||||
var i = (Enum) f.get(VisionManager.getCurrentUIVisionProcess().getCurrentPipeline());
|
||||
tmp.put(f.getName(), i.ordinal());
|
||||
}
|
||||
}
|
||||
@@ -242,27 +263,22 @@ public class ServerHandler {
|
||||
|
||||
private static HashMap<String, Object> getOrdinalCameraSettings() {
|
||||
HashMap<String, Object> tmp = new HashMap<>();
|
||||
try {
|
||||
var currentCamera = VisionManager.getCurrentCamera();
|
||||
tmp.put("fov", currentCamera.getFOV());
|
||||
tmp.put("streamDivisor", currentCamera.getStreamDivisor().ordinal());
|
||||
tmp.put("resolution", currentCamera.getVideoModeIndex());
|
||||
} catch (CameraException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
VisionProcess currentVisionProcess = VisionManager.getCurrentUIVisionProcess();
|
||||
CameraProcess currentCamera = VisionManager.getCurrentUIVisionProcess().getCamera();
|
||||
tmp.put("fov", currentCamera.getProperties().FOV);
|
||||
tmp.put("streamDivisor", currentVisionProcess.cameraStreamer.getDivisor().ordinal());
|
||||
// TODO: (HIGH) get videomode index!
|
||||
// tmp.put("resolution", currentCamera.getVideoModeIndex());
|
||||
return tmp;
|
||||
}
|
||||
|
||||
private static HashMap<String, Object> getOrdinalDriver() {
|
||||
HashMap<String, Object> tmp = new HashMap<>();
|
||||
try {
|
||||
var currentCamera = VisionManager.getCurrentCamera();
|
||||
tmp.put("isDriver", currentCamera.getDriverMode());
|
||||
tmp.put("driverBrightness", currentCamera.getDriverBrightness());
|
||||
tmp.put("driverExposure", currentCamera.getDriverExposure());
|
||||
} catch (CameraException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
VisionProcess currentProcess = VisionManager.getCurrentUIVisionProcess();
|
||||
CVPipelineSettings driverModeSettings = currentProcess.getDriverModeSettings();
|
||||
tmp.put("isDriver", currentProcess.getDriverMode());
|
||||
tmp.put("driverBrightness", driverModeSettings.brightness);
|
||||
tmp.put("driverExposure", driverModeSettings.exposure);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@@ -272,15 +288,16 @@ public class ServerHandler {
|
||||
try {
|
||||
fullSettings.put("settings", getOrdinalSettings());
|
||||
fullSettings.put("cameraSettings", getOrdinalCameraSettings());
|
||||
fullSettings.put("cameraList", VisionManager.getAllCameraByNickname());
|
||||
fullSettings.put("cameraList", VisionManager.getAllCameraNicknames());
|
||||
fullSettings.put("pipeline", getOrdinalPipeline());
|
||||
var currentCamera = VisionManager.getCurrentCamera();
|
||||
var currentVisionProcess = VisionManager.getCurrentUIVisionProcess();
|
||||
fullSettings.put("driverMode",getOrdinalDriver());
|
||||
fullSettings.put("pipelineList", currentCamera.getPipelinesNickname());
|
||||
fullSettings.put("resolutionList", currentCamera.getResolutionList());
|
||||
fullSettings.put("port", currentCamera.getStreamPort());
|
||||
fullSettings.put("currentPipelineIndex", VisionManager.getCurrentCamera().getCurrentPipelineIndex());
|
||||
fullSettings.put("currentCameraIndex", VisionManager.getCurrentCameraIndex());
|
||||
// TODO (HIGH) all of these settings!
|
||||
// fullSettings.put("pipelineList", currentVisionProcess.getPipelinesNickname());
|
||||
// fullSettings.put("resolutionList", currentVisionProcess.getResolutionList());
|
||||
// fullSettings.put("port", currentVisionProcess.getStreamPort());
|
||||
fullSettings.put("currentPipelineIndex", VisionManager.getCurrentUIVisionProcess().getCurrentPipelineIndex());
|
||||
// fullSettings.put("currentCameraIndex", VisionManager.getCurrentCameraIndex());
|
||||
} catch (CameraException | IllegalAccessException e) {
|
||||
System.err.println("No camera found!");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user