Monday, November 18, 2013

Halloween Milling

A few years ago I bought a cheap CNC mill from China. It's actually a "CNC engraving machine", but it's actually robust enough so that it can mill wood and soft metals such as aluminum. Ḯ've been using it to build electronics prototypes, both for milling PCBs and for milling enclosures.

To control the CNC mill I have been using LinuxCNC (formerly known as EMC2). LinuxCNC takes a toolpath written in G-code which says how the milling tool should move, and translates those into the electronic signals that drive the motors on the mill.

For PCB milling I've been using a tool called pcb2gcode which takes gerber files produced by a PCB CAD program such as Eagle and produces G-code. It works really well and makes it possible to quickly testing simple electronic designs.



For enclosures I have mostly been bying ready-made enclosures and then written a bit of G-code by hand to mill holes in them. I've also been milling wood and plastics for simple stuff such as this lid.



Writinga G-code by hand is a very tedious job, anything more complicated than a few holes requires a lot of work. There are a lot of tools and meta-languages for generating G-code from other languages. I wrote my own little Python library for generating G-code and it turns out that the Axis GUI for LinuxCNC can actually load and run Python programs and execute the G-codes that are printed by the program. But even with all these tools or meta-languages it's still quite tedious to generate the toolpaths by hand.

It would be even nicer if there was a way to create a 3D model in a tool such as OpenSCAD or Blender and then magically let a tool generate G-code, a toolpath which tells the mill how the tool should move to create a physical object which looks like the model. Most 3D modeling tools can export to a standardised interchange format called STL and there are lots of tools which can read STL and generate toolpaths.

Most of these tools are proprietary though and the cost ranges from expensive to insanely expensive. Most of them only run on Windows and I prefer to use Linux and anyway I like open source, so I would prefer to use an open source toolpath generator if possible. There are a bunch of those, but most are at the "alpha" level and nowhere close to being usable. The most mature open source toolpath generator I have found is PyCAM. Unfortunately PyCAM and I don't really get along, I don't like the toolpaths it generates and last time I tried, it was really, really slow. My guess is that one for PyCAM being so slow is that it tries to be very generic and handle models and milling tools of almost any shape. Algorithms to calculate a toolpath for an abitrary 3D shape around an arbitrary 3D model are complex and expensive.

For a long time there have been this thoght at the back of my head that "there must be an easier way". For almost everything I want to mill, I'm going to use a cylindrical tool. With a cylindrical milling tool, the toolpath generation problem is reduced to 2.5D, that is, for each position X and Y the tool is allowed to reach a certain depth Z. This 2.D problem ought to be a lot easier to solve than the generic 3D problem.

A fairly simple strategy of milling 2.5D shapes would be to slice up the 3D model into 2D layers. The algorithm would then start from the top, and remove material for each 2D layer until there is no more material to remove. This is called waterline machining. It might not be the fastest way to things, but it should be fairly foolproof.

For removing material there are lots of ways to do it. The simplest way is to just move back and forth in a zig-zag pattern. But there are much better ways to do it, to reduce the wear on the milling tool it's preferable to keep a constant load on the tool, i.e. cut with the same side of the tool at the same depth and at the same speed all the time. The most important thing is to avoid is rapid load changes such as cutting 90 degrees into a wal. This article att BobCAD-CAM shows some of the toolpah options that used. Option 3, the High Speed Machining (HSM) toolpath, is the best since it avoids any sharp corners and each cut is very smooth.

I have been toying with algorithms like these for a few years but have never gotten anywhere. But a few weeks ago just before Halloween I tried a slightly different approach. The goal was to find an algorithm which would remove material from a 2D outline and do it using the same side of the tool to perform all cuts and which would try to keep the cuts at a constant width.

What I did was to split the toolpath generation into four steps.

1. Take the model and shrink it by the milling tool radius. This way the algorithm can ignore the tool with for the rest of the calculations, instead it only have think about where the tool can move.

2. Find the center of largest circle that can be inscribed in the model. To do this just shrink the model until there is nothing left and use the center of the last polygon as the starting point.

3. Start cutting a spiral from the starting point outwards until the spiral intersects the outline. For each 360 degree turn the radius of the spiral grows by the cut width.

