Fixed homing in imperial mode, Limit motor max-velocity such that step rate cannot...
authorJoseph Coffland <joseph@cauldrondevelopment.com>
Tue, 21 Aug 2018 01:25:52 +0000 (18:25 -0700)
committerJoseph Coffland <joseph@cauldrondevelopment.com>
Tue, 21 Aug 2018 01:25:52 +0000 (18:25 -0700)
CHANGELOG.md
package.json
src/avr/src/motor.c
src/avr/src/vars.def
src/avr/src/vfd_spindle.c
src/jade/templates/motor-view.jade
src/js/motor-view.js
src/py/bbctrl/Mach.py
src/py/bbctrl/Planner.py
src/py/bbctrl/State.py

index 1d5589f1e3a953d9aa8e30482018370fb4264c18..b7293e3facbce4d3ff6622ba5546cc17e4a3829f 100644 (file)
@@ -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.
index ab3cfe43f59651b6950487dc8531c35997eaf788..aa5b3cda1394d6bc0020908078584679a24626ed 100644 (file)
@@ -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+",
index a494ed92195751a4958fa0593af1c50c3b0d671c..832c94fe6516a43b0c88dc97de171bee4f663683 100644 (file)
@@ -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;
 
index d16957c6e749f70e641489a3b6e6c24e5a7e18b1..dd163927ac806dca3e4d194021ddf7d846319e80 100644 (file)
@@ -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
 
index 53bec20249b718d9b85f51c19a6fcc550f863a4c..79acc7fdf7332246a517d4c723a600f93a3f19a2 100644 (file)
@@ -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()) {
index 6171570058ea917bd4b8abe1d97dec2fd82aed38..17c52a76139d3809528844a46c13da6c91f6afbc 100644 (file)
@@ -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)
 
index 9e40975fc980f178c8ebf35bf350aa269d2e4012..9c6c54316f9851f807d62053a1850484ee0a5bc9 100644 (file)
@@ -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;
     }
index 46a95274193ff4be75e2edfa80a696bcdf483010..3d85a50c3e1bf3ddfbed4068f99c7008ae47f389 100644 (file)
@@ -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>]
 '''
 
 
index fd824092c65ef613046d65ed3c0dc5dd1aec9ce8..6260c1ac98479984aed4c9bbce9b5b09c5fe5c66 100644 (file)
@@ -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
 
 
index dcbd4a38f222157fc8fa53c11571ede8375aefcd..a91b3ba7ca621902c153f0e547d0fce7462856a5 100644 (file)
@@ -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')