HeeksCNC can be finicky about profiles. Often I've found that a sketch which should be easily profiled won't generate any gcode at all. When I look in the console, I find an error like this
File "/usr/lib/heekscnc/kurve_funcs.py", line 247, in profileraise Exception, "couldn't offset kurve " + str(offset_curve)Exception: couldn't offset kurve <area.Curve object at 0xb6f4bf2c>
My interests in CNC and machining developed over a period of years in a very organic way. I have no formal training in either engineering or manufacturing --my interests were born out of necessity. Learning that way is great if you have the time and patience. Sometimes, however, it's just frustrating. You find yourself struggling with something that should be easy and only later find out that all kinds of people have the same issue and either they know how to work around it or perhaps they just feel each other's pain. But you, the loner, are left banging your head against the wall feeling like an idiot.
Meet the Spider
This post is about a perennial problem that I've faced in lots of CNC projects. It's something newbies like me are going to see eventually so this post is for you. I don't know if this problem has a name so I call it the 'spider problem'. If you know anything about this or how other CAM packages address it, leave a comment.
The first time I saw it was when I was playing with the HeeksCNC zigzag operation. To mill the spider, a lot of material needs to be removed but there are some areas that are very small and require a small cutter to reach. And there lies the problem. If you use a big cutter to go fast, you can't get into all the nooks and crannies like the space between the legs. You end up with a tool path that looks like this:
If you choose a small cutter that can get in there, your step over and step-down values have to be small. The run-time on the job is going to be excessively long - really REALLY long.
Roughing and Finishing
The intuitive solution is to rough the spider out with the big cutter, then do a finishing pass with the small cutter. With a model that doesn't have all those tight corners, this works great. It's exactly the technique I used on this pinewood derby car.
But it doesn't work here. Finishing assumes that the roughing phase has left a small, roughly uniform amount of material all over the model. The finish pass doesn't limit step-down because it doesn't have to. Ideally you're already within one step-down distance of the model everywhere. Cutting our spider, we're within one-step-down everywhere except the small areas between the legs. There, the remaining material is 5, 10, or more step increments away -- we're still roughing in those areas.
Of course you can limit the step down value but now you're back to where you started. You're either spending a LOT of time milling air, or you're plunging your cutter and breaking it off.
The fundamental problem is that the CAM software doesn't know what material has been removed.
Manually controlling the boundaries.
The only other solution I've found, and one I use regularly, is to artificially limit the boundaries of the operation. This means creating some geometry -- a sketch -- to limit the work area of of a roughing operation. For instance, I could create a boundary sketch like this:
The resulting toolpath will focus on the problem areas. This works but it's a compromise. If the model is complicated with lots of small problem areas, it can be difficult or impossible to create the right kinds of boundaries. It's also manually intensive and, at least in my case, that means mistakes are likely.
Not just about 3D sculpting.
The example I've given might make it seem like this problem is only about milling 3D irregular models but it isn't. Imagine cutting a simple rectangular pocket. If the pocket is large, you'll want to use a big cutter to remove a lot of material but you'll have rounded corners with the radius of the cutter. If you use a small cutter to get in tighter, you'll either spend a lot of time milling or you'll have to add some artificial bounding geometry to keep your itty-bitty cutter working in the corner and not milling air that the big cutter already cleared. The problem is the same and the available solutions are the same too. All compromises.
What would a better solution look like?
A smarter CAM tool would remember where previous operations had sent the tool and avoid re-milling those areas in subsequent operations. The workflow I would like to see would look like this:
1) The user selects the model and creates a roughing operation, specifying the tool to use and the feeds and speeds. The boundaries of the model are used to determine the work envelope. The step-over and step-down could be suggested from the tool or overriden by the user.
2) The user selects the previous operation and creates a refinement operation. The user selects the tool, feeds,speeds, and step-overs just like above.
3) Optionally, additional refinements can be added with progressively smaller tools, each time, the refinement references the previous operation not the original model.
4) When the tool path is generated, the system first generates the roughing operation tool path. It then constructs a solid in memory using the bounds of the path - the area swept out be the tool. It performs a boolean operation comparing the new solid to the original model to see where material still remains to be cleared. The resulting area, or its perimeter at least, is used as the bounding box for the refinement operation.
5). The user selects the original model and adds a finishing operation, which works just like it does today.
I'm sure there's a lot I'm missing in this approach -- maybe even some legitimate reasons it won't work at all -- but I'm listening and willing to learn.
When I first started using HeeksCNC I was totally confused. It seemed overly complex. When I finally understood it, I realized what a great model it is. I still won't claim to be an expert but from my perspective it meets three really big objectives. One of these is compromised in every other solution I've seen:
1) It keeps the computationally intensive algorithms in C++ where they run fast. Other systems that are flexible and customizable are written in interpreted languages and that means they're slow for computationally intensive tasks. Generating a complex path can tax a processor and really needs to be fast.
2) It provides a scriptable interface in a friendly language (Python). No matter how good the developer was, there's no way he can anticipate every need. That's why we like applications like blender, inkscape, gimp, and FreeCAD. These apps assume that the user may want to extend the application. Making the tool path generation accessible through a scripting language unleashes a lot of power.
3) It allows customization for the machine specific output without recompiling. This is the Post-processor. Not all machines are created equal. Different capabilities and different controllers mean the final output must be tailored.
Dan Falck did a great write-up of how Python is used in HeeksCNC to generate tool paths using the C++ libraries. I hope a future CAM workbench for FreeCAD has a structure like this.
Machines in the real world vary greatly. They use different controllers, have different capabilities, and are customized for different uses. One of the most powerful features of HeeksCNC is the way in which the post-processor can be extended and customized to produce exactly the g-code your machine needs to do the job you want.
Note: The following article appeared in Digital Machinist Volume 5 No. 3 Fall 2010. HeeksCAD has continued to mature since then. The current user interface may vary significantly from the images below.
No Secrets: Open-source CAM application bares all.
In the opening scene of the 1981 movie Raiders of the Lost Ark, explorers come upon an idol hidden in the jungle. Weaker men flee, but the hero, undaunted, continues on to discover a treasure.
The first words on the HeeksCAD website are a little like that: “HeeksCAD is not finished, yet. “ Those who make it past this warning, will face challenges but are ultimately rewarded with a prize: HeeksCAD and it's CAM plug-in HeeksCNC are quite usable – and powerful- even in their unfinished condition.
Here's my first attempt at using HeeksCNC to generate g-code for my makerbot. I wanted to print a part with a screen. That should be a pretty easy part, but since skeinforge wants to slice a .stl, it turns out hand coding it is easier. Enter HeeksCNC. I used the pocketing operation with a custom post-processor to do the work. This is a very limited application, but it shows the promise of using HeeksCNC operations.
When I made the arrow of light awards, each one took about 45 minutes to cut on the CNC router. That was o.k. since it was a one-off (actually nine-off) project. Since then, I've had some more requests for them so I'm looking into whether I can get the machine time and cost low enough to make it worth while.
The reason they took so long to cut was because I had to use a router bit that could plunge into the material. HeeksCNC doesn't have a feature (yet) to do ramp or helical entry and plunge is the only option. Router bits that can plunge tend to be narrow so I was using a 1/4" spiral cutter.
To try to speed things up, I'd like to use a 3/4" cutter and hand-code a ramped entry. Talking with DanielFalck on the #cam IRC channel, he showed me how to edit the area_funcs.py file to do this. The first part of the file contains a function to lower the tool into the material for each pocketing pass. The routine moves the tool into place at X,Y and then moves it down to X,Y,Z before proceeding. His approach was to change the routine to move to X-(some amount),Y and then descend to X,Y,Z. By my figuring, 'some amount' is at least the radius of the tool.
The first image is the regular tool path generated by libarea. The second is with the modified code. Cool.
This works o.k. as long as the pocket isn't too small or the cutter too big. If so, X-some-amount may push the starting location back into the part. In that case you get some 'clipping' of the corner. That's what I've got. You can see the clipped edges in the pocket at the lower right. This approach might work if I could manually specify the entry point for the pocket.
The Arrow of Light is the highest rank achieved in the BSA Cub Scout Program. It's usually earned by boys in the 5th grade. Our pack had 9 boys earn the award this year. Most of them went ahead and crossed over to the troop to become Boy Scouts.
It's tradition to award a "career arrow" to signify the accomplishment. Sometimes the arrows are put on a wood plaque or are decorated in another way. I did a lot of hunting but never found a design I really liked so I took a bunch of ideas and merged what I liked from each. The final plaque was cut from 1 inch red oak and finished with a mahogany stain. The arrows were 5/16" pine dowel striped and stained to look primitive and then fletched and pointed. The fletching is a cherokee two feather style. The points are reproductions. I found a great deal on ebay. The overall plaque and arrow design mimics the Arrow of light insignia, shown above. I've been told the design is based on a petroglyph in the painted desert national park. Here's my earlier posts on this project. Click the pictures for a larger version.
The last CNC operation we need to do is drilling. The arrows will be mounted in the large pocket and will be epoxied to two posts. The posts will be glued into holes drilled into the plaque. I drew two circles in HeeksCNC to represent where I wanted the holes drilled. Then I selected the holes and added a drilling operation. The parameters are all pretty straight forward.
To hang the plaques, I'm going to cut a keyhole on the back. This is done with a keyhole cutter.
The cutting process works like this:
- The cutter does rapid movement to position itself over the hole location
- It plunges into the material to the desired depth.
- It moves forward toward the top of the plaque to create the keyway.
- It stops and moves back to the hole.
- It rapids upward clear of the stock.
HeeksCNC doesn't have an operation like this but it's fairly simple to accomplish anyway.
I started by adding a sketch with a single line segment to represent the key way. I selected the sketch and added a profile operation. I set the parameters so the cutter would cut 'on' the line and at the depth I needed for the bottom of the hole (-9 mm). In the resulting path, steps 1, 2, and 3 are represented, but then the cutter moves up to clear.
All we need to do is hand edit the g-code to add rapid back to the previous location before ascending.
G17(Select XY Plane)
G54(Select Relative Coordinate System)
(tool change to 1/4" carbide 2 flute endmill)
G01Z-9.000F593.970 (descend into the material)
G01X165.048Y304.802F500.000 (forward cut)
G00Z5.000 (retract out)
All we need to do is add this line before the retract:
Now the backplot (shown in emc2) looks like this: