Fixed rapid view, fixed timing
authorJoseph Coffland <joseph@cauldrondevelopment.com>
Sun, 7 Oct 2018 23:08:00 +0000 (16:08 -0700)
committerJoseph Coffland <joseph@cauldrondevelopment.com>
Sun, 7 Oct 2018 23:08:21 +0000 (16:08 -0700)
24 files changed:
package-lock.json
package.json
src/js/control-view.js
src/js/main.js
src/js/path-viewer.js
src/js/tool-button.js [deleted file]
src/pug/index.pug
src/pug/templates/admin-network-view.pug
src/pug/templates/axis-control.pug
src/pug/templates/cheat-sheet-view.pug
src/pug/templates/control-view.pug
src/pug/templates/help-view.pug
src/pug/templates/indicators.pug
src/pug/templates/path-viewer.pug
src/pug/templates/settings-view.pug
src/pug/templates/tool-button.pug [deleted file]
src/pug/templates/tool-view.pug
src/py/bbctrl/Ctrl.py
src/py/bbctrl/PlanTimer.py [new file with mode: 0644]
src/py/bbctrl/Planner.py
src/py/bbctrl/Preplanner.py
src/py/bbctrl/Web.py
src/py/bbctrl/__init__.py
src/stylus/style.styl

index e87ebe89102d428bb2023824c384fc4111178b26..d88c5c8843c3cb5ea9bb24e15f380c90be1943e4 100644 (file)
         "through2": "^2.0.3"
       }
     },
+    "gulp-inline-images": {
+      "version": "1.2.6",
+      "resolved": "https://registry.npmjs.org/gulp-inline-images/-/gulp-inline-images-1.2.6.tgz",
+      "integrity": "sha1-vNNBcHfF3Zvkq42XFO2mZNLVufo=",
+      "requires": {
+        "cheerio": "^0.22.0",
+        "gulp": "^3.9.1",
+        "gulp-util": "^3.0.8",
+        "through2": "^2.0.3"
+      }
+    },
     "gulp-pug": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/gulp-pug/-/gulp-pug-4.0.1.tgz",
         "vinyl-sourcemaps-apply": "^0.2.0"
       }
     },
+    "gulp-uglify": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/gulp-uglify/-/gulp-uglify-3.0.1.tgz",
+      "integrity": "sha512-KVffbGY9d4Wv90bW/B1KZJyunLMyfHTBbilpDvmcrj5Go0/a1G3uVpt+1gRBWSw/11dqR3coJ1oWNTt1AiXuWQ==",
+      "requires": {
+        "gulplog": "^1.0.0",
+        "has-gulplog": "^0.1.0",
+        "lodash": "^4.13.1",
+        "make-error-cause": "^1.1.1",
+        "safe-buffer": "^5.1.2",
+        "through2": "^2.0.0",
+        "uglify-js": "^3.0.5",
+        "vinyl-sourcemaps-apply": "^0.2.0"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "4.17.11",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+          "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
+        },
+        "safe-buffer": {
+          "version": "5.1.2",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+          "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+        }
+      }
+    },
     "gulp-util": {
       "version": "3.0.8",
       "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz",
         "es5-ext": "~0.10.2"
       }
     },
+    "make-error": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz",
+      "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g=="
+    },
+    "make-error-cause": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz",
+      "integrity": "sha1-3wOI/NCzeBbf8KX7gQiTl3fcvJ0=",
+      "requires": {
+        "make-error": "^1.2.0"
+      }
+    },
     "make-iterator": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
index 42aff748d64719588a863e7308831a9425d6ae34..81516c67b0c5145391e5162513e337aafbdf7ce4 100644 (file)
     "gulp-concat": "^2.6.1",
     "gulp-csso": "^3.0.1",
     "gulp-inline": "^0.1.3",
+    "gulp-inline-images": "^1.2.6",
     "gulp-pug": "^4.0.1",
     "gulp-sourcemaps": "^2.6.4",
     "gulp-stylus": "^2.7.0",
+    "gulp-uglify": "^3.0.1",
     "jshint": "",
     "pug-cli": "^1.0.0-alpha6",
     "stylus": ">=0.42.3",
index 2648fca5d07dee98c839127c9bfda4b4acb2a720..1e38a2117080b07718f853041f0000538d778e2b 100644 (file)
@@ -139,7 +139,24 @@ module.exports = {
     },
 
 
-    highlight_reason: function () {return this.reason != ''}
+    highlight_reason: function () {return this.reason != ''},
+    plan_time: function () {return this.state.plan_time},
+
+
+    eta: function () {
+      if (this.mach_state != 'RUNNING') return '';
+      var remaining = this.toolpath.time - this.plan_time;
+      var d = new Date();
+      d.setSeconds(d.getSeconds() + remaining);
+      return d.toLocaleString();
+    },
+
+
+    progress: function () {
+      if (!this.toolpath.time) return 0;
+      var p = this.plan_time / this.toolpath.time;
+      return p < 1 ? p : 1;
+    }
   },
 
 
