Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Algae #1

Merged
merged 29 commits into from
Feb 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2bd0055
Initial Python pipeline code
samdev-7 Feb 1, 2025
872f71e
Preliminary client side support
samdev-7 Feb 1, 2025
9ac3584
Merge branch 'dev' into algae
samdev-7 Feb 16, 2025
b7ef79d
Initial port of algae pipeline
samdev-7 Feb 16, 2025
841c766
Output values to photonvision
samdev-7 Feb 16, 2025
82f0b10
Clean code and change debug drawing
samdev-7 Feb 16, 2025
ad2ef80
new camera matrix and PhotonVision java integration
EomLions Feb 19, 2025
2365d47
cameraOffset is 0
EomLions Feb 19, 2025
051ff53
todo list and in m
EomLions Feb 19, 2025
1a42cb8
converted single pipe to pipeline
EomLions Feb 21, 2025
dd54323
Do not use padding within pipe
samdev-7 Feb 22, 2025
b218cf2
Output threshold image
samdev-7 Feb 22, 2025
8d891d2
Code clean uo & expose params
samdev-7 Feb 22, 2025
fff82ae
Formatting fixes
samdev-7 Feb 22, 2025
0c27281
photon-client formatting fixes
samdev-7 Feb 22, 2025
7115ff0
Remove extra line
samdev-7 Feb 22, 2025
b948c37
Merge remote-tracking branch 'upstream/main' into algae
samdev-7 Feb 22, 2025
b44e76a
Configure settings for photon-client
samdev-7 Feb 22, 2025
9b179e9
Use area percentages in contour filtering
samdev-7 Feb 22, 2025
19dd6f4
Dynamic padding
samdev-7 Feb 22, 2025
167d16a
Add other algae pipeline settings to UI
samdev-7 Feb 22, 2025
a776dad
Formatting fixes
samdev-7 Feb 22, 2025
eb9bd36
Java formatting fixes
samdev-7 Feb 22, 2025
231a864
cahnged unit conversions for distance
EomLions Feb 22, 2025
4ce47f7
updated diameter of the ball
EomLions Feb 22, 2025
0917706
[TESTED] distance and angle with built in color thresholding
EomLions Feb 22, 2025
77978f4
Merge branch 'main' into algae
samdev-7 Feb 24, 2025
57410d7
Formatting
samdev-7 Feb 25, 2025
520872c
Add newline to end of file
samdev-7 Feb 25, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ const changeCurrentCameraUniqueName = (cameraUniqueName: string) => {
case PipelineType.ObjectDetection:
pipelineType.value = WebsocketPipelineType.ObjectDetection;
break;
case PipelineType.Algae:
pipelineType.value = WebsocketPipelineType.Algae;
break;
}
};

