Config fixes, add JUnit maven dependency, potential fix for stream latency

This commit is contained in:
Banks Troutman
2019-11-27 14:59:36 -05:00
parent e195cce026
commit 6b5bd75dbe
15 changed files with 110 additions and 62 deletions

View File

@@ -0,0 +1,19 @@
package com.chameleonvision;
public class Debug {
private Debug() {}
private static boolean isTestMode() {
return Main.testMode;
}
public static void printInfo(String infoMessage) {
if (isTestMode()) {
System.out.println(infoMessage);
}
}
public static void printInfo(String smallInfo, String largeInfo) {
System.out.println(isTestMode() ? String.format("%s - %s" , smallInfo, largeInfo) : smallInfo);
}
}

View File

@@ -30,7 +30,7 @@ public class Main {
private static boolean manageNetwork = true;
private static boolean ignoreRoot = false;
private static String ntClientModeServer = null;
private static boolean testMode = false;
public static boolean testMode = false;
private static class NTLogger implements Consumer<LogMessage> {
@@ -77,12 +77,12 @@ public class Main {
if (value != null) {
if (value.equals("localhost")) {
ntClientModeServer = "127.0.0.1";
return;
continue;
}
if (Utilities.isValidIPV4(value)) {
ntClientModeServer = value;
return;
continue;
}
}
System.err.println("Argument for NT Server Host was invalid, defaulting to team number host");

View File

@@ -31,7 +31,6 @@ public class CameraConfig {
checkPipelines();
checkDriverMode();
// todo: add pipelines and drivermode loads
return loadConfig();
}

View File

@@ -29,10 +29,12 @@ public class ConfigManager {
private static void checkSettingsFolder() {
if (!settingsFolderExists()) {
try {
new File(SettingsPath.toUri()).mkdirs();
if( !(new File(SettingsPath.toUri()).mkdirs()) ) {
System.err.println("Failed to create settings folder: " + SettingsPath.toString());
}
Files.createDirectory(SettingsPath);
} catch (IOException e) {
if(!(e instanceof java.nio.file.FileAlreadyExistsException || e instanceof java.nio.file.FileAlreadyExistsException))
if(!(e instanceof java.nio.file.FileAlreadyExistsException))
e.printStackTrace();
}
}
@@ -74,7 +76,6 @@ public class ConfigManager {
saveSettingsFile();
}
// TODO: (HIGH) cleanup!
public static List<FullCameraConfiguration> initializeCameras(List<CameraJsonConfig> preliminaryConfigs) {
List<FullCameraConfiguration> configList = new ArrayList<>();
@@ -96,14 +97,17 @@ public class ConfigManager {
}
public static void saveCameraConfig(String cameraName, CameraJsonConfig config) {
cameraConfigs.get(cameraName).saveConfig(config);
var camConf = cameraConfigs.get(cameraName);
camConf.saveConfig(config);
}
public static void saveCameraPipelines(String cameraName, List<CVPipelineSettings> pipelines) {
cameraConfigs.get(cameraName).savePipelines(pipelines);
var camConf = cameraConfigs.get(cameraName);
camConf.savePipelines(pipelines);
}
public static void saveCameraDriverMode(String cameraName, CVPipelineSettings driverMode) {
cameraConfigs.get(cameraName).saveDriverMode(driverMode);
var camConf = cameraConfigs.get(cameraName);
camConf.saveDriverMode(driverMode);
}
}

View File

@@ -138,7 +138,7 @@ public class VisionManager {
}
public static void saveCameras() {
public static void saveAllCameras() {
visionProcesses.forEach((vpm) -> {
VisionProcess process = vpm.visionProcess;
String cameraName = process.getCamera().getProperties().name;

View File

@@ -1,5 +1,7 @@
package com.chameleonvision.vision;
import com.chameleonvision.Debug;
import com.chameleonvision.Main;
import com.chameleonvision.config.ConfigManager;
import com.chameleonvision.util.LoopingRunnable;
import com.chameleonvision.vision.camera.CameraCapture;
@@ -263,7 +265,6 @@ public class VisionProcess {
}
public void setDriverModeSettings(CVPipelineSettings settings) {
driverModePipeline.settings = settings;
}
@@ -282,7 +283,6 @@ public class VisionProcess {
volatile Double fps = 0.0;
private CircularBuffer fpsAveragingBuffer = new CircularBuffer(7);
private Mat streamBuffer = new Mat();
@Override
public void run() {
@@ -305,9 +305,10 @@ public class VisionProcess {
}
try {
streamFrameQueue.clear();
streamFrameQueue.add(lastPipelineResult.outputMat);
} catch (Exception e) {
System.out.println("Vision running faster than stream");
Debug.printInfo("Vision running faster than stream.");
}
var deltaTimeNanos = lastUpdateTimeNanos - System.nanoTime();
@@ -340,17 +341,12 @@ public class VisionProcess {
@Override
protected void process() {
try {
if (!streamFrameQueue.isEmpty()) {
Mat latestMat = streamFrameQueue.take();
if (!latestMat.empty()) {
streamer.runStream(latestMat);
} else {
System.out.println("stream mat empty");
}
if (!streamFrameQueue.isEmpty()) {
try {
streamer.runStream(streamFrameQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

View File

@@ -2,7 +2,7 @@ package com.chameleonvision.vision.enums;
import org.opencv.core.Core;
public enum ImageRotation {
public enum ImageRotationMode {
DEG_0(-1),
DEG_90(Core.ROTATE_90_CLOCKWISE),
DEG_180(Core.ROTATE_180),
@@ -10,7 +10,7 @@ public enum ImageRotation {
public final int value;
ImageRotation(int value) {
ImageRotationMode(int value) {
this.value = value;
}
}

View File

@@ -1,7 +0,0 @@
package com.chameleonvision.vision.enums;
public enum Orientation {
//TODO: (low) add 90 and 270 deg rotation?
Normal,
Inverted;
}

View File

@@ -1,12 +1,12 @@
package com.chameleonvision.vision.pipeline;
import com.chameleonvision.Main;
import com.chameleonvision.vision.camera.CameraCapture;
import com.chameleonvision.vision.camera.CaptureStaticProperties;
import com.chameleonvision.vision.pipeline.pipes.*;
import com.chameleonvision.vision.enums.ImageRotation;
import com.chameleonvision.vision.enums.ImageRotationMode;
import org.apache.commons.lang3.tuple.Pair;
import org.opencv.core.*;
import org.opencv.imgproc.Imgproc;
import java.util.List;
@@ -55,7 +55,7 @@ public class CVPipeline2d extends CVPipeline<CVPipeline2dResult, CVPipeline2dSet
hsvLower = new Scalar(settings.hue.get(0).intValue(), settings.saturation.get(0).intValue(), settings.value.get(0).intValue());
hsvUpper = new Scalar(settings.hue.get(1).intValue(), settings.saturation.get(1).intValue(), settings.value.get(1).intValue());
rotateFlipPipe = new RotateFlipPipe(ImageRotation.DEG_0, settings.flipMode);
rotateFlipPipe = new RotateFlipPipe(ImageRotationMode.DEG_0, settings.flipMode);
blurPipe = new BlurPipe(5);
erodeDilatePipe = new ErodeDilatePipe(settings.erode, settings.dilate, 7);
hsvPipe = new HsvPipe(hsvLower, hsvUpper);
@@ -63,7 +63,7 @@ public class CVPipeline2d extends CVPipeline<CVPipeline2dResult, CVPipeline2dSet
filterContoursPipe = new FilterContoursPipe(settings.area, settings.ratio, settings.extent, camProps);
speckleRejectPipe = new SpeckleRejectPipe(settings.speckle.doubleValue());
groupContoursPipe = new GroupContoursPipe(settings.targetGroup, settings.targetIntersection);
sortContoursPipe = new SortContoursPipe(settings.sortMode, camProps);
sortContoursPipe = new SortContoursPipe(settings.sortMode, camProps, 5);
collect2dTargetsPipe = new Collect2dTargetsPipe(settings.calibrationMode, settings.point,
settings.dualTargetCalibrationM, settings.dualTargetCalibrationB, camProps);
draw2dContoursSettings = new Draw2dContoursPipe.Draw2dContoursSettings();
@@ -96,14 +96,14 @@ public class CVPipeline2d extends CVPipeline<CVPipeline2dResult, CVPipeline2dSet
// prepare pipes
hsvLower = new Scalar(settings.hue.get(0).intValue(), settings.saturation.get(0).intValue(), settings.value.get(0).intValue());
hsvUpper = new Scalar(settings.hue.get(1).intValue(), settings.saturation.get(1).intValue(), settings.value.get(1).intValue());
rotateFlipPipe.setConfig(ImageRotation.DEG_0, settings.flipMode);
rotateFlipPipe.setConfig(ImageRotationMode.DEG_0, settings.flipMode);
blurPipe.setConfig(0);
erodeDilatePipe.setConfig(settings.erode, settings.dilate, 7);
hsvPipe.setConfig(hsvLower, hsvUpper);
filterContoursPipe.setConfig(settings.area, settings.ratio, settings.extent, camProps);
speckleRejectPipe.setConfig(settings.speckle.doubleValue());
groupContoursPipe.setConfig(settings.targetGroup, settings.targetIntersection);
sortContoursPipe.setConfig(settings.sortMode, camProps);
sortContoursPipe.setConfig(settings.sortMode, camProps, 5);
collect2dTargetsPipe.setConfig(settings.calibrationMode, settings.point,
settings.dualTargetCalibrationM, settings.dualTargetCalibrationB, camProps);
draw2dContoursPipe.setConfig(camProps);
@@ -164,7 +164,7 @@ public class CVPipeline2d extends CVPipeline<CVPipeline2dResult, CVPipeline2dSet
pipelineTimeStringBuilder.append(String.format("OutputMat: %.2fms, ", outputMatResult.getRight() / 1000000.0));
pipelineTimeStringBuilder.append(String.format("Draw2dContours: %.2fms, ", draw2dContoursResult.getRight() / 1000000.0));
if (true) {
if (Main.testMode) {
System.out.println(pipelineTimeStringBuilder.toString());
double totalPipelineTimeMillis = totalPipelineTimeNanos / 1000000.0;
double totalPipelineTimeFPS = 1.0 / (totalPipelineTimeMillis / 1000.0);

View File

@@ -1,25 +1,25 @@
package com.chameleonvision.vision.pipeline.pipes;
import com.chameleonvision.vision.enums.ImageFlipMode;
import com.chameleonvision.vision.enums.ImageRotation;
import com.chameleonvision.vision.enums.ImageRotationMode;
import org.apache.commons.lang3.tuple.Pair;
import org.opencv.core.Core;
import org.opencv.core.Mat;
public class RotateFlipPipe implements Pipe<Mat, Mat> {
private ImageRotation rotation;
private ImageRotationMode rotation;
private ImageFlipMode flip;
private Mat processBuffer = new Mat();
private Mat outputMat = new Mat();
public RotateFlipPipe(ImageRotation rotation, ImageFlipMode flip) {
public RotateFlipPipe(ImageRotationMode rotation, ImageFlipMode flip) {
this.rotation = rotation;
this.flip = flip;
}
public void setConfig(ImageRotation rotation, ImageFlipMode flip) {
public void setConfig(ImageRotationMode rotation, ImageFlipMode flip) {
this.rotation = rotation;
this.flip = flip;
}
@@ -29,7 +29,7 @@ public class RotateFlipPipe implements Pipe<Mat, Mat> {
long processStartNanos = System.nanoTime();
boolean shouldFlip = !flip.equals(ImageFlipMode.NONE);
boolean shouldRotate = !rotation.equals(ImageRotation.DEG_0);
boolean shouldRotate = !rotation.equals(ImageRotationMode.DEG_0);
if (shouldFlip || shouldRotate) {
input.copyTo(processBuffer);

View File

@@ -23,20 +23,22 @@ public class SortContoursPipe implements Pipe<List<RotatedRect>, List<RotatedRec
private static final Comparator<RotatedRect> SortByLeftmostComparator = Comparator.comparingDouble(rect -> rect.center.x);
private static final Comparator<RotatedRect> SortByRightmostComparator = SortByLeftmostComparator.reversed();
private SortMode sort;
private CaptureStaticProperties camProps;
private int maxTargets;
private List<RotatedRect> sortedContours = new ArrayList<>();
public SortContoursPipe(SortMode sort, CaptureStaticProperties camProps) {
public SortContoursPipe(SortMode sort, CaptureStaticProperties camProps, int maxTargets) {
this.sort = sort;
this.camProps = camProps;
this.maxTargets = maxTargets;
}
public void setConfig(SortMode sort, CaptureStaticProperties camProps) {
public void setConfig(SortMode sort, CaptureStaticProperties camProps, int maxTargets) {
this.sort = sort;
this.camProps = camProps;
this.maxTargets = maxTargets;
}
@Override
@@ -46,7 +48,7 @@ public class SortContoursPipe implements Pipe<List<RotatedRect>, List<RotatedRec
sortedContours.clear();
if (input.size() > 0) {
sortedContours.addAll(input);
sortedContours.addAll(input.subList(0, Math.min(input.size(), maxTargets - 1)));
switch (sort) {
case Largest:

View File

@@ -147,7 +147,8 @@ public class ServerHandler {
break;
case "save":
ConfigManager.saveGeneralSettings();
System.out.println("saved Settings");
VisionManager.saveAllCameras();
System.out.println("Saved Settings");
break;
}
// used to define all incoming commands
@@ -168,9 +169,11 @@ public class ServerHandler {
switch (entry.getKey()) {
case "exposure": {
currentCamera.setExposure((Integer) entry.getValue());
VisionManager.saveCurrentCameraPipelines();
}
case "brightness": {
currentCamera.setBrightness((Integer) entry.getValue());
VisionManager.saveCurrentCameraPipelines();
}
}
break;