diff --git a/photon-core/src/main/java/org/photonvision/common/configuration/ConfigManager.java b/photon-core/src/main/java/org/photonvision/common/configuration/ConfigManager.java index 9e96448f6..2492ac7a7 100644 --- a/photon-core/src/main/java/org/photonvision/common/configuration/ConfigManager.java +++ b/photon-core/src/main/java/org/photonvision/common/configuration/ConfigManager.java @@ -332,8 +332,8 @@ public class ConfigManager { return loadedConfigurations; } - public void addCameraConfigurations(HashMap sources) { - getConfig().addCameraConfigs(sources.values()); + public void addCameraConfigurations(List sources) { + getConfig().addCameraConfigs(sources); requestSave(); } diff --git a/photon-core/src/main/java/org/photonvision/common/configuration/PhotonConfiguration.java b/photon-core/src/main/java/org/photonvision/common/configuration/PhotonConfiguration.java index 7c0c15d87..429327719 100644 --- a/photon-core/src/main/java/org/photonvision/common/configuration/PhotonConfiguration.java +++ b/photon-core/src/main/java/org/photonvision/common/configuration/PhotonConfiguration.java @@ -28,6 +28,7 @@ import org.photonvision.common.util.SerializationUtils; import org.photonvision.raspi.PicamJNI; import org.photonvision.vision.processes.VisionModule; import org.photonvision.vision.processes.VisionModuleManager; +import org.photonvision.vision.processes.VisionSource; // TODO rename this class public class PhotonConfiguration { @@ -75,9 +76,9 @@ public class PhotonConfiguration { return cameraConfigurations; } - public void addCameraConfigs(Collection config) { - for (var c : config) { - addCameraConfig(c); + public void addCameraConfigs(Collection sources) { + for (var s : sources) { + addCameraConfig(s.getCameraConfiguration()); } } diff --git a/photon-core/src/main/java/org/photonvision/vision/processes/VisionModuleManager.java b/photon-core/src/main/java/org/photonvision/vision/processes/VisionModuleManager.java index 45619401e..4efbc5eb6 100644 --- a/photon-core/src/main/java/org/photonvision/vision/processes/VisionModuleManager.java +++ b/photon-core/src/main/java/org/photonvision/vision/processes/VisionModuleManager.java @@ -17,9 +17,8 @@ package org.photonvision.vision.processes; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; import org.photonvision.common.configuration.CameraConfiguration; /** VisionModuleManager has many VisionModules, and provides camera configuration data to them. */ @@ -52,25 +51,31 @@ public class VisionModuleManager { return visionModules.get(i); } - public List addSources(HashMap visionSources) { - var addedModules = new ArrayList(); - for (var entry : visionSources.entrySet()) { - var visionSource = entry.getKey(); - var pipelineManager = new PipelineManager(entry.getValue()); + public List addSources(List visionSources) { + var addedModules = new HashMap(); - assignCameraIndex(visionSource.getSettables().getConfiguration()); + for (var visionSource : visionSources) { + var pipelineManager = new PipelineManager(visionSource.getCameraConfiguration()); + assignCameraIndex(visionSource.getCameraConfiguration()); var module = new VisionModule(pipelineManager, visionSource, visionModules.size()); visionModules.add(module); - addedModules.add(module); + addedModules.put(visionSource.getCameraConfiguration().streamIndex, module); } - return addedModules; + + var sortedModulesList = + addedModules.entrySet().stream() + .sorted(Comparator.comparingInt(Map.Entry::getKey)) // sort by stream index + .map(Map.Entry::getValue) // map to Stream of VisionModule + .collect(Collectors.toList()); // collect in a List + + return sortedModulesList; } private void assignCameraIndex(CameraConfiguration config) { var max = visionModules.stream() - .mapToInt(it -> it.visionSource.getSettables().getConfiguration().streamIndex) + .mapToInt(it -> it.visionSource.getCameraConfiguration().streamIndex) .max() .orElse(-1); diff --git a/photon-core/src/main/java/org/photonvision/vision/processes/VisionSourceManager.java b/photon-core/src/main/java/org/photonvision/vision/processes/VisionSourceManager.java index 85ae179d2..6cdc5e9e4 100644 --- a/photon-core/src/main/java/org/photonvision/vision/processes/VisionSourceManager.java +++ b/photon-core/src/main/java/org/photonvision/vision/processes/VisionSourceManager.java @@ -75,12 +75,12 @@ public class VisionSourceManager { () -> List.of(UsbCamera.enumerateUsbCameras()); protected void tryMatchUSBCams() { - var visionSourceMap = tryMatchUSBCamImpl(); - if (visionSourceMap == null) return; + var visionSourceList = tryMatchUSBCamImpl(); + if (visionSourceList == null) return; - logger.info("Adding " + visionSourceMap.size() + " configs to VMM."); - ConfigManager.getInstance().addCameraConfigurations(visionSourceMap); - var addedSources = VisionModuleManager.getInstance().addSources(visionSourceMap); + logger.info("Adding " + visionSourceList.size() + " configs to VMM."); + ConfigManager.getInstance().addCameraConfigurations(visionSourceList); + var addedSources = VisionModuleManager.getInstance().addSources(visionSourceList); addedSources.forEach(VisionModule::start); DataChangeService.getInstance() .publishEvent( @@ -88,7 +88,7 @@ public class VisionSourceManager { "fullsettings", ConfigManager.getInstance().getConfig().toHashMap())); } - protected HashMap tryMatchUSBCamImpl() { + protected List tryMatchUSBCamImpl() { // Detect cameras using CSCore List connectedCameras = new ArrayList<>(filterAllowedDevices(cameraInfoSupplier.get())); @@ -154,20 +154,18 @@ public class VisionSourceManager { // Turn these camera configs into vision sources var sources = loadVisionSourcesFromCamConfigs(matchedCameras); - // We want to return a map between vision sources and camera configurations - var visionSourceMap = new HashMap(); + // Print info about each vision source for (var src : sources) { - var usbSrc = src; - visionSourceMap.put(usbSrc, usbSrc.getSettables().getConfiguration()); logger.debug( () -> "Matched config for camera \"" + src.getFrameProvider().getName() + "\" and loaded " - + usbSrc.getSettables().getConfiguration().pipelineSettings.size() + + src.getCameraConfiguration().pipelineSettings.size() + " pipelines"); } - return visionSourceMap; + + return sources; } /** @@ -292,12 +290,12 @@ public class VisionSourceManager { private static List loadVisionSourcesFromCamConfigs( List camConfigs) { - List cameraSources = new ArrayList<>(); + var cameraSources = new ArrayList(); for (var configuration : camConfigs) { if (configuration.baseName.startsWith("mmal service") && PicamJNI.isSupported()) { configuration.cameraType = CameraType.ZeroCopyPicam; - VisionSource picamSrc = new ZeroCopyPicamSource(configuration); - cameraSources.add(picamSrc); + var piCamSrc = new ZeroCopyPicamSource(configuration); + cameraSources.add(piCamSrc); continue; } cameraSources.add(new USBCameraSource(configuration)); diff --git a/photon-core/src/test/java/org/photonvision/vision/processes/VisionModuleManagerTest.java b/photon-core/src/test/java/org/photonvision/vision/processes/VisionModuleManagerTest.java index cec6506d7..3464a4ac8 100644 --- a/photon-core/src/test/java/org/photonvision/vision/processes/VisionModuleManagerTest.java +++ b/photon-core/src/test/java/org/photonvision/vision/processes/VisionModuleManagerTest.java @@ -20,6 +20,7 @@ package org.photonvision.vision.processes; import edu.wpi.cscore.VideoMode; import edu.wpi.first.wpilibj.geometry.Rotation2d; import java.util.HashMap; +import java.util.List; import org.junit.jupiter.api.*; import org.photonvision.common.configuration.CameraConfiguration; import org.photonvision.common.configuration.ConfigManager; @@ -41,8 +42,8 @@ public class VisionModuleManagerTest { private final FrameProvider provider; - public TestSource(FrameProvider provider) { - super(new CameraConfiguration("", "", "", "")); + public TestSource(FrameProvider provider, CameraConfiguration cameraConfiguration) { + super(cameraConfiguration); this.provider = provider; } @@ -108,16 +109,16 @@ public class VisionModuleManagerTest { @Test public void setupManager() { ConfigManager.getInstance().load(); - var sources = new HashMap(); - sources.put( - new TestSource( - new FileFrameProvider( - TestUtils.getWPIImagePath( - TestUtils.WPI2019Image.kCargoStraightDark72in_HighRes, false), - TestUtils.WPI2019Image.FOV)), - new CameraConfiguration("Foo", "Barr")); - var modules = VisionModuleManager.getInstance().addSources(sources); + var conf = new CameraConfiguration("Foo", "Bar"); + var ffp = + new FileFrameProvider( + TestUtils.getWPIImagePath(TestUtils.WPI2019Image.kCargoStraightDark72in_HighRes, false), + TestUtils.WPI2019Image.FOV); + + var testSource = new TestSource(ffp, conf); + + var modules = VisionModuleManager.getInstance().addSources(List.of(testSource)); var module0DataConsumer = new TestDataConsumer(); VisionModuleManager.getInstance().visionModules.get(0).addResultConsumer(module0DataConsumer); diff --git a/photon-server/src/main/java/org/photonvision/Main.java b/photon-server/src/main/java/org/photonvision/Main.java index 8ffc31c22..a706319d4 100644 --- a/photon-server/src/main/java/org/photonvision/Main.java +++ b/photon-server/src/main/java/org/photonvision/Main.java @@ -19,7 +19,6 @@ package org.photonvision; import edu.wpi.cscore.CameraServerCvJNI; import java.util.ArrayList; -import java.util.HashMap; import org.apache.commons.cli.*; import org.photonvision.common.configuration.CameraConfiguration; import org.photonvision.common.configuration.ConfigManager; @@ -88,7 +87,7 @@ public class Main { } private static void addTestModeSources() { - var collectedSources = new HashMap(); + var collectedSources = new ArrayList(); var camConf2019 = new CameraConfiguration("WPI2019", TestUtils.getTestMode2019ImagePath().toString()); @@ -121,12 +120,10 @@ public class Main { var fvs2020 = new FileVisionSource(camConf2020); - var cfg2019 = new CameraConfiguration("2019", "2019"); - cfg2019.pipelineSettings = psList2019; - var cfg2020 = new CameraConfiguration("2019", "2019"); - cfg2020.pipelineSettings = psList2020; - collectedSources.put(fvs2019, cfg2019); - collectedSources.put(fvs2020, cfg2020); + fvs2019.getCameraConfiguration().pipelineSettings = psList2019; + fvs2020.getCameraConfiguration().pipelineSettings = psList2020; + collectedSources.add(fvs2019); + collectedSources.add(fvs2020); // logger.info("Adding " + allSources.size() + " configs to VMM."); VisionModuleManager.getInstance().addSources(collectedSources).forEach(VisionModule::start);