The legacy Vue 1 motor settings page had nine `current_xxx` computed
props mirroring controller state vars (`<idx>vm`, `<idx>am`,
`<idx>jm`, `<idx>sa`, `<idx>tr`, `<idx>mi`, `<idx>tm`,
`<idx>tn`, `<idx>an`) paired with watchers that copied the state
value back into `config.motors[index]`, plus an `attached()` hook
running the same sync on mount.
The controller streams those vars continuously over the websocket.
Whenever a user typed into a field, the next state tick reverted it
to the controller's pre-edit value, so the form felt racy and edits
disappeared before Save. The same path also nuked unsaved edits when
navigating to another settings page and back.
The watcher logic was added in 749d63e to handle the case where
toggling rotary mode (PUT /api/rotary) rewrites motor 1+2 in
config.json on the server. Move that fix to the right place: refetch
config after the rotary PUT in app.js. The form now edits config
directly, Save PUTs it, and incoming controller state never overwrites
the user's in-progress edits.
Also drop the unused `syncStateToConfig` method.
132 lines
4.0 KiB
JavaScript
132 lines
4.0 KiB
JavaScript
"use strict";
|
|
|
|
module.exports = {
|
|
template: "#motor-view-template",
|
|
props: [ "index", "config", "template", "state" ],
|
|
|
|
computed: {
|
|
metric: function() {
|
|
return this.$root.display_units === "METRIC";
|
|
},
|
|
|
|
is_slave: function() {
|
|
for (let i = 0; i < this.index; i++) {
|
|
if (this.motor.axis == this.config.motors[i].axis) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
},
|
|
|
|
motor: function() {
|
|
return this.config.motors[this.index];
|
|
},
|
|
|
|
invalidMaxVelocity: function() {
|
|
return this.maxMaxVelocity < this.motor["max-velocity"];
|
|
},
|
|
|
|
maxMaxVelocity: function() {
|
|
return 1 * (15 * this.umPerStep / this.motor["microsteps"]).toFixed(3);
|
|
},
|
|
|
|
ustepPerSec: function() {
|
|
return this.rpm * this.stepsPerRev * this.motor["microsteps"] / 60;
|
|
},
|
|
|
|
rpm: function() {
|
|
return 1000 * this.motor["max-velocity"] / this.motor["travel-per-rev"];
|
|
},
|
|
|
|
gForce: function() {
|
|
return this.motor["max-accel"] * 0.0283254504;
|
|
},
|
|
|
|
gForcePerMin: function() {
|
|
return this.motor["max-jerk"] * 0.0283254504;
|
|
},
|
|
|
|
stepsPerRev: function() {
|
|
return 360 / this.motor["step-angle"];
|
|
},
|
|
|
|
umPerStep: function() {
|
|
return this.motor["travel-per-rev"] * this.motor["step-angle"] / 0.36;
|
|
},
|
|
|
|
milPerStep: function() {
|
|
return this.umPerStep / 25.4;
|
|
},
|
|
|
|
invalidStallVelocity: function() {
|
|
if (!this.motor["homing-mode"].startsWith("stall-")) {
|
|
return false;
|
|
}
|
|
|
|
return this.maxStallVelocity < this.motor["search-velocity"];
|
|
},
|
|
|
|
stallRPM: function() {
|
|
const v = this.motor["search-velocity"];
|
|
return 1000 * v / this.motor["travel-per-rev"];
|
|
},
|
|
|
|
maxStallVelocity: function() {
|
|
const maxRate = 900000 / this.motor["stall-sample-time"];
|
|
const ustep = this.motor["stall-microstep"];
|
|
const angle = this.motor["step-angle"];
|
|
const travel = this.motor["travel-per-rev"];
|
|
const maxStall = maxRate * 60 / 360 / 1000 * angle / ustep * travel;
|
|
|
|
return 1 * maxStall.toFixed(3);
|
|
},
|
|
|
|
stallUStepPerSec: function() {
|
|
const ustep = this.motor["stall-microstep"];
|
|
return this.stallRPM * this.stepsPerRev * ustep / 60;
|
|
},
|
|
|
|
// NOTE: do not add `current_xxx` computed props that mirror
|
|
// controller state vars (`<idx>vm`, `<idx>am`, …) and pair
|
|
// them with watchers that copy state -> motor config. The
|
|
// controller streams those vars continuously over the WS;
|
|
// any watcher that writes them back into
|
|
// `config.motors[index]` will clobber whatever the user is
|
|
// typing into the form between websocket ticks. The form
|
|
// edits config directly; Save (app.js) PUTs it to the
|
|
// server. The server-side rotary toggle is handled by
|
|
// refetching config after the PUT, not by watching state.
|
|
},
|
|
|
|
events: {
|
|
"input-changed": function() {
|
|
Vue.nextTick(function() {
|
|
// Limit max-velocity
|
|
if (this.invalidMaxVelocity) {
|
|
this.$set('motor["max-velocity"]', this.maxMaxVelocity);
|
|
}
|
|
|
|
//Limit stall-velocity
|
|
if (this.invalidStallVelocity) {
|
|
this.$set('motor["search-velocity"]', this.maxStallVelocity);
|
|
}
|
|
|
|
this.$dispatch("config-changed");
|
|
}.bind(this));
|
|
|
|
return false;
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
show: function(name, templ) {
|
|
if (templ.hmodes == undefined) {
|
|
return true;
|
|
}
|
|
|
|
return templ.hmodes.indexOf(this.motor["homing-mode"]) != -1;
|
|
}
|
|
}
|
|
};
|