Added "hooks" to wizard choices to allow for computation as part of a config choice

Added page-scope components for wizard pages
This commit is contained in:
PAJohnson
2020-09-14 21:44:09 -04:00
parent 7324fb69cf
commit 40c3fae9e6
8 changed files with 277 additions and 17 deletions
+60 -7
View File
@@ -2,6 +2,12 @@ import odriveEnums from "../odriveEnums.json";
// wizard is an object of pages.
// each page has a number, title, vue component name, next destination, back destination, and array of choices
// certain choices require a hook - for example, hall effect encoder cpr is 6 * motor.config.pole_pairs
// each hook takes a config object, modifies it, and returns it after running appropriate calculations.
// see choiceHandler() in Wizard.vue for how this happens
// Pages can also have custom components displayed below the choice tiles
// Example - on motor pages, there are buttons to run motor calibration and clear errors.
export let pages = {
ODrive: {
number: 0,
@@ -15,13 +21,16 @@ export let pages = {
{
imageURL: require("../images/24v_300x300.png"),
text: "ODrive v3.6 24V",
hooks: [],
},
{
imageURL: require("../images/56v_300x300.png"),
text: "ODrive v3.6 56V",
hooks: [],
},
],
customComponents: [],
pageComponents: [],
},
Motor_0: {
number: 1,
@@ -35,14 +44,16 @@ export let pages = {
{
imageURL: require("../images/D5065_300x300.png"),
text: "ODrive D5065",
hooks: [],
configStub: {
axis0: {
motor: {
config: {
pole_pairs: 7,
torque_constant: 8.27 / 270,
phase_resistance: 0.039, // from test rig
phase_inductance: 1.57e-5,
// R and L come from "Calibrate Motor" button on page
//phase_resistance: 0.039, // from test rig
//phase_inductance: 1.57e-5,
motor_type: odriveEnums.MOTOR_TYPE_HIGH_CURRENT, // MOTOR_TYPE_HIGH_CURRENT
},
},
@@ -52,14 +63,16 @@ export let pages = {
{
imageURL: require("../images/D6374_300x300.png"),
text: "ODrive D6374",
hooks: [],
configStub: {
axis0: {
motor: {
config: {
pole_pairs: 7,
torque_constant: 8.27 / 150,
phase_resistance: 0.041, // measurement from PJ
phase_inductance: 2.23e-5,
// R and L come from "Calibrate Motor" button on page
//phase_resistance: 0.041, // measurement from PJ
//phase_inductance: 2.23e-5,
motor_type: odriveEnums.MOTOR_TYPE_HIGH_CURRENT, // MOTOR_TYPE_HIGH_CURRENT,
},
},
@@ -76,6 +89,22 @@ export let pages = {
}
},
],
pageComponents: [
{
component: "wizardMotorMeasure",
id: 0,
data: {
axis: "axis0",
}
},
{
component: "wizardClearErrors",
id: 1,
data: {
axis: "axis0"
}
}
]
},
Encoder_0: {
number: 2,
@@ -89,6 +118,7 @@ export let pages = {
{
imageURL: require("../images/amt102-v_300x300.png"),
text: "CUI AMT102V",
hooks: [],
configStub: {
axis0: {
encoder: {
@@ -104,11 +134,18 @@ export let pages = {
{
imageURL: require("../images/hall_effect_300x300.png"),
text: "Hall Effect",
hooks: [
// hook takes a config object (normally this.wizardConfig in Wizard.vue), creates and returns a copy
(configObj) => {
let newConfig = configObj;
newConfig.axis0.encoder.config.cpr = 6 * newConfig.axis0.motor.config.pole_pairs;
return newConfig;
},
],
configStub: {
axis0: {
encoder: {
config: {
cpr: 8192,
use_index: false,
mode: odriveEnums.ENCODER_MODE_HALL,
}
@@ -133,6 +170,7 @@ export let pages = {
}
},
],
pageComponents: [],
},
Misc_0: {
number: 3,
@@ -152,6 +190,7 @@ export let pages = {
}
},
],
pageComponents: [],
},
Motor_1: {
number: 4,
@@ -165,6 +204,7 @@ export let pages = {
{
imageURL: require("../images/D5065_300x300.png"),
text: "ODrive D5065",
hooks: [],
configStub: {
axis1: {
motor: {
@@ -182,6 +222,7 @@ export let pages = {
{
imageURL: require("../images/D6374_300x300.png"),
text: "ODrive D6374",
hooks: [],
configStub: {
axis1: {
motor: {
@@ -206,6 +247,7 @@ export let pages = {
}
},
],
pageComponents: [],
},
Encoder_1: {
number: 5,
@@ -219,6 +261,7 @@ export let pages = {
{
imageURL: require("../images/amt102-v_300x300.png"),
text: "CUI AMT102V",
hooks: [],
configStub: {
axis0: {
encoder: {
@@ -234,11 +277,18 @@ export let pages = {
{
imageURL: require("../images/hall_effect_300x300.png"),
text: "Hall Effect",
hooks: [
// hook takes a config object, creates and returns a copy
(configObj) => {
let newConfig = configObj;
newConfig.axis1.encoder.config.cpr = 6 * newConfig.axis1.motor.config.pole_pairs;
return newConfig;
},
],
configStub: {
axis0: {
encoder: {
config: {
cpr: 8192,
use_index: false,
mode: odriveEnums.ENCODER_MODE_HALL, // ENCODER_MODE_INCREMENTAL
}
@@ -263,6 +313,7 @@ export let pages = {
}
},
],
pageComponents: [],
},
Misc_1: {
number: 6,
@@ -282,6 +333,7 @@ export let pages = {
}
},
],
pageComponents: [],
},
End: {
number: 7,
@@ -297,6 +349,7 @@ export let pages = {
component: "wizardEnd",
id: 0,
}
]
],
pageComponents: [],
}
}
@@ -54,6 +54,7 @@ export default {
this.$emit("choice", {
choice: "Incremental",
configStub: configStub,
hooks: [],
});
},
},
@@ -54,6 +54,7 @@ export default {
this.$emit("choice", {
choice: "IncrementalIndex",
configStub: configStub,
hooks: [],
});
},
},
+47 -3
View File
@@ -15,7 +15,7 @@
export default {
name: "wizardMisc",
props: {
data: Object
data: Object,
},
data: function () {
return {
@@ -27,7 +27,13 @@ export default {
},
computed: {
velocityLimit: function () {
let keys = ["odrive0", this.data.axis, "controller", "config", "vel_limit"];
let keys = [
"odrive0",
this.data.axis,
"controller",
"config",
"vel_limit",
];
let odriveObj = this.$store.state.odrives;
for (const key of keys) {
odriveObj = odriveObj[key];
@@ -45,7 +51,7 @@ export default {
},
methods: {
sendConfig() {
if ((this.vel_set == true && this.current_set == true)) {
if (this.vel_set == true && this.current_set == true) {
console.log("emitting choice event from limits page");
this.$emit("choice", {
choice: "Limits " + this.data.axis,
@@ -53,6 +59,44 @@ export default {
vel_limit: this.vel_limit,
current_lim: this.current_lim,
},
hooks: [],
});
let configStub = undefined;
if (this.data.axis == "axis0") {
configStub = {
axis0: {
controller: {
config: {
vel_limit: this.vel_limit,
}
},
motor: {
config: {
current_lim: this.current_lim,
}
}
},
};
} else if (this.data.axis == "axis1") {
configStub = {
axis1: {
controller: {
config: {
vel_limit: this.vel_limit,
}
},
motor: {
config: {
current_lim: this.current_lim,
}
}
},
};
}
this.$emit("choice", {
choice: "Misc " + this.data.axis,
configStub: configStub,
hooks: [],
});
}
},
+3 -3
View File
@@ -10,13 +10,12 @@
</div>
<div class="left">
<span>Phase Resistance =</span>
<span>{{" " + resistance}}</span>
<span>{{" " + resistance}} R</span>
</div>
<div class="left">
<span>Phase Inductace =</span>
<span>{{" " + inductance}}</span>
<span>{{" " + inductance}} H</span>
</div>
<button class="measure-button card" @click="measure">Measure Resistance and Inductance</button>
<span class="name">Other Motor</span>
</div>
</template>
@@ -174,6 +173,7 @@ export default {
this.$emit("choice", {
choice: "Other motor",
configStub: configStub,
hooks: [],
});
}
},
@@ -0,0 +1,48 @@
<template>
<div>
<button class="measure-button card" @click="calibrate">Calibrate Motor</button>
</div>
</template>
<script>
const axios = require("axios");
import odriveEnums from "../../assets/odriveEnums.json";
export default {
name: "wizardMotorMeasure",
props: {
data: Object,
},
methods: {
calibrate() {
// ask ODrive to measure resistance and inductance
var params = new URLSearchParams();
let keys = ["odrive0", this.data.axis, "requested_state"];
for (const key of keys) {
params.append("key", key);
}
params.append("val", odriveEnums.AXIS_STATE_MOTOR_CALIBRATION);
params.append("type", "number");
console.log(params.toString());
let request = {
params: params,
};
console.log(request);
axios.put(
this.$store.state.odriveServerAddress + "/api/property",
null,
request
);
this.$emit('page-comp-event', {data: "motor calibration", axis: this.data.axis});
},
},
};
</script>
<style scoped>
.measure-button:active {
background-color: var(--bg-color);
}
</style>
+26 -2
View File
@@ -9,7 +9,7 @@
:key="choice.id"
:imageUrl="choice.imageURL"
:text="choice.text"
v-on:click.native="selectedChoice=choice.text;$emit('choice', {title: title, choice: choice.text, configStub: choice.configStub})"
v-on:click.native="selectedChoice=choice.text;$emit('choice', {title: title, choice: choice.text, configStub: choice.configStub, hooks: choice.hooks})"
/>
<template v-for="customComponent in customComponents">
<component
@@ -24,6 +24,16 @@
/>
</template>
</div>
<div class="page-components">
<template v-for="pageComponent in pageComponents">
<component
v-bind:is="pageComponent.component"
v-bind:data="pageComponent.data"
v-bind:key="pageComponent.id"
v-on:page-comp-event="pageCompEvent"
/>
</template>
</div>
</div>
</template>
@@ -34,6 +44,8 @@ import wizardMotor from "./wizardMotor.vue";
import wizardEncoderIncremental from "./wizardEncoderIncremental.vue";
import wizardEncoderIncrementalIndex from "./wizardEncoderIncrementalIndex.vue";
import wizardEnd from "./wizardEnd.vue";
import wizardClearErrors from "./wizardClearErrors.vue";
import wizardMotorMeasure from "./wizardMotorMeasure.vue";
export default {
name: "wizardPage",
@@ -43,6 +55,7 @@ export default {
customComponents: Array,
axis: String,
config: Object,
pageComponents: Array,
},
components: {
wizardChoice,
@@ -51,6 +64,8 @@ export default {
wizardEncoderIncremental,
wizardEncoderIncrementalIndex,
wizardEnd,
wizardClearErrors,
wizardMotorMeasure,
},
data: function () {
return {
@@ -60,7 +75,10 @@ export default {
methods: {
handleCustomChoice(e) {
console.log(e);
this.$emit('choice', e);
this.$emit("choice", e);
},
pageCompEvent(e) {
this.$emit('page-comp-event',e);
}
},
};
@@ -79,6 +97,12 @@ export default {
flex-wrap: wrap;
}
.page-components {
display: flex;
flex-direction: row;
justify-content: center;
}
.chosen {
border: 2px solid black;
}
+91 -2
View File
@@ -8,22 +8,28 @@
:key="page.number"
class="wizard-link"
v-bind:class="{'active-link': currentStep == page}"
@click="currentStep=page"
@click="currentStep = page; choiceMade = false"
>{{page.link}}</span>
</div>
<div class="wizard-page">
<wizardPage
:choices="currentStep.choices"
:customComponents="currentStep.customComponents"
:pageComponents="currentStep.pageComponents"
:title="currentStep.title"
:config="wizardConfig"
v-on:choice="choiceHandler"
v-on:page-comp-event="pageEventHandler"
/>
<div class="wizard-controls">
<!-- show breadcrumbs, back, apply, next buttons -->
<button class="wizard-button card" @click="back">Back</button>
<button class="wizard-button card" @click="finish">Finish</button>
<button class="wizard-button card" @click="next">Next</button>
<button
class="wizard-button card"
v-bind:class="{'next-green': choiceMade}"
@click="next"
>Next</button>
</div>
</div>
</div>
@@ -48,6 +54,7 @@ export default {
return {
currentStep: pages.ODrive,
wizardConfig: configTemplate,
choiceMade: false,
};
},
computed: {
@@ -56,8 +63,83 @@ export default {
},
},
methods: {
pageEventHandler(e) {
this.choiceMade = false;
if (e.data == "motor calibration") {
// set a timeout to grab axis resistance and inductance values
setTimeout(() => {
let configStub = undefined;
let inductance;
let resistance;
let keys_L = [
"odrive0",
e.axis,
"motor",
"config",
"phase_inductance",
];
let keys_R = [
"odrive0",
e.axis,
"motor",
"config",
"phase_resistance",
];
let odriveObj = this.$store.state.odrives;
for (const key of keys_L) {
odriveObj = odriveObj[key];
}
inductance = parseFloat(odriveObj["val"]);
odriveObj = this.$store.state.odrives;
for (const key of keys_R) {
odriveObj = odriveObj[key];
}
resistance = parseFloat(odriveObj["val"]);
if (e.axis == "axis0") {
configStub = {
axis0: {
motor: {
config: {
phase_resistance: resistance,
phase_inductance: inductance,
},
},
},
};
} else if (e.axis == "axis1") {
configStub = {
axis1: {
motor: {
config: {
phase_resistance: resistance,
phase_inductance: inductance,
},
},
},
};
}
this.choiceHandler({
choice: "Motor Calibration",
configStub: configStub,
hooks: [],
})
}, 6000);
}
},
choiceHandler(e) {
// apply static configStub
this.updateConfig(this.wizardConfig, e.configStub);
// run hooks
for (const fn of e.hooks) {
this.wizardConfig = fn(this.wizardConfig);
}
// ugly, but a special case.
if (e.choice != "ODrive D5065" && e.choice != "ODrive D6374" && e.choice != "Other motor"){
this.choiceMade = true;
}
console.log(JSON.parse(JSON.stringify(this.wizardConfig)));
},
updateConfig(config, configStub) {
@@ -75,6 +157,7 @@ export default {
next() {
console.log("next");
this.currentStep = pages[this.currentStep.next];
this.choiceMade = false;
},
finish() {
console.log("finish");
@@ -83,6 +166,7 @@ export default {
back() {
console.log("back");
this.currentStep = pages[this.currentStep.back];
this.choiceMade = false;
},
},
};
@@ -147,4 +231,9 @@ export default {
.wizard-button:active {
background-color: var(--bg-color);
}
.next-green {
color: green;
font-weight: bold;
}
</style>