diff --git a/apriltagmodel/best.pt b/apriltagmodel/best.pt new file mode 100644 index 0000000000..ee9ee46910 Binary files /dev/null and b/apriltagmodel/best.pt differ diff --git a/photon-client/src/components/dashboard/tabs/AprilTagTab.vue b/photon-client/src/components/dashboard/tabs/AprilTagTab.vue index 249f80607e..6b908b0d57 100644 --- a/photon-client/src/components/dashboard/tabs/AprilTagTab.vue +++ b/photon-client/src/components/dashboard/tabs/AprilTagTab.vue @@ -5,19 +5,50 @@ import PvSlider from "@/components/common/pv-slider.vue"; import PvSwitch from "@/components/common/pv-switch.vue"; import { computed } from "vue"; import { useStateStore } from "@/stores/StateStore"; -import type { ActivePipelineSettings } from "@/types/PipelineTypes"; +import type { AprilTagPipelineSettings } from "@/types/PipelineTypes"; import { useCameraSettingsStore } from "@/stores/settings/CameraSettingsStore"; +import { useSettingsStore } from "@/stores/settings/GeneralSettingsStore"; +import type { ObjectDetectionModelProperties } from "@/types/SettingTypes"; import { useDisplay } from "vuetify"; // 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( - () => useCameraSettingsStore().currentPipelineSettings +const currentPipelineSettings = computed( + () => useCameraSettingsStore().currentPipelineSettings as AprilTagPipelineSettings ); const { mdAndDown } = useDisplay(); const interactiveCols = computed(() => mdAndDown.value && (!useStateStore().sidebarFolded || useCameraSettingsStore().isDriverMode) ? 8 : 7 ); + +// Check if ML detection is available on this platform +const mlDetectionAvailable = computed(() => useSettingsStore().general.supportedBackends.length > 0); + +// Filter models to only those supported by available backends +const supportedModels = computed(() => { + const { availableModels, supportedBackends } = useSettingsStore().general; + const isSupported = (model: ObjectDetectionModelProperties) => { + return supportedBackends.some((backend: string) => backend.toLowerCase() === model.family.toLowerCase()); + }; + return availableModels.filter(isSupported); +}); + +const selectedModel = computed({ + get: () => { + const currentModelName = currentPipelineSettings.value.mlModelName; + if (!currentModelName) return undefined; + + const index = supportedModels.value.findIndex((model) => model.nickname === currentModelName); + return index === -1 ? undefined : index; + }, + + set: (v) => { + if (v !== undefined && v >= 0 && v < supportedModels.value.length) { + const newModel = supportedModels.value[v]; + useCameraSettingsStore().changeCurrentPipelineSetting({ mlModelName: newModel.nickname }, true); + } + } +}); diff --git a/photon-client/src/components/dashboard/tabs/OutputTab.vue b/photon-client/src/components/dashboard/tabs/OutputTab.vue index 520288be30..22033ead30 100644 --- a/photon-client/src/components/dashboard/tabs/OutputTab.vue +++ b/photon-client/src/components/dashboard/tabs/OutputTab.vue @@ -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(() =>