Bootup sprint (#18)

* Did some stuff

* Fix gradle, start implementing mjpeg frame consumer

* Did some stuff

* bade changes

* rename camera config to USBCameraConfiguration, add name

* unrename cameraconfiguration

* Add pub/sub framework

* Add setResolution to mjpeg frame consumer

* add NTDataConsumer

* Add some totally broken hsv hacks

* Start refactoring UI data

* Update index.js

* Commit and push, he says

* Fix up some errors

* Fix input tab

* Fix fps

* Update index.js

* Add pipeline field setting, update PipelineManager, fix nullpointers and USBCameraSettables

* Change v-model to point to data()

* update hsv to use mutations

* Work on saving, fix hsv

* Rename shouldErode/shouldDilate to erode and dilate

* Hook all the tabs up to the Store

* Change handleData to handlePipelineData

* camera quirk redo, add ICCSub to SocketHandler

* Fix some property names

* Fixed tons of naming in UI, fix backend for multi-val PSCs, fix PSC enums

* change pipeline type to an int in store

* Fix mutation naming

* Attempt threshold fix

* Update SocketHandler.java

* Add truthy data sending

* Start adding logging support

* [UI] Add delay to slider input boxes (#1)

* [UI] [Backend] potentially fix camera settings, various logging tweaks

* Don't release raw input mat

* add setVideoModeIndex to vision settables

* Implement pipeline index in socket handler, add framework for renaming/changing pipes

* (ish) get pipeline change working

* Create index.html

* Cleanups, fix pipeline index bug, fix stream res for MJPG, add dashboard stream (unused)

* Refactor UI to use mutatePipeline, send pipeline results

* Update NetworkConfig.java

* Change double to number

* Run spotless

* Fix reversal of large/small comparators

* Fix left/right

* Fix pitch/yaw calculation bug, fix area bug

* Use Vue.set instead of assignment

This fixes {{ }}

* Update App.vue

* run spotless

* Actually add pipelines and reassign indecies

* Delete old pipeline configs

Fixes duplication on renaming pipeline

* Start working on deleting pipes

* Fix camera nickname change

* run spotless

* Fix some test stuff

* Update VisionModuleManagerTest.java

* vision source manager test is still broken

* Fix VisionSourceManager test

* Apply spotless 2 electric boogaloo

Co-authored-by: Banks Troutman <btrout.dhrs@gmail.com>
Co-authored-by: Declan Freeman-Gleason <declanfreemangleason@gmail.com>
Co-authored-by: Aaryan Agrawal <54345060+13Ducks@users.noreply.github.com>
This commit is contained in:
Matt
2020-07-07 01:01:58 -07:00
committed by GitHub
parent 01712a7396
commit 4cd2262acc
106 changed files with 3666 additions and 623 deletions

View File

@@ -118,14 +118,19 @@
},
methods: {
handleMessage(key, value) {
if (this.$store.state.hasOwnProperty(key)) {
if (key === "logMessage") {
console.log(value)
this.logMessage(value, 0)
} else if (key === "updatePipelineResult") {
this.$store.commit('mutatePipelineResults', value)
} else if (this.$store.state.hasOwnProperty(key)) {
this.$store.commit(key, value);
} else if (this.$store.state.pipeline.hasOwnProperty(key)) {
} else if (this.$store.getters.currentPipelineSettings.hasOwnProperty(key)) {
this.$store.commit('mutatePipeline', {'key': key, 'value': value});
} else {
switch (key) {
default: {
console.log(key + " : " + value);
console.log(value);
}
}
}
@@ -141,7 +146,7 @@
}
this.timer = setInterval(this.saveSettings, 4000);
},
logMessage({message, level}) {
logMessage(message, level) {
const colors = ["\u001b[31m", "\u001b[32m", "\u001b[33m", "\u001b[34m"]
const reset = "\u001b[0m"
this.log += `${colors[level]}${message}${reset}\n`

View File

@@ -23,6 +23,7 @@
<script>
export default {
name: 'Icon',
// eslint-disable-next-line vue/require-prop-types
props: ['color', 'tooltip', 'text', 'right', 'hover'],
data() {
return {}

View File

@@ -12,6 +12,7 @@
<script>
export default {
name: "CvImage",
// eslint-disable-next-line vue/require-prop-types
props: ['address', 'scale'],
data: () => {
return {}

View File

@@ -24,6 +24,7 @@ s
<script>
export default {
name: 'Input',
// eslint-disable-next-line vue/require-prop-types
props: ['name', 'value', 'disabled', 'errorMessage'],
data() {
return {}

View File

@@ -26,6 +26,7 @@
<script>
export default {
name: 'NumberInput',
// eslint-disable-next-line vue/require-prop-types
props: ['name', 'value', 'step'],
data() {
return {}

View File

@@ -20,6 +20,7 @@
<script>
export default {
name: 'Radio',
// eslint-disable-next-line vue/require-prop-types
props: ['value', 'list'],
data() {
return {}

View File

@@ -1,9 +1,6 @@
<template>
<div>
<v-row
dense
align="center"
>
<v-row dense align="center">
<v-col :cols="2">
<span>{{ name }}</span>
</v-col>
@@ -62,46 +59,65 @@
</template>
<script>
export default {
name: 'RangeSlider',
props: ['name', 'min', 'max', 'value', 'step'],
data() {
return {
prependFocused: false,
appendFocused: false
}
},
computed: {
localValue: {
get() {
return this.value;
},
set(value) {
this.$emit('input', value)
}
}
},
methods: {
handleChange(val) {
let i = 0;
if (this.prependFocused === false && this.appendFocused === true) {
i = 1;
}
if (this.prependFocused || this.appendFocused) {
this.$set(this.localValue, i, val);
this.$emit('rollback', this.localValue)
}
},
handleInput(val) {
if (!this.prependFocused || !this.appendFocused) {
this.localValue = val;
}
}
}
export default {
name: "RangeSlider",
// eslint-disable-next-line vue/require-prop-types
props: ["name", "min", "max", "value", "step"],
data() {
return {
prependFocused: false,
appendFocused: false,
currentBoxVals: [null, null]
};
},
computed: {
localValue: {
get() {
return Object.values(this.value);
},
set(value) {
this.$emit("input", value);
}
}
},
methods: {
// handleChange(val) {
// let i = 0;
// if (this.prependFocused === false && this.appendFocused === true) {
// i = 1;
// }
// if (this.prependFocused || this.appendFocused) {
// this.$set(this.localValue, i, val);
// this.$emit('rollback', this.localValue)
// }
// },
handleChange(val) {
let i = 0;
if (this.prependFocused === false && this.appendFocused === true) {
i = 1;
}
this.currentBoxVals[i] = val;
setTimeout(() => {
if (this.currentBoxVals[i] !== val) return;
//if (this.prependFocused || this.appendFocused) {
let tmp = this.localValue;
let parsed = parseFloat(val);
if (isNaN(parsed)) return;
tmp[i] = parsed;
this.localValue = tmp;
this.$emit("rollback", this.localValue);
//}
}, 200);
},
handleInput(val) {
if (!this.prependFocused || !this.appendFocused) {
this.localValue = val;
}
}
}
};
</script>
<style lang="" scoped>
</style>

View File

@@ -27,6 +27,7 @@
<script>
export default {
name: 'Select',
// eslint-disable-next-line vue/require-prop-types
props: ['list', 'name', 'value', 'disabled'],
data() {
return {}

View File

@@ -1,9 +1,6 @@
<template>
<div>
<v-row
dense
align="center"
>
<v-row dense align="center">
<v-col :cols="2">
<span>{{ name }}</span>
</v-col>
@@ -19,7 +16,7 @@
:step="step"
@start="isClicked = true"
@end="isClicked = false"
@change="handleclick"
@change="handleClick"
@input="handleInput"
@mousedown="$emit('rollback', localValue)"
>
@@ -47,46 +44,51 @@
</template>
<script>
export default {
name: 'Slider',
props: ['min', 'max', 'name', 'value', 'step'],
data() {
return {
isFocused: false,
isClicked: false
}
},
computed: {
localValue: {
get() {
return this.value;
},
set(value) {
this.$emit('input', value)
}
}
},
methods: {
handleChange(val) {
if (this.isFocused) {
this.localValue = parseFloat(val);
this.$emit('rollback', this.localValue)
}
},
handleInput(val) {
if (!this.isFocused && this.isClicked) {
this.localValue = val;
}
},
handleclick(val) {
if (!this.isFocused) {
this.localValue = val;
}
}
}
export default {
name: "Slider",
// eslint-disable-next-line vue/require-prop-types
props: ["min", "max", "name", "value", "step"],
data() {
return {
isFocused: false,
isClicked: false,
currentBoxVal: null
};
},
computed: {
localValue: {
get() {
return this.value;
},
set(value) {
this.$emit("input", value);
}
}
},
methods: {
handleChange(val) {
this.currentBoxVal = val;
setTimeout(() => {
if (this.currentBoxVal !== val) return;
// if (this.isFocused) {
this.localValue = parseFloat(val);
this.$emit("rollback", this.localValue);
// }
}, 200);
},
handleInput(val) {
if (!this.isFocused && this.isClicked) {
this.localValue = val;
}
},
handleClick(val) {
if (!this.isFocused) {
this.localValue = val;
}
}
}
};
</script>
<style lang="" scoped>
</style>

View File

@@ -23,6 +23,7 @@
<script>
export default {
name: 'CVSwitch',
// eslint-disable-next-line vue/require-prop-types
props: ['name', 'value', 'disabled'],
data() {
return {}

View File

@@ -57,7 +57,9 @@
export default {
name: "MiniMap",
props: {
// eslint-disable-next-line vue/require-default-prop
targets: Array,
// eslint-disable-next-line vue/require-default-prop
horizontalFOV: Number
},
data() {

View File

@@ -58,7 +58,7 @@
v-model="currentPipelineIndex"
name="Pipeline"
:list="['Driver Mode'].concat($store.getters.pipelineList)"
@input="handleInput('currentPipeline',currentPipelineIndex - 1)"
@input="handleInputWithIndex('currentPipeline',currentPipelineIndex - 1)"
/>
</v-col>
<v-col
@@ -265,7 +265,7 @@
for (let cam in this.cameraList) {
if (this.cameraList.hasOwnProperty(cam)) {
if (this.newCameraName === this.cameraList[cam]) {
return "Camera by that name already Exists"
return "Camera by that name already exists"
}
}
}
@@ -296,7 +296,7 @@
return this.$store.getters.currentCameraIndex;
},
set(value) {
this.$store.commit('currentPipelineIndex', value - 1);
this.$store.commit('currentCameraIndex', value);
}
},
currentPipelineIndex: {
@@ -315,7 +315,7 @@
},
saveCameraNameChange() {
if (this.checkCameraName === "") {
this.handleInput("changeCameraName", this.newCameraName);
this.handleInputWithIndex("changeCameraName", this.newCameraName);
this.discardCameraNameChange();
}
},
@@ -342,7 +342,7 @@
},
deleteCurrentPipeline() {
if (this.$store.getters.pipelineList.length > 1) {
this.handleInput('command', 'deleteCurrentPipeline');
this.handleInputWithIndex('command', 'deleteCurrentPipeline');
} else {
this.snackbar = true;
}
@@ -350,9 +350,9 @@
savePipelineNameChange() {
if (this.checkPipelineName === "") {
if (this.isPipelineNameEdit) {
this.handleInput("changePipelineName", this.newPipelineName);
this.handleInputWithIndex("changePipelineName", this.newPipelineName);
} else {
this.handleInput("addNewPipeline", this.newPipelineName);
this.handleInputWithIndex("addNewPipeline", this.newPipelineName);
}
this.discardPipelineNameChange();
}

View File

@@ -44,6 +44,7 @@
<script>
export default {
name: "DualCalibration",
// eslint-disable-next-line vue/require-prop-types
props: ['rawPoint'],
data() {
return {

View File

@@ -32,6 +32,7 @@
<script>
export default {
name: "SingleCalibration",
// eslint-disable-next-line vue/require-prop-types
props: ['rawPoint'],
methods: {
clearPoint() {

View File

@@ -31,6 +31,7 @@ Vue.prototype.$msgPack = msgPack(true);
import {dataHandleMixin} from './mixins/global/dataHandleMixin'
Vue.mixin(dataHandleMixin);
new Vue({
router,
store,

View File

@@ -4,8 +4,35 @@ export const dataHandleMixin = {
let msg = this.$msgPack.encode({[key]: value});
this.$socket.send(msg);
},
handleInputWithIndex(key, value) {
let msg = this.$msgPack.encode({
[key]: value,
["cameraIndex"]: this.$store.getters.currentCameraIndex
});
this.$socket.send(msg);
},
handleData(val) {
this.handleInput(val, this.value[val]);
this.handleInput(val, this[val]);
this.$emit('update')
},
handlePipelineData(val) {
let msg = this.$msgPack.encode({
["changePipelineSetting"]: {
[val]: this[val],
["cameraIndex"]: this.$store.getters.currentCameraIndex
}
});
this.$socket.send(msg);
this.$emit('update')
},
handleTruthyPipelineData(val) {
let msg = this.$msgPack.encode({
["changePipelineSetting"]: {
[val]: !!(this[val]),
["cameraIndex"]: this.$store.getters.currentCameraIndex
}
});
this.$socket.send(msg);
this.$emit('update')
},
rollback(val, e) {

View File

@@ -1,9 +1,7 @@
import Vue from 'vue'
import Vuex from 'vuex'
import pipeline from "./modules/pipeline";
import generalSettings from "./modules/generalSettings";
import cameraSettings from "./modules/cameraSettings";
import networkSettings from "./modules/networkSettings"
import undoRedo from "./modules/undoRedo";
Vue.use(Vuex);
@@ -14,53 +12,137 @@ const set = key => (state, val) => {
export default new Vuex.Store({
modules: {
pipeline: pipeline,
settings: generalSettings,
cameraSettings: cameraSettings,
reflectivePipelineSettings: {
state: {
currentResolutionIndex: 0,
},
},
networkSettings: networkSettings,
undoRedo: undoRedo
},
state: {
resolutionList: [],
port: 1181,
currentCameraIndex: 0,
currentPipelineIndex: 0,
cameraList: [],
pipelineList: [],
point: {},
saveBar: false
saveBar: false,
cameraSettings: [ // This is a list of objects representing the settings of all cameras
{
tiltDegrees: 0.0,
currentPipelineIndex: 0,
pipelineNicknames: ["Unknown"],
streamPort: 1181,
nickname: "Unknown",
videoFormatList: [
{
"width": 1920,
"height": 1080,
"fps": 30,
"pixelFormat": "BGR"
}
],
fov: 70.0,
calibrated: false,
currentPipelineSettings: {
pipelineType: 2, // One of "driver", "reflective", "shape"
// 2 is reflective
// Settings that apply to all pipeline types
cameraExposure: 1,
cameraBrightness: 2,
cameraGain: 3,
inputImageRotationMode: 0,
cameraVideoModeIndex: 0,
outputFrameDivisor: 0,
// Settings that apply to reflective
hsvHue: [0, 15],
hsvSaturation: [0, 15],
hsvValue: [0, 25],
erode: false,
dilate: false,
contourArea: [0, 12],
contourRatio: [0, 12],
contourExtent: [0, 12],
contourSpecklePercentage: 5,
contourGroupingMode: 0,
contourIntersection: 0,
contourSortMode: 0,
outputShowMultipleTargets: false,
outputShowThresholded: 0,
offsetRobotOffsetMode: 0,
solvePNPEnabled: false,
targetRegion: 0,
contourTargetOrientation: 1
// Settings that apply to shape
}
}
],
pipelineResults: [
{
fps: 0,
targets: [{
// Available in both 2D and 3D
pitch: 0,
yaw: 0,
skew: 0,
area: 0,
// 3D only
pose: {x: 0, y: 0, rot: 0},
}]
}
]
},
mutations: {
settings: set('settings'),
pipeline: set('pipeline'),
cameraSettings: set('cameraSettings'),
resolutionList: set('resolutionList'),
port: set('port'),
saveBar: set('saveBar'),
currentCameraIndex: set('currentCameraIndex'),
currentPipelineIndex: set('currentPipelineIndex'),
cameraList: set('cameraList'),
pipelineList: set('pipelineList'),
point: set('point'),
driverMode: set('driverMode'),
saveBar: set("saveBar")
pipelineResults: set('pipelineResults'),
networkSettings: set('networkSettings'),
currentPipelineIndex: (state, val) => {
const settings = state.cameraSettings[state.currentCameraIndex];
Vue.set(settings, 'currentPipelineIndex', val);
},
// TODO change everything to use this
mutatePipeline: (state, payload) => {
for (let key in payload) {
if (!payload.hasOwnProperty(key)) continue;
const value = payload[key];
const settings = state.cameraSettings[state.currentCameraIndex].currentPipelineSettings;
if (settings.hasOwnProperty(key)) {
Vue.set(settings, key, value);
}
}
},
mutatePipelineResults(state, payload) {
// Key: index, value: result
let newResultArray = [];
for (let key in payload) {
if (!payload.hasOwnProperty(key)) continue;
const index = parseInt(key);
newResultArray[index] = payload[key];
}
Vue.set(state, 'pipelineResults', newResultArray)
}
},
getters: {
streamAddress: state => {
return "http://" + location.hostname + ":" + state.port + "/stream.mjpg";
pipelineSettings: state => state.pipelineSettings,
streamAddress: state =>
"http://" + location.hostname + ":" + state.cameraSettings[state.currentCameraIndex].streamPort + "/stream.mjpg",
targets: state => state.pipelineResults.length,
currentPipelineResults: state =>
state.pipelineResults[state.cameraSettings[state.currentCameraIndex].currentPipelineIndex],
cameraList: state => state.cameraSettings.map(it => it.nickname),
currentCameraSettings: state => state.cameraSettings[state.currentCameraIndex],
currentCameraIndex: state => state.currentCameraIndex,
currentPipelineIndex: state => state.cameraSettings[state.currentCameraIndex].currentPipelineIndex,
currentPipelineSettings: state => state.cameraSettings[state.currentCameraIndex].currentPipelineSettings,
videoFormatList: state => {
return Object.values(state.cameraSettings[state.currentCameraIndex].videoFormatList); // convert to a list
},
targets: state => {
return state.point['targets']
},
cameraList: state => {
return state.cameraList
},
pipelineList: state => {
return state.pipelineList
},
currentCameraIndex: state => {
return state.currentCameraIndex
},
currentPipelineIndex: state => {
return state.currentPipelineIndex
}
pipelineList: state => state.cameraSettings[state.currentCameraIndex].pipelineNicknames,
currentCameraFPS: state => state.pipelineResults[state.currentCameraIndex].fps
}
})
})

View File

@@ -1,14 +0,0 @@
export default {
state: {
calibration: [],
fov: 0,
resolution: 0,
streamDivisor: 0,
tilt: 0
},
getters: {
cameraSettings: state => {
return state
}
}
}

View File

@@ -1,10 +0,0 @@
export default {
state:{
teamNumber: 0,
connectionType: 0,
ip: "",
gateway: "",
netmask: "",
hostname: "photon-vision"
}
}

View File

@@ -0,0 +1,17 @@
export default {
state: {
netmask: "",
ip: "",
teamNumber: "",
connectionType: "",
gateway: ""
},
mutations: {
},
actions: {},
getters: {
pipeline: state => {
return state
}
}
};

View File

@@ -52,14 +52,14 @@
<!-- camera image tabs -->
<v-tabs
v-if="($store.getters.currentPipelineIndex + 1) !== 0"
v-model="isBinaryNumber"
v-model="outputShowThresholded"
background-color="#232c37"
dark
height="48"
slider-color="#ffd843"
centered
style="padding-bottom:10px"
@change="handleInput('isBinary',$store.getters.pipeline.isBinary)"
@change="handleTruthyPipelineData('outputShowThresholded')"
>
<v-tab>Normal</v-tab>
<v-tab>Threshold</v-tab>
@@ -106,7 +106,7 @@
</thead>
<tbody>
<tr
v-for="(value, index) in $store.getters.targets"
v-for="(value, index) in $store.getters.currentPipelineResults.targets"
:key="index"
>
<td>{{ index }}</td>
@@ -165,16 +165,15 @@
return {
selectedTab: 0,
snackbar: false,
}
},
computed: {
isBinaryNumber: {
outputShowThresholded: {
get() {
return this.$store.getters.pipeline.isBinary ? 1 : 0
return this.$store.getters.currentPipelineSettings.outputShowThresholded ? 1 : 0;
},
set(value) {
this.$store.commit('isBinary', !!value);
this.$store.commit('mutatePipeline', {'outputShowThresholded': !!value});
}
},
selectedComponent: {
@@ -184,7 +183,7 @@
},
fps: {
get() {
return this.$store.state.point.fps;
return this.$store.getters.currentCameraFPS;
}
}
},

View File

@@ -90,6 +90,7 @@
CVslider,
miniMap
},
// eslint-disable-next-line vue/require-prop-types
props: ['value'],
data() {
return {
@@ -106,14 +107,14 @@
computed: {
targets: {
get() {
return this.$store.state.point.targets;
return 330; // TODO fix
}
},
horizontalFOV: {
get() {
let index = this.$store.state.cameraSettings.resolution;
let FOV = this.$store.state.cameraSettings.fov;
let resolution = this.$store.state.resolutionList[index];
let resolution = this.$store.getters.videoFormatList[index];
let diagonalView = FOV * (Math.PI / 180);
let diagonalAspect = Math.hypot(resolution.width, resolution.height);
return Math.atan(Math.tan(diagonalView / 2) * (resolution.width / diagonalAspect)) * 2 * (180 / Math.PI)
@@ -121,8 +122,9 @@
},
allow3D: {
get() {
let currentRes = this.$store.state.resolutionList[this.$store.state.pipeline.videoModeIndex];
for (let res of this.$store.state.cameraSettings.calibration) {
let index = this.$store.state.cameraSettings.resolution;
let currentRes = this.$store.getters.videoFormatList[index];
for (let res of this.$store.state.cameraSettings.calibrated) {
if (currentRes.width === res.width && currentRes.height === res.height) {
return false;
}

View File

@@ -1,55 +1,55 @@
<template>
<div>
<CVrangeSlider
v-model="value.area"
name="Area"
:min="0"
:max="100"
:step="0.1"
@input="handleData('area')"
@rollback="e=> rollback('area',e)"
/>
<CVrangeSlider
v-model="value.ratio"
name="Ratio (W/H)"
:min="0"
:max="100"
:step="0.1"
@input="handleData('ratio')"
@rollback="e=> rollback('ratio',e)"
/>
<CVrangeSlider
v-model="value.extent"
name="Extent"
:min="0"
:max="100"
@input="handleData('extent')"
@rollback="e=> rollback('extent',e)"
/>
<CVslider
v-model="value.speckle"
name="Speckle Rejection"
:min="0"
:max="100"
@input="handleData('speckle')"
@rollback="e=> rollback('speckle',e)"
/>
<CVselect
v-model="value.targetGroup"
name="Target Group"
:list="['Single','Dual']"
@input="handleData('targetGroup')"
@rollback="e=> rollback('targetGroup',e)"
/>
<CVselect
v-model="value.targetIntersection"
name="Target Intersection"
:list="['None','Up','Down','Left','Right']"
:disabled="isDisabled"
@input="handleData('targetIntersection')"
@rollback="e=> rollback('targetIntersection',e)"
/>
</div>
<div>
<CVrangeSlider
v-model="contourArea"
name="Area"
:min="0"
:max="100"
:step="0.1"
@input="handlePipelineData('contourArea')"
@rollback="e=> rollback('contourArea',e)"
/>
<CVrangeSlider
v-model="contourRatio"
name="Ratio (W/H)"
:min="0"
:max="100"
:step="0.1"
@input="handlePipelineData('contourRatio')"
@rollback="e=> rollback('contourRatio',e)"
/>
<CVrangeSlider
v-model="contourExtent"
name="Extent"
:min="0"
:max="100"
@input="handlePipelineData('contourExtent')"
@rollback="e=> rollback('contourExtent',e)"
/>
<CVslider
v-model="contourSpecklePercentage"
name="Speckle Rejection"
:min="0"
:max="100"
@input="handlePipelineData('contourSpecklePercentage')"
@rollback="e=> rollback('contourSpecklePercentage',e)"
/>
<CVselect
v-model="contourGroupingMode"
name="Target Group"
:list="['Single','Dual']"
@input="handlePipelineData('targetGroup')"
@rollback="e=> rollback('targetGroup',e)"
/>
<CVselect
v-model="contourIntersection"
name="Target Intersection"
:list="['None','Up','Down','Left','Right']"
:disabled="contourGroupingMode === 0"
@input="handlePipelineData('contourIntersection')"
@rollback="e=> rollback('contourIntersection',e)"
/>
</div>
</template>
<script>
@@ -64,15 +64,60 @@
CVselect,
CVslider
},
// eslint-disable-next-line vue/require-prop-types
props: ['value'],
data() {
return {}
},
computed: {
isDisabled() {
return this.value.targetGroup === 0;
contourArea: {
get() {
return this.$store.getters.currentPipelineSettings.contourArea
},
set(val) {
this.$store.commit("mutatePipeline", {"contourArea": val});
}
},
contourRatio: {
get() {
return this.$store.getters.currentPipelineSettings.contourRatio
},
set(val) {
this.$store.commit("mutatePipeline", {"contourRatio": val});
}
},
contourExtent: {
get() {
return this.$store.getters.currentPipelineSettings.contourExtent
},
set(val) {
this.$store.commit("mutatePipeline", {"contourExtent": val});
}
},
contourSpecklePercentage: {
get() {
return this.$store.getters.currentPipelineSettings.contourSpecklePercentage
},
set(val) {
this.$store.commit("mutatePipeline", {"contourSpecklePercentage": val});
}
},
contourGroupingMode: {
get() {
return this.$store.getters.currentPipelineSettings.contourGroupingMode
},
set(val) {
this.$store.commit("mutatePipeline", {"contourGroupingMode": val});
}
},
contourIntersection: {
get() {
return this.$store.getters.currentPipelineSettings.contourIntersection
},
set(val) {
this.$store.commit("mutatePipeline", {"contourIntersection": val});
}
}
},
methods: {},

View File

@@ -1,50 +1,50 @@
<template>
<div>
<CVslider
v-model="value.exposure"
v-model="cameraExposure"
name="Exposure"
:min="0"
:max="100"
@input="handleData('exposure')"
@rollback="e => rollback('exposure', e)"
@input="handlePipelineData('cameraExposure')"
@rollback="e => rollback('cameraExposure', e)"
/>
<CVslider
v-model="value.brightness"
v-model="cameraBrightness"
name="Brightness"
:min="0"
:max="100"
@input="handleData('brightness')"
@rollback="e => rollback('brightness', e)"
@input="handlePipelineData('cameraBrightness')"
@rollback="e => rollback('cameraBrightness', e)"
/>
<CVslider
v-if="value.gain !== -1"
v-model="value.gain"
v-if="cameraGain !== -1"
v-model="cameraGain"
name="Gain"
:min="0"
:max="100"
@input="handleData('gain')"
@rollback="e => rollback('gain', e)"
@input="handlePipelineData('cameraGain')"
@rollback="e => rollback('cameraGain', e)"
/>
<CVselect
v-model="value.rotationMode"
v-model="inputImageRotationMode"
name="Orientation"
:list="['Normal','90° CW','180°','90° CCW']"
@input="handleData('rotationMode')"
@rollback="e => e => rollback('rotationMode',e)"
@input="handlePipelineData('inputImageRotationMode')"
@rollback="e => rollback('inputImageRotationMode',e)"
/>
<CVselect
v-model="value.videoModeIndex"
v-model="cameraVideoModeIndex"
name="Resolution"
:list="resolutionList"
@input="handleData('videoModeIndex')"
@rollback="e => rollback('videoModeIndex', e)"
@input="handlePipelineData('cameraVideoModeIndex')"
@rollback="e => rollback('cameraVideoModeIndex', e)"
/>
<CVselect
v-model="value.streamDivisor"
v-model="outputFrameDivisor"
name="Stream Resolution"
:list="streamResolutionList"
@input="handleData('streamDivisor')"
@rollback="e => rollback('streamDivisor', e)"
@input="handlePipelineData('outputFrameDivisor')"
@rollback="e => rollback('outputFrameDivisor', e)"
/>
</div>
</template>
@@ -59,24 +59,75 @@
CVslider,
CVselect,
},
// eslint-disable-next-line vue/require-prop-types
// eslint-disable-next-line vue/require-prop-types
props: ['value'],
data() {
return {}
},
computed: {
cameraExposure: {
get() {
return parseInt(this.$store.getters.currentPipelineSettings.cameraExposure);
},
set(val) {
this.$store.commit("mutatePipeline", {"cameraExposure": parseInt(val)});
}
},
cameraBrightness: {
get() {
return parseInt(this.$store.getters.currentPipelineSettings.cameraBrightness)
},
set(val) {
this.$store.commit("mutatePipeline", {"cameraBrightness": parseInt(val)});
}
},
cameraGain: {
get() {
return parseInt(this.$store.getters.currentPipelineSettings.cameraGain)
},
set(val) {
this.$store.commit("mutatePipeline", {"cameraGain": parseInt(val)});
}
},
inputImageRotationMode: {
get() {
return this.$store.getters.currentPipelineSettings.inputImageRotationMode
},
set(val) {
this.$store.commit("mutatePipeline", {"inputImageRotationMode": val});
}
},
cameraVideoModeIndex: {
get() {
return this.$store.getters.currentPipelineSettings.cameraVideoModeIndex
},
set(val) {
this.$store.commit("mutatePipeline", {"cameraVideoModeIndex": val});
}
},
outputFrameDivisor: {
get() {
return this.$store.getters.currentPipelineSettings.outputFrameDivisor
},
set(val) {
this.$store.commit("mutatePipeline", {"outputFrameDivisor": val});
}
},
resolutionList: {
get() {
let tmp_list = [];
for (let i of this.$store.state.resolutionList) {
for (let i of this.$store.getters.videoFormatList) {
tmp_list.push(`${i['width']} X ${i['height']} at ${i['fps']} FPS, ${i['pixelFormat']}`)
}
return tmp_list;
}
},
streamResolutionList: {
get() {
let cam_res = this.$store.state.resolutionList[this.value.videoModeIndex];
let cam_res = this.$store.getters.videoFormatList[
this.$store.getters.currentCameraSettings.currentPipelineSettings.cameraVideoModeIndex]
let tmp_list = [];
tmp_list.push(`${Math.floor(cam_res['width'])} X ${Math.floor(cam_res['height'])}`);
for (let x = 2; x <= 6; x += 2) {

View File

@@ -1,46 +1,46 @@
<template>
<div>
<CVselect
v-model="value.sortMode"
v-model="contourSortMode"
name="Sort Mode"
:list="['Largest','Smallest','Highest','Lowest','Rightmost','Leftmost','Centermost']"
@input="handleData('sortMode')"
@rollback="rollback('sortMode',e)"
@input="handlePipelineData('contourSortMode')"
@rollback="e => rollback('contourSortMode', e)"
/>
<CVselect
v-model="value.targetRegion"
name="Target Region"
v-model="contourTargetOffsetPointEdge"
name="Target Offset Point"
:list="['Center','Top','Bottom','Left','Right']"
@input="handleData('targetRegion')"
@rollback="e=> rollback('targetRegion',e)"
@input="handlePipelineData('contourTargetOffsetPointEdge')"
@rollback="e=> rollback('contourTargetOffsetPointEdge', e)"
/>
<CVselect
v-model="value.targetOrientation"
v-model="contourTargetOrientation"
name="Target Orientation"
:list="['Portrait', 'Landscape']"
@input="handleData('targetOrientation')"
@rollback="e=> rollback('targetOrientation',e)"
@input="handlePipelineData('contourTargetOrientation')"
@rollback="e=> rollback('contourTargetOrientation', e)"
/>
<CVswitch
v-model="value.multiple"
name="Output multiple"
@input="handleData('multiple')"
@rollback="e=> rollback('multiple',e)"
v-model="outputShowMultipleTargets"
name="Show Multiple Targets"
@input="handlePipelineData('outputShowMultipleTargets')"
@rollback="e=> rollback('outputShowMultipleTargets', e)"
/>
<span>Calibrate:</span>
<span>Robot Offset:</span>
<v-divider
dark
color="white"
/>
<CVselect
v-model="value.calibrationMode"
name="Calibration Mode"
:list="['None','Single point','Dual point']"
@input="handleData('calibrationMode')"
@rollback="e=> rollback('calibrationMode',e)"
v-model="offsetRobotOffsetMode"
name="Robot Offset Mode"
:list="['None','Single Point','Dual Point']"
@input="handlePipelineData('offsetRobotOffsetMode')"
@rollback="e=> rollback('offsetRobotOffsetMode',e)"
/>
<component
:is="selectedComponent"
@@ -82,6 +82,7 @@
DualCalibration,
},
// eslint-disable-next-line vue/require-prop-types
props: ['value'],
data() {
@@ -91,22 +92,65 @@
}
},
computed: {
contourSortMode: {
get() {
return this.$store.getters.currentPipelineSettings.contourSortMode
},
set(val) {
this.$store.commit("mutatePipeline", {"contourSortMode": val});
}
},
contourTargetOffsetPointEdge: {
get() {
return this.$store.getters.currentPipelineSettings.contourTargetOffsetPointEdge
},
set(val) {
this.$store.commit("mutatePipeline", {"contourTargetOffsetPointEdge": val});
}
},
contourTargetOrientation: {
get() {
return this.$store.getters.currentPipelineSettings.contourTargetOrientation
},
set(val) {
this.$store.commit("mutatePipeline", {"contourTargetOrientation": val});
}
},
outputShowMultipleTargets: {
get() {
return this.$store.getters.currentPipelineSettings.outputShowMultipleTargets
},
set(val) {
this.$store.commit("mutatePipeline", {"outputShowMultipleTargets": val});
}
},
offsetRobotOffsetMode: {
get() {
return this.$store.getters.currentPipelineSettings.offsetRobotOffsetMode
},
set(val) {
this.$store.commit("mutatePipeline", {"offsetRobotOffsetMode": val});
}
},
selectedComponent: {
get() {
switch (this.value.calibrationMode) {
case 0:
return "";
case 1:
return "SingleCalibration";
return "Single Point";
case 2:
return "DualCalibration"
return "Dual Point"
}
return ""
}
},
rawPoint: {
get() {
return this.$store.state.point.rawPoint;
return undefined; // TODO fix
}
}
},

View File

@@ -1,76 +1,76 @@
<template>
<div>
<CVrangeSlider
v-model="value.hue"
name="Hue"
:min="0"
:max="180"
@input="handleData('hue')"
@rollback="e => rollback('hue',e)"
/>
<CVrangeSlider
v-model="value.saturation"
name="Saturation"
:min="0"
:max="255"
@input="handleData('saturation')"
@rollback="e => rollback('saturation',e)"
/>
<CVrangeSlider
v-model="value.value"
name="Value"
:min="0"
:max="255"
@input="handleData('value')"
@rollback="e => rollback('value',e)"
/>
<v-divider
color="black"
style="margin-top: 5px"
/>
<v-row justify="center">
<v-btn
style="margin: 20px;"
color="#ffd843"
small
@click="setFunction(1)"
>
<v-icon>colorize</v-icon>
Eye drop
</v-btn>
<v-btn
style="margin: 20px;"
color="#ffd843"
small
@click="setFunction(2)"
>
<v-icon>add</v-icon>
Expand Selection
</v-btn>
<v-btn
style="margin: 20px;"
color="#ffd843"
small
@click="setFunction(3)"
>
<v-icon>remove</v-icon>
Shrink Selection
</v-btn>
</v-row>
<v-divider color="black" />
<CVswitch
v-model="value.erode"
name="Erode"
@input="handleData('erode')"
@rollback="e => rollback('erode',e)"
/>
<CVswitch
v-model="value.dilate"
name="Dilate"
@input="handleData('dilate')"
@rollback="e => rollback('dilate',e)"
/>
</div>
<div>
<CVrangeSlider
v-model="hsvHue"
name="Hue"
:min="0"
:max="180"
@input="handlePipelineData('hsvHue')"
@rollback="e => rollback('hue',e)"
/>
<CVrangeSlider
v-model="hsvSaturation"
name="Saturation"
:min="0"
:max="255"
@input="handlePipelineData('hsvSaturation')"
@rollback="e => rollback('saturation',e)"
/>
<CVrangeSlider
v-model="hsvValue"
name="Value"
:min="0"
:max="255"
@input="handlePipelineData('hsvValue')"
@rollback="e => rollback('value',e)"
/>
<v-divider
color="black"
style="margin-top: 5px"
/>
<v-row justify="center">
<v-btn
style="margin: 20px;"
color="#ffd843"
small
@click="setFunction(1)"
>
<v-icon>colorize</v-icon>
Eye drop
</v-btn>
<v-btn
style="margin: 20px;"
color="#ffd843"
small
@click="setFunction(2)"
>
<v-icon>add</v-icon>
Expand Selection
</v-btn>
<v-btn
style="margin: 20px;"
color="#ffd843"
small
@click="setFunction(3)"
>
<v-icon>remove</v-icon>
Shrink Selection
</v-btn>
</v-row>
<v-divider color="black"/>
<CVswitch
v-model="erode"
name="Erode"
@input="handlePipelineData('erode')"
@rollback="e => rollback('erode',e)"
/>
<CVswitch
v-model="dilate"
name="Dilate"
@input="handlePipelineData('dilate')"
@rollback="e => rollback('dilate',e)"
/>
</div>
</template>
<script>
@@ -83,28 +83,56 @@
CVrangeSlider,
CVswitch
},
// eslint-disable-next-line vue/require-prop-types
props: ['value'],
data() {
return {
currentFunction: undefined,
colorPicker: undefined,
currentBinaryState: 0
showThresholdState: 0
}
},
computed: {
pipeline: {
hsvHue: {
get() {
return this.$store.state.pipeline;
}
},
driverState: {
get() {
return this.$store.state.driverMode;
return this.$store.getters.currentPipelineSettings.hsvHue
},
set(val) {
this.$store.commit("driverMode", val);
this.$store.commit("mutatePipeline", {"hsvHue": val})
}
}
},
hsvSaturation: {
get() {
return this.$store.getters.currentPipelineSettings.hsvSaturation
},
set(val) {
this.$store.commit("mutatePipeline", {"hsvSaturation": val})
}
},
hsvValue: {
get() {
return this.$store.getters.currentPipelineSettings.hsvValue
},
set(val) {
this.$store.commit("mutatePipeline", {"hsvValue": val})
}
},
erode: {
get() {
return this.$store.getters.currentPipelineSettings.erode
},
set(val) {
this.$store.commit("mutatePipeline", {"erode": val});
}
},
dilate: {
get() {
return this.$store.getters.currentPipelineSettings.dilate
},
set(val) {
this.$store.commit("mutatePipeline", {"dilate": val});
}
},
},
mounted: function () {
const self = this;
@@ -119,25 +147,24 @@
let hsvArray = this.colorPicker.colorPickerClick(event, this.currentFunction,
[[this.value.hue[0], this.value.saturation[0], this.value.value[0]], [this.value.hue[1], this.value.saturation[1], this.value.value[1]]]);
this.currentFunction = undefined;
this.value.hue = [hsvArray[0][0], hsvArray[1][0]];
this.value.saturation = [hsvArray[0][1], hsvArray[1][1]];
this.value.value = [hsvArray[0][2], hsvArray[1][2]];
this.value.isBinary = this.currentBinaryState;
let msg = this.$msgPack.encode({
'hue': this.value.hue,
'saturation': this.value.saturation,
'value': this.value.value,
'isBinary': this.value.isBinary
"changePipelineSetting": {
'hsvHue': [hsvArray[0][0], hsvArray[1][0]],
'hsvSaturation': [hsvArray[0][1], hsvArray[1][1]],
'hsvValue': [hsvArray[0][2], hsvArray[1][2]],
'outputShowThresholded': this.showThresholdState,
'cameraIndex': this.$store.state.currentCameraIndex
}
});
this.$socket.send(msg);
this.$emit('update');
}
},
setFunction(index) {
this.currentBinaryState = this.value.isBinary;
if (this.currentBinaryState === true) {
this.value.isBinary = false;
this.handleData('isBinary')
this.showThresholdState = this.value.outputShowThresholded;
if (this.showThresholdState === true) {
this.value.outputShowThresholded = false;
this.handlePipelineData('outputShowThresholded')
}
switch (index) {
case 0: