Dashboard now filters the parameter tree depending on what type of element is being added

This commit is contained in:
PAJohnson
2020-09-27 23:23:51 -04:00
parent 0ec763bdb4
commit c1f0fa67b0
22 changed files with 113 additions and 61 deletions
+1 -4
View File
@@ -26,7 +26,7 @@
<script>
import odriveEnums from "../assets/odriveEnums.json";
import clearErrors from "./clearErrors.vue";
import { getVal } from "../odrive_utils.js";
import { getVal } from "../lib/odrive_utils";
const axisErrors = {
0x00000000: "AXIS_ERROR_NONE",
@@ -248,9 +248,6 @@ export default {
setTimeout(update, 1000);
}
update();
console.log(this.axis);
console.log(this.axisErr);
console.log(this.motorErr);
}
};
</script>
+1 -1
View File
@@ -10,7 +10,7 @@
</template>
<script>
import { putVal } from "../../odrive_utils.js";
import { putVal } from "../../lib/odrive_utils.js";
export default {
name: "Action",
+1 -1
View File
@@ -5,7 +5,7 @@
</template>
<script>
import { putVal } from "../odrive_utils.js";
import { putVal } from "../lib/odrive_utils.js";
export default {
name: "clearErrors.vue",
+1 -1
View File
@@ -16,7 +16,7 @@
</template>
<script>
import { getVal, getReadonly, putVal } from "../../odrive_utils.js";
import { getVal, getReadonly, putVal } from "../../lib/odrive_utils.js";
export default {
name: "CtrlBoolean",
+1 -1
View File
@@ -14,7 +14,7 @@
</template>
<script>
import { getVal, getReadonly, putVal } from "../../odrive_utils.js";
import { getVal, getReadonly, putVal } from "../../lib/odrive_utils.js";
export default {
name: "CtrlNumeric",
+1 -1
View File
@@ -6,7 +6,7 @@
</template>
<script>
import { callFcn } from "../../odrive_utils.js";
import { callFcn } from "../../lib/odrive_utils.js";
export default {
name: "CtrlFunction",
+1 -1
View File
@@ -10,7 +10,7 @@
</template>
<script>
import { getVal, getReadonly, putVal } from "../../odrive_utils.js";
import { getVal, getReadonly, putVal } from "../../lib/odrive_utils.js";
export default {
name: "CtrlNumeric",
+1 -1
View File
@@ -16,7 +16,7 @@
<script>
import VueSlider from "vue-slider-component";
import "vue-slider-component/theme/default.css";
import { getVal, putVal } from "../../odrive_utils.js";
import { getVal, putVal } from "../../lib/odrive_utils.js";
export default {
name: "CtrlSlider",
@@ -9,7 +9,7 @@
</template>
<script>
import { getUnit } from '../../../odrive_utils.js';
import { getUnit } from '../../../lib/odrive_utils.js';
export default {
name: "wizardBrake",
@@ -12,7 +12,7 @@
<script>
import { enumVars } from "../../../assets/wizard/wizard.js";
import { putVal } from "../../../odrive_utils.js"
import { putVal } from "../../../lib/odrive_utils.js"
export default {
name: "wizardEnd",
@@ -11,7 +11,7 @@
<script>
import odriveEnums from "../../../assets/odriveEnums.json";
import { getVal } from "../../../odrive_utils.js"
import { getVal } from "../../../lib/odrive_utils.js"
export default {
name: "wizardInputFiltered",
@@ -24,7 +24,7 @@
</template>
<script>
import { getVal } from "../../../odrive_utils.js"
import { getVal } from "../../../lib/odrive_utils.js"
export default {
name: "wizardInputTrajectory",
@@ -11,7 +11,7 @@
<script>
import odriveEnums from "../../../assets/odriveEnums.json";
import { getVal } from "../../../odrive_utils.js"
import { getVal } from "../../../lib/odrive_utils.js"
export default {
name: "wizardInputVelRamp",
@@ -14,7 +14,7 @@
</template>
<script>
import { getVal, getUnit } from "../../../odrive_utils.js"
import { getVal, getUnit } from "../../../lib/odrive_utils.js"
export default {
name: "wizardMisc",
@@ -24,7 +24,7 @@
<script>
import odriveEnums from "../../../assets/odriveEnums.json";
import { getVal } from "../../../odrive_utils.js"
import { getVal } from "../../../lib/odrive_utils.js"
export default {
name: "wizardMotor",
@@ -6,7 +6,7 @@
<script>
import odriveEnums from "../../../assets/odriveEnums.json";
import { putVal } from "../../../odrive_utils.js"
import { putVal } from "../../../lib/odrive_utils.js"
export default {
name: "wizardMotorCal",
@@ -1,5 +1,5 @@
import store from "./store.js";
import * as socketio from "./comms/socketio.js";
import store from "../store.js";
import * as socketio from "../comms/socketio.js";
// helper functions and utilities for getting ODrive values
+33
View File
@@ -0,0 +1,33 @@
// general utilities for use in the GUI
// given an object and a test function, return a new object where only
// the values where test(value) == true are kept, as well as the parents
// of those objects. Nested non-matching children are set to {}
// ex: obj = {parent: {child1: {child2: "hello"}, child1a: {child2a: "world"}}}, test = ((o) => o == "hello"),
// filterBy(obj, test) -> {parent: {child1: {child2: "hello"}, child1a: {}}}
export let filterBy = (obj, test) => {
let retobj = {};
Object.entries(obj).forEach(([key, val]) => {
if (test(val)) {
retobj[key] = val;
}
else if (typeof val == 'object' && val != null) {
retobj[key] = filterBy(val, test);
}
})
return retobj;
}
// given an object and test function, delete values where test(val) == true
// modifies obj in place
export let deleteBy = (obj, test) => {
Object.keys(obj).forEach((key) => {
if (typeof obj[key] == 'object' && obj[key] != null) {
deleteBy(obj[key], test);
}
if (test(obj[key])) {
delete obj[key];
}
})
}
+32 -16
View File
@@ -3,6 +3,7 @@ import Vuex from 'vuex';
import ConfigDashOld from "./assets/dashboards/Config_0_4_12.json";
import ConfigDashNew from "./assets/dashboards/Config_0_5_1.json";
import * as socketio from "./comms/socketio";
import {filterBy, deleteBy } from "./lib/utils.js";
//import { v4 as uuidv4 } from "uuid";
@@ -15,6 +16,8 @@ export default new Vuex.Store({
state: {
odrives: Object,
odriveConfigs: Object,
odriveParameters: Object,
odriveFunctions: Object,
axes: Array,
odriveServerAddress: String,
serverConnected: Boolean,
@@ -60,9 +63,7 @@ export default new Vuex.Store({
state.dashboards.push(ConfigDash);
// plots will have variables associated, add them to sampled variables list
for (const plot of ConfigDash.plots) {
console.log(plot);
for (const plotVar of plot.vars) {
console.log(plotVar);
//addsampledprop(path);
let path = plotVar.path;
if (!(path in state.sampledProperties)) {
@@ -70,10 +71,6 @@ export default new Vuex.Store({
newPath.splice(0, 1);
state.sampledProperties.push(newPath.join('.'));
state.propSamples[newPath.join('.')] = [];
console.log(state.propSamples);
}
for (const path of state.sampledProperties) {
console.log(path);
}
socketio.sendEvent({
type: 'sampledVarNames',
@@ -86,8 +83,12 @@ export default new Vuex.Store({
}
state.firstConn = true;
},
setOdriveConfigs(state, odriveConfigs) {
state.odriveConfigs = odriveConfigs;
setOdriveConfigs(state, payload) {
state.odriveConfigs['full'] = payload.full;
state.odriveConfigs['functions'] = payload.functions;
state.odriveConfigs['params'] = payload.params;
state.odriveConfigs['writeAble'] = payload.writeAble;
state.odriveConfigs['writeAbleNumeric'] = payload.writeAbleNumeric;
},
setAxes(state, axes) {
state.axes = axes;
@@ -100,7 +101,6 @@ export default new Vuex.Store({
// payload is {path, value}
//
const createNestedObject = (odrive, path) => {
console.log("from createNestedObject " + path);
let ref = odrive;
let keys = path.split('.');
for (const key of keys) {
@@ -117,10 +117,6 @@ export default new Vuex.Store({
newPath.splice(0, 1);
state.sampledProperties.push(newPath.join('.'));
state.propSamples[newPath.join('.')] = [];
console.log(state.propSamples);
}
for (const path of state.sampledProperties) {
console.log(path);
}
socketio.sendEvent({
type: 'sampledVarNames',
@@ -211,7 +207,6 @@ export default new Vuex.Store({
for (const action of dash.actions) {
if (obj.actionID == action.id) {
action.val = obj.val;
console.log("Setting action val to " + obj.val);
break;
}
}
@@ -263,7 +258,29 @@ export default new Vuex.Store({
}
return retObj;
}
context.commit('setOdriveConfigs', treeParse(context.state.odrives));
// full parameter tree
// create object containing only ODrive functions
let fullTree = treeParse(context.state.odrives);
let fcns = filterBy(fullTree, ((o) => o == "function"));
deleteBy(fcns, ((o) => o.constructor == Object && Object.keys(o).length == 0));
// create object containing only ODrive parameters
let params = filterBy(fullTree, ((o) => o != "function" && typeof o != "object"));
deleteBy(params, ((o) => o.constructor == Object && Object.keys(o).length == 0))
// create object containing only ODrive parameters with write access
let writeAble = filterBy(context.state.odrives, ((o) => o['readonly'] == false));
deleteBy(writeAble, ((o) => o.constructor == Object && Object.keys(o).length == 0))
// create object of only ODrive parameters that are writeable and numeric
let writeAbleNumeric = filterBy(context.state.odrives, ((o) => o['readonly'] == false && ['float', 'int', 'bool'].includes(o['type'])));
deleteBy(writeAbleNumeric, ((o) => o.constructor == Object && Object.keys(o).length == 0))
context.commit('setOdriveConfigs', {full: fullTree,
functions: fcns,
params: params,
writeAble: treeParse(writeAble),
writeAbleNumeric: treeParse(writeAbleNumeric)});
},
getAxes(context) {
let axes = [];
@@ -319,7 +336,6 @@ export default new Vuex.Store({
socketio.addEventListener({
type: "odrives",
callback: odrives => {
console.log("response from odrive socketio" + JSON.parse(odrives))
context.commit('setOdrives', JSON.parse(odrives));
context.dispatch('getOdriveConfigs');
context.dispatch('getAxes');
+29 -7
View File
@@ -9,7 +9,7 @@
</div>
<div class="param-tree">
<json-view
:data="odriveConfigs"
:data="treeParams"
:rootKey="'odrives'"
v-on:selected="addVarToElement"
/>
@@ -32,6 +32,7 @@
<div class="control-buttons">
<div class="add-button card" @click="addComponent('control')">Add Control</div>
<div class="add-button card" @click="addComponent('slider')">Add Slider</div>
<div class="add-button card" @click="addComponent('function')">Add Function</div>
</div>
<template v-for="(action, index) in dash.actions">
<action
@@ -271,13 +272,9 @@ export default {
paramsVisible: false,
addCompType: undefined,
currentPlot: undefined,
treeParams: undefined,
};
},
computed: {
odriveConfigs: function () {
return this.$store.state.odriveConfigs;
},
},
methods: {
deleteAction(e) {
this.$emit("delete-action", e);
@@ -299,13 +296,32 @@ export default {
},
addComponent(componentType) {
this.addCompType = componentType;
switch (this.addCompType) {
case "control":
this.treeParams = this.$store.state.odriveConfigs['params'];
break;
case "plot":
this.treeParams = this.$store.state.odriveConfigs['params'];
break;
case "slider":
this.treeParams = this.$store.state.odriveConfigs['writeAbleNumeric'];
break;
case "action":
this.treeParams = this.$store.state.odriveConfigs['writeAble'];
break;
case "function":
this.treeParams = this.$store.state.odriveConfigs['functions'];
break;
default:
break;
}
this.paramsVisible = true;
},
addVarToElement(e) {
//when the parameter tree is open and a parameter is clicked,
//add the clicked parameter to the list of controls for the
//current dashboard
console.log(e);
console.log(e);
switch (this.addCompType) {
case "control":
switch (typeof e.value) {
@@ -342,6 +358,12 @@ export default {
break;
}
break;
case "function":
this.dash.controls.push({
controlType: "CtrlFunction",
path: e.path,
});
break;
case "plot":
// add the selected element to the plot var list
// add the selected element to the sampling var list
-16
View File
@@ -13,13 +13,10 @@
<div class="server-msgs" v-if="showServerMessages">
<div class="server-msg" v-for="(msg, index) in serverMessages" :key="msg + index">{{msg}}</div>
</div>
<button @click="getParamTest">Get parameter</button>
<button @click="setParamTest">Set parameter</button>
</div>
</template>
<script>
import * as socketio from "../comms/socketio.js";
export default {
name: 'Home',
@@ -55,19 +52,6 @@ export default {
console.log(e.target.value);
this.$store.dispatch("setServerAddress", e.target.value);
},
getParamTest() {
// send getparam event, figure out what it looks like on the server side
socketio.sendEvent({
type: "getProperty",
data: {path: "odrive0.axis0.current_state"},
});
},
setParamTest() {
socketio.sendEvent({
type: "setProperty",
data: {path: "odrive0.axis0.requested_state", val: "8", type: "number"}
})
}
}
}
</script>
+1 -1
View File
@@ -49,7 +49,7 @@ import configTemplate from "../assets/wizard/configTemplate.json";
import wizardPage from "../components/wizard/wizardPage.vue";
import odriveEnums from "../assets/odriveEnums.json";
import { pages } from "../assets/wizard/wizard.js";
import { getVal, putVal } from "../odrive_utils.js"
import { getVal, putVal } from "../lib/odrive_utils.js"
// see wizard.js for what wizard pages exist and what they contain