gcode_arcs: support XY, XZ and YZ planes
add G17, G18 and G19 commands to select arc planes enhance G2/G3 to support arc moves in XY, XZ and YZ planes
Signed-off-by: Andrew Mirsky [email protected]
Thanks. As a high-level question - what 3rd party software depends on the G17,G18,G19 commands? In general, we only add old-style g-code commands if it enables support for a popular 3rd party application. There is a blurb on this at https://www.klipper3d.org/G-Codes.html#g-code-commands .
On the procedural side, the parsedump.py changes would need to be separated out to its own commit (and probably its own PR as well). That's important for using tools like git bisect and git revert if needed.
Finally, I'm unsure about the changes to gcode.py - probably simpler if those were kept in gcode_arcs.py .
-Kevin
Appreciate the feedback. Will move items out of gcode.py and i'll move the changes to parsedump.py to a separate PR.
I'm using klipper to control a Sherline end mill CNC. Fusion 360 generates G17/18/19 frequently when doing roughing operations as well as radii moves in the YZ or XZ planes. I know the focus of klipper has been 3D printing but had seen this posting. Should probably first confirm that the discussion about adding cnc support is still an active idea? There have been attempts at doing the commands in gcode_macros with some success. But enhancements such as expanded G2/G3 support and a few other commands are challenging/fragile as macros and would be better done as extras.
--Andrew
Thanks. I agree it would be useful if Klipper could support gcode produced by Fusion360.
Can you give a high-level overview of what is needed for Klipper to support g-code from Fusion360? What other commands or features also need to be implemented?
Cheers, -Kevin
Instead of picking any one gcode "standard", Fusion 360 enables CAM to CNC by having controller-specific post-processor plugins following a javascript-based scripting API. The two options are:
- create a klipper-specific post-processor and implement additional functionality with extended gcodes
- use an existing post-processor and implement additional functionality with existing gcode patterns (grbl seems to be the defacto standard for non-commercial cnc machines).
My preference would the latter; leverage an existing command set (grbl v1.1) instead of having to (re)invent a command set and create yet another standard for how cnc machines operate. This also enables CAM tools other than Fusion 360 who follow the grbl command set to produce gcode for klipper-based cnc machines.
Either way, I think these are the minimum command types that Fusion 360's post processor API requires (only listing the ones that klipper doesn't already support):
- Establish material origins, tool and stock offsets (G10L2, G10L20, G53, G54-59, G38.2-5)
- G2/G3 support for XY (G17), XZ (G18) and YZ (G19)
- Tool selection (T/M6)
- Spindle commands (M3, M4, M5)
- Coolant state (M7, M8, M9)
In order to see what grbl support might look like, I sketched out changes to handle work offsets. It's not pull request ready, but was helpful to figure out how commands/features might be implemented as extras.
I did this mostly for fun and as an interesting "let's learn CNC gcodes" - https://github.com/vladbabii/klippy-cnc/
I managed to get fusion to generate klipper-readable g-code by setting these output option https://github.com/vladbabii/klippy-cnc/blob/master/docs/fusion360.md
While
On using klipper as cnc software in general...
For basic (2.5D simple milling) most people are fine with what klipper supports right now as gcode. What almost all wanted is a probing solution that can work in any direction. Basically move in one direction until a button/endstop/etc changes state (either released or pressed) then stop without changing any coordinates. This would allow building macros for aligning pieces, for detecting circle centers, for probing piece shapes, etc.. Also making automatic tool changes for cnc would need this, to be able to measure tool length...
On the other hand, having a 3d probe could allow creation of macros for 3d printing that allows resuming prints by probing the printed part shape and then calculating the offset to be applied on where to continue printing.
This could also work as auto calibration - print a thick wall then probe it on both sides to calculate actual thickness and use that to calibrate flow...
Coming back to this specific thread - I agree with @ajmirsky that these basic operations should be added to klipper. While klipper is not indended for CNC-ing at least 100 people have used it for this at least once (and talkwed with me about it) and they said it's working great (auto per axis tramming and other things are not available on some grbl forks for example and with dual Y motors it quickly becomes a huge pain to tram everything)
Thanks. In general it looks fine. I'll try to set aside some time in the coming days to make a final review and commit.
-Kevin
Thanks. I committed this change. I don't think the import of the gcode module is necessary though - so I also added commit ba365aff on top.
-Kevin
The new G2/G3 statements are causing the throwing the "!! G2/G3 requires IJ, IK or JK parameters" error. Sliced file worked fine with previous version of Klipper builds. Going to do some testing today to figure which gcode line specifically is throwing the error. Know others on the Ender 5 Mercury 1 discord are also having the same issue.
Here's an example line that will cause it to break: G2 X33.409 Y140.307 I-0.000 J14.730
The I and J parameters should accept zero values, proposed fix:
diff --git a/klippy/extras/gcode_arcs.py b/klippy/extras/gcode_arcs.py
index 7707cd66..5cf30aa1 100644
--- a/klippy/extras/gcode_arcs.py
+++ b/klippy/extras/gcode_arcs.py
@@ -75,16 +75,16 @@ class ArcSupport:
raise gcmd.error("G2/G3 does not support R moves")
# determine the plane coordinates and the helical axis
- asPlanar = [ gcmd.get_float(a, 0.) for i,a in enumerate('IJ') ]
+ asPlanar = [gcmd.get_float(a, None) for a in 'IJ']
axes = (X_AXIS, Y_AXIS, Z_AXIS)
if self.plane == ARC_PLANE_X_Z:
- asPlanar = [ gcmd.get_float(a, 0.) for i,a in enumerate('IK') ]
+ asPlanar = [gcmd.get_float(a, None) for a in 'IK']
axes = (X_AXIS, Z_AXIS, Y_AXIS)
elif self.plane == ARC_PLANE_Y_Z:
- asPlanar = [ gcmd.get_float(a, 0.) for i,a in enumerate('JK') ]
+ asPlanar = [gcmd.get_float(a, None) for a in 'JK']
axes = (Y_AXIS, Z_AXIS, X_AXIS)
- if not asPlanar[0] or not asPlanar[1]:
+ if asPlanar[0] is None or asPlanar[1] is None:
raise gcmd.error("G2/G3 requires IJ, IK or JK parameters")
asE = gcmd.get_float("E", None)