{{ useStateStore().snackbarData.message }}
diff --git a/photon-client/src/components/app/photon-log-view.vue b/photon-client/src/components/app/photon-log-view.vue
index 41f05ff4e1..39710939b0 100644
--- a/photon-client/src/components/app/photon-log-view.vue
+++ b/photon-client/src/components/app/photon-log-view.vue
@@ -48,18 +48,18 @@ document.addEventListener("keydown", e => {
dark
>
View Program Logs
mdi-download
@@ -68,41 +68,44 @@ document.addEventListener("keydown", e => {
{{ getLogLevelFromIndex(level) }}
-
+
There are no Logs to show
-
+
{{ item.message }}
@@ -115,9 +118,9 @@ document.addEventListener("keydown", e => {
useStateStore().showLogModal = false"
+ color="white"
+ text
+ @click="() => useStateStore().showLogModal = false"
>
Close
diff --git a/photon-client/src/components/app/photon-sidebar.vue b/photon-client/src/components/app/photon-sidebar.vue
index 719f107093..f2f979db0f 100644
--- a/photon-client/src/components/app/photon-sidebar.vue
+++ b/photon-client/src/components/app/photon-sidebar.vue
@@ -14,37 +14,37 @@ const mdAndUp = computed(() => getCurrentInstance()?.proxy.$vuetify.bre
mdi-view-dashboard
@@ -54,9 +54,9 @@ const mdAndUp = computed(() => getCurrentInstance()?.proxy.$vuetify.bre
mdi-camera
@@ -66,8 +66,8 @@ const mdAndUp = computed(() => getCurrentInstance()?.proxy.$vuetify.bre
mdi-cog
@@ -77,8 +77,8 @@ const mdAndUp = computed(() => getCurrentInstance()?.proxy.$vuetify.bre
mdi-bookshelf
@@ -88,9 +88,9 @@ const mdAndUp = computed(() => getCurrentInstance()?.proxy.$vuetify.bre
compact = !compact"
+ v-if="mdAndUp"
+ link
+ @click="() => compact = !compact"
>
@@ -115,35 +115,35 @@ const mdAndUp = computed(() => getCurrentInstance()?.proxy.$vuetify.bre
mdi-robot
mdi-robot-off
NetworkTables server running for {{ useStateStore().ntConnectionStatus.clients }} clients
NetworkTables Server Connected!
- {{ useStateStore().ntConnectionStatus.address }}
-
+ {{ useStateStore().ntConnectionStatus.address }}
+
Not connected to NetworkTables Server!
@@ -156,8 +156,8 @@ const mdAndUp = computed(() => getCurrentInstance()?.proxy.$vuetify.bre
mdi-server-network
mdi-server-network-off
diff --git a/photon-client/src/components/cameras/CalibrationCard.vue b/photon-client/src/components/cameras/CalibrationCard.vue
index 65ad44d39a..67a5cde008 100644
--- a/photon-client/src/components/cameras/CalibrationCard.vue
+++ b/photon-client/src/components/cameras/CalibrationCard.vue
@@ -170,84 +170,84 @@ const endCalibration = () => {
Camera Calibration
useCameraSettingsStore().changeCurrentPipelineSetting({cameraVideoModeIndex: v}, false)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.cameraVideoModeIndex"
+ label="Resolution"
+ :select-cols="7"
+ :disabled="isCalibrating"
+ tooltip="Resolution to calibrate at (you will have to calibrate every resolution you use 3D mode on)"
+ :items="useCameraSettingsStore().currentCameraSettings.validVideoFormats.map(f => `${f.resolution.width} X ${f.resolution.height}`)"
+ @input="v => useCameraSettingsStore().changeCurrentPipelineSetting({cameraVideoModeIndex: v}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({streamingFrameDivisor: v}, false)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.streamingFrameDivisor"
+ label="Decimation"
+ tooltip="Resolution to which camera frames are downscaled for detection. Calibration still uses full-res"
+ :items="calibrationDivisors"
+ :select-cols="7"
+ @input="v => useCameraSettingsStore().changeCurrentPipelineSetting({streamingFrameDivisor: v}, false)"
/>
@@ -260,7 +260,7 @@ const endCalibration = () => {
Standard Deviation
-
+
Horizontal FOV
@@ -272,25 +272,25 @@ const endCalibration = () => {
-
- {{value.resolution.width}} X {{value.resolution.height}}
- {{value.mean !== undefined ? value.mean.toFixed(2) + "px" : "-"}}
- {{value.standardDeviation !== undefined ? value.standardDeviation.toFixed(2) + "px" : "-"}}
- {{value.horizontalFOV !== undefined ? value.horizontalFOV.toFixed(2) + "°" : "-"}}
- {{value.verticalFOV !== undefined ? value.verticalFOV.toFixed(2) + "°" : "-"}}
- {{value.diagonalFOV !== undefined ? value.diagonalFOV.toFixed(2) + "°" : "-"}}
-
+
+ {{ value.resolution.width }} X {{ value.resolution.height }}
+ {{ value.mean !== undefined ? value.mean.toFixed(2) + "px" : "-" }}
+ {{ value.standardDeviation !== undefined ? value.standardDeviation.toFixed(2) + "px" : "-" }}
+ {{ value.horizontalFOV !== undefined ? value.horizontalFOV.toFixed(2) + "°" : "-" }}
+ {{ value.verticalFOV !== undefined ? value.verticalFOV.toFixed(2) + "°" : "-" }}
+ {{ value.diagonalFOV !== undefined ? value.diagonalFOV.toFixed(2) + "°" : "-" }}
+
Snapshots: {{ useStateStore().calibrationData.imageCount }} of at least {{ useStateStore().calibrationData.minimumImageCount }}
@@ -299,62 +299,62 @@ const endCalibration = () => {
useCameraSettingsStore().changeCurrentPipelineSetting({cameraExposure: args}, false)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.cameraExposure"
+ :disabled="useCameraSettingsStore().currentCameraSettings.pipelineSettings.cameraAutoExposure"
+ label="Exposure"
+ tooltip="Directly controls how much light is allowed to fall onto the sensor, which affects apparent brightness"
+ :min="0"
+ :max="100"
+ :slider-cols="8"
+ :step="0.1"
+ @input="args => useCameraSettingsStore().changeCurrentPipelineSetting({cameraExposure: args}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({cameraBrightness: args}, false)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.cameraBrightness"
+ label="Brightness"
+ :min="0"
+ :max="100"
+ :slider-cols="8"
+ @input="args => useCameraSettingsStore().changeCurrentPipelineSetting({cameraBrightness: args}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({cameraAutoExposure: args}, false)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.cameraAutoExposure"
+ class="pt-2"
+ label="Auto Exposure"
+ :label-cols="4"
+ tooltip="Enables or Disables camera automatic adjustment for current lighting conditions"
+ @input="args => useCameraSettingsStore().changeCurrentPipelineSetting({cameraAutoExposure: args}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({cameraGain: args}, false)"
+ v-if="useCameraSettingsStore().currentPipelineSettings.cameraGain >= 0"
+ v-model="useCameraSettingsStore().currentPipelineSettings.cameraGain"
+ label="Camera Gain"
+ tooltip="Controls camera gain, similar to brightness"
+ :min="0"
+ :max="100"
+ @input="args => useCameraSettingsStore().changeCurrentPipelineSetting({cameraGain: args}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({cameraRedGain: args}, false)"
+ v-if="useCameraSettingsStore().currentPipelineSettings.cameraRedGain !== -1"
+ v-model="useCameraSettingsStore().currentPipelineSettings.cameraRedGain"
+ label="Red AWB Gain"
+ :min="0"
+ :max="100"
+ tooltip="Controls red automatic white balance gain, which affects how the camera captures colors in different conditions"
+ @input="args => useCameraSettingsStore().changeCurrentPipelineSetting({cameraRedGain: args}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({cameraBlueGain: args}, false)"
+ v-if="useCameraSettingsStore().currentPipelineSettings.cameraBlueGain !== -1"
+ v-model="useCameraSettingsStore().currentPipelineSettings.cameraBlueGain"
+ label="Blue AWB Gain"
+ :min="0"
+ :max="100"
+ tooltip="Controls blue automatic white balance gain, which affects how the camera captures colors in different conditions"
+ @input="args => useCameraSettingsStore().changeCurrentPipelineSetting({cameraBlueGain: args}, false)"
/>
@@ -362,23 +362,23 @@ const endCalibration = () => {
{{ isCalibrating ? "Take Snapshot" : "Start Calibration" }}
{{ useStateStore().calibrationData.hasEnoughImages ? "Finish Calibration" : "Cancel Calibration" }}
@@ -387,12 +387,12 @@ const endCalibration = () => {
mdi-download
@@ -402,11 +402,11 @@ const endCalibration = () => {
mdi-upload
@@ -414,32 +414,34 @@ const endCalibration = () => {
Import From CalibDB
- Camera Calibration
+
+ Camera Calibration
+
mdi-cancel
@@ -447,26 +449,26 @@ const endCalibration = () => {
Camera is being calibrated. This process may take several minutes...
mdi-check-bold
- Camera has been successfully calibrated for {{useCameraSettingsStore().currentVideoFormat.resolution}}!
+ Camera has been successfully calibrated for {{ useCameraSettingsStore().currentVideoFormat.resolution }}!
mdi-close
@@ -477,10 +479,10 @@ const endCalibration = () => {
OK
diff --git a/photon-client/src/components/cameras/CameraSettingsCard.vue b/photon-client/src/components/cameras/CameraSettingsCard.vue
index 10307c622c..e484e33690 100644
--- a/photon-client/src/components/cameras/CameraSettingsCard.vue
+++ b/photon-client/src/components/cameras/CameraSettingsCard.vue
@@ -41,34 +41,34 @@ const saveCameraSettings = () => {
Camera Settings
useCameraSettingsStore().setCurrentCameraIndex(args)"
+ v-model="useStateStore().currentCameraIndex"
+ label="Camera"
+ :items="useCameraSettingsStore().cameraNames"
+ :disabled="useCameraSettingsStore().cameraNames.length <= 1"
+ :select-cols="8"
+ @input="args => useCameraSettingsStore().setCurrentCameraIndex(args)"
/>
mdi-content-save
diff --git a/photon-client/src/components/common/cv-icon.vue b/photon-client/src/components/common/cv-icon.vue
index 7dec9d02cc..4b100c710f 100644
--- a/photon-client/src/components/common/cv-icon.vue
+++ b/photon-client/src/components/common/cv-icon.vue
@@ -21,12 +21,12 @@ const hoverClass = props.hover ? "hover" : "";
nudge-right="10"
:disabled="tooltip === undefined"
>
-
+
{{ iconName }}
diff --git a/photon-client/src/components/common/cv-range-slider.vue b/photon-client/src/components/common/cv-range-slider.vue
index a1925fe623..3b600e0cef 100644
--- a/photon-client/src/components/common/cv-range-slider.vue
+++ b/photon-client/src/components/common/cv-range-slider.vue
@@ -64,10 +64,9 @@ const changeFromSlot = (v, i) => {
thumb-color="accent"
:step="step"
>
-
+
changeFromSlot(v, 0)"
dark
color="accent"
class="mt-0 pt-0"
@@ -78,12 +77,12 @@ const changeFromSlot = (v, i) => {
:step="step"
type="number"
style="width: 60px"
+ @input="v => changeFromSlot(v, 0)"
/>
-
+
changeFromSlot(v, 1)"
dark
color="accent"
class="mt-0 pt-0"
@@ -94,6 +93,7 @@ const changeFromSlot = (v, i) => {
:step="step"
type="number"
style="width: 60px"
+ @input="v => changeFromSlot(v, 1)"
/>
diff --git a/photon-client/src/components/common/cv-slider.vue b/photon-client/src/components/common/cv-slider.vue
index c31ac04281..e938f17927 100644
--- a/photon-client/src/components/common/cv-slider.vue
+++ b/photon-client/src/components/common/cv-slider.vue
@@ -52,7 +52,7 @@ const localValue = computed({
:disabled="disabled"
:step="step"
>
-
+
-
+
{
-
+
useCameraSettingsStore().setCurrentCameraIndex(args)"
+ v-if="!isCameraNameEdit"
+ v-model="useStateStore().currentCameraIndex"
+ label="Camera"
+ :items="useCameraSettingsStore().cameraNames"
+ :disabled="useCameraSettingsStore().cameraNames.length <= 1"
+ @input="args => useCameraSettingsStore().setCurrentCameraIndex(args)"
/>
-
+
-
- useCameraSettingsStore().changeCurrentPipelineIndex(args, true)"
- />
+
+ useCameraSettingsStore().changeCurrentPipelineIndex(args, true)"
+ />
savePipelineNameEdit(v)"
- @onEscape="cancelPipelineNameEdit"
+ v-else
+ v-model="currentPipelineName"
+ :input-cols="12-3"
+ :rules="[v => checkPipelineName(v)]"
+ label="Pipeline"
+ @onEnter="v => savePipelineNameEdit(v)"
+ @onEscape="cancelPipelineNameEdit"
/>
-
+
-
+
mdi-menu
+ color="#c5c5c5"
+ :right="true"
+ icon-name="mdi-pencil"
+ tooltip="Edit pipeline name"
+ />
@@ -241,69 +254,72 @@ const cancelChangePipelineType = () => {
-
+
Create New Pipeline
Save
Cancel
@@ -311,18 +327,18 @@ const cancelChangePipelineType = () => {
Pipeline Deletion Confirmation
@@ -333,14 +349,14 @@ const cancelChangePipelineType = () => {
Yes, Im Sure
No, Take me Back
@@ -348,13 +364,13 @@ const cancelChangePipelineType = () => {
Change Pipeline Type
@@ -364,14 +380,14 @@ const cancelChangePipelineType = () => {
Yes, Im Sure
No, Take me Back
diff --git a/photon-client/src/components/dashboard/CamerasCard.vue b/photon-client/src/components/dashboard/CamerasCard.vue
index 1f68122837..357ec7dd2f 100644
--- a/photon-client/src/components/dashboard/CamerasCard.vue
+++ b/photon-client/src/components/dashboard/CamerasCard.vue
@@ -30,22 +30,22 @@ const fpsTooLow = computed(() => {
Cameras
Processing @ {{ Math.round(useStateStore().pipelineResults?.fps || 0) }} FPS –
@@ -63,17 +63,20 @@ const fpsTooLow = computed(() => {
-
+
-
+
(() => {
style="max-width: 500px; display: flex; align-items: center"
>
diff --git a/photon-client/src/components/dashboard/PipelineConfigCard.vue b/photon-client/src/components/dashboard/PipelineConfigCard.vue
index 777dbcbb0d..1f5a0d4a5c 100644
--- a/photon-client/src/components/dashboard/PipelineConfigCard.vue
+++ b/photon-client/src/components/dashboard/PipelineConfigCard.vue
@@ -116,35 +116,38 @@ onBeforeUpdate(() => {
-
+
- {{tabConfig.tabName}}
+ {{ tabConfig.tabName }}
-
+
diff --git a/photon-client/src/components/dashboard/PipelineConfigTabs/AprilTagTab.vue b/photon-client/src/components/dashboard/PipelineConfigTabs/AprilTagTab.vue
index d7e6d76c98..d64c9927ed 100644
--- a/photon-client/src/components/dashboard/PipelineConfigTabs/AprilTagTab.vue
+++ b/photon-client/src/components/dashboard/PipelineConfigTabs/AprilTagTab.vue
@@ -17,69 +17,69 @@ const interactiveCols = computed(() => (getCurrentInstance()?.proxy.$vuetify.bre
useCameraSettingsStore().changeCurrentPipelineSetting({tagFamily: value}, false)"
+ v-model="currentPipelineSettings.tagFamily"
+ label="Target family"
+ :items="['AprilTag Family 36h11', 'AprilTag Family 25h9', 'AprilTag Family 16h5']"
+ :select-cols="interactiveCols"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({tagFamily: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({decimate: value}, false)"
+ v-model="currentPipelineSettings.decimate"
+ class="pt-2"
+ :slider-cols="interactiveCols"
+ label="Decimate"
+ tooltip="Increases FPS at the expense of range by reducing image resolution initially"
+ :min="1"
+ :max="8"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({decimate: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({blur: value}, false)"
+ v-model="currentPipelineSettings.blur"
+ class="pt-2"
+ :slider-cols="interactiveCols"
+ label="Blur"
+ tooltip="Gaussian blur added to the image, high FPS cost for slightly decreased noise"
+ :min="0"
+ :max="5"
+ :step="0.1"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({blur: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({threads: value}, false)"
+ v-model="currentPipelineSettings.threads"
+ class="pt-2"
+ :slider-cols="interactiveCols"
+ label="Threads"
+ tooltip="Number of threads spawned by the AprilTag detector"
+ :min="1"
+ :max="8"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({threads: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({refineEdges: value}, false)"
+ v-model="currentPipelineSettings.refineEdges"
+ class="pt-2"
+ label="Refine Edges"
+ tooltip="Further refines the AprilTag corner position initial estimate, suggested left on"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({refineEdges: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({decisionMargin: value}, false)"
+ v-model="currentPipelineSettings.decisionMargin"
+ class="pt-2 pb-4"
+ :slider-cols="interactiveCols"
+ label="Decision Margin Cutoff"
+ tooltip="Tags with a 'margin' (decoding quality score) less than this wil be rejected. Increase this to reduce the number of false positive detections"
+ :min="0"
+ :max="250"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({decisionMargin: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({numIterations: value}, false)"
+ v-model="currentPipelineSettings.numIterations"
+ class="pt-2 pb-4"
+ :slider-cols="interactiveCols"
+ label="Pose Estimation Iterations"
+ tooltip="Number of iterations the pose estimation algorithm will run, 50-100 is a good starting point"
+ :min="0"
+ :max="500"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({numIterations: value}, false)"
/>
diff --git a/photon-client/src/components/dashboard/PipelineConfigTabs/ArucoTab.vue b/photon-client/src/components/dashboard/PipelineConfigTabs/ArucoTab.vue
index 1a91719c25..88487467f8 100644
--- a/photon-client/src/components/dashboard/PipelineConfigTabs/ArucoTab.vue
+++ b/photon-client/src/components/dashboard/PipelineConfigTabs/ArucoTab.vue
@@ -15,36 +15,36 @@ const interactiveCols = computed(() => (getCurrentInstance()?.proxy.$vuetify.bre
useCameraSettingsStore().changeCurrentPipelineSetting({decimate: value}, false)"
+ v-model="currentPipelineSettings.decimate"
+ class="pt-2"
+ :slider-cols="interactiveCols"
+ label="Decimate"
+ tooltip="Increases FPS at the expense of range by reducing image resolution initially"
+ :min="1"
+ :max="8"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({decimate: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({numIterations: value}, false)"
+ v-model="currentPipelineSettings.numIterations"
+ class="pt-2"
+ :slider-cols="interactiveCols"
+ label="Corner Iterations"
+ tooltip="How many iterations are going to be used in order to refine corners. Higher values are lead to more accuracy at the cost of performance"
+ :min="30"
+ :max="1000"
+ :step="5"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({numIterations: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({cornerAccuracy: value}, false)"
+ v-model="currentPipelineSettings.cornerAccuracy"
+ class="pt-2"
+ :slider-cols="interactiveCols"
+ label="Corner Accuracy"
+ tooltip="Minimum accuracy for the corners, lower is better but more performance intensive "
+ :min="0.01"
+ :max="100"
+ :step="0.01"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({cornerAccuracy: value}, false)"
/>
diff --git a/photon-client/src/components/dashboard/PipelineConfigTabs/ContoursTab.vue b/photon-client/src/components/dashboard/PipelineConfigTabs/ContoursTab.vue
index 67ea2fa0cf..77ab033a9d 100644
--- a/photon-client/src/components/dashboard/PipelineConfigTabs/ContoursTab.vue
+++ b/photon-client/src/components/dashboard/PipelineConfigTabs/ContoursTab.vue
@@ -47,110 +47,110 @@ const interactiveCols = computed(() => (getCurrentInstance()?.proxy.$vuetify.bre
useCameraSettingsStore().changeCurrentPipelineSetting({contourArea: value}, false)"
+ v-model="contourArea"
+ label="Area"
+ :min="0"
+ :max="100"
+ :slider-cols="interactiveCols"
+ :step="0.01"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourArea: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({contourRatio: value}, false)"
+ v-if="useCameraSettingsStore().currentPipelineType !== PipelineType.ColoredShape"
+ v-model="contourRatio"
+ label="Ratio (W/H)"
+ tooltip="Min and max ratio between the width and height of a contour's bounding rectangle"
+ :min="0"
+ :max="100"
+ :slider-cols="interactiveCols"
+ :step="0.1"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourRatio: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({contourTargetOrientation: value}, false)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.contourTargetOrientation"
+ label="Target Orientation"
+ tooltip="Used to determine how to calculate target landmarks, as well as aspect ratio"
+ :items="['Portrait', 'Landscape']"
+ :select-cols="interactiveCols"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourTargetOrientation: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({contourFullness: value}, false)"
+ v-if="useCameraSettingsStore().currentPipelineType === PipelineType.ColoredShape"
+ v-model="contourFullness"
+ label="Fullness"
+ tooltip="Min and max ratio between a contour's area and its bounding rectangle"
+ :min="0"
+ :max="100"
+ :slider-cols="interactiveCols"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourFullness: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({contourPerimeter: value}, false)"
+ v-if="currentPipelineSettings.pipelineType === PipelineType.ColoredShape"
+ v-model="contourPerimeter"
+ label="Perimeter"
+ tooltip="Min and max perimeter of the shape, in pixels"
+ min="0"
+ max="4000"
+ :slider-cols="interactiveCols"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourPerimeter: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({contourSpecklePercentage: value}, false)"
+ 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"
+ :min="0"
+ :max="100"
+ :slider-cols="interactiveCols"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourSpecklePercentage: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({contourFilterRangeX: value}, false)"
+ v-model="currentPipelineSettings.contourFilterRangeX"
+ label="X Filter Tightness"
+ tooltip="Rejects contours whose center X is further than X standard deviations above/below the mean X location"
+ :min="0.1"
+ :max="4"
+ :step="0.1"
+ :slider-cols="interactiveCols"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourFilterRangeX: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({contourFilterRangeY: value}, false)"
+ v-model="currentPipelineSettings.contourFilterRangeY"
+ label="Y Filter Tightness"
+ tooltip="Rejects contours whose center Y is further than X standard deviations above/below the mean Y location"
+ :min="0.1"
+ :max="4"
+ :step="0.1"
+ :slider-cols="interactiveCols"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourFilterRangeY: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({contourGroupingMode: value}, false)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.contourGroupingMode"
+ label="Target Grouping"
+ tooltip="Whether or not every two targets are paired with each other (good for e.g. 2019 targets)"
+ :select-cols="interactiveCols"
+ :items="['Single','Dual','Two or More']"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourGroupingMode: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({contourIntersection: value}, false)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.contourIntersection"
+ label="Target Intersection"
+ tooltip="If target grouping is in dual mode it will use this dropdown to decide how targets are grouped with adjacent targets"
+ :select-cols="interactiveCols"
+ :items="['None','Up','Down','Left','Right']"
+ :disabled="useCameraSettingsStore().currentPipelineSettings.contourGroupingMode === 0"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourIntersection: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({contourShape: value}, false)"
+ v-model="currentPipelineSettings.contourShape"
+ label="Target Shape"
+ tooltip="The shape of targets to look for"
+ :select-cols="interactiveCols"
+ :items="['Circle', 'Polygon', 'Triangle', 'Quadrilateral']"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourShape: value}, false)"
/>
(getCurrentInstance()?.proxy.$vuetify.bre
@input="value => useCameraSettingsStore().changeCurrentPipelineSetting({accuracyPercentage: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({circleDetectThreshold: value}, false)"
+ v-model="currentPipelineSettings.circleDetectThreshold"
+ :disabled="currentPipelineSettings.contourShape !== 0"
+ label="Circle match distance"
+ tooltip="How close the centroid of a contour must be to the center of a circle in order for them to be matched"
+ :min="1"
+ :max="100"
+ :slider-cols="interactiveCols"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({circleDetectThreshold: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({contourRadius: value}, false)"
+ v-model="contourRadius"
+ :disabled="currentPipelineSettings.contourShape !== 0"
+ label="Radius"
+ :min="0"
+ :max="100"
+ :slider-cols="interactiveCols"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourRadius: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({maxCannyThresh: value}, false)"
+ v-model="currentPipelineSettings.maxCannyThresh"
+ :disabled="currentPipelineSettings.contourShape !== 0"
+ label="Max Canny Threshold"
+ :min="1"
+ :max="100"
+ :slider-cols="interactiveCols"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({maxCannyThresh: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({circleAccuracy: value}, false)"
+ v-model="currentPipelineSettings.circleAccuracy"
+ :disabled="currentPipelineSettings.contourShape !== 0"
+ label="Circle Accuracy"
+ :min="1"
+ :max="100"
+ :slider-cols="interactiveCols"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({circleAccuracy: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({contourSortMode: value}, false)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.contourSortMode"
+ label="Target Sort"
+ tooltip="Chooses the sorting mode used to determine the 'best' targets to provide to user code"
+ :select-cols="interactiveCols"
+ :items="['Largest','Smallest','Highest','Lowest','Rightmost','Leftmost','Centermost']"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourSortMode: value}, false)"
/>
diff --git a/photon-client/src/components/dashboard/PipelineConfigTabs/InputTab.vue b/photon-client/src/components/dashboard/PipelineConfigTabs/InputTab.vue
index 7f9da91f8c..6523b4b84f 100644
--- a/photon-client/src/components/dashboard/PipelineConfigTabs/InputTab.vue
+++ b/photon-client/src/components/dashboard/PipelineConfigTabs/InputTab.vue
@@ -48,85 +48,85 @@ const interactiveCols = computed(() => (getCurrentInstance()?.proxy.$vuetify.bre
useCameraSettingsStore().changeCurrentPipelineSetting({cameraExposure: args}, false)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.cameraExposure"
+ :disabled="useCameraSettingsStore().currentCameraSettings.pipelineSettings.cameraAutoExposure"
+ label="Exposure"
+ tooltip="Directly controls how much light is allowed to fall onto the sensor, which affects apparent brightness"
+ :min="0"
+ :max="100"
+ :slider-cols="interactiveCols"
+ :step="0.1"
+ @input="args => useCameraSettingsStore().changeCurrentPipelineSetting({cameraExposure: args}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({cameraBrightness: args}, false)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.cameraBrightness"
+ label="Brightness"
+ :min="0"
+ :max="100"
+ :slider-cols="interactiveCols"
+ @input="args => useCameraSettingsStore().changeCurrentPipelineSetting({cameraBrightness: args}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({cameraAutoExposure: args}, false)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.cameraAutoExposure"
+ class="pt-2"
+ label="Auto Exposure"
+ :switch-cols="interactiveCols"
+ tooltip="Enables or Disables camera automatic adjustment for current lighting conditions"
+ @input="args => useCameraSettingsStore().changeCurrentPipelineSetting({cameraAutoExposure: args}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({cameraGain: args}, false)"
+ v-if="useCameraSettingsStore().currentPipelineSettings.cameraGain >= 0"
+ v-model="useCameraSettingsStore().currentPipelineSettings.cameraGain"
+ label="Camera Gain"
+ tooltip="Controls camera gain, similar to brightness"
+ :min="0"
+ :max="100"
+ :slider-cols="interactiveCols"
+ @input="args => useCameraSettingsStore().changeCurrentPipelineSetting({cameraGain: args}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({cameraRedGain: args}, false)"
+ v-if="useCameraSettingsStore().currentPipelineSettings.cameraRedGain !== -1"
+ v-model="useCameraSettingsStore().currentPipelineSettings.cameraRedGain"
+ label="Red AWB Gain"
+ :min="0"
+ :max="100"
+ :slider-cols="interactiveCols"
+ tooltip="Controls red automatic white balance gain, which affects how the camera captures colors in different conditions"
+ @input="args => useCameraSettingsStore().changeCurrentPipelineSetting({cameraRedGain: args}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({cameraBlueGain: args}, false)"
+ v-if="useCameraSettingsStore().currentPipelineSettings.cameraBlueGain !== -1"
+ v-model="useCameraSettingsStore().currentPipelineSettings.cameraBlueGain"
+ label="Blue AWB Gain"
+ :min="0"
+ :max="100"
+ :slider-cols="interactiveCols"
+ tooltip="Controls blue automatic white balance gain, which affects how the camera captures colors in different conditions"
+ @input="args => useCameraSettingsStore().changeCurrentPipelineSetting({cameraBlueGain: args}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({inputImageRotationMode: args}, false)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.inputImageRotationMode"
+ label="Orientation"
+ tooltip="Rotates the camera stream"
+ :items="cameraRotations"
+ :select-cols="interactiveCols"
+ @input="args => useCameraSettingsStore().changeCurrentPipelineSetting({inputImageRotationMode: args}, false)"
/>
handleResolutionChange(args)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.cameraVideoModeIndex"
+ label="Resolution"
+ tooltip="Resolution and FPS the camera should directly capture at"
+ :items="cameraResolutions"
+ :select-cols="interactiveCols"
+ @input="args => handleResolutionChange(args)"
/>
handleStreamResolutionChange(args)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.streamingFrameDivisor"
+ label="Stream Resolution"
+ tooltip="Resolution to which camera frames are downscaled for streaming to the dashboard"
+ :items="streamResolutions"
+ :select-cols="interactiveCols"
+ @input="args => handleStreamResolutionChange(args)"
/>
diff --git a/photon-client/src/components/dashboard/PipelineConfigTabs/Map3DTab.vue b/photon-client/src/components/dashboard/PipelineConfigTabs/Map3DTab.vue
index 21c57da550..77fc5853fb 100644
--- a/photon-client/src/components/dashboard/PipelineConfigTabs/Map3DTab.vue
+++ b/photon-client/src/components/dashboard/PipelineConfigTabs/Map3DTab.vue
@@ -22,14 +22,16 @@ const trackedTargets = computed(() => useStateStore().pipelineRe
-
+
Target Visualization
-
+
diff --git a/photon-client/src/components/dashboard/PipelineConfigTabs/OutputTab.vue b/photon-client/src/components/dashboard/PipelineConfigTabs/OutputTab.vue
index a9fdd8e67c..02a637c7e5 100644
--- a/photon-client/src/components/dashboard/PipelineConfigTabs/OutputTab.vue
+++ b/photon-client/src/components/dashboard/PipelineConfigTabs/OutputTab.vue
@@ -41,64 +41,75 @@ const interactiveCols = computed(() => (getCurrentInstance()?.proxy.$vuetify.bre
useCameraSettingsStore().changeCurrentPipelineSetting({contourTargetOffsetPointEdge: value}, false)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.contourTargetOffsetPointEdge"
+ label="Target Offset Point"
+ tooltip="Changes where the 'center' of the target is (used for calculating e.g. pitch and yaw)"
+ :items="['Center','Top','Bottom','Left','Right']"
+ :select-cols="interactiveCols"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourTargetOffsetPointEdge: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({contourTargetOrientation: value}, false)"
+ v-if="!isTagPipeline"
+ v-model="useCameraSettingsStore().currentPipelineSettings.contourTargetOrientation"
+ label="Target Orientation"
+ tooltip="Used to determine how to calculate target landmarks (e.g. the top, left, or bottom of the target)"
+ :items="['Portrait', 'Landscape']"
+ :select-cols="interactiveCols"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({contourTargetOrientation: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({outputShowMultipleTargets: value}, false)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.outputShowMultipleTargets"
+ label="Show Multiple Targets"
+ tooltip="If enabled, up to five targets will be displayed and sent to user code, instead of just one"
+ :disabled="isTagPipeline"
+ :switch-cols="interactiveCols"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({outputShowMultipleTargets: value}, false)"
/>
-
-
+
+
-
- {{item.header}}
+
+ {{ item.header }}
-
- {{item.value}}
+
+ {{ item.value }}
useCameraSettingsStore().changeCurrentPipelineSetting({offsetRobotOffsetMode: value}, false)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.offsetRobotOffsetMode"
+ label="Robot Offset Mode"
+ tooltip="Used to add an arbitrary offset to the location of the targeting crosshair"
+ :items="['None','Single Point','Dual Point']"
+ :select-cols="interactiveCols"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({offsetRobotOffsetMode: value}, false)"
/>
Take Point
@@ -107,22 +118,22 @@ const interactiveCols = computed(() => (getCurrentInstance()?.proxy.$vuetify.bre
Take First Point
Take Second Point
@@ -130,10 +141,10 @@ const interactiveCols = computed(() => (getCurrentInstance()?.proxy.$vuetify.bre
Clear All Points
diff --git a/photon-client/src/components/dashboard/PipelineConfigTabs/PnPTab.vue b/photon-client/src/components/dashboard/PipelineConfigTabs/PnPTab.vue
index 59fb0fabed..225fbad678 100644
--- a/photon-client/src/components/dashboard/PipelineConfigTabs/PnPTab.vue
+++ b/photon-client/src/components/dashboard/PipelineConfigTabs/PnPTab.vue
@@ -12,30 +12,30 @@ const interactiveCols = computed(() => (getCurrentInstance()?.proxy.$vuetify.bre
useCameraSettingsStore().changeCurrentPipelineSetting({targetModel: value}, false)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.targetModel"
+ label="Target Model"
+ :items="[
+ {name: '2020 High Goal Outer', value: TargetModel.k2020HighGoalOuter},
+ {name: '2020 High Goal Inner', value: TargetModel.k2020HighGoalInner},
+ {name: '2019 Dual Target', value: TargetModel.k2019DualTarget},
+ {name: '2020 Power Cell (7in)', value: TargetModel.kCircularPowerCell7in},
+ {name: '2022 Cargo Ball (9.5in)', value: TargetModel.k2022CircularCargoBall},
+ {name: '2016 High Goal', value: TargetModel.k2016HighGoal},
+ {name: '200mm AprilTag', value: TargetModel.k200mmAprilTag},
+ {name: '6in (16h5) Aruco', value: TargetModel.kAruco6in_16h5},
+ {name: '6in (16h5) AprilTag', value: TargetModel.k6in_16h5}
+ ]"
+ :select-cols="interactiveCols"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({targetModel: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({cornerDetectionAccuracyPercentage: value}, false)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.cornerDetectionAccuracyPercentage"
+ class="pt-2"
+ :slider-cols="interactiveCols"
+ label="Contour simplification Percentage"
+ :min="0"
+ :max="100"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({cornerDetectionAccuracyPercentage: value}, false)"
/>
diff --git a/photon-client/src/components/dashboard/PipelineConfigTabs/TargetsTab.vue b/photon-client/src/components/dashboard/PipelineConfigTabs/TargetsTab.vue
index 31b66bac0f..9e9d5db817 100644
--- a/photon-client/src/components/dashboard/PipelineConfigTabs/TargetsTab.vue
+++ b/photon-client/src/components/dashboard/PipelineConfigTabs/TargetsTab.vue
@@ -7,26 +7,26 @@ import { useStateStore } from "@/stores/StateStore";
-
+
Target Count
Fiducial ID
@@ -63,29 +63,29 @@ import { useStateStore } from "@/stores/StateStore";
-
- {{ index }}
-
- {{target.fiducialId}}
-
-
- {{target.pitch.toFixed(2)}}°
- {{target.yaw.toFixed(2)}}°
- {{target.skew.toFixed(2)}}°
- {{target.area.toFixed(2)}}°
-
-
- {{target.pose?.x.toFixed(2)}} m
- {{target.pose?.y.toFixed(2)}} m
- {{(target.pose?.angle_z * 180.0 / Math.PI).toFixed(2)}}°
-
-
- {{target.ambiguity?.toFixed(2)}}%
-
-
+
+ {{ index }}
+
+ {{ target.fiducialId }}
+
+
+ {{ target.pitch.toFixed(2) }}°
+ {{ target.yaw.toFixed(2) }}°
+ {{ target.skew.toFixed(2) }}°
+ {{ target.area.toFixed(2) }}°
+
+
+ {{ target.pose?.x.toFixed(2) }} m
+ {{ target.pose?.y.toFixed(2) }} m
+ {{ (target.pose?.angle_z * 180.0 / Math.PI).toFixed(2) }}°
+
+
+ {{ target.ambiguity?.toFixed(2) }}%
+
+
diff --git a/photon-client/src/components/dashboard/PipelineConfigTabs/ThresholdTab.vue b/photon-client/src/components/dashboard/PipelineConfigTabs/ThresholdTab.vue
index 79691ceddd..357dc51910 100644
--- a/photon-client/src/components/dashboard/PipelineConfigTabs/ThresholdTab.vue
+++ b/photon-client/src/components/dashboard/PipelineConfigTabs/ThresholdTab.vue
@@ -106,7 +106,10 @@ const interactiveCols = computed(() => (getCurrentInstance()?.proxy.$vuetify.bre
-
+
(getCurrentInstance()?.proxy.$vuetify.bre
@input="value => useCameraSettingsStore().changeCurrentPipelineSetting({hsvHue: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({hsvSaturation: value}, false)"
+ id="sat-slider"
+ v-model="hsvSaturation"
+ class="normal-slider"
+ label="Saturation"
+ tooltip="Describes colorfulness; the smaller this value the 'whiter' the color becomes"
+ :min="0"
+ :max="255"
+ :slider-cols="interactiveCols"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({hsvSaturation: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({hsvValue: value}, false)"
+ id="value-slider"
+ v-model="hsvValue"
+ class="normal-slider"
+ label="Value"
+ tooltip="Describes lightness; the smaller this value the 'blacker' the color becomes"
+ :min="0"
+ :max="255"
+ :slider-cols="interactiveCols"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({hsvValue: value}, false)"
/>
useCameraSettingsStore().changeCurrentPipelineSetting({hueInverted: value}, false)"
+ v-model="useCameraSettingsStore().currentPipelineSettings.hueInverted"
+ label="Invert Hue"
+ :switch-cols="interactiveCols"
+ tooltip="Selects the hue range outside of the hue slider bounds instead of inside"
+ @input="value => useCameraSettingsStore().changeCurrentPipelineSetting({hueInverted: value}, false)"
/>
Color Picker
mdi-minus
@@ -172,10 +175,10 @@ const interactiveCols = computed(() => (getCurrentInstance()?.proxy.$vuetify.bre
Shrink Range
mdi-plus-minus
@@ -183,10 +186,10 @@ const interactiveCols = computed(() => (getCurrentInstance()?.proxy.$vuetify.bre
{{ useCameraSettingsStore().currentPipelineSettings.hueInverted ? "Exclude" : "Set to" }} Average
mdi-plus
@@ -196,11 +199,11 @@ const interactiveCols = computed(() => (getCurrentInstance()?.proxy.$vuetify.bre
Cancel
diff --git a/photon-client/src/components/dashboard/StreamConfigCard.vue b/photon-client/src/components/dashboard/StreamConfigCard.vue
index 652a9c87a1..9f7b29790c 100644
--- a/photon-client/src/components/dashboard/StreamConfigCard.vue
+++ b/photon-client/src/components/dashboard/StreamConfigCard.vue
@@ -35,28 +35,28 @@ const processingMode = computed({
color="primary"
>
Processing Mode
mdi-square-outline
2D
mdi-cube-outline
3D
@@ -68,22 +68,22 @@ const processingMode = computed({
Stream Display
mdi-import
Raw
mdi-export
Processed
diff --git a/photon-client/src/components/settings/DeviceControlCard.vue b/photon-client/src/components/settings/DeviceControlCard.vue
index 9af5f87319..b78f1a962b 100644
--- a/photon-client/src/components/settings/DeviceControlCard.vue
+++ b/photon-client/src/components/settings/DeviceControlCard.vue
@@ -189,21 +189,21 @@ const handleSettingsImport = () => {
Device Control
mdi-restart
@@ -212,13 +212,13 @@ const handleSettingsImport = () => {
mdi-restart-alert
@@ -227,12 +227,12 @@ const handleSettingsImport = () => {
mdi-upload
@@ -240,23 +240,23 @@ const handleSettingsImport = () => {
Offline Update
-
+
showImportDialog = true"
+ color="secondary"
+ @click="() => showImportDialog = true"
>
mdi-import
@@ -264,50 +264,50 @@ const handleSettingsImport = () => {
Import Settings
{
- importType = -1;
- importFile = null;
- }"
+ v-model="showImportDialog"
+ width="600"
+ @input="() => {
+ importType = -1;
+ importFile = null;
+ }"
>
Import Settings
Upload and apply previously saved or exported PhotonVision settings to this device
importFile = file"
+ :disabled="importType === -1"
+ :error-messages="importType === -1 ? 'Settings type not selected' : ''"
+ :accept="importType === ImportType.AllSettings ? '.zip' : '.json'"
+ @change="(file) => importFile = file"
/>
mdi-import
@@ -320,12 +320,12 @@ const handleSettingsImport = () => {
mdi-export
@@ -333,20 +333,20 @@ const handleSettingsImport = () => {
Export Settings
mdi-download
@@ -355,21 +355,21 @@ const handleSettingsImport = () => {
mdi-eye
diff --git a/photon-client/src/components/settings/LightingControlCard.vue b/photon-client/src/components/settings/LightingControlCard.vue
index 02f850d121..0a792a4604 100644
--- a/photon-client/src/components/settings/LightingControlCard.vue
+++ b/photon-client/src/components/settings/LightingControlCard.vue
@@ -5,20 +5,20 @@ import { useSettingsStore } from "@/stores/settings/GeneralSettingsStore";
Lighting Control
useSettingsStore().changeLEDBrightness(args)"
+ v-model="useSettingsStore().lighting.brightness"
+ label="Brightness"
+ class="pt-2"
+ :slider-cols="12"
+ :min="0"
+ :max="100"
+ @input="args => useSettingsStore().changeLEDBrightness(args)"
/>
diff --git a/photon-client/src/components/settings/MetricsCard.vue b/photon-client/src/components/settings/MetricsCard.vue
index ff7e3096e4..4b98ffbcdc 100644
--- a/photon-client/src/components/settings/MetricsCard.vue
+++ b/photon-client/src/components/settings/MetricsCard.vue
@@ -82,47 +82,73 @@ onBeforeMount(() => {
Stats
-
PhotonVision General Metrics
-
+
+ PhotonVision General Metrics
+
+
-
- {{item.header}}
+
+ {{ item.header }}
-
- {{item.value}}
+
+ {{ item.value }}
-
PhotonVision Hardware Metrics
-
+
+ PhotonVision Hardware Metrics
+
+
-
- {{item.header}}
+
+ {{ item.header }}
-
- {{item.value}}
+
+ {{ item.value }}
---
diff --git a/photon-client/src/components/settings/NetworkingCard.vue b/photon-client/src/components/settings/NetworkingCard.vue
index 72d9b7cefd..0363f77445 100644
--- a/photon-client/src/components/settings/NetworkingCard.vue
+++ b/photon-client/src/components/settings/NetworkingCard.vue
@@ -77,15 +77,15 @@ const saveGeneralSettings = () => {
Networking
{
The NetworkTables Server Address is not set or is invalid. NetworkTables is unable to connect.
{
Save
diff --git a/photon-client/src/views/CameraSettingsView.vue b/photon-client/src/views/CameraSettingsView.vue
index c200467ec4..b9711458b3 100644
--- a/photon-client/src/views/CameraSettingsView.vue
+++ b/photon-client/src/views/CameraSettingsView.vue
@@ -14,25 +14,25 @@ onMounted(() => {
-
-
+
+
diff --git a/photon-client/src/views/DashboardView.vue b/photon-client/src/views/DashboardView.vue
index f772956ba0..086f1b4c40 100644
--- a/photon-client/src/views/DashboardView.vue
+++ b/photon-client/src/views/DashboardView.vue
@@ -37,32 +37,32 @@ const cameraViewType = computed
({
-
+
-
-
+
+
-
+
diff --git a/photon-client/src/views/DocsView.vue b/photon-client/src/views/DocsView.vue
index aea64def76..e5c8a5d9ec 100644
--- a/photon-client/src/views/DocsView.vue
+++ b/photon-client/src/views/DocsView.vue
@@ -4,11 +4,11 @@ const devMode = process.env.NODE_ENV === "development";
PhotonClient is in development mode so the documentation page will not load.
@@ -16,13 +16,13 @@ const devMode = process.env.NODE_ENV === "development";
diff --git a/photon-client/src/views/GeneralSettingsView.vue b/photon-client/src/views/GeneralSettingsView.vue
index f88de44aa7..e76696e8b7 100644
--- a/photon-client/src/views/GeneralSettingsView.vue
+++ b/photon-client/src/views/GeneralSettingsView.vue
@@ -8,17 +8,17 @@ import { useSettingsStore } from "@/stores/settings/GeneralSettingsStore";
-
-
-
-
+
+
+
+
diff --git a/photon-client/src/views/NotFoundView.vue b/photon-client/src/views/NotFoundView.vue
index ea4ee157f7..9e71928661 100644
--- a/photon-client/src/views/NotFoundView.vue
+++ b/photon-client/src/views/NotFoundView.vue
@@ -9,9 +9,9 @@