index 9aa3aad77c424c1fc06ce362dd2eeeb38397b3fa..1a742c258bc93c5c264907edbc233d231d3b5b9f 100644 (file)
@@ -88,12 +88,13 @@ $(function() {
     if (MIN <= value) {
       parts.push(value / MIN);
       value %= MIN;
-    }
 
-    parts.push(value.toFixed(precision));
+    } else parts.push(0);
+
+    parts.push(value);
 
-    for (var i = 0; i < parts.length - 1; i++) {
-      parts[i] = parts[i].toFixed(0);
+    for (var i = 0; i < parts.length; i++) {
+      parts[i] = parts[i].toFixed(i == parts.length - 1 ? precision : 0);
       if (i && parts[i] < 10) parts[i] = '0' + parts[i];
     }
 
index 2fe9d67f60f2c4128fb47888474d7b05a5e91ceb..45299995d014fe68db5d2c8ac138900d1f82c338 100644 (file)
@@ -62,11 +62,6 @@ module.exports = {
   },
 
 
-  components: {
-    'tool-button': require('./tool-button')
-  },
-
-
   computed: {
     hasPath: function () {return typeof this.toolpath.path != 'undefined'}
   },
@@ -385,7 +380,8 @@ module.exports = {
         var step = this.toolpath.path[i];
         var newColor = step.rapid ? rapid : cutting;
 
-        if (!i) {
+        // Handle color change
+        if (!i || newColor != color) {
           color = newColor;
           positions.push(x, y, z);
           colors.push.apply(colors, color);
@@ -397,13 +393,6 @@ module.exports = {
 
         positions.push(x, y, z);
         colors.push.apply(colors, color);
-
-        // Handle type change
-        if (newColor != color) {
-          color = newColor;
-          positions.push(x, y, z);
-          colors.push.apply(colors, color);
-        }
       }
 
       var geometry = new THREE.BufferGeometry();
diff --git a/src/js/tool-button.js b/src/js/tool-button.js
deleted file mode 100644 (file)
index f77d0fd..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/******************************************************************************\
-
-                    Copyright 2018. Buildbotics LLC
-                              All Rights Reserved.
-
-                  For information regarding this software email:
-                                 Joseph Coffland
-                          joseph@buildbotics.com
-
-        This software is free software: you can redistribute it and/or
-        modify it under the terms of the GNU Lesser General Public License
-        as published by the Free Software Foundation, either version 2.1 of
-        the License, or (at your option) any later version.
-
-        This software is distributed in the hope that it will be useful,
-        but WITHOUT ANY WARRANTY; without even the implied warranty of
-        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-        Lesser General Public License for more details.
-
-        You should have received a copy of the GNU Lesser General Public
-        License along with the C! library.  If not, see
-        <http://www.gnu.org/licenses/>.
-
-\******************************************************************************/
-
-'use strict'
-
-
-module.exports = {
-  template: '#tool-button-template',
-  props: ['name', 'active']
-}
index d50f5aeb8df38d5ba0939064e7858cce9ce3dd8a..ef26fc6026e7c47902608149f97b09e09a0c8dab 100644 (file)
@@ -160,7 +160,7 @@ html(lang="en")
     message(:show.sync="confirmUpload")
       h3(slot="header") Upload Firmware?
       div(slot="body")
-        p Are you sure you want to upload firmware <em>{{firmwareName}}</em>?
+        p Are you sure you want to upload firmware #[em {{firmwareName}}]?
 
         p.pure-control-group
           label(for="pass") Password
index 1ff0b4b84e11ef106f80f023c58213af7118381a..341a4b8f2e39227cc60f823c9e43cabb9874a412 100644 (file)
@@ -37,7 +37,7 @@ script#admin-network-view-template(type="text/x-template")
     message(:show.sync="hostnameSet")
       h3(slot="header") Hostname Set
       div(slot="body")
-        p Hostname was successfuly set to <strong>{{hostname}}</strong>.
+        p Hostname was successfuly set to #[strong {{hostname}}].
         p Rebooting to apply changes.
         p Redirecting to new hostname in {{redirectTimeout}} seconds.
       div(slot="footer")
@@ -84,7 +84,7 @@ script#admin-network-view-template(type="text/x-template")
         label(for="wifi_ch") Channel
         select(name="wifi_ch", v-model="wifi_ch")
           each ch in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
-            option(value="#{ch}")= ch
+            option(value=ch)= ch
       .pure-control-group(v-if="wifi_mode != 'disabled'")
         label(for="ssid") Network (SSID)
         input(name="ssid", v-model="wifi_ssid")
index 37ec1f3173bc5b4329fe23e5f2d3d47cf69d9b4f..e41a76c0331dfe306a275f848dacadd7c232707f 100644 (file)
@@ -56,11 +56,11 @@ script#axis-control-template(type="text/x-template")
 
 
       each color in 'red green blue orange cyan purple'.split(' ')
-        lineargradient(xlink:href="##{color}", id="#{color}-1",
+        lineargradient(xlink:href="#" + color, id=color + "-1",
           gradientunits="userSpaceOnUse", gradienttransform="rotate(180 7 5)",
           x1="0", y1="0", x2="15", y2="10")
 
-        lineargradient(xlink:href="##{color}", id="#{color}-2",
+        lineargradient(xlink:href="#" + color, id=color + "-2",
           gradientunits="userSpaceOnUse", x1="10", y1="10", x2="40", y2="40")
 
 
index 41f422f149995e6af0559f5a501e8cca5f55cd74..bbe04ca7882fb8f59566fc323ea7aa92e8a1c7cb 100644 (file)
@@ -42,47 +42,47 @@ script#cheat-sheet-view-template(type="text/x-template")
         th(colspan='3') Motion
       tr
         td
-          a(href="#{base}/g-code.html#gcode:g0") G0
+          a(href=`${base}/g-code.html#gcode:g0`) G0
         td
         td Rapid Move
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g1") G1
+          a(target="_blank", href=`${base}/g-code.html#gcode:g1`) G1
         td
         td Linear Move
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g2-g3") G2, G3
+          a(target="_blank", href=`${base}/g-code.html#gcode:g2-g3`) G2, G3
         td I J K or R, P
         td Arc Move
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g4") G4
+          a(target="_blank", href=`${base}/g-code.html#gcode:g4`) G4
         td P
         td Dwell
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g5") G5
+          a(target="_blank", href=`${base}/g-code.html#gcode:g5`) G5
         td I J P Q
         td Cubic Spline
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g5.1") G5.1
+          a(target="_blank", href=`${base}/g-code.html#gcode:g5.1`) G5.1
         td I J
         td Quadratic Spline
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g5.2-g5.3") G5.2
+          a(target="_blank", href=`${base}/g-code.html#gcode:g5.2-g5.3`) G5.2
         td P L
         td NURBS
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g38") G38.2 - G38.5
+          a(target="_blank", href=`${base}/g-code.html#gcode:g38`) G38.2 - G38.5
         td
         td Straight Probe
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g33.1") G33.1
+          a(target="_blank", href=`${base}/g-code.html#gcode:g33.1`) G33.1
         td K
         td Rigid Tapping
 
@@ -91,52 +91,52 @@ script#cheat-sheet-view-template(type="text/x-template")
         th(colspan='3') Tool Control
       tr
         td
-          a(href="#{base}/other-code.html#sec:select-tool") T
+          a(href=`${base}/other-code.html#sec:select-tool`) T
         td
         td Select Tool
       tr
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m6") M6
+          a(target="_blank", href=`${base}/m-code.html#mcode:m6`) M6
         td T
         td Tool Change
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m61") M61
+          a(target="_blank", href=`${base}/m-code.html#mcode:m61`) M61
         td Q
         td Set Current Tool
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g10-l1") G10 L1
+          a(target="_blank", href=`${base}/g-code.html#gcode:g10-l1`) G10 L1
         td P Q R
         td Set Tool Table
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g10-l10") G10 L10
+          a(target="_blank", href=`${base}/g-code.html#gcode:g10-l10`) G10 L10
         td P
         td Set Tool Table
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g10-l11") G10 L11
+          a(target="_blank", href=`${base}/g-code.html#gcode:g10-l11`) G10 L11
         td P
         td Set Tool Table
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g43") G43
+          a(target="_blank", href=`${base}/g-code.html#gcode:g43`) G43
         td  H
         td Tool Length Offset
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g43.1") G43.1
+          a(target="_blank", href=`${base}/g-code.html#gcode:g43.1`) G43.1
         td
         td Dynamic Tool Length Offset
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g43.2") G43.2
+          a(target="_blank", href=`${base}/g-code.html#gcode:g43.2`) G43.2
         td  H
         td Apply additional Tool Length Offset
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g49") G49
+          a(target="_blank", href=`${base}/g-code.html#gcode:g49`) G49
         td
         td Cancel Tool Length Compensation
 
@@ -145,23 +145,23 @@ script#cheat-sheet-view-template(type="text/x-template")
         th(colspan='3') Feed Control
       tr
         td
-          a(href="#{base}/other-code.html#sec:set-feed-rate") F
+          a(href=`${base}/other-code.html#sec:set-feed-rate`) F
         td
         td Set Feed Rate
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g93-g94-g95")
+          a(target="_blank", href=`${base}/g-code.html#gcode:g93-g94-g95`)
             | G93, G94, G95
         td
         td Feed Rate Mode
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m52") M52
+          a(target="_blank", href=`${base}/m-code.html#mcode:m52`) M52
         td P0 (off) or P1 (on)
         td Adaptive Feed Control
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m53") M53
+          a(target="_blank", href=`${base}/m-code.html#mcode:m53`) M53
         td P0 (off) or P1 (on)
         td Feed Stop Control
 
@@ -170,28 +170,28 @@ script#cheat-sheet-view-template(type="text/x-template")
         th(colspan='3') Spindle Control
       tr
         td
-          a(href="#{base}/other-code.html#sec:set-spindle-speed") S
+          a(href=`${base}/other-code.html#sec:set-spindle-speed`) S
         td
         td Set Spindle Speed
       tr
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m3-m4-m5")
+          a(target="_blank", href=`${base}/m-code.html#mcode:m3-m4-m5`)
             | M3, M4, M5
         td S
         td Spindle Control
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m19") M19
+          a(target="_blank", href=`${base}/m-code.html#mcode:m19`) M19
         td
         td Orient Spindle
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g96-g97") G96, G97
+          a(target="_blank", href=`${base}/g-code.html#gcode:g96-g97`) G96, G97
         td  S D
         td Spindle Control Mode
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g33") G33
+          a(target="_blank", href=`${base}/g-code.html#gcode:g33`) G33
         td K
         td Spindle Synchronized Motion
 
@@ -200,7 +200,7 @@ script#cheat-sheet-view-template(type="text/x-template")
         th(colspan='3') Coolant
       tr
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m7-m8-m9")
+          a(target="_blank", href=`${base}/m-code.html#mcode:m7-m8-m9`)
             | M7, M8, M9
         td
         td Coolant Control
@@ -210,17 +210,17 @@ script#cheat-sheet-view-template(type="text/x-template")
         th(colspan='3') Stopping
       tr
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m0-m1") M0, M1
+          a(target="_blank", href=`${base}/m-code.html#mcode:m0-m1`) M0, M1
         td
         td Program Pause
       tr
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m2-m30") M2, M30
+          a(target="_blank", href=`${base}/m-code.html#mcode:m2-m30`) M2, M30
         td
         td Program End
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m60") M60
+          a(target="_blank", href=`${base}/m-code.html#mcode:m60`) M60
         td
         td Pallet Change Pause
 
@@ -229,7 +229,7 @@ script#cheat-sheet-view-template(type="text/x-template")
         th(colspan='3') Units
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g20-g21") G20, G21
+          a(target="_blank", href=`${base}/g-code.html#gcode:g20-g21`) G20, G21
         td
         td Units (inch, mm)
 
@@ -238,23 +238,23 @@ script#cheat-sheet-view-template(type="text/x-template")
         th(colspan='3') Distance Mode
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g90-g91") G90, G91
+          a(target="_blank", href=`${base}/g-code.html#gcode:g90-g91`) G90, G91
         td
         td Distance Mode
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g90.1-g91.1")
+          a(target="_blank", href=`${base}/g-code.html#gcode:g90.1-g91.1`)
             | G90.1, G91.1
         td
         td Arc Distance Mode
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g7") G7
+          a(target="_blank", href=`${base}/g-code.html#gcode:g7`) G7
         td
         td Lathe Diameter Mode
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g8") G8
+          a(target="_blank", href=`${base}/g-code.html#gcode:g8`) G8
         td
         td Lathe Radius Mode
 
@@ -263,17 +263,17 @@ script#cheat-sheet-view-template(type="text/x-template")
         th(colspan='3') Cutter Radius Compensation
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g40") G40
+          a(target="_blank", href=`${base}/g-code.html#gcode:g40`) G40
         td
         td Compensation Off
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g41-g42") G41,G42
+          a(target="_blank", href=`${base}/g-code.html#gcode:g41-g42`) G41,G42
         td D
         td Cutter Compensation
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g41.1-g42.1")
+          a(target="_blank", href=`${base}/g-code.html#gcode:g41.1-g42.1`)
             | G41.1, G42.1
         td D L
         td Dynamic Cutter Compensation
@@ -283,13 +283,13 @@ script#cheat-sheet-view-template(type="text/x-template")
         th(colspan='3') Path Control Mode
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g61-g61.1")
+          a(target="_blank", href=`${base}/g-code.html#gcode:g61-g61.1`)
             | G61 G61.1
         td
         td Exact Path Mode
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g64") G64
+          a(target="_blank", href=`${base}/g-code.html#gcode:g64`) G64
         td P Q
         td Path Blending
 
@@ -298,17 +298,17 @@ script#cheat-sheet-view-template(type="text/x-template")
         th(colspan='3') Overrides
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m48-m49") M48, M49
+          a(target="_blank", href=`${base}/m-code.html#mcode:m48-m49`) M48, M49
         td
         td Speed and Feed Override Control
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m50") M50
+          a(target="_blank", href=`${base}/m-code.html#mcode:m50`) M50
         td P0 (off) or P1 (on)
         td Feed Override Control
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m51") M51
+          a(target="_blank", href=`${base}/m-code.html#mcode:m51`) M51
         td P0 (off) or P1 (on)
         td Spindle Speed Override Control
 
@@ -317,56 +317,56 @@ script#cheat-sheet-view-template(type="text/x-template")
         th(colspan='3') Coordinate Systems, Offsets & Planes
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g54-g59.3")
+          a(target="_blank", href=`${base}/g-code.html#gcode:g54-g59.3`)
             | G54-G59.3
         td
         td Select Coordinate System
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g10-l2") G10 L2
+          a(target="_blank", href=`${base}/g-code.html#gcode:g10-l2`) G10 L2
         td P R
         td Set Coordinate System
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g10-l20") G10 L20
+          a(target="_blank", href=`${base}/g-code.html#gcode:g10-l20`) G10 L20
         td P
         td Set Coordinate System
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g53") G53
+          a(target="_blank", href=`${base}/g-code.html#gcode:g53`) G53
         td
         td Move in Machine Coordinates
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g92") G92
+          a(target="_blank", href=`${base}/g-code.html#gcode:g92`) G92
         td
         td Coordinate System Offset
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g92.1-g92.2")
+          a(target="_blank", href=`${base}/g-code.html#gcode:g92.1-g92.2`)
             | G92.1, G92.2
         td
         td Reset G92 Offsets
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g92.3") G92.3
+          a(target="_blank", href=`${base}/g-code.html#gcode:g92.3`) G92.3
         td
         td Restore G92 Offsets
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g28-g28.1")
+          a(target="_blank", href=`${base}/g-code.html#gcode:g28-g28.1`)
             | G28, G28.1
         td
         td Go/Set Predefined Position
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g30-g30.1")
+          a(target="_blank", href=`${base}/g-code.html#gcode:g30-g30.1`)
             | G30, G30.1
         td
         td Go/Set Predefined Position
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g17-g19.1")
+          a(target="_blank", href=`${base}/g-code.html#gcode:g17-g19.1`)
             | G17 - G19.1
         td (affects G2, G3, G81…G89, G40…G42)
         td Plane Select
@@ -376,33 +376,33 @@ script#cheat-sheet-view-template(type="text/x-template")
         th(colspan='3') Flow-control Codes
       tr
         td
-          a(target="_blank", href="#{base}/o-code.html#ocode:subroutines")
+          a(target="_blank", href=`${base}/o-code.html#ocode:subroutines`)
             | o sub/endsub/call
         td
         td Subroutines, sub/endsub call
       tr
         td
-          a(target="_blank", href="#{base}/o-code.html#ocode:looping") o while
+          a(target="_blank", href=`${base}/o-code.html#ocode:looping`) o while
         td
         td Looping, while/endwhile do/while
       tr
         td
-          a(target="_blank", href="#{base}/o-code.html#ocode:conditional") o if
+          a(target="_blank", href=`${base}/o-code.html#ocode:conditional`) o if
         td
         td Conditional, if/else/endif
       tr
         td
-          a(target="_blank", href="#{base}/o-code.html#ocode:repeat") o repeat
+          a(target="_blank", href=`${base}/o-code.html#ocode:repeat`) o repeat
         td
         td Repeat a loop of code
       tr
         td
-          a(target="_blank", href="#{base}/o-code.html#ocode:indirection") []
+          a(target="_blank", href=`${base}/o-code.html#ocode:indirection`) []
         td
         td Indirection
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/o-code.html#ocode:calling-files")
+          a(target="_blank", href=`${base}/o-code.html#ocode:calling-files`)
             | o call
         td
         td Call named or numbered file
@@ -412,22 +412,22 @@ script#cheat-sheet-view-template(type="text/x-template")
         th(colspan='3') Modal State
       tr
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m70") M70
+          a(target="_blank", href=`${base}/m-code.html#mcode:m70`) M70
         td
         td Save modal state
       tr
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m71") M71
+          a(target="_blank", href=`${base}/m-code.html#mcode:m71`) M71
         td
         td Invalidate stored state
       tr
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m72") M72
+          a(target="_blank", href=`${base}/m-code.html#mcode:m72`) M72
         td
         td Restore modal state
       tr
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m73") M73
+          a(target="_blank", href=`${base}/m-code.html#mcode:m73`) M73
         td
         td Save and Auto-restore modal state
 
@@ -436,22 +436,22 @@ script#cheat-sheet-view-template(type="text/x-template")
         th(colspan='3') Input/Output
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m62-m65") M62 - M65
+          a(target="_blank", href=`${base}/m-code.html#mcode:m62-m65`) M62 - M65
         td P
         td Digital Output Control
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m66") M66
+          a(target="_blank", href=`${base}/m-code.html#mcode:m66`) M66
         td P E L Q
         td Wait on Input
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m67") M67
+          a(target="_blank", href=`${base}/m-code.html#mcode:m67`) M67
         td T
         td Analog Output,Synchronized
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m68") M68
+          a(target="_blank", href=`${base}/m-code.html#mcode:m68`) M68
         td T
         td Analog Output, Immediate
 
@@ -460,7 +460,7 @@ script#cheat-sheet-view-template(type="text/x-template")
         th(colspan='3') User Defined Commands
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/m-code.html#mcode:m100-m199")
+          a(target="_blank", href=`${base}/m-code.html#mcode:m100-m199`)
             | M101 - M199
         td P Q
         td User Defined Commands
@@ -470,47 +470,47 @@ script#cheat-sheet-view-template(type="text/x-template")
         th(colspan='3') Canned cycles
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g80") G80
+          a(target="_blank", href=`${base}/g-code.html#gcode:g80`) G80
         td
         td Cancel Canned Cycle
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g81") G81
+          a(target="_blank", href=`${base}/g-code.html#gcode:g81`) G81
         td R L (P)
         td Drilling Cycle
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g82") G82
+          a(target="_blank", href=`${base}/g-code.html#gcode:g82`) G82
         td R L (P)
         td Drilling Cycle, Dwell
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g83") G83
+          a(target="_blank", href=`${base}/g-code.html#gcode:g83`) G83
         td R L Q
         td Drilling Cycle, Peck
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g73") G73
+          a(target="_blank", href=`${base}/g-code.html#gcode:g73`) G73
         td R L Q
         td Drilling Cycle, Chip Breaking
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g85") G85
+          a(target="_blank", href=`${base}/g-code.html#gcode:g85`) G85
         td R L (P)
         td Boring Cycle, Feed Out
       tr
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g89") G89
+          a(target="_blank", href=`${base}/g-code.html#gcode:g89`) G89
         td R L (P)
         td Boring Cycle, Dwell, Feed Out
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g76") G76
+          a(target="_blank", href=`${base}/g-code.html#gcode:g76`) G76
         td P Z I J R K Q H L E
         td Threading Cycle
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/g-code.html#gcode:g98-g99") G98, G99
+          a(target="_blank", href=`${base}/g-code.html#gcode:g98-g99`) G98, G99
         td
         td Canned Cycle Return Level
 
@@ -519,23 +519,23 @@ script#cheat-sheet-view-template(type="text/x-template")
         th(colspan='3') Comments & Messages
       tr
         td
-          a(target="_blank", href="#{base}/overview.html#gcode:comments") ; (…)
+          a(target="_blank", href=`${base}/overview.html#gcode:comments`) ; (…)
         td
         td Comments
       tr
         td
-          a(target="_blank", href="#{base}/overview.html#gcode:messages")
+          a(target="_blank", href=`${base}/overview.html#gcode:messages`)
             | (MSG,…)
         td
         td Messages
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/overview.html#gcode:debug") (DEBUG,…)
+          a(target="_blank", href=`${base}/overview.html#gcode:debug`) (DEBUG,…)
         td
         td Debug Messages
       tr.unimplemented(v-if="showUnimplemented")
         td
-          a(target="_blank", href="#{base}/overview.html#gcode:print") (PRINT,…)
+          a(target="_blank", href=`${base}/overview.html#gcode:print`) (PRINT,…)
         td
         td Print Messages
 
@@ -548,7 +548,7 @@ script#cheat-sheet-view-template(type="text/x-template")
     p
       | The Buildbotics controller implements a subset of LinuxCNC GCode.
       | Supported commands are listed above.  You can find further help with
-      | <a href="http://wikipedia.com/wiki/G-code" target="_blank">GCode</a>
+      | #[a(href="http://wikipedia.com/wiki/G-code", target="_blank") GCode]
       | programming on the LinuxCNC website:
 
     ul
index 7b753bbc51129ff7147c315c28afdf7ab34f85ee..e965f554d8bf8765acfc83647ec98de55449ce54 100644 (file)
@@ -42,29 +42,29 @@ script#control-view-template(type="text/x-template")
             .fa.fa-home
 
       each axis in 'xyzabc'
-        tr.axis(:class="{'homed': is_homed('#{axis}'), 'axis-#{axis}': true}",
-          v-if="enabled('#{axis}')")
-          th.name #{axis}
+        tr.axis(:class=`{'homed': is_homed('${axis}'), 'axis-${axis}': true}`,
+          v-if=`enabled('${axis}')`)
+          th.name= axis
           td.position
-            unit-value(:value="get_position('#{axis}')", precision="4")
-          td.absolute: unit-value(:value="state.#{axis}p", precision="3")
-          td.offset: unit-value(:value="get_offset('#{axis}')", precision="3")
+            unit-value(:value=`get_position('${axis}')`, precision="4")
+          td.absolute: unit-value(:value="state." + axis + "p", precision="3")
+          td.offset: unit-value(:value=`get_offset('${axis}')`, precision="3")
           th.actions
             button.pure-button(:disabled="!is_ready",
-              title="Set {{'#{axis}' | upper}} axis position.",
-              @click="show_set_position('#{axis}')")
+              title=`Set {{'${axis}' | upper}} axis position.`,
+              @click=`show_set_position('${axis}')`)
               .fa.fa-cog
 
             button.pure-button(:disabled="!is_ready",
-              title="Zero {{'#{axis}' | upper}} axis offset.",
-              @click="zero('#{axis}')") &empty;
+              title=`Zero {{'${axis}' | upper}} axis offset.`,
+              @click=`zero('${axis}')`) &empty;
 
             button.pure-button(:disabled="!is_ready",
-              title="Home {{'#{axis}' | upper}} axis.",
-              @click="home('#{axis}')")
+              title=`Home {{'${axis}' | upper}} axis.`,
+              @click=`home('${axis}')`)
               .fa.fa-home
 
-            message(:show.sync="position_msg['#{axis}']")
+            message(:show.sync=`position_msg['${axis}']`)
               h3(slot="header") Set {{'#{axis}' | upper}} axis position
 
               div(slot="body")
@@ -72,21 +72,21 @@ script#control-view-template(type="text/x-template")
                   .pure-control-group
                     label Position
                     input(v-model="axis_position",
-                      @keyup.enter="set_position('#{axis}', axis_position)")
+                      @keyup.enter=`set_position('${axis}', axis_position)`)
                 p
 
               div(slot="footer")
-                button.pure-button(@click="position_msg['#{axis}'] = false")
+                button.pure-button(@click=`position_msg['${axis}'] = false`)
                   | Cancel
 
-                button.pure-button(v-if="is_homed('#{axis}')",
-                  @click="unhome('#{axis}')") Unhome
+                button.pure-button(v-if="is_homed('" + axis + "')",
+                  @click=`unhome('${axis}')`) Unhome
 
                 button.pure-button.button-success(
-                  @click="set_position('#{axis}', axis_position)") Set
+                  @click=`set_position('${axis}', axis_position)`) Set
 
 
-            message(:show.sync="manual_home['#{axis}']")
+            message(:show.sync=`manual_home['${axis}']`)
               h3(slot="header") Manually home {{'#{axis}' | upper}} axis
 
               div(slot="body")
@@ -96,17 +96,17 @@ script#control-view-template(type="text/x-template")
                   .pure-control-group
                     label Absolute
                     input(v-model="axis_position",
-                      @keyup.enter="set_home('#{axis}', axis_position)")
+                      @keyup.enter=`set_home('${axis}', axis_position)`)
 
                 p
 
               div(slot="footer")
-                button.pure-button(@click="manual_home['#{axis}'] = false")
+                button.pure-button(@click=`manual_home['${axis}'] = false`)
                   | Cancel
 
                 button.pure-button.button-success(
-                  title="Home {{'#{axis}' | upper}} axis.",
-                  @click="set_home('#{axis}', axis_position)") Set
+                  title=`Home {{'${axis}' | upper}} axis.`,
+                  @click=`set_home('${axis}', axis_position)`) Set
 
     table.info
       tr
