From 96f32cae5a0635103bbdb627fde3380f316c2a94 Mon Sep 17 00:00:00 2001 From: J-Dunn Date: Tue, 2 Sep 2025 18:15:37 +0200 Subject: [PATCH] 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> --- src/Mod/CAM/Path/Post/scripts/grbl_post.py | 113 ++++++++++----------- 1 file changed, 56 insertions(+), 57 deletions(-) diff --git a/src/Mod/CAM/Path/Post/scripts/grbl_post.py b/src/Mod/CAM/Path/Post/scripts/grbl_post.py index 435e4482e5..2f0d5977eb 100644 --- a/src/Mod/CAM/Path/Post/scripts/grbl_post.py +++ b/src/Mod/CAM/Path/Post/scripts/grbl_post.py @@ -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: