-
Notifications
You must be signed in to change notification settings - Fork 1
Apriltag ml experimental #2
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
base: main
Are you sure you want to change the base?
Changes from all commits
3cd4e18
b90978d
3c2cab3
2cfef2a
38d649b
588c58f
bdc7c60
acb758d
112bc5f
e40f174
38770a1
59ce99b
631a08e
815e5ca
76e7408
f317823
096ab59
826a44c
bb09502
10cc9cf
7555c35
1b5e2c0
4a1c0fa
1c9142f
9e7d958
e956409
6f19b1b
a8373bc
9fd655d
09bad7e
c470cca
df4d5af
95d5796
f6a2f2c
11570b1
3daac05
b22d54c
121f7ed
7956e10
7865a20
4e63e44
cb77d57
8287a6d
dc85ac7
17935a3
8e97a64
40c23f7
993da22
38f8075
6898af4
0c41b40
c1024fd
a2b9f3a
b82ffed
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,6 +3,7 @@ import PvSelect from "@/components/common/pv-select.vue"; | |
| import { useCameraSettingsStore } from "@/stores/settings/CameraSettingsStore"; | ||
| import { type ActivePipelineSettings, PipelineType, RobotOffsetPointMode } from "@/types/PipelineTypes"; | ||
| import PvSwitch from "@/components/common/pv-switch.vue"; | ||
| import PvSlider from "@/components/common/pv-slider.vue"; | ||
| import { computed } from "vue"; | ||
| import { RobotOffsetType } from "@/types/SettingTypes"; | ||
| import { useStateStore } from "@/stores/StateStore"; | ||
|
|
@@ -58,14 +59,17 @@ const interactiveCols = computed(() => | |
|
|
||
| <template> | ||
| <div> | ||
| <pv-switch | ||
| v-model="useCameraSettingsStore().currentPipelineSettings.outputShowMultipleTargets" | ||
| label="Show Multiple Targets" | ||
| tooltip="If enabled, up to five targets will be displayed and sent via PhotonLib, instead of just one" | ||
| :disabled="isTagPipeline" | ||
| <pv-slider | ||
| v-model="useCameraSettingsStore().currentPipelineSettings.outputMaximumTargets" | ||
| label="Maximum Targets" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Maximum ML-detected Tags" is more clear maybe. obviously this was copy-pasted from object detection where more general language is needed |
||
| tooltip="The maximum number of targets to display and send." | ||
| :hidden="isTagPipeline" | ||
| :min="1" | ||
| :max="127" | ||
| :step="1" | ||
| :switch-cols="interactiveCols" | ||
| @update:modelValue=" | ||
| (value) => useCameraSettingsStore().changeCurrentPipelineSetting({ outputShowMultipleTargets: value }, false) | ||
| (value) => useCameraSettingsStore().changeCurrentPipelineSetting({ outputMaximumTargets: value }, false) | ||
| " | ||
| /> | ||
| <pv-switch | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -66,7 +66,7 @@ export interface PipelineSettings { | |
| hsvHue: WebsocketNumberPair | [number, number]; | ||
| ledMode: boolean; | ||
| hueInverted: boolean; | ||
| outputShowMultipleTargets: boolean; | ||
| outputMaximumTargets: number; | ||
| contourSortMode: number; | ||
| cameraExposureRaw: number; | ||
| cameraMinExposureRaw: number; | ||
|
|
@@ -108,7 +108,7 @@ export type ConfigurablePipelineSettings = Partial< | |
| // Omitted settings are changed for all pipeline types | ||
| export const DefaultPipelineSettings: Omit< | ||
| PipelineSettings, | ||
| "cameraGain" | "targetModel" | "ledMode" | "outputShowMultipleTargets" | "cameraExposureRaw" | "pipelineType" | ||
| "cameraGain" | "targetModel" | "ledMode" | "cameraExposureRaw" | "pipelineType" | ||
| > = { | ||
| offsetRobotOffsetMode: RobotOffsetPointMode.None, | ||
| streamingFrameDivisor: 0, | ||
|
|
@@ -137,6 +137,7 @@ export const DefaultPipelineSettings: Omit< | |
| offsetDualPointB: { x: 0, y: 0 }, | ||
| hsvHue: { first: 50, second: 180 }, | ||
| hueInverted: false, | ||
| outputMaximumTargets: 20, | ||
| contourSortMode: 0, | ||
| offsetSinglePoint: { x: 0, y: 0 }, | ||
| cameraBrightness: 50, | ||
|
|
@@ -166,7 +167,7 @@ export const DefaultReflectivePipelineSettings: ReflectivePipelineSettings = { | |
| cameraGain: 20, | ||
| targetModel: TargetModel.InfiniteRechargeHighGoalOuter, | ||
| ledMode: true, | ||
| outputShowMultipleTargets: false, | ||
| outputMaximumTargets: 20, | ||
| cameraExposureRaw: 6, | ||
| pipelineType: PipelineType.Reflective, | ||
|
|
||
|
|
@@ -197,7 +198,7 @@ export const DefaultColoredShapePipelineSettings: ColoredShapePipelineSettings = | |
| cameraGain: 75, | ||
| targetModel: TargetModel.InfiniteRechargeHighGoalOuter, | ||
| ledMode: true, | ||
| outputShowMultipleTargets: false, | ||
| outputMaximumTargets: 20, | ||
| cameraExposureRaw: 20, | ||
| pipelineType: PipelineType.ColoredShape, | ||
|
|
||
|
|
@@ -227,6 +228,14 @@ export interface AprilTagPipelineSettings extends PipelineSettings { | |
| tagFamily: AprilTagFamily; | ||
| doMultiTarget: boolean; | ||
| doSingleTargetAlways: boolean; | ||
| // ML-assisted detection settings | ||
| useMLDetection: boolean; | ||
| mlConfidenceThreshold: number; | ||
| mlNmsThreshold: number; | ||
| mlRoiPaddingPixels: number; | ||
| mlFallbackToTraditional: boolean; | ||
| mlModelName: string | null; | ||
| showDetectionBoxes: boolean; | ||
| } | ||
| export type ConfigurableAprilTagPipelineSettings = Partial< | ||
| Omit<AprilTagPipelineSettings, "pipelineType" | "hammingDist" | "debug"> | ||
|
|
@@ -237,10 +246,9 @@ export const DefaultAprilTagPipelineSettings: AprilTagPipelineSettings = { | |
| cameraGain: 75, | ||
| targetModel: TargetModel.AprilTag6p5in_36h11, | ||
| ledMode: false, | ||
| outputShowMultipleTargets: true, | ||
| outputMaximumTargets: 127, | ||
| cameraExposureRaw: 20, | ||
| pipelineType: PipelineType.AprilTag, | ||
|
|
||
| hammingDist: 0, | ||
| numIterations: 40, | ||
| decimate: 1, | ||
|
|
@@ -251,7 +259,15 @@ export const DefaultAprilTagPipelineSettings: AprilTagPipelineSettings = { | |
| threads: 4, | ||
| tagFamily: AprilTagFamily.Family36h11, | ||
| doMultiTarget: false, | ||
| doSingleTargetAlways: false | ||
| doSingleTargetAlways: false, | ||
| // ML-assisted detection defaults | ||
| useMLDetection: false, | ||
| mlConfidenceThreshold: 0.5, | ||
| mlNmsThreshold: 0.45, | ||
| mlRoiPaddingPixels: 40, | ||
| mlFallbackToTraditional: true, | ||
| mlModelName: null, | ||
| showDetectionBoxes: true | ||
| }; | ||
|
|
||
| export interface ArucoPipelineSettings extends PipelineSettings { | ||
|
|
@@ -278,13 +294,12 @@ export type ConfigurableArucoPipelineSettings = Partial<Omit<ArucoPipelineSettin | |
| export const DefaultArucoPipelineSettings: ArucoPipelineSettings = { | ||
| ...DefaultPipelineSettings, | ||
| cameraGain: 75, | ||
| outputShowMultipleTargets: true, | ||
| outputMaximumTargets: 127, | ||
| targetModel: TargetModel.AprilTag6p5in_36h11, | ||
| cameraExposureRaw: -1, | ||
| cameraAutoExposure: true, | ||
| ledMode: false, | ||
| pipelineType: PipelineType.Aruco, | ||
|
|
||
| tagFamily: AprilTagFamily.Family36h11, | ||
| threshWinSizes: { first: 11, second: 91 }, | ||
| threshStepSize: 40, | ||
|
|
@@ -316,7 +331,7 @@ export const DefaultObjectDetectionPipelineSettings: ObjectDetectionPipelineSett | |
| cameraGain: 20, | ||
| targetModel: TargetModel.InfiniteRechargeHighGoalOuter, | ||
| ledMode: true, | ||
| outputShowMultipleTargets: false, | ||
| outputMaximumTargets: 20, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. gonna suggest this goes to 127, but maybe the PV/Wave stuff already addresses this |
||
| cameraExposureRaw: 6, | ||
| confidence: 0.9, | ||
| nms: 0.45, | ||
|
|
@@ -335,7 +350,7 @@ export const DefaultCalibration3dPipelineSettings: Calibration3dPipelineSettings | |
| cameraGain: 20, | ||
| targetModel: TargetModel.InfiniteRechargeHighGoalOuter, | ||
| ledMode: true, | ||
| outputShowMultipleTargets: false, | ||
| outputMaximumTargets: 1, | ||
| cameraExposureRaw: 6, | ||
| drawAllSnapshots: false | ||
| }; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -311,6 +311,56 @@ public Optional<Model> getDefaultModel() { | |
| return models.get(supportedBackends.get(0)).stream().findFirst(); | ||
| } | ||
|
|
||
| /** | ||
| * Gets the default AprilTag detection model. Searches for a model with "apriltag" in its | ||
| * nickname (case-insensitive). | ||
| * | ||
| * @return Optional containing the AprilTag model if found | ||
| */ | ||
| public Optional<Model> getDefaultAprilTagModel() { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this ok? this seems potentially cursed
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. specifically looking for "apriltag". Would this cause issues if an object detection model with "apriltag" (dumb, but you know...) in the name was used? Would it be better to use |
||
| if (models == null || supportedBackends.isEmpty()) { | ||
| return Optional.empty(); | ||
| } | ||
|
|
||
| for (Family backend : supportedBackends) { | ||
| if (models.containsKey(backend)) { | ||
| Optional<Model> model = | ||
| models.get(backend).stream() | ||
| .filter(m -> m.getNickname().toLowerCase().contains("apriltag")) | ||
| .findFirst(); | ||
| if (model.isPresent()) { | ||
| return model; | ||
| } | ||
| } | ||
| } | ||
| return Optional.empty(); | ||
| } | ||
|
|
||
| /** | ||
| * Gets a model by its exact nickname. | ||
| * | ||
| * @param name The nickname of the model to retrieve | ||
| * @return Optional containing the model if found | ||
| */ | ||
| public Optional<Model> getModelByName(String name) { | ||
| if (models == null || supportedBackends.isEmpty() || name == null) { | ||
| return Optional.empty(); | ||
| } | ||
|
|
||
| for (Family backend : supportedBackends) { | ||
| if (models.containsKey(backend)) { | ||
| Optional<Model> model = | ||
| models.get(backend).stream() | ||
| .filter(m -> m.getNickname().equals(name)) | ||
| .findFirst(); | ||
| if (model.isPresent()) { | ||
| return model; | ||
| } | ||
| } | ||
| } | ||
| return Optional.empty(); | ||
| } | ||
|
|
||
| // Do checking later on, when we create the model object | ||
| private void loadModel(Path path) { | ||
| if (models == null) { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i have no idea what this is. just leaving a comment here, no suggested fix rn