4. Cut away the rest of the material. Start by creating a polygon with the the material that has already been cut away, this will roughly be the convex hull of the spiral. Grow the polygon by the cut width and then clip it with the model. The difference between the polygon of already removed material and the grown and clipped polygon are a number of polygons with material that is possible to remove. Choose one of them, mill away the material, add the polygon of just removed material to the big polygon of removed material and start over again until there is no more material to remove.

I started out by using the Python port of the Clipper library to do the shrinking, growing and clipping but switched to Shapely after a while because I needed some function that wasn't available in Clipper. A function that I ended up not using in the end anyway, but by then I couldn't be bothered to switch back.

This actually turned out to work quite well. Because it was Halloween I decided to do a small test with a witch silhouette I found. I converted it by hand from SVG to a bunch of coordinates (and managed to flip the image horizontally and lose a few parts of the broom on the way).

The following video shows the algorithm running.


Since this seemed to work so well I quickly added some functions to generate G-code and then used LinuxCNC to run the G-code on the mill. And what do you know, it actually worked quite well.


The video is speeded up 10 times, in real life it took about 20 minutes to run.  The algorithm video and the actual milling video differ a bit in the cuts since I tweaked the algorithm slightly in between.

Of course this is just a quick proof of concept hack to see if the algorithm would work at fall, but it does look rather promising.

There are lots of things to do though to bang this into shape so that it is actually useful.

The algorithm makes a few mistakes where removes too much material at the same time. It really should try to find a way of smoothly moving into each cut.

The algorithm does not support multiple pockets or pockets with holes.

The algorithm only cuts one layer in 2D, to be useful for milling it needs to be extended to 2.5D.

Yet another pre alpha not even close to production ready piece of software for generating toolpaths. Probably not that interesting, but if anyone wants to see the source code, drop me a line.

Friday, November 15, 2013

Lifehacking

I'm a nerd, I find technology fascinating. In my career I've done just about everything with computers, from being a system administrator changing disk packs for backups to writing J2EE code or designing and building simple electronics. And just about everywhere I've seen fascinating stuff that I would like to learn more about and have had ideas about interesting things that I'd like to try out. But over the last few years I have been working full time or more and really have not had the time nor energy to do that.

So I've decided to make a bit of an experiment with my life. A few months ago one of the customer projects I was working on was coming to an end, and instead of getting a new full time contract I decided to try to work part time, one week at a customer and then one week on my own. That didn't work out too well, as soon as some former colleagues heard I was free they convinced me to work on another customer project, so I ended up working full time again. Oops. Anyway, now that project has ended, so it's time to try again.

So what am I going to do with this week on my own?

Well, one thing I'll do is to try to spread the word that I'm available for hire if anyone has any interesting problems they want solved. I like really hard troubleshooting under time pressure, a "mission impossible" in the borderland between hardware and software, for example where a customer has a problem with a device driver or new piece of hardware that just won't work reliably and the deadline is approaching rapidly. I've actually had some success in solving a few problems like this where the customer didn't know if it was a problem with the hardware or the software and was running out of ideas.
“In the fields of observation luck favors only the prepared mind.“ – Louis Pasteur
I don't always succeed, but somehow I'm quite often "lucky" and usually manage to solve the problem or at least identify the cause.

But I probably can't count on getting these kinds of jobs all the time, so I'll probably have a lot of free time on my hands. I'll try to dig up some of my old ideas and see if I can do something with them. Or maybe just spend some time writing about them on my blog and see if someone else might get inspired and do something.

One such idea I've had since Google Reader was shut down is to write my own feed reader. And when I finally did get around to it, it didn't take much more than a week to actually write something that worked. The result is Weader, a simple atom/rss feed reader for Android. This was all about scratching an itch, I didn't like any of the existing feed readers out there, so I wrote one that works the way I wanted. And it also means that I got up to speed with writing Android applications, something that I've been meaning to do for a long time.

I'll probably run out of money long before I run out of ideas, so my plan is to try this out for a few months, after that I'll probably have to go back to working full time, but who knows, it might work out. And if anyone has any interesting problems that need solving and want to hire me, drop me a line. My rates are negotiable.