Expand Down Expand Up @@ -130,7 +133,8 @@ const validNewPipelineTypes = computed(() => {
{ name: "Reflective", value: WebsocketPipelineType.Reflective },
{ name: "Colored Shape", value: WebsocketPipelineType.ColoredShape },
{ name: "AprilTag", value: WebsocketPipelineType.AprilTag },
{ name: "Aruco", value: WebsocketPipelineType.Aruco }
{ name: "Aruco", value: WebsocketPipelineType.Aruco },
{ name: "Algae", value: WebsocketPipelineType.Algae }
];
if (useSettingsStore().general.supportedBackends.length > 0) {
pipelineTypes.push({ name: "Object Detection", value: WebsocketPipelineType.ObjectDetection });
Expand Down Expand Up @@ -168,7 +172,8 @@ const pipelineTypesWrapper = computed<{ name: string; value: number }[]>(() => {
{ name: "Reflective", value: WebsocketPipelineType.Reflective },
{ name: "Colored Shape", value: WebsocketPipelineType.ColoredShape },
{ name: "AprilTag", value: WebsocketPipelineType.AprilTag },
{ name: "Aruco", value: WebsocketPipelineType.Aruco }
{ name: "Aruco", value: WebsocketPipelineType.Aruco },
{ name: "Algae", value: WebsocketPipelineType.Algae }
];
if (useSettingsStore().general.supportedBackends.length > 0) {
pipelineTypes.push({ name: "Object Detection", value: WebsocketPipelineType.ObjectDetection });
Expand Down Expand Up @@ -230,6 +235,9 @@ useCameraSettingsStore().$subscribe((mutation, state) => {
case PipelineType.ObjectDetection:
pipelineType.value = WebsocketPipelineType.ObjectDetection;
break;
case PipelineType.Algae:
pipelineType.value = WebsocketPipelineType.Algae;
break;
}
});
const wrappedCameras = computed<SelectItem[]>(() =>
Expand Down
3 changes: 2 additions & 1 deletion photon-client/src/components/dashboard/ConfigOptions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,14 @@ const tabGroups = computed<ConfigOption[][]>(() => {
const isAruco = useCameraSettingsStore().currentWebsocketPipelineType === WebsocketPipelineType.Aruco;
const isObjectDetection =
useCameraSettingsStore().currentWebsocketPipelineType === WebsocketPipelineType.ObjectDetection;
const isAlgae = useCameraSettingsStore().currentWebsocketPipelineType === WebsocketPipelineType.Algae;

return getTabGroups()
.map((tabGroup) =>
tabGroup.filter(
(tabConfig) =>
!(!allow3d && tabConfig.tabName === "3D") && //Filter out 3D tab any time 3D isn't calibrated
!((!allow3d || isAprilTag || isAruco || isObjectDetection) && tabConfig.tabName === "PnP") && //Filter out the PnP config tab if 3D isn't available, or we're doing AprilTags
!((!allow3d || isAprilTag || isAruco || isObjectDetection || isAlgae) && tabConfig.tabName === "PnP") && //Filter out the PnP config tab if 3D isn't available, or we're doing AprilTags
!((isAprilTag || isAruco || isObjectDetection) && tabConfig.tabName === "Threshold") && //Filter out threshold tab 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
Expand Down
87 changes: 86 additions & 1 deletion photon-client/src/components/dashboard/tabs/ContoursTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,28 @@ const contourRadius = computed<[number, number]>({
}
}
});
const circularity = computed<[number, number]>({
get: () =>
currentPipelineSettings.value.pipelineType === PipelineType.Algae
? (Object.values(currentPipelineSettings.value.circularity) as [number, number])
: ([0, 0] as [number, number]),
set: (v) => {
if (currentPipelineSettings.value.pipelineType === PipelineType.Algae) {
currentPipelineSettings.value.circularity = v;
}
}
});
const edgeThresholds = computed<[number, number]>({
get: () =>
currentPipelineSettings.value.pipelineType === PipelineType.Algae
? (Object.values(currentPipelineSettings.value.edgeThresholds) as [number, number])
: ([0, 0] as [number, number]),
set: (v) => {
if (currentPipelineSettings.value.pipelineType === PipelineType.Algae) {
currentPipelineSettings.value.edgeThresholds = v;
}
}
});

const interactiveCols = computed(() =>
(getCurrentInstance()?.proxy.$vuetify.breakpoint.mdAndDown || false) &&
Expand All @@ -60,6 +82,7 @@ const interactiveCols = computed(() =>
<template>
<div>
<pv-select
v-if="currentPipelineSettings.pipelineType !== PipelineType.Algae"
v-model="useCameraSettingsStore().currentPipelineSettings.contourTargetOrientation"
label="Target Orientation"
tooltip="Used to determine how to calculate target landmarks, as well as aspect ratio"
Expand Down Expand Up @@ -87,7 +110,10 @@ const interactiveCols = computed(() =>
@input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ contourArea: value }, false)"
/>
<pv-range-slider
v-if="useCameraSettingsStore().currentPipelineType !== PipelineType.ColoredShape"
v-if="
useCameraSettingsStore().currentPipelineType !== PipelineType.ColoredShape &&
useCameraSettingsStore().currentPipelineType !== PipelineType.Algae
"
v-model="contourRatio"
label="Ratio (W/H)"
tooltip="Min and max ratio between the width and height of a contour's bounding rectangle"
Expand Down Expand Up @@ -118,6 +144,7 @@ const interactiveCols = computed(() =>
@input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ contourPerimeter: value }, false)"
/>
<pv-slider
v-if="currentPipelineSettings.pipelineType !== PipelineType.Algae"
v-model="useCameraSettingsStore().currentPipelineSettings.contourSpecklePercentage"
label="Speckle Rejection"
tooltip="Rejects contours whose average area is less than the given percentage of the average area of all the other contours"
Expand Down Expand Up @@ -231,5 +258,63 @@ const interactiveCols = computed(() =>
@input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ contourRadius: value }, false)"
/>
</template>
<template v-else-if="currentPipelineSettings.pipelineType === PipelineType.Algae">
<pv-range-slider
v-model="circularity"
label="Circularity"
:min="0"
:max="100"
:slider-cols="interactiveCols"
@input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ circularity: value }, false)"
/>
<pv-slider
v-model="currentPipelineSettings.padding"
label="Padding"
:min="0"
:max="500"
:slider-cols="interactiveCols"
@input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ padding: value }, false)"
/>
<pv-slider
v-model="currentPipelineSettings.erosion"
label="Erosion"
:min="0"
:max="8"
:slider-cols="interactiveCols"
@input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ erosion: value }, false)"
/>
<pv-slider
v-model="currentPipelineSettings.initialDilation"
label="Initial Dilation"
:min="0"
:max="8"
:slider-cols="interactiveCols"
@input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ initialDilation: value }, false)"
/>
<pv-range-slider
v-model="edgeThresholds"
label="Edge Threshold"
:min="0"
:max="1000"
:slider-cols="interactiveCols"
@input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ edgeThresholds: value }, false)"
/>
<pv-slider
v-model="currentPipelineSettings.edgeDilation"
label="Edge Dilation"
:min="0"
:max="8"
:slider-cols="interactiveCols"
@input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ edgeDilation: value }, false)"
/>
<pv-slider
v-model="currentPipelineSettings.finalDilation"
label="Final Dilation"
:min="0"
:max="8"
:slider-cols="interactiveCols"
@input="(value) => useCameraSettingsStore().changeCurrentPipelineSetting({ finalDilation: value }, false)"
/>
</template>
</div>
</template>
10 changes: 8 additions & 2 deletions photon-client/src/components/dashboard/tabs/PnPTab.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
<script setup lang="ts">
import PvSelect from "@/components/common/pv-select.vue";
import { useCameraSettingsStore } from "@/stores/settings/CameraSettingsStore";
import { TargetModel } from "@/types/PipelineTypes";
import { PipelineType, TargetModel, type ActivePipelineSettings } from "@/types/PipelineTypes";
import PvSlider from "@/components/common/pv-slider.vue";
import { computed, getCurrentInstance } from "vue";
import { useStateStore } from "@/stores/StateStore";

// TODO fix pipeline typing in order to fix this, the store settings call should be able to infer that only valid pipeline type settings are exposed based on pre-checks for the entire config section
// Defer reference to store access method
const currentPipelineSettings = computed<ActivePipelineSettings>(
() => useCameraSettingsStore().currentPipelineSettings
);

const interactiveCols = computed(() =>
(getCurrentInstance()?.proxy.$vuetify.breakpoint.mdAndDown || false) &&
(!useStateStore().sidebarFolded || useCameraSettingsStore().isDriverMode)
Expand All @@ -15,7 +21,7 @@ const interactiveCols = computed(() =>
</script>

<template>
<div>
<div v-if="currentPipelineSettings.pipelineType !== PipelineType.Algae">
<pv-select
v-model="useCameraSettingsStore().currentPipelineSettings.targetModel"
label="Target Model"
Expand Down
34 changes: 33 additions & 1 deletion photon-client/src/types/PipelineTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ export enum PipelineType {
ColoredShape = 3,
AprilTag = 4,
Aruco = 5,
ObjectDetection = 6
ObjectDetection = 6,
Algae = 7
}

export enum AprilTagFamily {
Expand Down Expand Up @@ -316,6 +317,35 @@ export const DefaultObjectDetectionPipelineSettings: ObjectDetectionPipelineSett
model: ""
};

export interface AlgaePipelineSettings extends PipelineSettings {
pipelineType: PipelineType.Algae;
circularity: WebsocketNumberPair | [number, number];
padding: number;
erosion: number;
initialDilation: number;
edgeThresholds: WebsocketNumberPair | [number, number];
edgeDilation: number;
finalDilation: number;
}
export type ConfigurableAlgaePipelineSettings = Partial<Omit<AlgaePipelineSettings, "pipelineType">> &
ConfigurablePipelineSettings;
export const DefaultAlgaePipelineSettings: AlgaePipelineSettings = {
...DefaultPipelineSettings,
cameraGain: 20,
targetModel: TargetModel.InfiniteRechargeHighGoalOuter,
ledMode: true,
outputShowMultipleTargets: false,
cameraExposureRaw: 6,
pipelineType: PipelineType.Algae,
circularity: { first: 30, second: 100 },
padding: 20,
erosion: 2,
initialDilation: 2,
edgeThresholds: { first: 100, second: 300 },
edgeDilation: 3,
finalDilation: 3
};

export interface Calibration3dPipelineSettings extends PipelineSettings {
drawAllSnapshots: boolean;
}
Expand All @@ -338,6 +368,7 @@ export type ActivePipelineSettings =
| AprilTagPipelineSettings
| ArucoPipelineSettings
| ObjectDetectionPipelineSettings
| AlgaePipelineSettings
| Calibration3dPipelineSettings;

export type ActiveConfigurablePipelineSettings =
Expand All @@ -346,4 +377,5 @@ export type ActiveConfigurablePipelineSettings =
| ConfigurableAprilTagPipelineSettings
| ConfigurableArucoPipelineSettings
| ConfigurableObjectDetectionPipelineSettings
| ConfigurableAlgaePipelineSettings
| ConfigurableCalibration3dPipelineSettings;
3 changes: 2 additions & 1 deletion photon-client/src/types/WebsocketDataTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,5 +115,6 @@ export enum WebsocketPipelineType {
ColoredShape = 1,
AprilTag = 2,
Aruco = 3,
ObjectDetection = 4
ObjectDetection = 4,
Algae = 5
}
Loading
Loading