@@ -157,21 +157,22 @@ script#control-view-template(type="text/x-template")
       tr
         th Time
         td(title="Total run time (days:hours:mins:secs)")
-          |  {{toolpath.time / 1000 | time}}
+          span(v-if="plan_time") {{plan_time | time}} of&nbsp;
+          | {{toolpath.time | time}}
       tr
         th ETA
-        td
+        td {{eta}}
       tr
         th Line
         td
-          | {{0 <= state.line ? state.line : '0'}}
+          | {{0 <= state.line ? state.line : 0 | number}}
           span(v-if="toolpath.lines")
             | &nbsp;of {{toolpath.lines | number}}
       tr
         th Progress
         td.progress
-          label {{(state.progress || 0) | percent}}
-          .bar(:style="'width:' + (state.progress || 0.01) * 100 + '%'")
+          label {{(progress || 0) | percent}}
+          .bar(:style="'width:' + (progress || 0) * 100 + '%'")
 
     .override(title="Feed rate override.")
       label Feed
@@ -221,15 +222,16 @@ script#control-view-template(type="text/x-template")
             .fa.fa-step-forward
 
           button.pure-button(title="Upload a new GCode program.", @click="open",
-            :disabled="is_running || is_stopping")
+            :disabled="!is_ready")
             .fa.fa-folder-open
 
           input.gcode-file-input(type="file", @change="upload",
-            style="display:none", accept=".nc,.gcode,.gc,.ngc")
+            style="display:none", accept=".nc,.gcode,.gc,.ngc",
+            :disabled="!is_ready")
 
           button.pure-button(title="Delete current GCode program.",
             @click="deleteGCode = true",
-            :disabled="!state.selected || is_running || is_stopping")
+            :disabled="!state.selected || !is_ready")
             .fa.fa-trash
 
           message(:show.sync="deleteGCode")
