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.USBCameras; 019 020import edu.wpi.first.cscore.UsbCamera; 021import edu.wpi.first.cscore.VideoException; 022import edu.wpi.first.math.MathUtil; 023import org.photonvision.common.configuration.CameraConfiguration; 024import org.photonvision.common.util.math.MathUtils; 025 026public class LifeCam3kCameraSettables extends GenericUSBCameraSettables { 027 // Lifecam only allows specific exposures. Pulled this list from 028 // https://github.com/wpilibsuite/allwpilib/blob/main/cscore/src/main/native/linux/UsbCameraImpl.cpp#L129 029 private static int[] allowableExposures = {5, 10, 20, 39, 78, 156, 312, 625}; 030 031 public LifeCam3kCameraSettables(CameraConfiguration configuration, UsbCamera camera) { 032 super(configuration, camera); 033 } 034 035 @Override 036 protected void setUpExposureProperties() { 037 autoExposureProp = findProperty("exposure_auto", "auto_exposure").get(); 038 exposureAbsProp = findProperty("raw_exposure_time_absolute", "raw_exposure_absolute").get(); 039 040 this.minExposure = exposureAbsProp.getMin(); 041 this.maxExposure = exposureAbsProp.getMax(); 042 } 043 044 @Override 045 public void setExposureRaw(double exposureRaw) { 046 if (exposureRaw >= 0.0) { 047 try { 048 int propVal = (int) MathUtil.clamp(exposureRaw, minExposure, maxExposure); 049 050 propVal = MathUtils.quantize(propVal, allowableExposures); 051 052 logger.debug( 053 "Setting property " 054 + autoExposureProp.getName() 055 + " to " 056 + propVal 057 + " (user requested " 058 + exposureRaw 059 + " )"); 060 061 exposureAbsProp.set(propVal); 062 063 this.lastExposureRaw = exposureRaw; 064 065 // Lifecam requires setting brightness again after exposure 066 // And it requires setting it twice, ensuring the value is different 067 // This camera is very bork. 068 if (lastBrightness >= 0) { 069 setBrightness(lastBrightness - 1); 070 } 071 072 } catch (VideoException e) { 073 logger.error("Failed to set camera exposure!", e); 074 } 075 } 076 } 077 078 @Override 079 public void setAllCamDefaults() { 080 // Common settings for all cameras to attempt to get their image 081 // as close as possible to what we want for image processing 082 softSet("raw_contrast", 5); 083 softSet("raw_saturation", 85); 084 softSet("raw_sharpness", 25); 085 softSet("white_balance_automatic", 0); 086 softSet("white_balance_temperature", 4000); 087 } 088}