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
This commit is contained in:
parent
f0b63a8e7f
commit
dba95ee94f
8 changed files with 73 additions and 38 deletions
|
|
@ -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"])
|
||||
|
|
|
|||
|
|
@ -205,7 +205,8 @@ default_settings = {
|
|||
"modelSizeDetection": True,
|
||||
"firmwareDetection": True,
|
||||
"printCancelConfirmation": True,
|
||||
"blockWhileDwelling": False
|
||||
"blockWhileDwelling": False,
|
||||
"g90InfluencesExtruder": False
|
||||
},
|
||||
"folder": {
|
||||
"uploads": None,
|
||||
|
|
|
|||
|
|
@ -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 = [];
|
||||
|
|
|
|||
|
|
@ -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"]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -41,6 +41,13 @@
|
|||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" data-bind="checked: feature_g90InfluencesExtruder" id="settings-g90InfluencesExtruder"> {{ _('<code>G90</code>/<code>G91</code> overrides relative extruder mode') }} <span class="label">{{ _('Smoothieware') }}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<div class="controls">
|
||||
<label class="checkbox">
|
||||
|
|
|
|||
|
|
@ -230,9 +230,9 @@ class gcode(object):
|
|||
maxExtrusion = [0.0]
|
||||
currentExtruder = 0
|
||||
totalMoveTimeMinute = 0.0
|
||||
absoluteE = True
|
||||
relativeE = False
|
||||
relativeMode = False
|
||||
scale = 1.0
|
||||
posAbs = True
|
||||
fwretractTime = 0
|
||||
fwretractDist = 0
|
||||
fwrecoverTime = 0
|
||||
|
|
@ -242,6 +242,8 @@ class gcode(object):
|
|||
feedrate = 2000
|
||||
offsets = printer_profile["extruder"]["offsets"]
|
||||
|
||||
g90InfluencesExtruder = settings().getBoolean(["feature", "g90InfluencesExtruder"])
|
||||
|
||||
for line in gcodeFile:
|
||||
if self._abort:
|
||||
raise AnalysisAborted(reenqueue=self._reenqueue)
|
||||
|
|
@ -318,23 +320,25 @@ class gcode(object):
|
|||
|
||||
# Use new coordinates if provided. If not provided, use prior coordinates (minus tool offset)
|
||||
# in absolute and 0.0 in relative mode.
|
||||
newPos = Vector3D(x if x is not None else (pos.x - toolOffset.x if posAbs else 0.0),
|
||||
y if y is not None else (pos.y - toolOffset.y if posAbs else 0.0),
|
||||
z if z is not None else (pos.z - toolOffset.z if posAbs else 0.0))
|
||||
newPos = Vector3D(x if x is not None else (0.0 if relativeMode else pos.x - toolOffset.x),
|
||||
y if y is not None else (0.0 if relativeMode else pos.y - toolOffset.y),
|
||||
z if z is not None else (0.0 if relativeMode else pos.z - toolOffset.z))
|
||||
|
||||
if posAbs:
|
||||
# Absolute mode: scale coordinates and apply tool offsets
|
||||
pos = newPos * scale + toolOffset
|
||||
else:
|
||||
if relativeMode:
|
||||
# Relative mode: scale and add to current position
|
||||
pos += newPos * scale
|
||||
else:
|
||||
# Absolute mode: scale coordinates and apply tool offsets
|
||||
pos = newPos * scale + toolOffset
|
||||
|
||||
if f is not None and f != 0:
|
||||
feedrate = f
|
||||
|
||||
if e is not None:
|
||||
if absoluteE:
|
||||
# make sure e is relative
|
||||
if relativeMode or relativeE:
|
||||
# e is already relative, nothing to do
|
||||
pass
|
||||
else:
|
||||
e -= currentE[currentExtruder]
|
||||
|
||||
# If move with extrusion, calculate new min/max coordinates of model
|
||||
|
|
@ -389,9 +393,13 @@ class gcode(object):
|
|||
if z is not None:
|
||||
pos.z = center.z
|
||||
elif G == 90: #Absolute position
|
||||
posAbs = True
|
||||
relativeMode = False
|
||||
if g90InfluencesExtruder:
|
||||
relativeE = False
|
||||
elif G == 91: #Relative position
|
||||
posAbs = False
|
||||
relativeMode = True
|
||||
if g90InfluencesExtruder:
|
||||
relativeE = True
|
||||
elif G == 92:
|
||||
x = getCodeFloat(line, 'X')
|
||||
y = getCodeFloat(line, 'Y')
|
||||
|
|
@ -417,9 +425,9 @@ class gcode(object):
|
|||
|
||||
elif M is not None:
|
||||
if M == 82: #Absolute E
|
||||
absoluteE = True
|
||||
relativeE = False
|
||||
elif M == 83: #Relative E
|
||||
absoluteE = False
|
||||
relativeE = True
|
||||
elif M == 207 or M == 208: #Firmware retract settings
|
||||
s = getCodeFloat(line, 'S')
|
||||
f = getCodeFloat(line, 'F')
|
||||
|
|
|
|||
Loading…
Reference in a new issue