mirror of
https://github.com/PhotonVision/photonvision
synced 2026-06-21 01:01:41 +00:00
Camera configuration rewrite, begin on CameraStreamer threading fix
This commit is contained in:
@@ -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);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -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");
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user