Camera configuration rewrite, begin on CameraStreamer threading fix

This commit is contained in:
Banks Troutman
2019-11-26 17:57:51 -05:00
parent 6506281ddf
commit d588b1a69e
11 changed files with 293 additions and 173 deletions

View File

@@ -1,7 +1,8 @@
package com.chameleonvision.vision;
import com.chameleonvision.config.CameraConfig;
import com.chameleonvision.config.CameraJsonConfig;
import com.chameleonvision.config.ConfigManager;
import com.chameleonvision.config.FullCameraConfiguration;
import com.chameleonvision.util.Helpers;
import com.chameleonvision.util.Platform;
import com.chameleonvision.vision.camera.CameraCapture;
@@ -20,7 +21,7 @@ public class VisionManager {
}
private static final LinkedHashMap<String, UsbCameraInfo> usbCameraInfosByCameraName = new LinkedHashMap<>();
private static final LinkedList<CameraConfig> loadedCameraConfigs = new LinkedList<>();
private static final LinkedList<FullCameraConfiguration> loadedCameraConfigs = new LinkedList<>();
private static final LinkedList<VisionProcessManageable> visionProcesses = new LinkedList<>();
private static class VisionProcessManageable {
@@ -57,7 +58,7 @@ public class VisionManager {
}
// load the config
List<CameraConfig> preliminaryConfigs = new ArrayList<>();
List<CameraJsonConfig> preliminaryConfigs = new ArrayList<>();
usbCameraInfosByCameraName.values().forEach((cameraInfo) -> {
String truePath;
@@ -68,10 +69,10 @@ public class VisionManager {
truePath = Arrays.stream(cameraInfo.otherPaths).filter(x -> x.contains("/dev/v4l/by-path")).findFirst().orElse(cameraInfo.path);
}
preliminaryConfigs.add(new CameraConfig(truePath, cameraInfo.name));
preliminaryConfigs.add(new CameraJsonConfig(truePath, cameraInfo.name));
});
loadedCameraConfigs.addAll(ConfigManager.initializeCameraConfig(preliminaryConfigs));
loadedCameraConfigs.addAll(ConfigManager.initializeCameras(preliminaryConfigs));
// TODO: (HIGH) Load pipelines from json
// UsbCameraInfosByCameraName.forEach((cameraName, cameraInfo) -> {
@@ -85,10 +86,15 @@ public class VisionManager {
public static boolean initializeProcesses() {
for (int i = 0; i < loadedCameraConfigs.size(); i++) {
CameraConfig config = loadedCameraConfigs.get(i);
CameraCapture camera = new USBCameraCapture(config);
VisionProcess process = new VisionProcess(camera, config.name);
visionProcesses.add(new VisionProcessManageable(i, config.name, process));
FullCameraConfiguration config = loadedCameraConfigs.get(i);
CameraJsonConfig cameraJsonConfig = config.cameraConfig;
CameraCapture camera = new USBCameraCapture(cameraJsonConfig);
VisionProcess process = new VisionProcess(camera, cameraJsonConfig.name);
config.pipelines.forEach(process::addPipeline);
process.setDriverModeSettings(config.drivermode);
visionProcesses.add(new VisionProcessManageable(i, cameraJsonConfig.name, process));
}
currentUIVisionProcess = getVisionProcessByIndex(0);
return true;
@@ -136,14 +142,10 @@ public class VisionManager {
String cameraName = process.getCamera().getProperties().name;
List<CVPipelineSettings> pipelines = process.getPipelines().stream().map(cvPipeline -> cvPipeline.settings).collect(Collectors.toList());
CVPipelineSettings driverMode = process.getDriverModeSettings();
CameraConfig config = CameraConfig.fromUSBCameraProcess((USBCameraCapture) process.getCamera());
try {
ConfigManager.saveCameraPipelines(cameraName, pipelines);
ConfigManager.saveCameraDriverMode(cameraName, driverMode);
ConfigManager.saveCameraConfig(cameraName, config);
} catch (IOException e) {
e.printStackTrace();
}
CameraJsonConfig config = CameraJsonConfig.fromUSBCameraProcess((USBCameraCapture) process.getCamera());
ConfigManager.saveCameraPipelines(cameraName, pipelines);
ConfigManager.saveCameraDriverMode(cameraName, driverMode);
ConfigManager.saveCameraConfig(cameraName, config);
});
}

View File

@@ -17,6 +17,8 @@ import org.opencv.core.Mat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
public class VisionProcess {
@@ -29,11 +31,12 @@ public class VisionProcess {
private CVPipeline currentPipeline;
private int currentPipelineIndex = 0;
private final CVPipelineSettings driverModeSettings = new CVPipelineSettings();
private CVPipeline driverModePipeline = new DriverVisionPipeline(driverModeSettings);
private CVPipeline driverModePipeline = new DriverVisionPipeline(new CVPipelineSettings());
private volatile CVPipelineResult lastPipelineResult;
BlockingQueue<Mat> streamFrameQueue = new LinkedBlockingDeque<>(1);
// network table stuff
private final NetworkTable defaultTable;
private NetworkTableEntry ntPipelineEntry;
@@ -240,6 +243,12 @@ public class VisionProcess {
pipelines.add(pipeline);
}
public void addPipeline(CVPipelineSettings settings) {
if (settings instanceof CVPipeline2dSettings) {
pipelines.add(new CVPipeline2d((CVPipeline2dSettings) settings));
}
}
public CameraCapture getCamera() {
return cameraCapture;
}
@@ -248,6 +257,11 @@ public class VisionProcess {
return (currentPipeline == driverModePipeline);
}
public void setDriverModeSettings(CVPipelineSettings settings) {
driverModePipeline.settings = settings;
}
public CVPipelineSettings getDriverModeSettings() {
return driverModePipeline.settings;
}
@@ -285,6 +299,12 @@ public class VisionProcess {
}
}
try {
streamFrameQueue.add(lastPipelineResult.outputMat);
} catch (Exception e) {
System.out.println("Vision running faster than stream");
}
var deltaTimeNanos = lastUpdateTimeNanos - System.nanoTime();
fpsAveragingBuffer.addFirst(1.0 / (deltaTimeNanos * 1E-09));
lastUpdateTimeNanos = System.nanoTime();
@@ -310,25 +330,13 @@ public class VisionProcess {
private CameraStreamerRunnable(int cameraFPS, CameraStreamer streamer) {
// add 2 FPS to allow for a bit of overhead
// TODO: (low) test the effect of this
// super(1000L/(cameraFPS + 2));
super(10L);
super(1000L/(cameraFPS + 2));
this.streamer = streamer;
}
@Override
protected void process() {
// System.out.println("running camera streamer");
// Mat latestMat = lastPipelineResult.outputMat; //visionRunnable.result;
// if (latestMat != null && latestMat.cols() > 0) {
// latestMat.copyTo(streamBuffer);
// streamer.runStream(streamBuffer);
// streamBuffer.release();
// if (toStreamMat != null && toStreamMat.cols() > 0) {
// } else {
// System.out.println("fuuuuck");
// }
// }
}
}
}

View File

@@ -1,6 +1,6 @@
package com.chameleonvision.vision.camera;
import com.chameleonvision.config.CameraConfig;
import com.chameleonvision.config.CameraJsonConfig;
import edu.wpi.cscore.CvSink;
import edu.wpi.cscore.UsbCamera;
import edu.wpi.cscore.VideoException;
@@ -15,7 +15,7 @@ public class USBCameraCapture implements CameraCapture {
private Mat imageBuffer = new Mat();
private USBCameraProperties properties;
public USBCameraCapture(CameraConfig config) {
public USBCameraCapture(CameraJsonConfig config) {
baseCamera = new UsbCamera(config.name, config.path);
cvSink = CameraServer.getInstance().getVideo(baseCamera);
properties = new USBCameraProperties(baseCamera, config);

View File

@@ -1,6 +1,6 @@
package com.chameleonvision.vision.camera;
import com.chameleonvision.config.CameraConfig;
import com.chameleonvision.config.CameraJsonConfig;
import com.chameleonvision.util.Platform;
import com.chameleonvision.vision.image.CaptureProperties;
import edu.wpi.cscore.UsbCamera;
@@ -40,7 +40,7 @@ public class USBCameraProperties extends CaptureProperties {
private String nickname;
public double FOV;
USBCameraProperties(UsbCamera baseCamera, CameraConfig config) {
USBCameraProperties(UsbCamera baseCamera, CameraJsonConfig config) {
FOV = config.fov;
name = config.name;
path = config.path;

View File

@@ -10,7 +10,7 @@ import org.opencv.core.Mat;
public abstract class CVPipeline<R extends CVPipelineResult, S extends CVPipelineSettings> {
protected Mat outputMat = new Mat();
CameraCapture cameraCapture;
public final S settings;
public S settings;
protected CVPipeline(S settings) {
this.settings = settings;