Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature request, support pcb milling with different tools #236

Open
AlexeyGusev opened this issue Dec 17, 2018 · 21 comments
Open

feature request, support pcb milling with different tools #236

AlexeyGusev opened this issue Dec 17, 2018 · 21 comments

Comments

@AlexeyGusev
Copy link

$ pcb2gcode --version
1.3.2
Git commit: v1.3.2-491-g9af2eac
Boost: 106200
Gerbv: 2.6.1

What did you try (include command-line arguments):

pcb2gcode --back MC33063_buck_5V_to_3V3-B.Cu.gbr 
--drill MC33063_buck_5V_to_3V3-PTH.drl --drill-side back 
--outline MC33063_buck_5V_to_3V3-Edge.Cuts.gbr

millproject file parameters of interest:

offset=0.1mm   # Distance by which the tool movement will be outset from the contours 
extra-passes=5 # Ignored when voronoi is in use

What happenned:

As expected, g-code with min amount of 1 and max amount of 5 passes per routed track was generated. So in narrow places, where space is tight (typically, tqfp or small soic), one pass of milling was generated, and in spacious places up to 5 passes of tool milled out unneeded copper.

What did you expect to happen:

Similarly to drilling holes with different drill sizes, would be so cool to mill away thick isolation with thick tool - this saves time and tools. Especially wanted when working on high voltage boards with small smd controllers like hv9660 or similar. You really want thick (up to several mm) isolation between high voltage power lines and have to be able to work with minuscule SOT package with 0.2-0.3 mm between copper traces.

Since auto-zero in the middle of a CNC job is a challenge in simpler setups, I propose generating several different g-code files for different tools.

Proposed parameters with sample values and comments:
mills-available=0.1mm,0.5mm,1mm,1.5mm # this parameter will tell pcb2gcode which mill bits are available. If, for example, extra-passes = 5, then pcb2gcode should generate a g-code file with up to 4 passes of 0.1mm engraver bit in places where distance between traces is < 0.5mm, and another g-code file with one pass of 0.5mm mill bit where distance between traces is ≥0.5mm and so on. In general, always try to use biggest tool available in given context; switch to smaller tool when distance between tracks is too small. If this parameter is not present, revert to normal, present behaviour.
max-mill=3mm # never mill more than 3 mm away from track. This is needed to avoid diving too deep into copper, if thick tool is provided in previous parameter and extra-passes is big enough. I propose to implement this parameter regardless of whether multitool is enabled or not, to limit countless milling into vast copper plane with big extra-passes value.

@eyal0
Copy link
Contributor

eyal0 commented Dec 18, 2018

This is an interesting idea and you are not the first to propose it.

First of all, I think that you could run pcb2gcode twice, once with the big milling tool and once with the small milling too, and then mill with each of those. It should do the right thing. You're right that extra passes would be needed for the smaller tool because it would need to fill the gap between the big tool and the small tool.

The extra passes on the small tool are only needed in some spots, however, so the milling would have to be pretty smart and figure out where to mill just with the big tool and where to mill with the small one. Hmm... Maybe it could be done.

I'd like to think more about the configuration, to keep it as simple as possible. mills-available seems like a good idea. But if we do it, do we still need extra-passes? Maybe we don't! All we really need is to know how much width to clear out around each trace and what mills are available. And then let pcb2gcode figure out which milling bits to use, how many passes for each, etc. Right?

@AlexeyGusev
Copy link
Author

mills-available seems like a good idea. But if we do it, do we still need extra-passes? Maybe we don't!

Still need extra-passes, because:

  • you might want to avoid using mills-available and use the software as it is today
  • you might have only very small and very big tool available. Consider you have 0.1mm and 1.5mm bits, and you want your isolation to be no less that 0.4 mm everywhere and 1.5mm in some places. This can be achieved by defining mills-available=0.1mm,1.5mm, extra-passes=3, max-mill=1.5mm. The software should choose 1.5mm bit to mill out wide tracks, use it only once because of max-mill, and run 0.1mm bit four times for narrow milling.

All we really need is to know how much width to clear out around each trace and what mills are available. And then let pcb2gcode figure out which milling bits to use, how many passes for each, etc. Right?

What if, again, you have very big difference between available tools, like in example above? Without extra-passes pcb2gcode will run 0.1mm tool twelve times in places where gerber file has a 1.2mm clearance between traces, but what if you don't want that much copper out, because you might be satisfied with 0.4mm instead of 1.2mm?

@eyal0
Copy link
Contributor

eyal0 commented Dec 19, 2018

First, I agree with your point about about backward compatibly. It should be maintained.

But I still think that it would be enough to specify which bits are available and the minimum isolation. Say we use your example of 0.1 and 1.5 mm bits and we want a minimum of 0.4mm. First, we would mill with the 1.5 everywhere possible. That gets us the best isolation. 1.5 is bigger than 0.4 so it would only need one pass.

In some places, traces are too close together to fit 1.5 so it wouldn't mill those. Next, the 0.1mm mill would start to work. In places where the 1.5 went, no need to mill. But where the 1.5 didn't fit, the 0.1 would go to work. It would automatically do 4 passes because it needs 0.4 mm in total. This could happen in tight corners or between tracks that are near.

So I think that would work. Another way to think about it is to say that we don't really care how the CNC does it, all we want is that there is a minimum clearance. And it is up to the software to figure out how to do that with the given milling bits. The user shouldn't have to know about extra passes.

@AlexeyGusev
Copy link
Author

Yeah, that will work, agree. However, in my example above I was elaborating how to limit maximums, not minimums, with extra-passes. Idea was that if your gerber file has, say, 1.2mm of free space between traces, but you are happy with just 0.5mm, then you would say extra-passes=4 and thus limit the width of isolation.

However, production is probably a bad stage to fix isolation widths. Right way would be to generate proper gerbers with well-defined geometry, and that is design stage. My thinking was methodologically wrong :)

So yes, the software should try it's best and mill the board as close to gerber description as possible, choosing most optimal tools from those defined in mills-available. The user shouldn't have to know about extra passes, right.

@eyal0
Copy link
Contributor

eyal0 commented Dec 28, 2018

I thought more about how to do this.

I could have the usual code generate a milling path using the big mill bit. It would create at least one path but maybe more if extra passes are needed. The number of extra passes is either set the old way, using the extra passes parameter, or the new way, in offset distance.

After that, I generate with the next milling bit some paths. And then I subtract from those paths all the places that the big mill bit already went.

There are some tricky things to think about:

First, the milling is usually done per trace. This is because of how the algorithm works: if two traces are so close together that the mill bit won't fit, it mills anyway and reports a warning. With big bits, we don't want to do this! Instead, just skip those areas. Only with the smallest bit we should go ahead and mill and then report the contention if one exists.

Another problem is that we usually try to keep paths connected so that the tool doesn't have to go up and down too much. The deleting of parts of the path will disconnect things. So the software, after deleting, needs to go in and reconnect paths where possible. Path connection is possible whenever two mill paths are less than a tool radius apart. Those are easy to find and clean up.

So it'll work like this:

Make paths for the biggest tool. If there are places where the tool won't fit, don't go. Number of extra passes depends on the clearance wanted and the diameter of the tool.

Make a path for the next biggest tool, same as above. If a previous path already covers an area, delete it from the current path. Then reconnect adjacent paths. Repeat for the rest of the mid-sized bits.

For the smallest one, make paths like before but this time go even if the traces are too close to each other to fit. If those contentions happen, report a warning. Then again delete paths as needed and reconnect paths where needed.

Would it be best to have one file per bit or all of them in one file with tool changes requested in the file?

@AlexeyGusev
Copy link
Author

Excellent workflow.

