diff --git a/Main/src/main/java/com/chameleonvision/Main.java b/Main/src/main/java/com/chameleonvision/Main.java index d52eff63a..37e2e7cba 100644 --- a/Main/src/main/java/com/chameleonvision/Main.java +++ b/Main/src/main/java/com/chameleonvision/Main.java @@ -15,6 +15,8 @@ import edu.wpi.first.networktables.NetworkTableInstance; import java.io.IOException; import java.util.function.Consumer; +import static com.chameleonvision.settings.Platform.CurrentPlatform; + public class Main { private static final String NT_SERVERMODE_KEY = "--nt-servermode"; // no args for this setting @@ -44,8 +46,6 @@ public class Main { } } - private static final Platform CurrentPlatform = Platform.getCurrentPlatform(); - private static void handleArgs(String[] args) { for (int i = 0; i < args.length; i++) { var key = args[i].toLowerCase(); @@ -127,13 +127,13 @@ public class Main { CameraServerJNI.forceLoad(); CameraServerCvJNI.forceLoad(); } catch (UnsatisfiedLinkError | IOException e) { - if(Platform.getCurrentPlatform().isWindows()) + if(CurrentPlatform.isWindows()) { System.err.println("Try to download the VC++ Redistributable, https://aka.ms/vs/16/release/vc_redist.x64.exe"); + } throw new RuntimeException("Failed to load JNI Libraries!"); } if (testMode) { - // todo: boot in to the new classabstraction stuff boolean visionSourcesOk = VisionManager.initializeSources(); if (!visionSourcesOk) { System.out.println("No cameras connected!"); diff --git a/Main/src/main/java/com/chameleonvision/classabstraction/VisionManager.java b/Main/src/main/java/com/chameleonvision/classabstraction/VisionManager.java index c113f5e94..9208a096d 100644 --- a/Main/src/main/java/com/chameleonvision/classabstraction/VisionManager.java +++ b/Main/src/main/java/com/chameleonvision/classabstraction/VisionManager.java @@ -2,6 +2,8 @@ package com.chameleonvision.classabstraction; import com.chameleonvision.settings.SettingsManager; import com.chameleonvision.util.FileHelper; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import edu.wpi.cscore.UsbCamera; import edu.wpi.cscore.UsbCameraInfo; import org.opencv.videoio.VideoCapture; @@ -46,19 +48,39 @@ public class VisionManager { 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)); + Path cameraPipelinesPath = Paths.get(cameraConfigFolder.toString(), "pipelines.json"); + Path cameraDrivermodePath = Paths.get(cameraConfigFolder.toString(), "drivermode.json"); - if (Files.exists(cameraConfigFolder)) { - if (Files.exists(cameraConfigPath)) { - File cameraConfigFile = new File(cameraConfigPath.toString()); + try { - } - } else { - try { + boolean cameraFolderExists = Files.exists(cameraConfigFolder); + + if (!cameraFolderExists) { Files.createDirectory(cameraConfigFolder); - } catch (IOException e) { - e.printStackTrace(); } + boolean cameraConfigExists = cameraFolderExists && Files.exists(cameraConfigPath); + + if (Files.exists(cameraConfigFolder)) { + if (Files.exists(cameraConfigPath)) { + File cameraConfigFile = new File(cameraConfigPath.toString()); + if (cameraConfigFile.length() != 0) { + try { + Gson gson = new GsonBuilder().create(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } else { + Files.createFile(cameraConfigPath); + } + } else { + Files.createDirectory(cameraConfigFolder); + } + } catch (IOException ex) { + } + + }); // FileHelper.CheckPath(CamConfigPath); diff --git a/Main/src/main/java/com/chameleonvision/classabstraction/camera/CameraProperties.java b/Main/src/main/java/com/chameleonvision/classabstraction/camera/CameraProperties.java index 639bfe361..fe457c047 100644 --- a/Main/src/main/java/com/chameleonvision/classabstraction/camera/CameraProperties.java +++ b/Main/src/main/java/com/chameleonvision/classabstraction/camera/CameraProperties.java @@ -1,6 +1,9 @@ package com.chameleonvision.classabstraction.camera; +import com.chameleonvision.Main; +import com.chameleonvision.settings.Platform; import edu.wpi.cscore.UsbCamera; +import edu.wpi.cscore.UsbCameraInfo; import edu.wpi.cscore.VideoMode; import org.apache.commons.math3.util.FastMath; @@ -25,12 +28,36 @@ public class CameraProperties { private static final Predicate 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 videoModes; + private String nickname; + public CameraProperties(UsbCamera baseCamera, double fov) { FOV = fov; videoModes = filterVideoModes(baseCamera.enumerateVideoModes()); + name = baseCamera.getName(); + + UsbCameraInfo baseCamInfo = baseCamera.getInfo(); + + if (Platform.CurrentPlatform.isWindows()) { + path = baseCamInfo.path; + } else { + var truePath = Arrays.stream(baseCamInfo.otherPaths).filter(x -> x.contains("/dev/v4l/by-path")).findFirst(); + path = truePath.orElse(baseCamInfo.path); + } + + nickname = name; + } + + public void setNickname(String nickname) { + this.nickname = nickname; + } + + public String getNickname() { + return nickname; } private List filterVideoModes(VideoMode[] videoModes) { diff --git a/Main/src/main/java/com/chameleonvision/classabstraction/camera/USBCameraProcess.java b/Main/src/main/java/com/chameleonvision/classabstraction/camera/USBCameraProcess.java index f9216e340..7e318fd16 100644 --- a/Main/src/main/java/com/chameleonvision/classabstraction/camera/USBCameraProcess.java +++ b/Main/src/main/java/com/chameleonvision/classabstraction/camera/USBCameraProcess.java @@ -13,7 +13,7 @@ public class USBCameraProcess implements CameraProcess { private final UsbCamera baseCamera; private final CvSink cvSink; private Mat imageBuffer = new Mat(); - public CameraProperties properties; + private CameraProperties properties; public USBCameraProcess(UsbCamera camera, CameraConfig config) { baseCamera = camera; diff --git a/Main/src/main/java/com/chameleonvision/classabstraction/config/CameraConfig.java b/Main/src/main/java/com/chameleonvision/classabstraction/config/CameraConfig.java index 22944dd27..56c2d25a8 100644 --- a/Main/src/main/java/com/chameleonvision/classabstraction/config/CameraConfig.java +++ b/Main/src/main/java/com/chameleonvision/classabstraction/config/CameraConfig.java @@ -5,6 +5,5 @@ public class CameraConfig { public String Path; public String Name; public String Nickname; - public com.chameleonvision.vision.camera.StreamDivisor StreamDivisor; -// public + } diff --git a/Main/src/main/java/com/chameleonvision/classabstraction/config/CameraSerializer.java b/Main/src/main/java/com/chameleonvision/classabstraction/config/CameraSerializer.java new file mode 100644 index 000000000..a03ba8ec0 --- /dev/null +++ b/Main/src/main/java/com/chameleonvision/classabstraction/config/CameraSerializer.java @@ -0,0 +1,25 @@ +package com.chameleonvision.classabstraction.config; + +import com.chameleonvision.classabstraction.camera.CameraProperties; +import com.chameleonvision.classabstraction.camera.USBCameraProcess; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; + +import java.io.IOException; + +public class CameraSerializer extends StdSerializer { + public CameraSerializer(Class t) { + super(t); + } + + @Override + public void serialize(USBCameraProcess value, JsonGenerator gen, SerializerProvider provider) throws IOException { + gen.writeStartObject(); + CameraProperties camProps = value.getProperties(); + gen.writeNumberField("FOV", camProps.FOV); + gen.writeStringField("Name", camProps.name); + gen.writeStringField("Path", camProps.path); + gen.writeStringField("Nickname", camProps.getNickname()); + } +} diff --git a/Main/src/main/java/com/chameleonvision/classabstraction/config/ConfigManager.java b/Main/src/main/java/com/chameleonvision/classabstraction/config/ConfigManager.java new file mode 100644 index 000000000..89da22410 --- /dev/null +++ b/Main/src/main/java/com/chameleonvision/classabstraction/config/ConfigManager.java @@ -0,0 +1,74 @@ +package com.chameleonvision.classabstraction.config; + +import com.chameleonvision.classabstraction.util.ProgramDirectoryUtilities; +import com.chameleonvision.settings.GeneralSettings; +import com.chameleonvision.util.FileHelper; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +public class ConfigManager { + private ConfigManager() {} + + private static final Path SettingsPath = Paths.get(ProgramDirectoryUtilities.getProgramDirectory(), "settings"); + private static final Path CamConfigPath = Paths.get(SettingsPath.toString(), "cameras"); + + public static GeneralSettings settings = new GeneralSettings(); + + public static void initializeSettings() { + boolean settingsFolderExists = Files.exists(SettingsPath); + + if (!settingsFolderExists) { + try { + Files.createDirectory(SettingsPath); + } catch (IOException e) { + e.printStackTrace(); + } + } + + Path settingsFilePath = Paths.get(SettingsPath.toString(), "settings.json"); + boolean settingsFileExists = Files.exists(settingsFilePath); + + if (!settingsFileExists) { + try { + FileHelper.Serializer(settings, settingsFilePath); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + try { + settings = FileHelper.DeSerializer(settingsFilePath, GeneralSettings.class); + } catch (IOException e) { + System.err.println("Failed to load settings.json, using defaults."); + } + } + + } + + public static List initializeCameraConfig(List cameraNames) { + + cameraNames.forEach((cameraName) -> { + final Path cameraConfigFolder = Paths.get(CamConfigPath.toString(), String.format("%s\\", cameraName)); + final Path cameraConfigPath = Paths.get(cameraConfigFolder.toString(), String.format("%s.json", cameraName)); + final Path cameraPipelinesPath = Paths.get(cameraConfigFolder.toString(), "pipelines.json"); + final Path cameraDrivermodePath = Paths.get(cameraConfigFolder.toString(), "drivermode.json"); + + boolean cameraConfigFolderExists = Files.exists(cameraConfigFolder); + + if (!cameraConfigFolderExists) { + try { + Files.createDirectory(cameraConfigFolder); + } catch (IOException e) { + e.printStackTrace(); + } + } + + }); + + return new ArrayList<>(); + } +} diff --git a/Main/src/main/java/com/chameleonvision/classabstraction/util/ProgramDirectoryUtilities.java b/Main/src/main/java/com/chameleonvision/classabstraction/util/ProgramDirectoryUtilities.java new file mode 100644 index 000000000..52bcfb0af --- /dev/null +++ b/Main/src/main/java/com/chameleonvision/classabstraction/util/ProgramDirectoryUtilities.java @@ -0,0 +1,51 @@ +package com.chameleonvision.classabstraction.util; + +import java.io.File; +import java.net.URISyntaxException; + +public class ProgramDirectoryUtilities +{ + private static String getJarName() + { + return new File(ProgramDirectoryUtilities.class.getProtectionDomain() + .getCodeSource() + .getLocation() + .getPath()) + .getName(); + } + + private static boolean runningFromJAR() + { + String jarName = getJarName(); + return jarName.contains(".jar"); + } + + public static String getProgramDirectory() + { + if (runningFromJAR()) + { + return getCurrentJARDirectory(); + } else + { + return getCurrentProjectDirectory(); + } + } + + private static String getCurrentProjectDirectory() + { + return new File("").getAbsolutePath(); + } + + private static String getCurrentJARDirectory() + { + try + { + return new File(ProgramDirectoryUtilities.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath()).getParent(); + } catch (URISyntaxException exception) + { + exception.printStackTrace(); + } + + return null; + } +} \ No newline at end of file diff --git a/Main/src/main/java/com/chameleonvision/settings/Platform.java b/Main/src/main/java/com/chameleonvision/settings/Platform.java index 64f70f1f7..478ab22f0 100644 --- a/Main/src/main/java/com/chameleonvision/settings/Platform.java +++ b/Main/src/main/java/com/chameleonvision/settings/Platform.java @@ -23,6 +23,7 @@ public enum Platform { private static final String OS_NAME = System.getProperty("os.name"); private static final String OS_ARCH = System.getProperty("os.arch"); + public static final Platform CurrentPlatform = getCurrentPlatform(); public boolean isWindows() { return this == WINDOWS_64; @@ -70,7 +71,7 @@ public enum Platform { } } - public static Platform getCurrentPlatform() { + private static Platform getCurrentPlatform() { if (OS_NAME.contains("Windows")) { if (OS_ARCH.equals("amd64")) return Platform.WINDOWS_64; } diff --git a/Main/src/main/java/com/chameleonvision/util/FileHelper.java b/Main/src/main/java/com/chameleonvision/util/FileHelper.java index 93320ca1b..8dc56450d 100644 --- a/Main/src/main/java/com/chameleonvision/util/FileHelper.java +++ b/Main/src/main/java/com/chameleonvision/util/FileHelper.java @@ -27,18 +27,16 @@ public class FileHelper { } } } + public static void Serializer(Object object, Path path) throws IOException { - File file = new File(path.toString()); PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().allowIfBaseType(Object.class).build(); ObjectMapper objectMapper = JsonMapper.builder().activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT).build(); - objectMapper.writeValue(file,object); + objectMapper.writeValue(new File(path.toString()), object); } - public static Object DeSerializer(Path path,Class ref) throws IOException { - File file = new File(path.toString()); + public static T DeSerializer(Path path, Class ref) throws IOException { PolymorphicTypeValidator ptv = BasicPolymorphicTypeValidator.builder().allowIfBaseType(Object.class).build(); ObjectMapper objectMapper = JsonMapper.builder().activateDefaultTyping(ptv, ObjectMapper.DefaultTyping.JAVA_LANG_OBJECT).build(); - Object o = objectMapper.readValue(file, ref); - return o; + return objectMapper.readValue(new File(path.toString()), ref); } } diff --git a/Main/src/main/java/com/chameleonvision/vision/camera/USBCamera.java b/Main/src/main/java/com/chameleonvision/vision/camera/USBCamera.java index 28f2db192..bad6e2419 100644 --- a/Main/src/main/java/com/chameleonvision/vision/camera/USBCamera.java +++ b/Main/src/main/java/com/chameleonvision/vision/camera/USBCamera.java @@ -77,11 +77,11 @@ public class USBCamera { FOV = fov; name = cameraName; - if (Platform.getCurrentPlatform().isWindows()) { + if (Platform.CurrentPlatform.isWindows()) { path = usbCamInfo.path; } else { var truePath = Arrays.stream(usbCamInfo.otherPaths).filter(x -> x.contains("/dev/v4l/by-path")).findFirst(); - path = truePath.orElse(null); + path = truePath.orElse(usbCamInfo.path); } streamDivisor = divisor; @@ -90,7 +90,7 @@ public class USBCamera { this.pipelines = pipelines; // set up video modes according to minimums - if (Platform.getCurrentPlatform() == Platform.WINDOWS_64 && !UsbCam.isConnected()) { + if (Platform.CurrentPlatform == Platform.WINDOWS_64 && !UsbCam.isConnected()) { System.out.print("Waiting on camera... "); long initTimeout = System.nanoTime(); while (!UsbCam.isConnected()) {