package com.chameleonvision.classabstraction.camera; import edu.wpi.cscore.UsbCamera; import edu.wpi.cscore.VideoMode; import org.apache.commons.math3.util.FastMath; import java.util.Arrays; import java.util.List; import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; public class CameraProperties { private static final double DEFAULT_FOV = 70; private static final int DEFAULT_EXPOSURE = 50; private static final int DEFAULT_BRIGHTNESS = 50; private static final int MINIMUM_FPS = 30; private static final int MINIMUM_WIDTH = 320; private static final int MINIMUM_HEIGHT = 200; private static final int MAX_INIT_MS = 1500; private static final List ALLOWED_PIXEL_FORMATS = Arrays.asList(VideoMode.PixelFormat.kYUYV, VideoMode.PixelFormat.kMJPEG); private static final Predicate kMinFPSPredicate = (videoMode -> videoMode.fps >= MINIMUM_FPS); private static final Predicate kMinSizePredicate = (videoMode -> videoMode.width >= MINIMUM_FPS && videoMode.height >= MINIMUM_FPS); private static final Predicate kPixelFormatPredicate = (videoMode -> ALLOWED_PIXEL_FORMATS.contains(videoMode.pixelFormat)); public CameraStaticProperties staticProperties; public final double FOV; public final List videoModes; public CameraProperties(UsbCamera baseCamera, double fov) { FOV = fov; videoModes = filterVideoModes(baseCamera.enumerateVideoModes()); } private List filterVideoModes(VideoMode[] videoModes) { Predicate fullPredicate = kMinFPSPredicate.and(kMinSizePredicate).and(kPixelFormatPredicate); Stream validModes = Arrays.stream(videoModes).filter(fullPredicate); return validModes.collect(Collectors.toList()); } public void updateVideoMode(VideoMode videoMode) { staticProperties = new CameraStaticProperties(videoMode.width, videoMode.height, FOV); } public double CalculatePitch(double PixelY, double centerY) { double pitch = FastMath.toDegrees(FastMath.atan((PixelY - centerY) / staticProperties.VerticalFocalLength)); return (pitch * -1); } public double CalculateYaw(double PixelX, double centerX) { return FastMath.toDegrees(FastMath.atan((PixelX - centerX) / staticProperties.HorizontalFocalLength)); } }