From 9f1f020d97009d4f683fbab1b145288d9481c6ce Mon Sep 17 00:00:00 2001 From: Joseph Coffland Date: Mon, 20 Aug 2018 18:25:52 -0700 Subject: [PATCH] Fixed homing in imperial mode, Limit motor max-velocity such that step rate cannot exceed 250k, Fixed deceleration bug at full 250k step rate, Show step rate on motor configuration page. --- CHANGELOG.md | 14 +++++++++ package.json | 2 +- src/avr/src/motor.c | 11 ++++--- src/avr/src/vars.def | 2 +- src/avr/src/vfd_spindle.c | 1 + src/jade/templates/motor-view.jade | 5 +++ src/js/motor-view.js | 19 ++++++++++++ src/py/bbctrl/Mach.py | 22 +++++++------ src/py/bbctrl/Planner.py | 6 ++-- src/py/bbctrl/State.py | 50 ++++++++++++++++++++++++++---- 10 files changed, 108 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d5589f..b7293e3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,20 @@ Buildbotics CNC Controller Firmware Changelog ============================================== +## v0.3.28 + - Show step rate on motor configuration page. + - Limit motor max-velocity such that step rate cannot exceed 250k. + - Fixed deceleration bug at full 250k step rate. + +## v0.3.27 + - Fixed homing in imperial mode. + +## v0.3.26 + - Removed VFD test. + - Show VFD status on configuration page. + - Show VFD commands fail counts. + - Marked some VFD types as beta. + ## v0.3.25 - Error on home if max-soft-limit <= min-soft-limit + 1. #139 - Decrease boot time networking delay. diff --git a/package.json b/package.json index ab3cfe4..aa5b3cd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bbctrl", - "version": "0.3.26", + "version": "0.3.28", "homepage": "http://buildbotics.com/", "repository": "https://github.com/buildbotics/bbctrl-firmware", "license": "GPL-3.0+", diff --git a/src/avr/src/motor.c b/src/avr/src/motor.c index a494ed9..832c94f 100644 --- a/src/avr/src/motor.c +++ b/src/avr/src/motor.c @@ -319,10 +319,13 @@ void motor_prep_move(int motor, float target) { float ticks_per_step = round(seg_clocks / steps); // Limit clock if step rate is too fast, disable if too slow - if (ticks_per_step < STEP_PULSE_WIDTH * 2) - ticks_per_step = STEP_PULSE_WIDTH * 2; // Too fast - if (0xffff <= ticks_per_step) m->timer_period = 0; // Too slow - else m->timer_period = ticks_per_step; // Just right + // We allow a slight fudge here (i.e. 1.9 instead 2) because the motor driver + // seems to be able to handle it and otherwise we could not actually hit + // an average rate of 250k usteps/sec. + if (ticks_per_step < STEP_PULSE_WIDTH * 1.9) + m->timer_period = STEP_PULSE_WIDTH * 1.9; // Too fast + else if (0xffff <= ticks_per_step) m->timer_period = 0; // Too slow + else m->timer_period = ticks_per_step; // Just right if (!steps) m->timer_period = 0; diff --git a/src/avr/src/vars.def b/src/avr/src/vars.def index d16957c..dd16392 100644 --- a/src/avr/src/vars.def +++ b/src/avr/src/vars.def @@ -57,7 +57,7 @@ VAR(driver_flags, df, u16, MOTORS, 0, 1) // Motor driver flags VAR(status_strings, ds, flags, MOTORS, 0, 1) // Motor driver status VAR(driver_stalled, sl, b8, MOTORS, 0, 1) // Motor driver status VAR(encoder, en, s32, MOTORS, 0, 0) // Motor encoder -VAR(error, ee, s32, MOTORS, 0, 0) // Motor position error +VAR(error, ee, s32, MOTORS, 0, 1) // Motor position error VAR(motor_fault, fa, b8, 0, 0, 1) // Motor fault status diff --git a/src/avr/src/vfd_spindle.c b/src/avr/src/vfd_spindle.c index 53bec20..79acc7f 100644 --- a/src/avr/src/vfd_spindle.c +++ b/src/avr/src/vfd_spindle.c @@ -324,6 +324,7 @@ static void _load(const vfd_reg_t *_regs) { void vfd_spindle_init() { memset(&vfd, 0, sizeof(vfd)); + for (int i = 0; i < VFDREG; i++) regs[i].fails = 0; modbus_init(); switch (spindle_get_type()) { diff --git a/src/jade/templates/motor-view.jade b/src/jade/templates/motor-view.jade index 6171570..17c52a7 100644 --- a/src/jade/templates/motor-view.jade +++ b/src/jade/templates/motor-view.jade @@ -36,6 +36,11 @@ script#motor-view-template(type="text/x-template") templated-input(v-for="templ in category", :name="$key", :model.sync="motor[$key]", :template="templ") + label.extra(v-if="$key == 'microsteps'", slot="extra", + :class="{error: invalidMaxVelocity}", + title="Microsteps per second") + | ({{ustepPerSec / 1000 | fixed 1}}k µstep/sec) + label.extra(v-if="$key == 'max-velocity'", slot="extra", title="Revolutions Per Minute") ({{rpm | fixed 0}} RPM) diff --git a/src/js/motor-view.js b/src/js/motor-view.js index 9e40975..9c6c543 100644 --- a/src/js/motor-view.js +++ b/src/js/motor-view.js @@ -49,6 +49,21 @@ module.exports = { motor: function () {return this.config.motors[this.index]}, + invalidMaxVelocity: function () { + return this.maxMaxVelocity < this.motor['max-velocity']; + }, + + + maxMaxVelocity: function () { + return 15 * this.umPerStep / this.motor['microsteps']; + }, + + + ustepPerSec: function () { + return this.rpm * this.stepsPerRev * this.motor['microsteps'] / 60; + }, + + rpm: function () { return 1000 * this.motor['max-velocity'] / this.motor['travel-per-rev']; }, @@ -70,6 +85,10 @@ module.exports = { events: { 'input-changed': function() { + // Limit max-velocity + if (this.invalidMaxVelocity) + this.motor['max-velocity'] = this.maxMaxVelocity; + this.$dispatch('config-changed'); return false; } diff --git a/src/py/bbctrl/Mach.py b/src/py/bbctrl/Mach.py index 46a9527..3d85a50 100644 --- a/src/py/bbctrl/Mach.py +++ b/src/py/bbctrl/Mach.py @@ -38,19 +38,21 @@ log = logging.getLogger('Mach') # Axis homing procedure: # # Mark axis unhomed -# Seek closed (home_dir * (travel_max - travel_min) * 1.5) at search_velocity -# Seek open (home_dir * -latch_backoff) at latch_vel -# Seek closed (home_dir * latch_backoff * 1.5) at latch_vel -# Rapid to (home_dir * -zero_backoff + position) +# Set feed rate to search_vel +# Seek closed by search_dist +# Set feed rate to latch_vel +# Seek open latch_backoff +# Seek closed latch_backoff * -1.5 +# Rapid to zero_backoff # Mark axis homed and set absolute position axis_homing_procedure = ''' - G28.2 %(axis)s0 F[#<_%(axis)s_sv> * 1000] - G38.6 %(axis)s[#<_%(axis)s_hd> * [#<_%(axis)s_tm> - #<_%(axis)s_tn>] * 1.5] - G38.8 %(axis)s[#<_%(axis)s_hd> * -#<_%(axis)s_lb>] F[#<_%(axis)s_lv> * 1000] - G38.6 %(axis)s[#<_%(axis)s_hd> * #<_%(axis)s_lb> * 1.5] - G91 G0 G53 %(axis)s[#<_%(axis)s_hd> * -#<_%(axis)s_zb>] - G90 G28.3 %(axis)s[#<_%(axis)s_hp>] + G28.2 %(axis)s0 F[#<_%(axis)s_search_velocity>] + G38.6 %(axis)s[#<_%(axis)s_home_travel>] + G38.8 %(axis)s[#<_%(axis)s_latch_backoff>] F[#<_%(axis)s_latch_velocity>] + G38.6 %(axis)s[#<_%(axis)s_latch_backoff> * -1.5] + G91 G0 G53 %(axis)s[#<_%(axis)s_zero_backoff>] + G90 G28.3 %(axis)s[#<_%(axis)s_home_position>] ''' diff --git a/src/py/bbctrl/Planner.py b/src/py/bbctrl/Planner.py index fd82409..6260c1a 100644 --- a/src/py/bbctrl/Planner.py +++ b/src/py/bbctrl/Planner.py @@ -142,12 +142,14 @@ class Planner(): self.cmdq.release(id) - def _get_var_cb(self, name): + def _get_var_cb(self, name, units): value = 0 if len(name) and name[0] == '_': value = self.ctrl.state.get(name[1:], 0) + if units == 'IMPERIAL': value /= 25.4 # Assume metric + + log.info('Get: %s=%s (units=%s)' % (name, value, units)) - log.info('Get: %s=%s' % (name, value)) return value diff --git a/src/py/bbctrl/State.py b/src/py/bbctrl/State.py index dcbd4a3..a91b3ba 100644 --- a/src/py/bbctrl/State.py +++ b/src/py/bbctrl/State.py @@ -50,14 +50,23 @@ class State(object): 'speed': 0, } + # Add computed variable callbacks for each motor. + # + # NOTE, variable callbacks must return metric values only because + # the planner will scale returned values when in imperial mode. for i in range(4): - # Add home direction callbacks - self.set_callback(str(i) + 'hd', - lambda name, i = i: self.motor_home_direction(i)) - - # Add home position callbacks - self.set_callback(str(i) + 'hp', + self.set_callback(str(i) + 'home_position', lambda name, i = i: self.motor_home_position(i)) + self.set_callback(str(i) + 'home_travel', + lambda name, i = i: self.motor_home_travel(i)) + self.set_callback(str(i) + 'latch_backoff', + lambda name, i = i: self.motor_latch_backoff(i)) + self.set_callback(str(i) + 'zero_backoff', + lambda name, i = i: self.motor_zero_backoff(i)) + self.set_callback(str(i) + 'search_velocity', + lambda name, i = i: self.motor_search_velocity(i)) + self.set_callback(str(i) + 'latch_velocity', + lambda name, i = i: self.motor_latch_velocity(i)) self.reset() @@ -237,3 +246,32 @@ class State(object): if mode == 'switch-min': return self.vars['%dtn' % motor] if mode == 'switch-max': return self.vars['%dtm' % motor] return 0 # Disabled + + + def motor_home_travel(self, motor): + tmin = self.get(str(motor) + 'tm') + tmax = self.get(str(motor) + 'tn') + hdir = self.motor_home_direction(motor) + + # (travel_max - travel_min) * 1.5 * home_dir + return (tmin - tmax) * 1.5 * hdir + + + def motor_latch_backoff(self, motor): + lb = self.get(str(motor) + 'lb') + hdir = self.motor_home_direction(motor) + return -(lb * hdir) # -latch_backoff * home_dir + + + def motor_zero_backoff(self, motor): + zb = self.get(str(motor) + 'zb') + hdir = self.motor_home_direction(motor) + return -(zb * hdir) # -zero_backoff * home_dir + + + def motor_search_velocity(self, motor): + return 1000 * self.get(str(motor) + 'sv') + + + def motor_latch_velocity(self, motor): + return 1000 * self.get(str(motor) + 'lv') -- 2.27.0