In the last few weeks, there’s been a bunch of discussion on this forum about how Carbide Create and some of the more advanced tools do not, or no longer, create optimal gcode for retracts and rapids movement, and there has been a request to build a post-processor tool to optimize the gcode files coming out of the CAM tooling.
I’ve started building such a tool, and this will be some sort of running thread of the progress in case folks want to help beta test this.
As always, if you have ideas or requests don’t hesitate to put in a comment
new optimization: Movement at the top height is now converted to rapids.
This one is slightly tricky since detecting what the top is… ends up harder than it sounds since there are some movements well above the retract height (like between toolpaths)
if the gcode contain a G1 plunge at a location that the bit previously visited, use a G0 plunge to just above the previous location and then G1 the rest of the way
this should make Carbide Create cuts go much faster
I used Sphinx extensively on our Python tools and it is by far the easiest to maintain code docs tool I’ve seen yet, also https://readthedocs.org/ will host for free for open source projects so triggered builds from github can auto-export new code docs to readthedocs.
I’ve not used Sphinx before. I’m about to just add a pile of comments… once those are there I can either learn Sphinx or you can do a quick PR on github to sphinxiphy them
next step is to write code to keep existing unmodified lines the same as much as possible to make doing diffs easier, this will be key for creating the test suite
Looking good fenrus! I’ll review your code for comments in a minute.
I have my first draft typed up here:
It’s in python, and also about an hour old
I have a plan for automatic tests, but have ran into an issue: In the original version of the routine, Fusion performed G0 plunges beneath the feed height. I don’t know how to detect that this is OK (I think that fusion is able to do so because they know that they already milled out that material).
Unfortunately, unless we can nail down how to replicate this behavior, we’ll have to manually validate everything.
I’ve manually inspected a diff of my result with the “good” source and found that it matches perfectly (minus a few comments Fusion adds, etc, as well as the plunge issue above and a minor bug which results in a few seconds of G1 at the start of each toolpath, so a tiny bit slower but nbd)
For my code, the relevant logic can be almost completely described by this snippet of code, which should be almost self-evident:
conditionMovingDownPastClearance = zAtEndOfLine[i] < feedHeightCurrent and zAtEndOfLine[i] < zAtStartOfLine[i]
conditionMovingLaterallyBelowClearance = (zAtEndOfLine[i] < clearanceHeightCurrent or zAtEndOfLine[i] < zAtEndOfLine[i]) and (xAtStartOfLine[i]!=xAtEndOfLine[i] or yAtStartOfLine[i] != yAtEndOfLine[i] )
bInsertG0BecauseVerticalUp=xAtStartOfLine[i]==xAtEndOfLine[i] and yAtStartOfLine[i]==yAtEndOfLine[i] and zAtEndOfLine[i]>=clearanceHeightCurrent and newGmode != 'G0' and lineGmodes[i]=='G1'
bInsertG0BecauseLateralAbove=xAtStartOfLine[i]!=xAtEndOfLine[i] and yAtStartOfLine[i]!=yAtEndOfLine[i] and zAtEndOfLine[i]>=clearanceHeightCurrent and zAtStartOfLine[i]>=clearanceHeightCurrent and newGmode != 'G0' and lineGmodes[i]=='G1'
bSwitchToG1=(conditionMovingDownPastClearance or conditionMovingLaterallyBelowClearance) and newGmode == 'G0' and lineGmodes[i] == 'G1'
# if the current line does not move X or Y, and ends above the clearance height and is a G1 op, switch to G0
# if the current line does move X and/or Y, but starts and ends above the clearance height, switch to G0
if bInsertG0BecauseVerticalUp or bInsertG0BecauseLateralAbove:
[newGmode, tokensLine] = addStartOfG0(tokensLine)
alreadyChangedModes=True
# if the reassigned gMode (at the end of the upcoming line) is different from G1,
# .... and the gMode at the start of the line was a G0
# .... and the Z at the end of the line is less than the clearance height
# .... set it to a G1
elif bSwitchToG1:
[newGmode, tokensLine] = addStartOfG1(tokensLine, fAtEndOfLine[i])
alreadyChangedModes = True
@fenrus thoughts on the plunge issue? It would be really nice to have an automated path to testing this in the event of future updates.
Want me to post the other 6 test projects (about 12 *.nc files)
-I don’t write JS, but it appears as if you have hardcoded your feed height to be Z=0. If people set their zero to be the stock bottom instead of the stock top, I believe that your code will rapid straight through everything. Yikes! If you review my ugly python, I have a simple routine for pulling out the clearance/retract/feed height which are prominently placed at the beginning of each toolpath.
-Although your code is briefer, if you added spaces between your tokens and trimmed trailing zeros at the end of each floating point value, it would be easier to automatically diff your results
-Likewise, if you stripped redundant “G0” and “G1” commands, that would make using diff easier as well.
Great job! I like that you don’t have to install python to use it, lol
the top is zero shouldn’t be but I’ll re-audit the code for it
if you KNOW the gcode came from the current f360 then yes you can pull it out
I am trying to keep the tool much more generic though
as for the output, once my current cut is finished I’ll go back to coding and will fix the output diff issue, I have in my head figured out what it needs
the THEORY is that the code first computes a bounding box (min and max for each of X Y and Z) of the cuts, and then uses that bounding box as reasoning for all other things…
now I did borrow code from one of my other projects that DID assume zero-at-top so it could be something leaked in… so I will re-audit this
One concern aside from the zero thing is that many movements happen at rapid speeds but below the bounding box of all toolpaths, because fusion likes to start things off by going to the retract height (typically 0.4" above retract, where rapids usually happen at). So you’ll miss out on some time savings
Is it perhaps an idea to have the tool first scan the supplied .nc file and then report a summary to the user of what it thinks it has found in the file, retract heights etc. and then ask the user to confirm or reject an “above here there be rapids” measure?
Might also be worth reporting how many traverses are identified as being convertable to rapid (or the sum of the travel distance which is ~ time)?
I was more thinking along the lines of getting the user to actually think about what the converter script was going to do.
There’ll be no shortage of “non technical” folk who want to use this and if they treat is as a magic black box then they are likely to suffer nasty surprises when they feed it some weird toolpath that breaks the rules and produces an unwanted output.
Doing a propose / confirm or propose / alter pair with the user to say “I think you want me to do this” is more likely to get them to think about what the tool is doing before just pressing “Run”. It might also give opportunity to do more aggressive optimisations if the user thinks that is safe, e.g. if they are going to run it through a sim before loading it to a machine.
yeah can do; I already have the click buttons in the UI, so the user can toggle on/off these optimizations conceptually…
I’ll figure out how to somehow show this in a way that’s not too confusing.