Fixes program pause. Changes for move during pause.
authorJoseph Coffland <joseph@cauldrondevelopment.com>
Tue, 27 Nov 2018 05:39:28 +0000 (21:39 -0800)
committerJoseph Coffland <joseph@cauldrondevelopment.com>
Tue, 27 Nov 2018 05:39:28 +0000 (21:39 -0800)
src/avr/src/command.c
src/avr/src/state.c
src/js/control-view.js
src/pug/templates/control-view.pug
src/py/bbctrl/Comm.py
src/py/bbctrl/Mach.py
src/py/bbctrl/Planner.py

index 2b31db5a2027a648ae5e411c8c66b2b8531e7c4a..9f01b30e8ed496d051a814f1448ba0fec2204ea8 100644 (file)
@@ -162,6 +162,7 @@ void command_print_json() {
 void command_flush_queue() {
   sync_q_init();
   cmd.count = 0;
+  command_reset_position();
 }
 
 
index 4b4b3c17849ef71f5df8cfd9d0541e6bbd48682a..e4789415e4cab7dd80806ee546bdb50ba1f506b7 100644 (file)
@@ -169,7 +169,7 @@ void state_callback() {
   if (estop_triggered()) return;
 
   // Pause
-  if (s.pause_requested || s.flushing) {
+  if (s.pause_requested) {
     if (state_get() == STATE_RUNNING) {
       if (s.pause_requested) _set_hold_reason(HOLD_REASON_USER_PAUSE);
       _set_state(STATE_STOPPING);
index 8aa64b5993a3e95b38bc19c4efb52e838ed7875c..81af75ec3715a7ca62caed0892ac11678edc95c6 100644 (file)
@@ -117,6 +117,9 @@ module.exports = {
     },
 
 
+    pause_reason: function () {return this.state.pr},
+
+
     is_running: function () {
       return this.mach_state == 'RUNNING' || this.mach_state == 'HOMING';
     },
@@ -125,10 +128,23 @@ module.exports = {
     is_stopping: function () {return this.mach_state == 'STOPPING'},
     is_holding: function () {return this.mach_state == 'HOLDING'},
     is_ready: function () {return this.mach_state == 'READY'},
+    is_idle: function () {return this.state.cycle == 'idle'},
+
+
+    is_paused: function () {
+      return this.is_holding &&
+        (this.pause_reason == 'User pause' ||
+         this.pause_reason == 'Program pause')
+    },
+
+
+    can_mdi: function () {return this.is_idle || this.state.cycle == 'mdi'},
 
 
-    can_mdi: function () {
-      return this.state.cycle == 'idle' || this.state.cycle == 'mdi';
+    can_set_axis: function () {
+      return this.is_idle
+      // TODO allow setting axis position during pause
+      return this.is_idle || this.is_paused
     },
 
 
index 6097a1861d8497980dbc67801fd1387a1138be6b..1b719746e639da4fd730edfe47706dd94885d823 100644 (file)
@@ -35,11 +35,11 @@ script#control-view-template(type="text/x-template")
         th.offset Offset
         th.state State
         th.actions
-          button.pure-button(:disabled="!can_mdi",
+          button.pure-button(:disabled="!can_set_axis",
             title="Zero all axis offsets.", @click="zero()") &empty;
 
           button.pure-button(title="Home all axes.", @click="home()",
-            :disabled="!can_mdi")
+            :disabled="!is_idle")
             .fa.fa-home
 
       each axis in 'xyzabc'
@@ -54,16 +54,16 @@ script#control-view-template(type="text/x-template")
             | {{#{axis}.state}}
 
           th.actions
-            button.pure-button(:disabled="!can_mdi",
+            button.pure-button(:disabled="!can_set_axis",
               title=`Set {{'${axis}' | upper}} axis position.`,
               @click=`show_set_position('${axis}')`)
               .fa.fa-cog
 
-            button.pure-button(:disabled="!can_mdi",
+            button.pure-button(:disabled="!can_set_axis",
               title=`Zero {{'${axis}' | upper}} axis offset.`,
               @click=`zero('${axis}')`) &empty;
 
-            button.pure-button(:disabled="!can_mdi", @click=`home('${axis}')`,
+            button.pure-button(:disabled="!is_idle", @click=`home('${axis}')`,
               title=`Home {{'${axis}' | upper}} axis.`)
               .fa.fa-home
 
@@ -121,7 +121,7 @@ script#control-view-template(type="text/x-template")
       tr(title="Currently active machine units")
         th Units
         td.mach_units
-          select(v-model="mach_units", :disabled="!can_mdi")
+          select(v-model="mach_units", :disabled="!is_idle")
             option(value="METRIC") METRIC
             option(value="IMPERIAL") IMPERIAL
       tr
index f8468ba15f7a81385e8cf8b756de829684443381..c10dcc30b25da541b41fdd42c943d116ea1f592e 100644 (file)
@@ -100,6 +100,9 @@ class Comm(object):
         self.ctrl.ioloop.update_handler(self.sp, flags)
 
 
+    def flush(self): self._set_write(True)
+
+
     def _load_next_command(self, cmd):
         log.info('< ' + json.dumps(cmd).strip('"'))
         self.command = bytes(cmd.strip() + '\n', 'utf-8')
@@ -110,7 +113,7 @@ class Comm(object):
 
     def queue_command(self, cmd):
         self.queue.append(cmd)
-        self._set_write(True)
+        self.flush()
 
 
     def _serial_write(self):
@@ -204,7 +207,7 @@ class Comm(object):
                     self.ctrl.state.update(msg)
                     if 'xx' in msg:           # State change
                         self.ctrl.ready()     # We've received data from AVR
-                        self._set_write(True) # May have more data to send now
+                        self.flush()          # May have more data to send now
 
 
     def _serial_handler(self, fd, events):
index 434945d275bdf7c9ba67c747e74f8df3f55eb4e5..31a683721523fffac39b94fd235e508660c1539b 100644 (file)
@@ -91,24 +91,25 @@ class Mach(Comm):
 
 
     def _get_state(self): return self.ctrl.state.get('xx', '')
+    def _is_estopped(self): return self._get_state() == 'ESTOPPED'
     def _is_holding(self): return self._get_state() == 'HOLDING'
+    def _is_ready(self): return self._get_state() == 'READY'
     def _get_pause_reason(self): return self.ctrl.state.get('pr', '')
     def _get_cycle(self): return self.ctrl.state.get('cycle')
 
 
-    def _can_jog(self):
-        return self._get_cycle() == 'idle'
-        # TODO handle jog during pause for manual tool changes
-        return (self._get_cycle() == 'idle' or
-                (self._is_holding() and
-                 self._get_pause_reason() in ('User pause', 'Program pause')))
+    def _is_paused(self):
+        if not self._is_holding() or self.unpausing: return False
+        return self._get_pause_reason() in ('User pause', 'Program pause')
 
 
     def _begin_cycle(self, cycle):
         current = self._get_cycle()
         if current == cycle: return # No change
 
-        if (current == 'idle' or (cycle == 'jogging' and self._can_jog())):
+        # TODO handle jogging during pause
+        # if current == 'idle' or (cycle == 'jogging' and self._is_paused()):
+        if current == 'idle':
             self.ctrl.state.set('cycle', cycle)
             self.last_cycle = current
 
@@ -123,7 +124,7 @@ class Mach(Comm):
 
 
     def _update_cycle(self):
-        if (self._get_cycle() != 'idle' and self._get_state() == 'READY' and
+        if (self._get_cycle() != 'idle' and self._is_ready() and
             not self.planner.is_busy() and not super().is_active()):
             self.ctrl.state.set('cycle', 'idle')
 
@@ -171,6 +172,7 @@ class Mach(Comm):
         else: self.planner.restart()
 
         super().i2c_command(Cmd.UNPAUSE)
+        self.unpausing = True
 
 
     def _reset(self):
@@ -272,13 +274,11 @@ class Mach(Comm):
 
 
     def unhome(self, axis): self.mdi('G28.2 %c0' % axis)
-
-
     def estop(self): super().estop()
 
 
     def clear(self):
-        if self._get_state() == 'ESTOPPED':
+        if self._is_estopped():
             self._reset()
             super().clear()
 
@@ -311,11 +311,7 @@ class Mach(Comm):
 
 
     def unpause(self):
-        if self._get_state() != 'HOLDING' or self.unpausing: return
-
-        if self._get_pause_reason() in ('User pause', 'Program pause'):
-            self.unpausing = True
-            self._unpause()
+        if self._is_paused(): self._unpause()
 
 
     def optional_pause(self, enable = True):
@@ -326,15 +322,16 @@ class Mach(Comm):
         axis = axis.lower()
 
         if self.ctrl.state.is_axis_homed(axis):
-            self.mdi('G92 %s%f' % (axis, position))
+            # If homed, change the offset rather than the absolute position
+            self.mdi('G92%s%f' % (axis, position))
 
-        else:
-            if self._get_cycle() not in ['idle', 'mdi']:
-                raise Exception('Cannot zero position during ' +
+        elif self.ctrl.state.is_axis_enabled(axis):
+            if self._get_cycle() != 'idle' and not self._is_paused():
+                raise Exception('Cannot set position during ' +
                                 self._get_cycle())
 
-            self._begin_cycle('mdi')
-            self.planner.set_position({axis: position})
+            # Set the absolute position both locally and via the AVR
+            self.ctrl.state.set(axis + 'p', position)
             super().queue_command(Cmd.set_axis(axis, position))
 
 
index 06df2e668d7dcd3adce9f4584186fb3e4ddddb4e..5d3e8a51d759efd2a8925a75a4de87a881aa90c5 100644 (file)
@@ -75,12 +75,6 @@ class Planner():
         return position
 
 
-    def set_position(self, position):
-        for axis in 'xyzabc':
-            if not self.ctrl.state.is_axis_enabled(axis): continue
-            self.ctrl.state.set(axis + 'p', position[axis])
-
-
     def _get_config_vector(self, name, scale):
         state = self.ctrl.state
         v = {}