001/*
002 * Copyright (C) Photon Vision.
003 *
004 * This program is free software: you can redistribute it and/or modify
005 * it under the terms of the GNU General Public License as published by
006 * the Free Software Foundation, either version 3 of the License, or
007 * (at your option) any later version.
008 *
009 * This program is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012 * GNU General Public License for more details.
013 *
014 * You should have received a copy of the GNU General Public License
015 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
016 */
017
018package org.photonvision.vision.camera;
019
020import edu.wpi.first.cscore.UsbCameraInfo;
021import edu.wpi.first.cscore.VideoMode;
022import edu.wpi.first.util.PixelFormat;
023import java.nio.file.Path;
024import java.util.HashMap;
025import org.photonvision.common.configuration.CameraConfiguration;
026import org.photonvision.vision.frame.FrameProvider;
027import org.photonvision.vision.frame.FrameStaticProperties;
028import org.photonvision.vision.frame.provider.FileFrameProvider;
029import org.photonvision.vision.processes.VisionSource;
030import org.photonvision.vision.processes.VisionSourceSettables;
031
032public class FileVisionSource extends VisionSource {
033    private final FileFrameProvider frameProvider;
034    private final FileSourceSettables settables;
035
036    public FileVisionSource(CameraConfiguration cameraConfiguration) {
037        super(cameraConfiguration);
038        var calibration =
039                !cameraConfiguration.calibrations.isEmpty()
040                        ? cameraConfiguration.calibrations.get(0)
041                        : null;
042        frameProvider =
043                new FileFrameProvider(
044                        // TODO - create new File/replay camera info type
045                        Path.of(cameraConfiguration.getDevicePath()),
046                        cameraConfiguration.FOV,
047                        FileFrameProvider.MAX_FPS,
048                        calibration);
049
050        if (getCameraConfiguration().cameraQuirks == null)
051            getCameraConfiguration().cameraQuirks = QuirkyCamera.DefaultCamera;
052
053        settables =
054                new FileSourceSettables(cameraConfiguration, frameProvider.get().frameStaticProperties);
055    }
056
057    public FileVisionSource(String name, String imagePath, double fov) {
058        // TODO - create new File/replay camera info type
059        super(
060                new CameraConfiguration(
061                        PVCameraInfo.fromUsbCameraInfo(new UsbCameraInfo(0, imagePath, name, null, 0, 0)),
062                        name,
063                        name));
064        frameProvider = new FileFrameProvider(imagePath, fov);
065        settables =
066                new FileSourceSettables(cameraConfiguration, frameProvider.get().frameStaticProperties);
067    }
068
069    @Override
070    public FrameProvider getFrameProvider() {
071        return frameProvider;
072    }
073
074    @Override
075    public VisionSourceSettables getSettables() {
076        return settables;
077    }
078
079    @Override
080    public boolean isVendorCamera() {
081        return false;
082    }
083
084    @Override
085    public void remakeSettables() {
086        // Nothing to do, settables for this type of VisionSource should never be remade.
087        return;
088    }
089
090    @Override
091    public boolean hasLEDs() {
092        return false; // Assume USB cameras do not have photonvision-controlled LEDs
093    }
094
095    @Override
096    public void release() {
097        frameProvider.release();
098    }
099
100    public static class FileSourceSettables extends VisionSourceSettables {
101        private final VideoMode videoMode;
102
103        private final HashMap<Integer, VideoMode> videoModes = new HashMap<>();
104
105        FileSourceSettables(
106                CameraConfiguration cameraConfiguration, FrameStaticProperties frameStaticProperties) {
107            super(cameraConfiguration);
108            this.frameStaticProperties = frameStaticProperties;
109            videoMode =
110                    new VideoMode(
111                            PixelFormat.kMJPEG,
112                            frameStaticProperties.imageWidth,
113                            frameStaticProperties.imageHeight,
114                            30);
115            videoModes.put(0, videoMode);
116        }
117
118        @Override
119        public void setExposureRaw(double exposureRaw) {}
120
121        public void setAutoExposure(boolean cameraAutoExposure) {}
122
123        @Override
124        public void setBrightness(int brightness) {}
125
126        @Override
127        public void setGain(int gain) {}
128
129        @Override
130        public VideoMode getCurrentVideoMode() {
131            return videoMode;
132        }
133
134        @Override
135        protected void setVideoModeInternal(VideoMode videoMode) {
136            // Do nothing
137        }
138
139        @Override
140        public HashMap<Integer, VideoMode> getAllVideoModes() {
141            return videoModes;
142        }
143
144        @Override
145        public double getMinExposureRaw() {
146            return 1f;
147        }
148
149        @Override
150        public double getMaxExposureRaw() {
151            return 100f;
152        }
153
154        @Override
155        public void setAutoWhiteBalance(boolean autowb) {}
156
157        @Override
158        public void setWhiteBalanceTemp(double temp) {}
159
160        @Override
161        public double getMaxWhiteBalanceTemp() {
162            return 2;
163        }
164
165        @Override
166        public double getMinWhiteBalanceTemp() {
167            return 1;
168        }
169    }
170}