@@ -245,8 +247,7 @@ script#control-view-template(type="text/x-template")
                 | &nbsp;selected
 
           select(title="Select previously uploaded GCode programs.",
-            v-model="state.selected", @change="load",
-            :disabled="is_running || is_stopping")
+            v-model="state.selected", @change="load", :disabled="!is_ready")
             option(v-for="file in files", :value="file") {{file}}
 
         path-viewer(:toolpath="toolpath", :progress="progress",
index 1c0187be9f5f00f4f72734c7da9ae4631c175a65..6982a712be001bbbc2391e35a7aa9fddddc5ed8f 100644 (file)
@@ -29,25 +29,33 @@ script#help-view-template(type="text/x-template")
   #help
     h2 User Manual
     p
-      | You can find a detailed user manual at <a
-      | href="http://docs.buildbotics.com" target="_blank"
-      | >docs.buildbotics.com</a>.
+      | You can find a detailed user manual at
+      |
+      a(href="http://docs.buildbotics.com", target="_blank")
+        | docs.buildbotics.com
+      |.
 
     h2 Discussion Forum
     p
       | If you're having trouble or just want to chat with other Buildbotics
       | CNC controller owners, head over to the Buildbotics forum at
-      | <a href="http://forum.buildbotics.com" target="_blank"
-      | >forum.buildbotics.com</a>.  Register on the site and post a message.
-      | We'll be happy to help.
+      |
+      a(href="http://forum.buildbotics.com", target="_blank")
+        | forum.buildbotics.com
+      |.  Register on the site and post a message. We'll be happy to help.
 
     h2 CAD/CAM Software
     p
-      | <a href="http://wikipedia.com/wiki/Computer-aided_manufacturing"
-      | target="_blank">CAM</a> software can be used to create GCode
+      a(href="http://wikipedia.com/wiki/Computer-aided_manufacturing",
+        target="_blank") CAM
+      |
+      | software can be used to create GCode
       | automatically from
-      | <a href="http://wikipedia.com/wiki/Computer-aided_design"
-      | target="_blank">CAD</a> models.  Here are a few CAD/CAM resources:
+      |
+      a(href="http://wikipedia.com/wiki/Computer-aided_design",
+        target="_blank") CAD
+      |
+      | models.  Here are a few CAD/CAM resources:
     ul
       li: a(href="http://camotics.org/", target="_blank")
         | CAMotics - Open-Source CNC Simulator
index f9650c489ca5b0357eb835c7eea78dc033352467..9cec8148fe2f3b577101a596764608ee5ad5994c 100644 (file)
@@ -68,14 +68,14 @@ script#indicators-template(type="text/x-template")
       each motor in '0123'
         tr
           td
-            .fa.io(:class="get_input_class('#{motor}lw', '#{motor}ls')",
-              :title="get_input_tooltip('#{motor}lw', '#{motor}ls')")
+            .fa.io(:class=`get_input_class('${motor}lw', '${motor}ls')`,
+              :title=`get_input_tooltip('${motor}lw', '${motor}ls')`)
           td {{get_min_pin(#{motor})}}
           th Motor #{motor} Min
           th.separator
           td
-            .fa.io(:class="get_input_class('#{motor}xw', '#{motor}xs')",
-              :title="get_input_tooltip('#{motor}xw', '#{motor}xs')")
+            .fa.io(:class=`get_input_class('${motor}xw', '${motor}xs')`,
+              :title=`get_input_tooltip('${motor}xw', '${motor}xs')`)
           td {{get_max_pin(#{motor})}}
           th Motor #{motor} Max
 
@@ -239,7 +239,7 @@ script#indicators-template(type="text/x-template")
         th Current
 
     h2 DB25 breakout box
-    img(width=700, src="/images/DB25_breakout_box.png")
+    img(width=700, src="images/DB25_breakout_box.png")
 
     h2 DB25-M2 breakout
-    img(width=400, src="/images/DB25-M2_breakout.png")
+    img(width=400, src="images/DB25-M2_breakout.png")
index 044ac6bbd55d4b991a39a4d7971fd722fc42e7ec..33ce4b08081f4da4456416a986b51f3f5d0e76e1 100644 (file)
@@ -32,19 +32,21 @@ script#path-viewer-template(type="text/x-template")
         @click="small = !small", :class="{active: !small}")
         .fa.fa-arrows-alt
 
-      tool-button(name="tool", :active="showTool",
-        @click="showTool = !showTool", title="Show/hide tool.")
-      tool-button(name="bbox", :active="showBBox",
-        @click="showBBox = !showBBox", title="Show/hide bounding box.")
-      tool-button(name="axes", :active="showAxes",
-        @click="showAxes = !showAxes", title="Show/hide axes.")
+      .tool-button(@click="showTool = !showTool", :active="showTool",
+        title="Show/hide tool.")
+        img(src="images/tool.png")
 
-      tool-button(name="isometric", @click="snap('isometric')",
-        title="Snap to isometric view.")
-      tool-button(name="top",       @click="snap('top')",
-        title="Snap to top view.")
-      tool-button(name="front",     @click="snap('front')",
-        title="Snap to front view.")
+      .tool-button(@click="showBBox = !showBBox", :active="showBBox",
+        title="Show/hide bounding box.")
+        img(src="images/bbox.png")
+
+      .tool-button(@click="showAxes = !showAxes", :active="showAxes",
+        title="Show/hide axes.")
+        img(src="images/axes.png")
+
+      each view in "isometric top front".split(" ")
+        .tool-button(@click=`snap('${view}')`, title=`Snap to ${view} view.`)
+          img(src=`images/${view}.png`)
 
     .path-viewer-content(:class="{small: small}")
       .path-viewer-message(:class="{error: error}")
@@ -63,8 +65,8 @@ script#path-viewer-template(type="text/x-template")
         th Message
 
       tr(v-for="msg in toolpath.messages", :class="'log-' + msg.level")
-        td {{msg.level}}
-        td
+        td.level {{msg.level}}
+        td.location
           | {{msg.line}}
           span(v-if="msg.column") :{{msg.column}}
-        td {{msg.msg}}
+        td.message {{msg.msg}}
index cd3444b3f2a132a31ce920b52f12363c4418e306..dd568721bd218d8c0350276f0acb058a29f90f28 100644 (file)
@@ -31,8 +31,8 @@ script#settings-view-template(type="text/x-template")
           :template="template.settings.units")
 
         p
-          | Note, <tt>units</tt> sets both the machine default units and the
-          | units used in motor configuration.  GCode <tt>program-start</tt>,
+          | Note, #[tt units] sets both the machine default units and the
+          | units used in motor configuration.  GCode #[tt program-start],
           | set below, may also change the default machine units.
 
       fieldset
diff --git a/src/pug/templates/tool-button.pug b/src/pug/templates/tool-button.pug
deleted file mode 100644 (file)
index 8306fba..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-//-/////////////////////////////////////////////////////////////////////////////
-//-                                                                           //
-//-               Copyright (c) 2018, Cauldron Development LLC                //
-//-                           All rights reserved.                            //
-//-                                                                           //
-//-   This file ("the software") is free software: you can redistribute it    //
-//-   and/or modify it under the terms of the GNU General Public License,     //
-//-    version 2 as published by the Free Software Foundation. You should     //
-//-    have received a copy of the GNU General Public License, version 2      //
-//-   along with the software. If not, see <http://www.gnu.org/licenses/>.    //
-//-                                                                           //
-//-   The software is distributed in the hope that it will be useful, but     //
-//-        WITHOUT ANY WARRANTY; without even the implied warranty of         //
-//-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU      //
-//-             Lesser General Public License for more details.               //
-//-                                                                           //
-//-     You should have received a copy of the GNU Lesser General Public      //
-//-              License along with the software.  If not, see                //
-//-                     <http://www.gnu.org/licenses/>.                       //
-//-                                                                           //
-//-              For information regarding this software email:               //
-//-            "Joseph Coffland" <joseph@cauldrondevelopment.com>             //
-//-                                                                           //
-//-/////////////////////////////////////////////////////////////////////////////
-
-script#tool-button-template(type="text/x-template")
-  .tool-button(:class="{'active': active}")
-    img(:src="'images/' + name + '.png'")
index e8895029837a02dd4a6cd758e0fec29e5b148260..023ec95c7be9a11abf7371a88b7de6db8bd5a05a 100644 (file)
@@ -54,8 +54,8 @@ script#tool-view-template(type="text/x-template")
         v-if="is_modbus && this.tool_type != 'HUANYANG VFD'")
         h2 Active Modbus Program
         p
-          | (Click <tt class="save">Save</tt> to activate the selected
-          | <b>tool-type</b>.)
+          | (Click #[tt(class="save") Save] to activate the selected
+          | #[b tool-type].)
         table.modbus-regs.fixed-regs
           tr
             th Index
@@ -121,22 +121,25 @@ script#tool-view-template(type="text/x-template")
             td.reg-addr PD163
             td.reg-value 1
             td Modbus ID
-            td Must match <tt>bus-id</tt> above.
+            td Must match #[tt bus-id] above.
           tr
             td.reg-addr PD164
             td.reg-value 1
             td 9600 baud
-            td Must match <tt>baud</tt> above.
+            td Must match #[tt baud] above.
           tr
             td.reg-addr PD166
             td.reg-value 3
             td 8 bit, no parity, RTU mode
-            td Must match <tt>parity</tt> above.
+            td Must match #[tt parity] above.
 
         p
-          | Other settings according to the <a
-          | href="https://buildbotics.com/upload/vfd/Huanyang-VFD-manual.pdf"
-          | target="_blank">Huanyang VFD manual</a> and spindle type.
+          | Other settings according to the
+          |
+          a(href="https://buildbotics.com/upload/vfd/Huanyang-VFD-manual.pdf",
+            target="_blank") Huanyang VFD manual
+          |
+          | and spindle type.
 
       .notes(v-if="tool_type.startsWith('DELTA VFD015M21A')")
         h2 Notes
@@ -161,17 +164,17 @@ script#tool-view-template(type="text/x-template")
             td.reg-addr Pr.88
             td.reg-value 1
             td Modbus ID
-            td Must match <tt>bus-id</tt> above
+            td Must match #[tt bus-id] above
           tr
             td.reg-addr Pr.89
             td.reg-value 1
             td 9600 baud
-            td Must match <tt>baud</tt> above
+            td Must match #[tt baud] above
           tr
             td.reg-addr Pr.92
             td.reg-value 3
             td 8 bit, no parity, RTU mode
-            td Must match <tt>parity</tt> above
+            td Must match #[tt parity] above
           tr
             td.reg-addr Pr.157
             td.reg-value 1
@@ -179,6 +182,9 @@ script#tool-view-template(type="text/x-template")
             td Communication mode
 
         p
-          | Other settings according to the <a
-          | href="https://buildbotics.com/upload/vfd/Delta_VFD015M21A.pdf"
-          | target="_blank">Delta VFD015M21A VFD manual</a> and spindle type.
+          | Other settings according to the
+          |
+          a(href="https://buildbotics.com/upload/vfd/Delta_VFD015M21A.pdf",
+            target="_blank") Delta VFD015M21A VFD manual
+          |
+          | and spindle type.
index 69028ca7f5a85b79ede261c5b24ccb7fca3c35b2..47cfe8585cc617262d8a3047417a9cdc904d0296 100644 (file)
@@ -48,6 +48,7 @@ class Ctrl(object):
             self.lcd = bbctrl.LCD(self)
             self.mach = bbctrl.Mach(self)
             self.preplanner = bbctrl.Preplanner(self)
+            self.planTimer = bbctrl.PlanTimer(self)
             self.jog = bbctrl.Jog(self)
             self.pwr = bbctrl.Pwr(self)
 
diff --git a/src/py/bbctrl/PlanTimer.py b/src/py/bbctrl/PlanTimer.py
new file mode 100644 (file)
index 0000000..997fb6d
--- /dev/null
@@ -0,0 +1,106 @@
+################################################################################
+#                                                                              #
+#                This file is part of the Buildbotics firmware.                #
+#                                                                              #
+#                  Copyright (c) 2015 - 2018, Buildbotics LLC                  #
+#                             All rights reserved.                             #
+#                                                                              #
+#     This file ("the software") is free software: you can redistribute it     #
+#     and/or modify it under the terms of the GNU General Public License,      #
+#      version 2 as published by the Free Software Foundation. You should      #
+#      have received a copy of the GNU General Public License, version 2       #
+#     along with the software. If not, see <http://www.gnu.org/licenses/>.     #
+#                                                                              #
+#     The software is distributed in the hope that it will be useful, but      #
+#          WITHOUT ANY WARRANTY; without even the implied warranty of          #
+#      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       #
+#               Lesser General Public License for more details.                #
+#                                                                              #
+#       You should have received a copy of the GNU Lesser General Public       #
+#                License along with the software.  If not, see                 #
+#                       <http://www.gnu.org/licenses/>.                        #
+#                                                                              #
+#                For information regarding this software email:                #
+#                  "Joseph Coffland" <joseph@buildbotics.com>                  #
+#                                                                              #
+################################################################################
+
+import logging
+import time
+import bbctrl
+
+log = logging.getLogger('PlanTimer')
+
+
+class PlanTimer(object):
+    def __init__(self, ctrl):
+        self.ctrl = ctrl
+
+        self.reset()
+        self._report()
+
+        self.ctrl.state.set('plan_time', 0)
+        ctrl.state.add_listener(self._update)
+
+
+    def reset(self):
+        self.plan_time = 0
+        self.move_start = None
+        self.hold_start = None
+        self.plan_times = None
+        self.plan_index = 0
+
+
+    def _report(self):
+        if (self.plan_times is not None and
+            self.plan_index < len(self.plan_times) and
+            self.move_start is not None):
+            state = self.ctrl.state.get('xx', '')
+
+            if state in ['STOPPING', 'RUNNING']:
+                t = self.plan_time
+                delta = time.time() - self.move_start
+                nextT = self.plan_times[self.plan_index][1]
+                if t + delta < nextT: t += delta
+                else: t = nextT
+
+                self.ctrl.state.set('plan_time', round(t))
+
+        self.timer = self.ctrl.ioloop.call_later(1, self._report)
+
+
+    def _update(self, update):
+        # Check state
+        if 'xx' in update:
+            state = update['xx']
+
+            if state in ['READY', 'ESTOPPED']:
+                self.ctrl.state.set('plan_time', 0)
+                self.reset()
+
+            elif state == 'HOLDING': self.hold_start = time.time()
+            elif state == 'RUNNING' and self.hold_start is not None:
+                self.move_start += time.time() - self.hold_start
+                self.hold_start = None
+
+        # Get plan times
+        if self.plan_times is None or 'selected' in update:
+            active_plan = self.ctrl.state.get('selected', '')
+
+            if active_plan:
+                plan = self.ctrl.preplanner.get_plan(active_plan)
+
+                if plan is not None and plan.done():
+                    self.reset()
+                    self.plan_times = plan.result()[1]
+
+        # Get plan time for current id
+        if self.plan_times is not None and 'id' in update:
+            currentID = update['id']
+
+            while self.plan_index < len(self.plan_times):
+                id, t = self.plan_times[self.plan_index]
+                if id <= currentID: self.move_start = time.time()
+                if currentID <= id: break
+                self.plan_time = t
+                self.plan_index += 1
index b1db478b3d0144fdfafc082fdabd5b0d216b0cdf..4d228bddecc66064f0e7165d8e638bcd66619079 100644 (file)
@@ -38,7 +38,11 @@ from bbctrl.CommandQueue import CommandQueue
 log = logging.getLogger('Planner')
 
 reLogLine = re.compile(
-    r'^(?P<level>[A-Z])[0-9 ]:((?P<where>[^:]+:\d+:\d+):)?(?P<msg>.*)$')
+    r'^(?P<level>[A-Z])[0-9 ]:'
+    r'((?P<file>[^:]+):)?'
+    r'((?P<line>\d+):)?'
+    r'((?P<column>\d+):)?'
+    r'(?P<msg>.*)$')
 
 
 class Planner():
@@ -47,7 +51,6 @@ class Planner():
         self.cmdq = CommandQueue()
         self.logLock = threading.Lock()
         self.logIntercept = {}
-        self.time = 0
 
         ctrl.state.add_listener(self._update)
 
@@ -173,10 +176,14 @@ class Planner():
 
         level = m.group('level')
         msg = m.group('msg')
-        where = m.group('where')
+        filename = m.group('file')
+        line = m.group('line')
+        column = m.group('column')
 
-        if where is not None: filename, line, column = where.split(':')
-        else: filename, line, column = None, None, None
+        where = ':'.join(filter(None.__ne__, [filename, line, column]))
+
+        if line is not None: line = int(line)
+        if column is not None: column = int(column)
 
         # Per thread log intercept
         with self.logLock:
@@ -185,7 +192,7 @@ class Planner():
                 self.logIntercept[tid](level, msg, filename, line, column)
                 return
 
-        if where is not None: extra = dict(where = where)
+        if where: extra = dict(where = where)
         else: extra = None
 
         if   level == 'I': log.info    (msg, extra = extra)
@@ -202,10 +209,10 @@ class Planner():
 
 
     def __encode(self, block):
-        log.info('Cmd:' + json.dumps(block))
-
         type, id = block['type'], block['id']
 
+        if type != 'set': log.info('Cmd:' + json.dumps(block))
+
         if type == 'line':
             return Cmd.line(block['target'], block['exit-vel'],
                             block['max-accel'], block['max-jerk'],
index 09290bbfffa0f83314487b2b4cb9a85acfa17419..92e62a2505a4668ce09f43fce6b7e55728c9fd45 100644 (file)
@@ -103,7 +103,8 @@ class Preplanner(object):
         self.max_plan_time = max_plan_time
         self.max_loop_time = max_loop_time
 
-        if not os.path.exists('plans'): os.mkdir('plans')
+        for dir in ['plans', 'times']:
+            if not os.path.exists(dir): os.mkdir(dir)
 
         self.started = Future()
 
@@ -168,7 +169,8 @@ class Preplanner(object):
 
         # Copy state for thread
         state = self.ctrl.state.snapshot()
-        config = self.ctrl.mach.planner.get_config(False, True)
+        config = self.ctrl.mach.planner.get_config(False, False)
+        del config['default-units']
 
         # Start planner thread
         plan = yield self.pool.submit(self._exec_plan, filename, state, config)
@@ -200,8 +202,16 @@ class Preplanner(object):
         # Check if this plan was already run
         hid = plan_hash(filename, config)
         plan_path = 'plans/' + filename + '.' + hid + '.gz'
-        if os.path.exists(plan_path):
-            with open(plan_path, 'rb') as f: return f.read()
+        times_path = 'times/' + filename + '.' + hid + '.gz'
+
+        try:
+            if os.path.exists(plan_path) and os.path.exists(times_path):
+                with open(plan_path, 'rb') as f: data = f.read()
+                with open(times_path, 'rb') as f: times = f.read()
+                return (data, json.loads(gzip.decompress(times).decode('utf8')))
+
+        except Exception as e: log.error(e)
+
 
         # Clean up old plans
         self._clean_plans(filename)
@@ -227,6 +237,7 @@ class Preplanner(object):
         position = dict(x = 0, y = 0, z = 0)
         rapid = False
         moves = []
+        times = []
         messages = []
         count = 0
 
@@ -247,12 +258,15 @@ class Preplanner(object):
         try:
             while planner.has_more():
                 cmd = planner.next()
-                planner.set_active(cmd['id'])
+                planner.set_active(cmd['id']) # Release plan
+
                 # Cannot synchronize with actual machine so fake it
                 if planner.is_synchronizing(): planner.synchronize(0)
 
                 if cmd['type'] == 'line':
-                    totalTime += sum(cmd['times'])
+                    if not 'first' in cmd:
+                        totalTime += sum(cmd['times']) / 1000
+                        times.append((cmd['id'], totalTime))
 
                     target = cmd['target']
                     move = {}
@@ -272,7 +286,9 @@ class Preplanner(object):
                         maxLine = line
                         maxLineTime = time.time()
 
-                elif cmd['type'] == 'dwell': totalTime += cmd['seconds']
+                elif cmd['type'] == 'dwell':
+                    totalTime += cmd['seconds']
+                    times.append((cmd['id'], totalTime))
 
                 if not self._progress(filename, maxLine / totalLines):
                     raise Exception('Plan canceled.')
@@ -298,7 +314,9 @@ class Preplanner(object):
                     messages = messages)
         data = gzip.compress(dump_json(data).encode('utf8'))
 
-        # Save plan
+        # Save plan & times
         with open(plan_path, 'wb') as f: f.write(data)
+        with open(times_path, 'wb') as f:
+            f.write(gzip.compress(dump_json(times).encode('utf8')))
 
-        return data
+        return (data, times)
index ff68566eecc554b51ec83025674474b3cc53138d..f63d4b3fed65947eb8d786d693b25bb14295c796 100644 (file)
@@ -249,6 +249,7 @@ class PathHandler(bbctrl.APIHandler):
             return
 
         if data is not None:
+            data = data[0]
             self.set_header('Content-Encoding', 'gzip')
 
             # Respond with chunks to avoid long delays
index ff0d08d72c90935b0345ae3f163bcc0431dee481..098a80fe8e81431be8cd2c65b337be3f1da2a1dc 100644 (file)
@@ -57,6 +57,7 @@ from bbctrl.CommandQueue import CommandQueue
 from bbctrl.MainLCDPage import MainLCDPage
 from bbctrl.IPLCDPage import IPLCDPage
 from bbctrl.Camera import Camera, VideoHandler
+from bbctrl.PlanTimer import PlanTimer
 import bbctrl.Cmd as Cmd
 import bbctrl.v4l2 as v4l2
 
index 8fc0de6002dc2a46a3fedaf313b6bab7ea99f23a..56d5a658d6c45563325123e83075aaac809c1870 100644 (file)
@@ -495,6 +495,15 @@ span.unit
       background-color inherit
       color #ff3a3a
 
+  .path-viewer-messages
+    margin 0.125em 0
+
+    th, td
+      padding 0.125em
+
+      &.level
+        text-transform capitalize
+
   .path-viewer-content
     background-color #333
     background linear-gradient(to bottom, #666 0%, #222 100%);