From dba95ee94fac45052e2edaa190161f46abfa2962 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Wed, 10 May 2017 16:40:52 +0200 Subject: [PATCH] Handle G90/G91 and M82/M83 distinct by default By default G90/G91 define relativeMode, M82/M83 define relativeE. The extruder coordinate will be viewed as relative when either relativeMode or relativeE are set. This mirrors the implementation in Marlin (current and legacy forks) as well as Repetier. SmoothieWare's implementation resets the relative mode of the extruder on a G90/G91. To still accomodate this different implementation a new settings has been added under Settings > Feature: "G90/G91 overrides relative extruder mode". Checking this switches to the alternative interpretation for future gcode analysis and visualization. The only difference between the two of them is that the following segment of GCODE: M83 G90 will have the extruder still set to relative on Marlin and Repetier but set to absolute on Smoothieware. Please note that the setting in all likelihood will be moved to the printer profile in the future, since it makes more sense to have it on a per printer basis. It's not part of the set of features available for auto detection since it's required for GCODE analysis and hence needs to be known even outside of a connection to the printer. Implements #1818 --- src/octoprint/server/api/settings.py | 4 +- src/octoprint/settings.py | 3 +- src/octoprint/static/gcodeviewer/js/Worker.js | 44 +++++++++++-------- .../static/gcodeviewer/js/gCodeReader.js | 6 ++- .../static/js/app/viewmodels/gcode.js | 8 ++++ .../static/js/app/viewmodels/settings.js | 1 + .../dialogs/settings/features.jinja2 | 7 +++ src/octoprint/util/gcodeInterpreter.py | 38 +++++++++------- 8 files changed, 73 insertions(+), 38 deletions(-) diff --git a/src/octoprint/server/api/settings.py b/src/octoprint/server/api/settings.py index d5255cd3..02880093 100644 --- a/src/octoprint/server/api/settings.py +++ b/src/octoprint/server/api/settings.py @@ -128,7 +128,8 @@ def getSettings(): "modelSizeDetection": s.getBoolean(["feature", "modelSizeDetection"]), "firmwareDetection": s.getBoolean(["feature", "firmwareDetection"]), "printCancelConfirmation": s.getBoolean(["feature", "printCancelConfirmation"]), - "blockWhileDwelling": s.getBoolean(["feature", "blockWhileDwelling"]) + "blockWhileDwelling": s.getBoolean(["feature", "blockWhileDwelling"]), + "g90InfluencesExtruder": s.getBoolean(["feature", "g90InfluencesExtruder"]) }, "serial": { "port": connectionOptions["portPreference"], @@ -335,6 +336,7 @@ def _saveSettings(data): if "firmwareDetection" in data["feature"]: s.setBoolean(["feature", "firmwareDetection"], data["feature"]["firmwareDetection"]) if "printCancelConfirmation" in data["feature"]: s.setBoolean(["feature", "printCancelConfirmation"], data["feature"]["printCancelConfirmation"]) if "blockWhileDwelling" in data["feature"]: s.setBoolean(["feature", "blockWhileDwelling"], data["feature"]["blockWhileDwelling"]) + if "g90InfluencesExtruder" in data["feature"]: s.setBoolean(["feature", "g90InfluencesExtruder"], data["feature"]["g90InfluencesExtruder"]) if "serial" in data.keys(): if "autoconnect" in data["serial"]: s.setBoolean(["serial", "autoconnect"], data["serial"]["autoconnect"]) diff --git a/src/octoprint/settings.py b/src/octoprint/settings.py index e849aa17..e1a9fda9 100644 --- a/src/octoprint/settings.py +++ b/src/octoprint/settings.py @@ -205,7 +205,8 @@ default_settings = { "modelSizeDetection": True, "firmwareDetection": True, "printCancelConfirmation": True, - "blockWhileDwelling": False + "blockWhileDwelling": False, + "g90InfluencesExtruder": False }, "folder": { "uploads": None, diff --git a/src/octoprint/static/gcodeviewer/js/Worker.js b/src/octoprint/static/gcodeviewer/js/Worker.js index 4f3cf4ce..ea14a5c3 100644 --- a/src/octoprint/static/gcodeviewer/js/Worker.js +++ b/src/octoprint/static/gcodeviewer/js/Worker.js @@ -9,6 +9,7 @@ var firstReport; var toolOffsets = [ {x: 0, y: 0} ]; +var g90InfluencesExtruder = false; var z_heights = {}; var model = []; var max = {x: undefined, y: undefined, z: undefined}; @@ -232,8 +233,8 @@ var doParse = function () { var center_i, center_j, direction; var prevX = 0, prevY = 0, prevZ = 0; var f, lastF = 4000; - var extrude = false, extrudeRelative = false, retract = 0; - var positionRelative = false; + var extrude = false, relativeE = false, retract = 0; + var relativeMode = false; var zLift = false; var zLiftZ = undefined; var zLiftMoves = []; @@ -273,7 +274,7 @@ var doParse = function () { for (var j = 0; j < args.length; j++) { switch (argChar = args[j].charAt(0).toLowerCase()) { case 'x': - if (positionRelative) { + if (relativeMode) { x = prevX + Number(args[j].slice(1)) + offset.x; } else { x = Number(args[j].slice(1)) + offset.x; @@ -282,7 +283,7 @@ var doParse = function () { break; case 'y': - if (positionRelative) { + if (relativeMode) { y = prevY + Number(args[j].slice(1)) + offset.y; } else { y = Number(args[j].slice(1)) + offset.y; @@ -291,7 +292,7 @@ var doParse = function () { break; case 'z': - if (positionRelative) { + if (relativeMode) { z = prevZ + Number(args[j].slice(1)); } else { z = Number(args[j].slice(1)); @@ -306,13 +307,13 @@ var doParse = function () { assumeNonDC = true; numSlice = Number(args[j].slice(1)); - if (!extrudeRelative) { + if (relativeMode || relativeE) { + prev_extrude[tool]["abs"] = numSlice; + prev_extrude[tool][argChar] += numSlice; + } else { // absolute extrusion positioning prev_extrude[tool]["abs"] = numSlice - prev_extrude[tool][argChar]; prev_extrude[tool][argChar] = numSlice; - } else { - prev_extrude[tool]["abs"] = numSlice; - prev_extrude[tool][argChar] += numSlice; } extrude = prev_extrude[tool]["abs"] > 0; @@ -359,15 +360,19 @@ var doParse = function () { move = true; } } else if (/^(?:M82)/i.test(line)) { - extrudeRelative = false; + relativeE = false; } else if (/^(?:G91)/i.test(line)) { - positionRelative = true; - extrudeRelative = true; + relativeMode = true; + if (g90InfluencesExtruder) { + relativeE = true; + } } else if (/^(?:G90)/i.test(line)) { - positionRelative = false; - extrudeRelative = false; + relativeMode = false; + if (g90InfluencesExtruder) { + relativeE = false; + } } else if (/^(?:M83)/i.test(line)) { - extrudeRelative = true; + relativeE = true; } else if (/^(?:M101)/i.test(line)) { dcExtrude = true; } else if (/^(?:M103)/i.test(line)) { @@ -407,10 +412,10 @@ var doParse = function () { case 'b': case 'c': numSlice = Number(args[j].slice(1)); - if (!extrudeRelative) - prev_extrude[tool][argChar] = 0; - else { + if (relativeMode || relativeE) { prev_extrude[tool][argChar] = numSlice; + } else { + prev_extrude[tool][argChar] = 0; } break; } @@ -568,7 +573,8 @@ var parseGCode = function (message) { gcode = message.gcode; firstReport = message.options.firstReport; toolOffsets = message.options.toolOffsets; - if (!toolOffsets || toolOffsets.length == 0) toolOffsets = [{x: 0, y: 0}] + if (!toolOffsets || toolOffsets.length == 0) toolOffsets = [{x: 0, y: 0}]; + g90InfluencesExtruder = message.options.g90InfluencesExtruder; doParse(); gcode = []; diff --git a/src/octoprint/static/gcodeviewer/js/gCodeReader.js b/src/octoprint/static/gcodeviewer/js/gCodeReader.js index d0863642..bf0124ad 100644 --- a/src/octoprint/static/gcodeviewer/js/gCodeReader.js +++ b/src/octoprint/static/gcodeviewer/js/gCodeReader.js @@ -24,7 +24,8 @@ GCODE.gCodeReader = (function(){ analyzeModel: false, toolOffsets: [ {x: 0, y: 0} - ] + ], + g90InfluencesExtruder: false }; var percentageTree = undefined; @@ -138,7 +139,8 @@ GCODE.gCodeReader = (function(){ gcode: gcode, options: { firstReport: 5, - toolOffsets: gCodeOptions["toolOffsets"] + toolOffsets: gCodeOptions["toolOffsets"], + g90InfluencesExtruder: gCodeOptions["g90InfluencesExtruder"] } } } diff --git a/src/octoprint/static/js/app/viewmodels/gcode.js b/src/octoprint/static/js/app/viewmodels/gcode.js index ea8b4c6e..f1611873 100644 --- a/src/octoprint/static/js/app/viewmodels/gcode.js +++ b/src/octoprint/static/js/app/viewmodels/gcode.js @@ -138,6 +138,14 @@ $(function() { } }); + self.settings.feature_g90InfluencesExtruder.subscribe(function() { + GCODE.ui.updateOptions({ + reader: { + g90InfluencesExtruder: self.settings.feature_g90InfluencesExtruder() + } + }); + }); + self._retrieveBedDimensions = function(currentProfileData) { if (currentProfileData == undefined) { currentProfileData = self.settings.printerProfiles.currentProfileData(); diff --git a/src/octoprint/static/js/app/viewmodels/settings.js b/src/octoprint/static/js/app/viewmodels/settings.js index 5538917d..4b805ead 100644 --- a/src/octoprint/static/js/app/viewmodels/settings.js +++ b/src/octoprint/static/js/app/viewmodels/settings.js @@ -143,6 +143,7 @@ $(function() { self.feature_firmwareDetection = ko.observable(undefined); self.feature_printCancelConfirmation = ko.observable(undefined); self.feature_blockWhileDwelling = ko.observable(undefined); + self.feature_g90InfluencesExtruder = ko.observable(undefined); self.serial_port = ko.observable(); self.serial_baudrate = ko.observable(); diff --git a/src/octoprint/templates/dialogs/settings/features.jinja2 b/src/octoprint/templates/dialogs/settings/features.jinja2 index 116211f6..ab126489 100644 --- a/src/octoprint/templates/dialogs/settings/features.jinja2 +++ b/src/octoprint/templates/dialogs/settings/features.jinja2 @@ -41,6 +41,13 @@ +
+
+ +
+