mirror of
https://github.com/odriverobotics/ODrive.git
synced 2026-09-26 21:10:05 +08:00
Dashboard now filters the parameter tree depending on what type of element is being added
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { putVal } from "../../odrive_utils.js";
|
||||
import { putVal } from "../../lib/odrive_utils.js";
|
||||
|
||||
export default {
|
||||
name: "Action",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { putVal } from "../odrive_utils.js";
|
||||
import { putVal } from "../lib/odrive_utils.js";
|
||||
|
||||
export default {
|
||||
name: "clearErrors.vue",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { callFcn } from "../../odrive_utils.js";
|
||||
import { callFcn } from "../../lib/odrive_utils.js";
|
||||
|
||||
export default {
|
||||
name: "CtrlFunction",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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');
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user