CAM: correct grbl_post retract heights (#23010)

* CAM: correct grbl_post retract heights

Some small corrections to retraction heights in expansion of G8x drilling cycles for GRBL machines. 

Add comment blocks from NIST definitions to aid maintenance and understanding. 
Rename some variables for clarity and ease of future maintenance.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* correct typo which prevented final retract move

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
J-Dunn
2025-09-02 18:15:37 +02:00
committed by GitHub
parent dfcaeaa5d2
commit 96f32cae5a

View File

@@ -55,7 +55,7 @@ OUTPUT_LINE_NUMBERS = False # default doesn't output line numbers in output gCo
OUTPUT_BCNC = False # default doesn't add bCNC operation block headers in output gCode file
SHOW_EDITOR = True # default show the resulting file dialog output in GUI
PRECISION = 3 # Default precision for metric (see http://linuxcnc.org/docs/2.7/html/gcode/overview.html#_g_code_best_practices)
TRANSLATE_DRILL_CYCLES = False # If true, G81, G82 & G83 are translated in G0/G1 moves
TRANSLATE_DRILL_CYCLES = True # If true, G81, G82 & G83 are translated in G0/G1 moves
PREAMBLE = """G17 G90
""" # default preamble text will appear at the beginning of the gCode output file.
POSTAMBLE = """M5
@@ -570,8 +570,6 @@ def drill_translate(outstring, cmd, params):
global UNIT_SPEED_FORMAT
strFormat = "." + str(PRECISION) + "f"
strG0_Initial_Z = "G0 Z" + format(float(CURRENT_Z.getValueAs(UNIT_FORMAT)), strFormat) + "\n"
trBuff = ""
if OUTPUT_COMMENTS: # Comment the original command
@@ -582,37 +580,46 @@ def drill_translate(outstring, cmd, params):
# cycle conversion
# currently only cycles in XY are provided (G17)
# other plains ZX (G18) and YZ (G19) are not dealt with : Z drilling only.
drill_X = Units.Quantity(params["X"], FreeCAD.Units.Length)
drill_Y = Units.Quantity(params["Y"], FreeCAD.Units.Length)
drill_Z = Units.Quantity(params["Z"], FreeCAD.Units.Length)
RETRACT_Z = Units.Quantity(params["R"], FreeCAD.Units.Length)
param_X = Units.Quantity(params["X"], FreeCAD.Units.Length)
param_Y = Units.Quantity(params["Y"], FreeCAD.Units.Length)
param_Z = Units.Quantity(params["Z"], FreeCAD.Units.Length)
param_R = Units.Quantity(params["R"], FreeCAD.Units.Length)
# R less than Z is error
if RETRACT_Z < drill_Z:
if param_R < param_Z:
trBuff += linenumber() + "(drill cycle error: R less than Z )\n"
return trBuff
if MOTION_MODE == "G91": # G91 relative movements
drill_X += CURRENT_X
drill_Y += CURRENT_Y
drill_Z += CURRENT_Z
RETRACT_Z += CURRENT_Z
if MOTION_MODE == "G91": # G91 relative movements, (not generated by CAM WB drilling)
param_X += CURRENT_X
param_Y += CURRENT_Y
param_Z += CURRENT_Z
param_R += param_Z
#
# 3.5.20 Set Canned Cycle Return Level — G98 and G99
# When the spindle retracts during canned cycles, there is a choice of how far it retracts: (1) retract
# perpendicular to the selected plane to the position indicated by the R word, or (2) retract
# perpendicular to the selected plane to the position that axis was in just before the canned cycle
# started (unless that position is lower than the position indicated by the R word, in which case use
# the R word position).
# To use option (1), program G99. To use option (2), program G98. Remember that the R word has
# different meanings in absolute distance mode and incremental distance mode.
# """
# NIST-RS274
# 3.5.20 Set Canned Cycle Return Level — G98 and G99
# When the spindle retracts during canned cycles, there is a choice of how far it retracts: (1) retract
# perpendicular to the selected plane to the position indicated by the R word, or (2) retract
# perpendicular to the selected plane to the position that axis was in just before the canned cycle
# started (unless that position is lower than the position indicated by the R word, in which case use
# the R word position).
# To use option (1), program G99. To use option (2), program G98. Remember that the R word has
# different meanings in absolute distance mode and incremental distance mode.
# """
if DRILL_RETRACT_MODE == "G98" and CURRENT_Z >= RETRACT_Z:
RETRACT_Z = CURRENT_Z
if DRILL_RETRACT_MODE == "G99":
clear_Z = param_R
if DRILL_RETRACT_MODE == "G98" and CURRENT_Z >= param_R:
clear_Z = CURRENT_Z
else:
clear_Z = param_R
strG0_clear_Z = "G0 Z" + format(float(clear_Z.getValueAs(UNIT_FORMAT)), strFormat) + "\n"
strG0_param_R = "G0 Z" + format(float(param_R.getValueAs(UNIT_FORMAT)), strFormat) + "\n"
# get the other parameters
drill_feedrate = Units.Quantity(params["F"], FreeCAD.Units.Velocity)
strF_Feedrate = " F" + format(float(drill_feedrate.getValueAs(UNIT_SPEED_FORMAT)), ".2f") + "\n"
if cmd == "G83":
drill_Step = Units.Quantity(params["Q"], FreeCAD.Units.Length)
a_bit = (
@@ -626,51 +633,47 @@ def drill_translate(outstring, cmd, params):
if MOTION_MODE == "G91":
trBuff += linenumber() + "G90\n" # force absolute coordinates during cycles
strG0_RETRACT_Z = (
"G0 Z" + format(float(RETRACT_Z.getValueAs(UNIT_FORMAT)), strFormat) + "\n"
)
strF_Feedrate = (
" F" + format(float(drill_feedrate.getValueAs(UNIT_SPEED_FORMAT)), ".2f") + "\n"
)
print(strF_Feedrate)
# NIST-RS274
# 3.5.16.1 Preliminary and In-Between Motion
# At the very beginning of the execution of any of the canned cycles, with the XY-plane selected, if
# the current Z position is below the R position, the Z-axis is traversed to the R position. This
# happens only once, regardless of the value of L.
# In addition, at the beginning of the first cycle and each repeat, the following one or two moves are
# made:
# 1. a straight traverse parallel to the XY-plane to the given XY-position,
# 2. a straight traverse of the Z-axis only to the R position, if it is not already at the R position.
# preliminary movement(s)
if CURRENT_Z < RETRACT_Z:
trBuff += linenumber() + strG0_RETRACT_Z
if CURRENT_Z < param_R:
trBuff += linenumber() + strG0_param_R
trBuff += (
linenumber()
+ "G0 X"
+ format(float(drill_X.getValueAs(UNIT_FORMAT)), strFormat)
+ format(float(param_X.getValueAs(UNIT_FORMAT)), strFormat)
+ " Y"
+ format(float(drill_Y.getValueAs(UNIT_FORMAT)), strFormat)
+ format(float(param_Y.getValueAs(UNIT_FORMAT)), strFormat)
+ "\n"
)
if CURRENT_Z > RETRACT_Z:
# NIST GCODE 3.5.16.1 Preliminary and In-Between Motion says G0 to RETRACT_Z.
trBuff += (
linenumber()
+ "G0 Z"
+ format(float(RETRACT_Z.getValueAs(UNIT_FORMAT)), strFormat)
+ strF_Feedrate
)
last_Stop_Z = RETRACT_Z
if CURRENT_Z > param_R:
trBuff += linenumber() + strG0_param_R
last_Stop_Z = param_R
# drill moves
if cmd in ("G81", "G82"):
trBuff += (
linenumber()
+ "G1 Z"
+ format(float(drill_Z.getValueAs(UNIT_FORMAT)), strFormat)
+ format(float(param_Z.getValueAs(UNIT_FORMAT)), strFormat)
+ strF_Feedrate
)
# pause where applicable
if cmd == "G82":
trBuff += linenumber() + "G4 P" + str(drill_DwellTime) + "\n"
trBuff += linenumber() + strG0_RETRACT_Z
trBuff += linenumber() + strG0_clear_Z
else: # 'G83'
if params["Q"] != 0:
while 1:
if last_Stop_Z != RETRACT_Z:
if last_Stop_Z != clear_Z:
clearance_depth = (
last_Stop_Z + a_bit
) # rapid move to just short of last drilling depth
@@ -684,27 +687,23 @@ def drill_translate(outstring, cmd, params):
+ "\n"
)
next_Stop_Z = last_Stop_Z - drill_Step
if next_Stop_Z > drill_Z:
if next_Stop_Z > param_Z:
trBuff += (
linenumber()
+ "G1 Z"
+ format(float(next_Stop_Z.getValueAs(UNIT_FORMAT)), strFormat)
+ strF_Feedrate
)
trBuff += linenumber() + strG0_RETRACT_Z
trBuff += linenumber() + strG0_clear_Z
last_Stop_Z = next_Stop_Z
else:
trBuff += (
linenumber()
+ "G1 Z"
+ format(float(drill_Z.getValueAs(UNIT_FORMAT)), strFormat)
+ format(float(param_Z.getValueAs(UNIT_FORMAT)), strFormat)
+ strF_Feedrate
)
if DRILL_RETRACT_MODE == "G98":
trBuff += linenumber() + strG0_Initial_Z
else:
trBuff += linenumber() + strG0_RETRACT_Z
trBuff += linenumber() + strG0_clear_Z
break
except Exception as e: