Skip to content

Commit

Permalink
Actually implement OV9281/2311 things
Browse files Browse the repository at this point in the history
  • Loading branch information
mcm001 committed Jan 6, 2024
1 parent 4302710 commit 02bbe9b
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 12 deletions.
57 changes: 54 additions & 3 deletions photon-client/src/components/cameras/CameraSettingsCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import PvSelect from "@/components/common/pv-select.vue";
import PvNumberInput from "@/components/common/pv-number-input.vue";
import { useCameraSettingsStore } from "@/stores/settings/CameraSettingsStore";
import { useStateStore } from "@/stores/StateStore";
import { ref, watchEffect } from "vue";
import { computed, ref, watchEffect } from "vue";
import { CameraSettings } from "@/types/SettingTypes";
const currentFov = ref();
const saveCameraSettings = () => {
useCameraSettingsStore()
.updateCameraSettings({ fov: currentFov.value }, false)
.updateCameraSettings({ fov: currentFov.value, quirksToChange: quirksToChange.value }, false)
.then((response) => {
useCameraSettingsStore().currentCameraSettings.fov.value = currentFov.value;
useStateStore().showSnackbarMessage({
Expand Down Expand Up @@ -41,6 +42,50 @@ const saveCameraSettings = () => {
watchEffect(() => {
currentFov.value = useCameraSettingsStore().currentCameraSettings.fov.value;
});
const quirksToChange = ref({
ArduOV9281: false,
ArduOV2311: false,
})
let arducams = ["N/A", "OV9281", "OV2311"]
const arducamModel = computed({
get() {
const quirks = useCameraSettingsStore().currentCameraSettings.cameraQuirks.quirks;
if (quirks.ArduOV9281) {
return 1;
} else if (quirks.ArduOV2311) {
return 2;
}
return 0;
},
set(value) {
console.log("hi")
console.log(value)
if (value === 1) {
quirksToChange.value.ArduOV9281 = true;
quirksToChange.value.ArduOV2311 = false;
} else if (value === 2) {
quirksToChange.value.ArduOV9281 = false;
quirksToChange.value.ArduOV2311 = true;
} else {
quirksToChange.value.ArduOV9281 = false;
quirksToChange.value.ArduOV2311 = false;
}
}
})
const isArducam = () => {
const settings = useCameraSettingsStore().currentCameraSettings;
// console.log("Is arducam?")
// console.log(settings.cameraQuirks.quirks.ArudcamCamera)
return settings.cameraQuirks.quirks.ArudcamCamera;
}
</script>

<template>
Expand Down Expand Up @@ -70,12 +115,18 @@ watchEffect(() => {
:disabled="useCameraSettingsStore().currentCameraSettings.fov.managedByVendor"
:label-cols="4"
/>
<pv-select
v-model="arducamModel"
label="Arducam Model"
:disabled="!isArducam()"
:items="arducams"
:select-cols="8"
/>
<br />
<v-btn
style="margin-top: 10px"
small
color="secondary"
:disabled="currentFov === useCameraSettingsStore().currentCameraSettings.fov.value"
@click="saveCameraSettings"
>
<v-icon left> mdi-content-save </v-icon>
Expand Down
3 changes: 2 additions & 1 deletion photon-client/src/stores/settings/CameraSettingsStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,8 @@ export const useCameraSettingsStore = defineStore("cameraSettings", {
})),
pipelineNicknames: d.pipelineNicknames,
currentPipelineIndex: d.currentPipelineIndex,
pipelineSettings: d.currentPipelineSettings
pipelineSettings: d.currentPipelineSettings,
cameraQuirks: d.cameraQuirks
}));
},
/**
Expand Down
32 changes: 31 additions & 1 deletion photon-client/src/types/SettingTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,27 @@ export interface CameraCalibrationResult {

export interface ConfigurableCameraSettings {
fov: number;
// Need map of (quirk name string) -> boolean
quirksToChange: object
}

export interface QuirkyCamera {
baseName: string;
usbVid: number;
usbPid: number;
displayName: string;
quirks: {
AWBGain: boolean;
AdjustableFocus: boolean;
ArduOV9281: boolean;
ArduOV2311: boolean;
ArudcamCamera: boolean;
CompletelyBroken: boolean;
FPSCap100: boolean;
Gain: boolean;
PiCam: boolean;
StickyFPS: boolean;
};
}

export interface CameraSettings {
Expand All @@ -112,6 +133,8 @@ export interface CameraSettings {
currentPipelineIndex: number;
pipelineNicknames: string[];
pipelineSettings: ActivePipelineSettings;

cameraQuirks: QuirkyCamera;
}

export const PlaceholderCameraSettings: CameraSettings = {
Expand Down Expand Up @@ -145,7 +168,14 @@ export const PlaceholderCameraSettings: CameraSettings = {
pipelineNicknames: ["Placeholder Pipeline"],
lastPipelineIndex: 0,
currentPipelineIndex: 0,
pipelineSettings: DefaultAprilTagPipelineSettings
pipelineSettings: DefaultAprilTagPipelineSettings,
cameraQuirks: {
displayName: "Blank 1",
baseName: "Blank 2",
usbVid: -1,
usbPid: -1,
quirks: {}
}
};

export enum CalibrationBoardTypes {
Expand Down
3 changes: 2 additions & 1 deletion photon-client/src/types/WebsocketDataTypes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { GeneralSettings, LightingSettings, LogLevel, MetricData, NetworkSettings } from "@/types/SettingTypes";
import type { GeneralSettings, LightingSettings, LogLevel, MetricData, NetworkSettings, QuirkyCamera } from "@/types/SettingTypes";
import type { ActivePipelineSettings } from "@/types/PipelineTypes";
import type { AprilTagFieldLayout, PipelineResult } from "@/types/PhotonTrackingTypes";

Expand Down Expand Up @@ -56,6 +56,7 @@ export interface WebsocketCameraSettingsUpdate {
outputStreamPort: number;
pipelineNicknames: string[];
videoFormatList: WebsocketVideoFormat;
cameraQuirks: QuirkyCamera;
}
export interface WebsocketNTUpdate {
connected: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.photonvision.common.networking.NetworkUtils;
import org.photonvision.common.util.SerializationUtils;
import org.photonvision.raspi.LibCameraJNI;
import org.photonvision.vision.camera.QuirkyCamera;
import org.photonvision.vision.processes.VisionModule;
import org.photonvision.vision.processes.VisionModuleManager;
import org.photonvision.vision.processes.VisionSource;
Expand Down Expand Up @@ -174,5 +175,6 @@ public static class UICameraConfiguration {
public int inputStreamPort;
public List<HashMap<String, Object>> calibrations;
public boolean isFovConfigurable = true;
public QuirkyCamera cameraQuirks;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,17 @@ public enum CameraQuirk {
AdjustableFocus,
/** Changing FPS repeatedly with small delay does not work correctly */
StickyFPS,
/**
* Camera is an arducam. This means it shares VID/PID with other arducams (ew)
*/
ArudcamCamera,
/**
* Camera is an arducam ov9281 which has a funky exposure issue where it is defined in v4l as
* 1-5000 instead of 1-75
*/
ArduOV9281,
/**
* Dummy quirk to tell OV2311 from OV9281
*/
ArduOV2311,
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,15 @@ public class QuirkyCamera {
-1, -1, "mmal service 16.1", CameraQuirk.PiCam), // PiCam (via V4L2, not zerocopy)
new QuirkyCamera(-1, -1, "unicam", CameraQuirk.PiCam), // PiCam (via V4L2, not zerocopy)
new QuirkyCamera(0x85B, 0x46D, CameraQuirk.AdjustableFocus), // Logitech C925-e
// Generic arducam. Since OV2311 can't be differentiated at first boot, apply stickyFPS to the generic case, too
new QuirkyCamera(
0x6366, 0x0c45, "", "Arducam Generic"),
0x6366, 0x0c45, "", "Arducam Generic", CameraQuirk.ArudcamCamera, CameraQuirk.StickyFPS),
// Arducam OV2311
new QuirkyCamera(
0x6366, 0x0c45, "OV2311", "OV2311", CameraQuirk.StickyFPS), // Arducam OV2311
0x6366, 0x0c45, "OV2311", "OV2311", CameraQuirk.ArudcamCamera, CameraQuirk.ArduOV2311, CameraQuirk.StickyFPS),
// Arducam OV9281
new QuirkyCamera(
0x6366, 0x0c45, "OV9281", "OV9281", CameraQuirk.ArduOV9281) // Arducam OV9281
0x6366, 0x0c45, "OV9281", "OV9281", CameraQuirk.ArudcamCamera, CameraQuirk.ArduOV9281)
);

public static final QuirkyCamera DefaultCamera = new QuirkyCamera(0, 0, "");
Expand All @@ -67,10 +70,15 @@ public class QuirkyCamera {
CameraQuirk.Gain,
CameraQuirk.AWBGain); // PiCam (special zerocopy version)

@JsonProperty("baseName")
public final String baseName;
@JsonProperty("usbVid")
public final int usbVid;
@JsonProperty("usbPid")
public final int usbPid;
@JsonProperty("displayName")
public final String displayName;
@JsonProperty("quirks")
public final HashMap<CameraQuirk, Boolean> quirks;

/**
Expand Down Expand Up @@ -102,6 +110,7 @@ private QuirkyCamera(int usbVid, int usbPid, String baseName, CameraQuirk... qui
* @param usbVid USB VID of camera
* @param usbPid USB PID of camera
* @param baseName CSCore name of camera
* @param displayName Human-friendly quicky camera name
* @param quirks Camera quirks
*/
private QuirkyCamera(
Expand All @@ -125,7 +134,7 @@ public QuirkyCamera(
@JsonProperty("baseName") String baseName,
@JsonProperty("usbVid") int usbVid,
@JsonProperty("usbPid") int usbPid,
@JsonProperty("usbPid") String displayName,
@JsonProperty("displayName") String displayName,
@JsonProperty("quirks") HashMap<CameraQuirk, Boolean> quirks) {
this.baseName = baseName;
this.usbPid = usbPid;
Expand Down Expand Up @@ -201,4 +210,17 @@ public String toString() {
public int hashCode() {
return Objects.hash(usbVid, usbPid, baseName, quirks);
}

/**
* Add/remove quirks from the camera we're controlling
* @param quirksToChange map of true/false for quirks we should change
*/
public void updateQuirks(HashMap<CameraQuirk, Boolean> quirksToChange) {
for (var q : quirksToChange.entrySet()) {
var quirk = q.getKey();
var hasQuirk = q.getValue();

this.quirks.put(quirk, hasQuirk);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,7 @@ public PhotonConfiguration.UICameraConfiguration toUICameraConfig() {
SerializationUtils.objectToHashMap(pipelineManager.getCurrentPipelineSettings());
ret.currentPipelineIndex = pipelineManager.getCurrentPipelineIndex();
ret.pipelineNicknames = pipelineManager.getPipelineNicknames();
ret.cameraQuirks = visionSource.getSettables().getConfiguration().cameraQuirks;

// TODO refactor into helper method
var temp = new HashMap<Integer, HashMap<String, Object>>();
Expand Down Expand Up @@ -613,4 +614,13 @@ public void addCalibrationToConfig(CameraCalibrationCoefficients newCalibration)

saveAndBroadcastAll();
}

/**
* Add/remove quirks from the camera we're controlling
* @param quirksToChange map of true/false for quirks we should change
*/
public void changeCameraQuirks(HashMap<CameraQuirk, Boolean> quirksToChange) {
visionSource.getCameraConfiguration().cameraQuirks.updateQuirks(quirksToChange);
saveAndBroadcastAll();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@

package org.photonvision.server;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.javalin.http.Context;
import io.javalin.http.UploadedFile;
Expand All @@ -30,6 +32,7 @@
import java.util.Optional;
import javax.imageio.ImageIO;
import org.apache.commons.io.FileUtils;
import org.eclipse.jetty.util.VirtualThreads.Configurable;
import org.photonvision.common.configuration.ConfigManager;
import org.photonvision.common.configuration.NetworkConfig;
import org.photonvision.common.dataflow.DataChangeDestination;
Expand All @@ -43,8 +46,10 @@
import org.photonvision.common.networking.NetworkManager;
import org.photonvision.common.util.ShellExec;
import org.photonvision.common.util.TimedTaskManager;
import org.photonvision.common.util.file.JacksonUtils;
import org.photonvision.common.util.file.ProgramDirectoryUtilities;
import org.photonvision.vision.calibration.CameraCalibrationCoefficients;
import org.photonvision.vision.camera.CameraQuirk;
import org.photonvision.vision.processes.VisionModuleManager;

public class RequestHandler {
Expand Down Expand Up @@ -364,22 +369,32 @@ public static void onGeneralSettingsRequest(Context ctx) {
NetworkTablesManager.getInstance().setConfig(config);
}

public static class UICameraSettingsRequest {
@JsonProperty("fov")
double fov;
@JsonProperty("quirksToChange")
HashMap<CameraQuirk, Boolean> quirksToChange;
}

public static void onCameraSettingsRequest(Context ctx) {
try {
var data = kObjectMapper.readTree(ctx.body());

int index = data.get("index").asInt();
double fov = data.get("settings").get("fov").asDouble();
// double fov = data.get("settings").get("fov").asDouble();
var settings = JacksonUtils.deserialize(data.get("settings").toString(), UICameraSettingsRequest.class);
var fov = settings.fov;

var module = VisionModuleManager.getInstance().getModule(index);
module.setFov(fov);
module.changeCameraQuirks(settings.quirksToChange);

module.saveModule();

ctx.status(200);
ctx.result("Successfully saved camera settings");
logger.info("Successfully saved camera settings");
} catch (JsonProcessingException | NullPointerException e) {
} catch (NullPointerException | IOException e) {
ctx.status(400);
ctx.result("The provided camera settings were malformed");
logger.error("The provided camera settings were malformed", e);
Expand Down

0 comments on commit 02bbe9b

Please sign in to comment.