I vote for one file per bit, because:

  • not all CNCs support tool change well enough (grbl 0.9, AFAIK, doesn't support g-code M06 command)
  • changing tools without breaking Z axis' zero is a major MAJOR challenge; milling bits often won't have collars, but even if they had it would be impossible – common engraving depth is 0.05 mm, way too small for precise alignment, so auto-zeroing inside g-code file would be required after every tool change (spooky, what would happen if the copper layer where the software would attempt auto-zeroing is milled out? Broken tool or board, whichever is stronger).

It would be safest to mill one file with big tool, observe result, make corrections to e.g. heightmap if needed, re-run if needed, manually change tool, z-probe, run next file etc.

@eyal0
Copy link
Contributor

eyal0 commented Dec 28, 2018

pcb2gcode supports toolchange in a few ways. First, there is software that will do it natively. I use bCNC and it will see the M06 toll change command and run a canned script instead of sending the M06 to grbl. That script includes using the g43.1 command to lower until a point is touched. For LinuxCNC and others, a macro can be run. So depending on how you drive your CNC, it can work very reliably.

Anyway, only the drill file has changes currently. I will either put each mill file separate, I guess. It's easier for them to be separate and let users concatenate them rather than have them together and require users to split them if needed.

Anyway, I realize that some CNCs might not have proper zeroing. I'll make it an option to join or separate files.

@eyal0
Copy link
Contributor

eyal0 commented Jan 8, 2019

Okay, now that we've got #237 out of the way, I'll get to work on this. I need to figure out how to specify the options. Right now, there is only one option for the milling bit's width: offset. It has to be set to half the mill bit's width. When doing extra-passes, it is also used as the overlap.

I'm unhappy that the overlap and mill bit width are tied together. If you have a really big mill bit, you might want less than 50% overlap. So the overlaps and the mill bit size should be different, I think. I think that the overlap should be either a percentage or a distance. So I think that these options would replace offset:

  • mill-diameters: An ordered list of diameters of the milling bits. They need to be listed largest to smallest. The outputs will be generated so that all the milling will be correct if the bits are used in the order listed.
  • milling-overlap: If extra-passes is greater than 0, each pass will overlap the previous pass by this amount. It's either a distance or a percentage. If it's a distance, it has to be less than the diameter of the smallest bit. If it's a percentage, it has to be 0% to 100%.
  • isolation-width: This is a distance to clear around each trace. If should be 0 or more. The mill bits will be used in turn to clear out at least this much space around each trace.

It's an error to specify the above and offset at the same time. offset will keep working but it's deprecated. Using offset will be the same as setting mill-diameters to offset*2 and milling-overlap to 50%.

It's an error to specify isolation-width and extra-passes at the same time. extra-passes will keep working but it's deprecated. If extra-passes is specified, it'll be the same as setting isolation-width to be 'mill_bit_diameter+milling_overlap*extra_passes', which is consistent with what already exists.

@eyal0
Copy link
Contributor

eyal0 commented Feb 4, 2019

@AlexeyGusev Would you like to test out the latest code?

Try setting mill-diameters=3mm,1mm, for example. That will use a 3mm diameter mill around all the traces, but only where 3mm will fit. And it'll use a 1mm mill everywhere that the 3mm mill didn't fit. In cases where even the 1mm won't fit, it's going to try and go in there anyway, because it forces isolation on the final tool.

If you don't set extra-passes nor isolation-width, it'll just do a single pass for each. If you set either of those options then it might do extra passes for each milling bit to fit the size requested.

Finally, you can set the milling-overlap option to be either a percentage or a distance. That's how much overlap there will be for each pass. For example, if you set it to 50% then the 3mm bit will have extra-passes that are 1.5mm apart and the 1mm bit will have passes that are 0.75mm apart. But if you set it to 0.5mm, then the 3mm bit will have passes that are 2.5mm apart and the 1mm bit will have passes that are 0.5mm apart.

That's about it. I also made the SVG outputs look a little nicer so you might find those useful to see if pcb2gcode is doing a good job. Let me know how it goes!

@AlexeyGusev
Copy link
Author

AlexeyGusev commented Feb 10, 2019

I killed pcb2gcode (version f571ca5) after 3½ minutes of being stuck at «exporting front»:

$ pcb2gcode --front test-F.Cu.gbr --outline test-Edge.Cuts.gbr --drill test-PTH.drl 
Importing front side... DONE.
Importing back side... not specified.
Importing outline... DONE.
Processing input files... DONE.
Exporting front... ^C

I am sorry for not being able to debug this properly in debugger now, but here test2.zip are the gerbers that were fed to the program (and that worked well with my previous installed version fa57b8d)

@AlexeyGusev
Copy link
Author

essential millproject properties:

mill-diameters=1.5mm,1mm,0.8mm,0.6mm,0.1mm
milling-overlap=0.05mm           # overlap previous pass if extra-passes > 0 by this distance or %
#offset=0.1mm                    # Distance by which the tool movement will be outset from the contours 
extra-passes=14                  # Ignored when voronoi is in use

@eyal0
Copy link
Contributor

eyal0 commented Feb 11, 2019

Okay, I think that it took a long time because it was simply working very hard. The extra-passes were maybe too many. I have an idea of how to make it work better.

In the meanwhile, can you try fewer extra-passes? or better yet, just set "isolation-width=1.5mm" for example. I will try those options and look into other ideas, too.

@eyal0 eyal0 reopened this Feb 11, 2019
@eyal0
Copy link
Contributor

eyal0 commented Feb 11, 2019

I tried it with isolation-width=1.5mm and it finished running in 5.5 seconds on my laptop.

This is the 1.5mm mill:

image

This is the 1mm mill:

image

This is the 0.8mm mill (just little touch-ups):

image

This is 0.6mm (even smaller touch-ups):

image

This is 0.1mm, finally completing the isolation:

image

It will do all the outline with the biggest mill and eventually do the middle part with the smallest mill. You could probably get rid of all the other mills and just have the biggest one and the smallest one.

If you look at the SVG files generated called "processed_front_*.svg" you can see where the original traces area and also shaded region where the milling tool is expected to pass over and clear out material.

Right now it all makes a single ngc file that has tool change commands in it. I know that you didn't prefer that but it was hard to do it otherwise due to some of the autolevelling code: It's code that runs once before all milling on a side and it would need to run only with the first file and not the others. That was awkward to do.

If the change bit is really difficult for your setup, maybe just find the M6 command in the file and chop the file in two by yourself? Let me know how annoying this is and if it's really annoying then I can keep looking for a solution.

@AlexeyGusev
Copy link
Author

Okay, I think that it took a long time because it was simply working very hard. The extra-passes were maybe too many

Yeah. With 2 extra passes it was instant, with 4 - quick hardly noticeable delay, with 6 - 8 seconds delay, with 8 - 26 seconds delay.

If the change bit is really difficult for your setup, maybe just find the M6 command in the file and chop the file in two by yourself? Let me know how annoying this is and if it's really annoying then I can keep looking for a solution.

It's doable but as you said, very annoying. It just kills usability, really, and introduces one extra post-processing step (have to write some text processing script for automation). But actually, how about introducing an extra parameter, like --split-files=true, and disable built-in autoleveller if this parameter is set?

@eyal0
Copy link
Contributor

eyal0 commented Feb 20, 2019

I'll think about the split-files solution.

Also, if you provide some inputs for me to test on that show pcb2gcode running too slow, I can try to see where the slowness is and improve performance.

@eyal0
Copy link
Contributor

eyal0 commented Feb 20, 2019

Like, example with gerber files and also command-line or millproject file.

@AlexeyGusev
Copy link
Author

Also, if you provide some inputs for me to test on that show pcb2gcode running too slow, I can try to see where the slowness is and improve performance.

I already did so, here

@eyal0
Copy link
Contributor

eyal0 commented Feb 22, 2019

I did some speed improvements by making --path-finding-limit 0 by default. Can you try again and see if it is fast enough for you?

@AlexeyGusev
Copy link
Author

version 096f2f7
Essential millproject parameters:

mill-diameters=1.5mm,1mm,0.8mm,0.6mm,0.1mm
milling-overlap=0.05mm          
extra-passes=12                  

With --path-finding-limit 0, it finishes successfully in 1 minute 44 seconds but throws this output:

Exporting front...  CONFLICT 
 CONFLICT 
 CONFLICT 
// repeated 694 times
DONE. (Height: 14.922mm Width: 17.97mm)

Without --path-finding-limit 0, pcb2gcode runs 1 minute 41 seconds and throws no CONFLICTs to stdout. Output files with and without --path-finding-limit 0 are exactly the same.

With --path-finding-limit 5 pcb2gcode runs 2 minutes 16 seconds and generates the same g-code as previous two. No CONFLICTs in output. Not sure I understand the purpose of --path-finding-limit parameter and how it affects g-code generation.

By the way, take a look at this screenshot of generated g-code visualization. These multi-passes are using 0.1mm tool:
2019-02-28 09-58-43
Is 0.6mm tool too big to be used instead? I think pcb2gcode creates a ~0.4mm isolation trace here, but I am not sure.

And finally, with mill-diameters=0.1mm in millproject file and without --path-finding-limit 0 specified on command line, pcb2gcode runs instantly and generates a lot of passes.

It takes 3 minutes 40 seconds to run with extra-passes=14. That's a lot, but with proper selection of tools such use case can be eliminated. So it is quite slow if you have only very small and very big tool defined but need different isolation widths that can be accomplished with many passes of a small tool. If you have more or less equal distribution of tool sizes, you can achieve needed result somewhat quickly - I was able to generate the same g-code by reducing extra-passes from 12 to 4 (because when more than 4 passes were needed for the smallest tool, bigger tool was used) and got time reduction from ~1m40secs to 2 seconds.

@AlexeyGusev
Copy link
Author

Also, here is a shell script to split g-code file into sections, one file per tool, for those who need to run Z-probe manually (like me). More like a temporary hack, until this functionality appears in pcb2gcode. If you want, put it into your code distribution.

@eyal0
Copy link
Contributor

eyal0 commented Mar 4, 2019

That's strange to me that it's so slow. My laptop is pretty modern but not like, amazing, and I'm running your example in just 3 seconds.

How long does it take you to run ./integration_tests.py or the example in the testing/gerbv_example directory? The integration test takes under 30 seconds for all 50+ tests. Try going into one of those directories and running pcb2gcode to compare speed.

I made path finding off by default. It was an algorithm that I added to join milling paths where possible. There were situations where the milling tool goes up, moves over, and then goes back down to continue milling. It can be often faster to just mill between the two points instead of going up and down so that what it does. But you can't just mill between the two points because sometimes there are traces in the way, so it has to search to go around them. The path-finding-limit is how much effort to put into it. For cases like yours, 0 is probably best because it'll take way too long with more.

The only other thing that I can think of is maybe boost 1.62 is broken? It's happened before that some versions are just not working well. Try installing 1.66? Here are the steps that I use to build boost in the continuous integration tests: https://github.com/pcb2gcode/pcb2gcode/blob/master/.travis.yml#L77

hannesweisbach added a commit to hannesweisbach/pcb2gcode that referenced this issue Sep 23, 2020
In pcb2gcode#236 the following script is proposed to split the mill files into one for each tool (cutter diameter):
https://github.com/pcb2gcode/pcb2gcode/files/2914413/split-gcode.txt

This script does not work as-is for drill files to split them into individual files for differently sized drills. The reason is that tool size messages are formatted differently, for example:
```(MSG, Change tool bit to drill size 0.4 mm)```
vs:
```(MSG, Change tool bit to mill diameter 1.20000mm)```

Notice the additional space in the drill tool change message.

This patch removes the space between diameter and unit for drill size output, making the script usable for both drill and mill files.
eyal0 pushed a commit to hannesweisbach/pcb2gcode that referenced this issue Oct 9, 2020
In pcb2gcode#236 the following script is proposed to split the mill files into one for each tool (cutter diameter):
https://github.com/pcb2gcode/pcb2gcode/files/2914413/split-gcode.txt

This script does not work as-is for drill files to split them into individual files for differently sized drills. The reason is that tool size messages are formatted differently, for example:
```(MSG, Change tool bit to drill size 0.4 mm)```
vs:
```(MSG, Change tool bit to mill diameter 1.20000mm)```

Notice the additional space in the drill tool change message.

This patch removes the space between diameter and unit for drill size output, making the script usable for both drill and mill files.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants