Attempt to write code

This commit is contained in:
Michael Mikovsky
2024-12-09 16:38:55 -07:00
parent e19463d624
commit fd817d49e5
16 changed files with 103 additions and 25 deletions
@@ -28,6 +28,9 @@ const changeCurrentCameraIndex = (index: number) => {
case PipelineType.ObjectDetection: case PipelineType.ObjectDetection:
pipelineType.value = WebsocketPipelineType.ObjectDetection; pipelineType.value = WebsocketPipelineType.ObjectDetection;
break; break;
case PipelineType.CustomTest:
pipelineType.value = WebsocketPipelineType.CustomTest;
break;
} }
}; };
@@ -130,7 +133,8 @@ const validNewPipelineTypes = computed(() => {
{ name: "Reflective", value: WebsocketPipelineType.Reflective }, { name: "Reflective", value: WebsocketPipelineType.Reflective },
{ name: "Colored Shape", value: WebsocketPipelineType.ColoredShape }, { name: "Colored Shape", value: WebsocketPipelineType.ColoredShape },
{ name: "AprilTag", value: WebsocketPipelineType.AprilTag }, { name: "AprilTag", value: WebsocketPipelineType.AprilTag },
{ name: "Aruco", value: WebsocketPipelineType.Aruco } { name: "Aruco", value: WebsocketPipelineType.Aruco },
{ name: "Custom Test", value: WebsocketPipelineType.CustomTest }
]; ];
if (useSettingsStore().general.supportedBackends.length > 0) { if (useSettingsStore().general.supportedBackends.length > 0) {
pipelineTypes.push({ name: "Object Detection", value: WebsocketPipelineType.ObjectDetection }); pipelineTypes.push({ name: "Object Detection", value: WebsocketPipelineType.ObjectDetection });
@@ -168,7 +172,8 @@ const pipelineTypesWrapper = computed<{ name: string; value: number }[]>(() => {
{ name: "Reflective", value: WebsocketPipelineType.Reflective }, { name: "Reflective", value: WebsocketPipelineType.Reflective },
{ name: "Colored Shape", value: WebsocketPipelineType.ColoredShape }, { name: "Colored Shape", value: WebsocketPipelineType.ColoredShape },
{ name: "AprilTag", value: WebsocketPipelineType.AprilTag }, { name: "AprilTag", value: WebsocketPipelineType.AprilTag },
{ name: "Aruco", value: WebsocketPipelineType.Aruco } { name: "Aruco", value: WebsocketPipelineType.Aruco },
{ name: "Custom Test", value: WebsocketPipelineType.CustomTest }
]; ];
if (useSettingsStore().general.supportedBackends.length > 0) { if (useSettingsStore().general.supportedBackends.length > 0) {
pipelineTypes.push({ name: "Object Detection", value: WebsocketPipelineType.ObjectDetection }); pipelineTypes.push({ name: "Object Detection", value: WebsocketPipelineType.ObjectDetection });
@@ -230,6 +235,9 @@ useCameraSettingsStore().$subscribe((mutation, state) => {
case PipelineType.ObjectDetection: case PipelineType.ObjectDetection:
pipelineType.value = WebsocketPipelineType.ObjectDetection; pipelineType.value = WebsocketPipelineType.ObjectDetection;
break; break;
case PipelineType.CustomTest:
pipelineType.value = WebsocketPipelineType.CustomTest;
break;
} }
}); });
</script> </script>
@@ -1,4 +1,4 @@
<script setup lang="ts"> zz<script setup lang="ts">
import { computed } from "vue"; import { computed } from "vue";
import { useCameraSettingsStore } from "@/stores/settings/CameraSettingsStore"; import { useCameraSettingsStore } from "@/stores/settings/CameraSettingsStore";
import { useStateStore } from "@/stores/StateStore"; import { useStateStore } from "@/stores/StateStore";
@@ -14,6 +14,7 @@ import TargetsTab from "@/components/dashboard/tabs/TargetsTab.vue";
import PnPTab from "@/components/dashboard/tabs/PnPTab.vue"; import PnPTab from "@/components/dashboard/tabs/PnPTab.vue";
import Map3DTab from "@/components/dashboard/tabs/Map3DTab.vue"; import Map3DTab from "@/components/dashboard/tabs/Map3DTab.vue";
import { WebsocketPipelineType } from "@/types/WebsocketDataTypes"; import { WebsocketPipelineType } from "@/types/WebsocketDataTypes";
import CustomTestTab from "@/components/dashboard/tabs/CustomTestTab.vue";
interface ConfigOption { interface ConfigOption {
tabName: string; tabName: string;
@@ -45,6 +46,10 @@ const allTabs = Object.freeze({
tabName: "Object Detection", tabName: "Object Detection",
component: ObjectDetectionTab component: ObjectDetectionTab
}, },
customTestTab: {
tabName: "Custom test",
component: CustomTestTab
},
outputTab: { outputTab: {
tabName: "Output", tabName: "Output",
component: OutputTab component: OutputTab
@@ -81,6 +86,7 @@ const getTabGroups = (): ConfigOption[][] => {
allTabs.apriltagTab, allTabs.apriltagTab,
allTabs.arucoTab, allTabs.arucoTab,
allTabs.objectDetectionTab, allTabs.objectDetectionTab,
allTabs.customTestTab,
allTabs.outputTab allTabs.outputTab
], ],
[allTabs.targetsTab, allTabs.pnpTab, allTabs.map3dTab] [allTabs.targetsTab, allTabs.pnpTab, allTabs.map3dTab]
@@ -94,6 +100,7 @@ const getTabGroups = (): ConfigOption[][] => {
allTabs.apriltagTab, allTabs.apriltagTab,
allTabs.arucoTab, allTabs.arucoTab,
allTabs.objectDetectionTab, allTabs.objectDetectionTab,
allTabs.customTestTab,
allTabs.outputTab allTabs.outputTab
], ],
[allTabs.targetsTab, allTabs.pnpTab, allTabs.map3dTab] [allTabs.targetsTab, allTabs.pnpTab, allTabs.map3dTab]
@@ -102,7 +109,7 @@ const getTabGroups = (): ConfigOption[][] => {
return [ return [
[allTabs.inputTab], [allTabs.inputTab],
[allTabs.thresholdTab], [allTabs.thresholdTab],
[allTabs.contoursTab, allTabs.apriltagTab, allTabs.arucoTab, allTabs.objectDetectionTab, allTabs.outputTab], [allTabs.contoursTab, allTabs.apriltagTab, allTabs.arucoTab, allTabs.objectDetectionTab, allTabs.customTestTab,allTabs.outputTab],
[allTabs.targetsTab, allTabs.pnpTab, allTabs.map3dTab] [allTabs.targetsTab, allTabs.pnpTab, allTabs.map3dTab]
]; ];
} }
@@ -116,8 +123,9 @@ const tabGroups = computed<ConfigOption[][]>(() => {
const allow3d = useCameraSettingsStore().currentPipelineSettings.solvePNPEnabled; const allow3d = useCameraSettingsStore().currentPipelineSettings.solvePNPEnabled;
const isAprilTag = useCameraSettingsStore().currentWebsocketPipelineType === WebsocketPipelineType.AprilTag; const isAprilTag = useCameraSettingsStore().currentWebsocketPipelineType === WebsocketPipelineType.AprilTag;
const isAruco = useCameraSettingsStore().currentWebsocketPipelineType === WebsocketPipelineType.Aruco; const isAruco = useCameraSettingsStore().currentWebsocketPipelineType === WebsocketPipelineType.Aruco;
const isObjectDetection = const isObjectDetection = useCameraSettingsStore().currentWebsocketPipelineType === WebsocketPipelineType.ObjectDetection;
useCameraSettingsStore().currentWebsocketPipelineType === WebsocketPipelineType.ObjectDetection; const isCustomTest = useCameraSettingsStore().currentWebsocketPipelineType === WebsocketPipelineType.CustomTest;
return getTabGroups() return getTabGroups()
.map((tabGroup) => .map((tabGroup) =>
@@ -129,7 +137,8 @@ const tabGroups = computed<ConfigOption[][]>(() => {
!((isAprilTag || isAruco || isObjectDetection) && tabConfig.tabName === "Contours") && //Filter out contours if we're doing AprilTags !((isAprilTag || isAruco || isObjectDetection) && tabConfig.tabName === "Contours") && //Filter out contours if we're doing AprilTags
!(!isAprilTag && tabConfig.tabName === "AprilTag") && //Filter out apriltag unless we actually are doing AprilTags !(!isAprilTag && tabConfig.tabName === "AprilTag") && //Filter out apriltag unless we actually are doing AprilTags
!(!isAruco && tabConfig.tabName === "Aruco") && !(!isAruco && tabConfig.tabName === "Aruco") &&
!(!isObjectDetection && tabConfig.tabName === "Object Detection") //Filter out aruco unless we actually are doing Aruco !(!isObjectDetection && tabConfig.tabName === "Object Detection") && //Filter out aruco unless we actually are doing Aruco
!(!isCustomTest && tabConfig.tabName === "Custom test") // Filter out custom test
) )
) )
.filter((it) => it.length); // Remove empty tab groups .filter((it) => it.length); // Remove empty tab groups
@@ -23,17 +23,39 @@ const interactiveCols = computed(() =>
</script> </script>
<template> <template>
<div v-if="currentPipelineSettings.pipelineType === PipelineType.AprilTag"> <div v-if="currentPipelineSettings.pipelineType === PipelineType.CustomTest">
<pv-slider <pv-slider
v-model="currentPipelineSettings.blur" v-model="currentPipelineSettings.test1"
class="pt-2" class="pt-2"
:slider-cols="interactiveCols" :slider-cols="interactiveCols"
label="Blur" label="Test 1"
tooltip="Gaussian blur added to the image, high FPS cost for slightly decreased noise" tooltip="Gaussian blur added to the image, high FPS cost for slightly decreased noise"
:min="0" :min="0"
:max="5" :max="10"
:step="0.1" :step="1"
@input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ blur: value }, false)" @input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ test1: value }, false)"
/>
<pv-slider
v-model="currentPipelineSettings.test2"
class="pt-2"
:slider-cols="interactiveCols"
label="Test 2"
tooltip="Gaussian blur added to the image, high FPS cost for slightly decreased noise"
:min="0"
:max="10"
:step="1"
@input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ test2: value }, false)"
/>
<pv-slider
v-model="currentPipelineSettings.test3"
class="pt-2"
:slider-cols="interactiveCols"
label="Test 3"
tooltip="Gaussian blur added to the image, high FPS cost for slightly decreased noise"
:min="0"
:max="10"
:step="1"
@input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ test3: value }, false)"
/> />
</div> </div>
</template> </template>
+2 -2
View File
@@ -318,7 +318,7 @@ export const DefaultObjectDetectionPipelineSettings: ObjectDetectionPipelineSett
}; };
export interface CustomTestPipelineSettings extends PipelineSettings { export interface CustomTestPipelineSettings extends PipelineSettings {
pipelineType: PipelineType.AprilTag; pipelineType: PipelineType.CustomTest;
test1: number; test1: number;
test2: number; test2: number;
test3: number; test3: number;
@@ -329,7 +329,7 @@ export type ConfigurableCustomTestPipelineSettings = Partial<
ConfigurablePipelineSettings; ConfigurablePipelineSettings;
export const DefaultCustomTestPipelineSettings: CustomTestPipelineSettings = { export const DefaultCustomTestPipelineSettings: CustomTestPipelineSettings = {
...DefaultPipelineSettings, ...DefaultPipelineSettings,
pipelineType: PipelineType.AprilTag, pipelineType: PipelineType.CustomTest,
cameraGain: 20, cameraGain: 20,
targetModel: TargetModel.InfiniteRechargeHighGoalOuter, targetModel: TargetModel.InfiniteRechargeHighGoalOuter,
ledMode: true, ledMode: true,
@@ -107,5 +107,6 @@ export enum WebsocketPipelineType {
ColoredShape = 1, ColoredShape = 1,
AprilTag = 2, AprilTag = 2,
Aruco = 3, Aruco = 3,
ObjectDetection = 4 ObjectDetection = 4,
CustomTest = 5
} }
@@ -17,9 +17,10 @@
package org.photonvision.vision.opencv; package org.photonvision.vision.opencv;
import java.util.Comparator;
import org.photonvision.vision.target.PotentialTarget; import org.photonvision.vision.target.PotentialTarget;
import java.util.Comparator;
public enum ContourSortMode { public enum ContourSortMode {
Largest( Largest(
Comparator.comparingDouble(PotentialTarget::getArea) Comparator.comparingDouble(PotentialTarget::getArea)
@@ -70,7 +70,9 @@ public class AprilTagDetectionPipe
@Override @Override
public void release() { public void release() {
m_detector.close(); if(m_detector != null) {
m_detector = null; m_detector.close();
m_detector = null;
}
} }
} }
@@ -68,7 +68,7 @@ public abstract class CVPipeline<R extends CVPipelineResult, S extends CVPipelin
public R run(Frame frame, QuirkyCamera cameraQuirks) { public R run(Frame frame, QuirkyCamera cameraQuirks) {
if (released) { if (released) {
throw new RuntimeException("Pipeline use-after-free!"); throw new RuntimeException( settings.pipelineNickname + " Pipeline use-after-free!");
} }
if (settings == null) { if (settings == null) {
throw new RuntimeException("No settings provided for pipeline!"); throw new RuntimeException("No settings provided for pipeline!");
@@ -92,6 +92,7 @@ public abstract class CVPipeline<R extends CVPipelineResult, S extends CVPipelin
*/ */
@Override @Override
public void release() { public void release() {
new Exception().printStackTrace();
released = true; released = true;
} }
} }
@@ -33,7 +33,8 @@ import org.photonvision.vision.opencv.ImageRotationMode;
@JsonSubTypes.Type(value = DriverModePipelineSettings.class), @JsonSubTypes.Type(value = DriverModePipelineSettings.class),
@JsonSubTypes.Type(value = AprilTagPipelineSettings.class), @JsonSubTypes.Type(value = AprilTagPipelineSettings.class),
@JsonSubTypes.Type(value = ArucoPipelineSettings.class), @JsonSubTypes.Type(value = ArucoPipelineSettings.class),
@JsonSubTypes.Type(value = ObjectDetectionPipelineSettings.class) @JsonSubTypes.Type(value = ObjectDetectionPipelineSettings.class),
@JsonSubTypes.Type(value = CustomTestPipelineSettings.class)
}) })
public class CVPipelineSettings implements Cloneable { public class CVPipelineSettings implements Cloneable {
public int pipelineIndex = 0; public int pipelineIndex = 0;
@@ -2,6 +2,8 @@ package org.photonvision.vision.pipeline;
import org.photonvision.vision.frame.Frame; import org.photonvision.vision.frame.Frame;
import org.photonvision.vision.frame.FrameThresholdType; import org.photonvision.vision.frame.FrameThresholdType;
import org.photonvision.vision.pipe.CVPipe;
import org.photonvision.vision.pipe.impl.BlurPipe;
import org.photonvision.vision.pipeline.result.CVPipelineResult; import org.photonvision.vision.pipeline.result.CVPipelineResult;
import java.util.List; import java.util.List;
@@ -9,8 +11,11 @@ import java.util.List;
public class CustomTestPipeline extends CVPipeline<CVPipelineResult, CustomTestPipelineSettings> { public class CustomTestPipeline extends CVPipeline<CVPipelineResult, CustomTestPipelineSettings> {
private static final FrameThresholdType PROCESSING_TYPE = FrameThresholdType.GREYSCALE; private static final FrameThresholdType PROCESSING_TYPE = FrameThresholdType.GREYSCALE;
public CustomTestPipeline(FrameThresholdType thresholdType) { private final BlurPipe blurPipe = new BlurPipe();
super(thresholdType);
public CustomTestPipeline() {
super(PROCESSING_TYPE);
settings = new CustomTestPipelineSettings();
} }
public CustomTestPipeline(CustomTestPipelineSettings settings) { public CustomTestPipeline(CustomTestPipelineSettings settings) {
@@ -20,7 +25,20 @@ public class CustomTestPipeline extends CVPipeline<CVPipelineResult, CustomTestP
@Override @Override
protected void setPipeParamsImpl() { protected void setPipeParamsImpl() {
// super.setPipeParamsImpl();
this.released = false;
blurPipe.setParams(new BlurPipe.BlurParams(5));
// if (frameStaticProperties.cameraCalibration != null) {
// var cameraMatrix = frameStaticProperties.cameraCalibration.getCameraIntrinsicsMat();
// if (cameraMatrix != null && cameraMatrix.rows() > 0) {
// var cx = cameraMatrix.get(0, 2)[0];
// var cy = cameraMatrix.get(1, 2)[0];
// var fx = cameraMatrix.get(0, 0)[0];
// var fy = cameraMatrix.get(1, 1)[0];
// }
// }
} }
@Override @Override
@@ -29,6 +47,16 @@ public class CustomTestPipeline extends CVPipeline<CVPipelineResult, CustomTestP
// We asked for a GREYSCALE frame, but didn't get one -- best we can do is give up // We asked for a GREYSCALE frame, but didn't get one -- best we can do is give up
return new CVPipelineResult(frame.sequenceID, 0, 0, List.of(), frame); return new CVPipelineResult(frame.sequenceID, 0, 0, List.of(), frame);
} }
return new CVPipelineResult(frame.sequenceID, 50, 10, List.of(), frame);
var pr = blurPipe.run(frame.processedImage.getMat());
return new CVPipelineResult(frame.sequenceID, pr.nanosElapsed, 10, List.of(), frame);
} }
// @Override
// public void release() {
// super.release();
// }
} }
@@ -128,7 +128,7 @@ public class ObjectDetectionPipeline
var filterContoursResult = filterContoursPipe.run(rknnResult.output); var filterContoursResult = filterContoursPipe.run(rknnResult.output);
sumPipeNanosElapsed += filterContoursResult.nanosElapsed; sumPipeNanosElapsed += filterContoursResult.nanosElapsed;
CVPipeResult<List<PotentialTarget>> sortContoursResult = CVPipeResult<List< PotentialTarget>> sortContoursResult =
sortContoursPipe.run( sortContoursPipe.run(
filterContoursResult.output.stream() filterContoursResult.output.stream()
.map(shape -> new PotentialTarget(shape)) .map(shape -> new PotentialTarget(shape))
@@ -229,6 +229,8 @@ public class OutputStreamPipeline {
pipeProfileNanos[7] = 0; pipeProfileNanos[7] = 0;
pipeProfileNanos[8] = 0; pipeProfileNanos[8] = 0;
} }
} else if (settings instanceof CustomTestPipelineSettings) {
//TODO
} }
} }
@@ -243,6 +243,7 @@ public class PipelineManager {
private void recreateUserPipeline() { private void recreateUserPipeline() {
// Cleanup potential old native resources before swapping over from a user // Cleanup potential old native resources before swapping over from a user
// pipeline // pipeline
// logger.info(currentUserPipeline.getSettings().pipelineNickname);
if (currentUserPipeline != null && !(currentPipelineIndex < 0)) { if (currentUserPipeline != null && !(currentPipelineIndex < 0)) {
currentUserPipeline.release(); currentUserPipeline.release();
} }
@@ -112,6 +112,7 @@ public class VisionRunner {
// There's no guarantee the processing type change will occur this tick, so pipelines should // There's no guarantee the processing type change will occur this tick, so pipelines should
// check themselves // check themselves
try { try {
// logger.info("Running pipeline with name: " + pipeline.getSettings().pipelineNickname);
var pipelineResult = pipeline.run(frame, cameraQuirks); var pipelineResult = pipeline.run(frame, cameraQuirks);
pipelineResultConsumer.accept(pipelineResult); pipelineResultConsumer.accept(pipelineResult);
} catch (Exception ex) { } catch (Exception ex) {
+1
View File
@@ -43,6 +43,7 @@ node {
} }
tasks.register('copyClientUIToResources', Copy) { tasks.register('copyClientUIToResources', Copy) {
dependsOn "processResources"
from "${projectDir}/../photon-client/dist/" from "${projectDir}/../photon-client/dist/"
into "${projectDir}/src/main/resources/web/" into "${projectDir}/src/main/resources/web/"
} }