Freesteel Blog » Unit testing CAM algorithms – what could that be about?

Unit testing CAM algorithms – what could that be about?

Friday, November 18th, 2011 at 6:12 pm Written by:

While trying to kick-start my engagement with some CAM algorithms I am supposed to be doing stuff about, I decided to try some of these new-fangled unit test concepts people have been going on about.

(Normally I object to unit test people quite a lot because they come with the attitude that if the code is not completely pre-infested with unit tests from start to finish throughout the development process, then it cannot possibly be any good, and by implication the programmers who wrote it are stupid, ignorant and ugly. Nevertheless we can salvage something from the ideas, if we can be bothered.)

Much of my CAM algorithms are self-tested with the use of assertions, rather than unit tested. Partly because it’s easier, and partly because the example failure cases are so big it’s never the cases which you think about that are the problems. Usually I have a slow, simple algorithm running against a fast highly optimized algorithm and I make sure (in debug mode) that the two answers are the same.

Generally, running big CAM algorithms in an isolated test harness is tedious and tricky, so you normally compile it into the final product and test it there. However, lately I’ve decided that maybe I ought to be trying a bit harder to take it out of that environment. Especially as we do have our C++ algorithms driven through SWIG into Python, so there is no excuse whatsoever for not trying it out.

Almost none of it is documented properly. So here is an idea of the code needed to plot a series of slices of a torus against a line.

First build the “surface” object, add one line into it (in the form of a triangle with two points the same), and “close” the object with the Build function (I’ll explain this some other day).

import hsmkernel as kernel

fssurf = kernel.FsSurf.New()
fssurf.PushTriangle(0,0,0, 0,0,0, 0.4,0.1,1)

Now make a horizontal tool surface, which is an object that defines a tool shape in a particular Z-plane and references a surface

fshoriztoolsurf = kernel.FsHorizontalToolSurface.New()
fshoriztoolsurf.AddTipShape(0.4, 0.3, 0.5)   # (corner_radius, flat_radius, z)

Now make an implicit area, which is an object that defines a subset of the 2D plane and a set of tolerances to which the boundary contour of that subset will be computed. Such an object can reference more than one horizontal tool surface, making it possible to handle compound tools, such as you get when you have a protection surfaces or large tool holders that should limit the 2D area.

fsimplicitarea = kernel.FsImplicitArea.New(0)
fsimplicitarea.SetContourConditions(0.99, -1.0, 0.002, 2, -1.0, 0.9)
    # (minCNdotContour, maxZdiffContour, deltaHdiffContour, maxHdiffContour, maxCPcuspContour, minBNdotContour) 

Those contour conditions (boundary tolerance values) don’t really belong here, but they have to get into the algorithm somewhere, and it doesn’t matter where. (At least that’s what I tell myself to overcome the sense that I have made a design mistake here.) These values are things like maximum segment length (maxHdiffContour), minimum segment length (deltaHdiffContour), maximum change in angle between two segments (cosine of value is minCNdotContour), and so on.

Now we build the structure which will model the subset of the 2D plane:

fsweave = kernel.FsWeave.New()
fsweave.SetShape(-5, 5, -5, 5, 0.17) # (xlo, xhi, ylo, yhi, approx_resolution)

Now, the contour created by the interference set of a near vertical line and a small torus (total diameter 1.4) moving in a horizontal plane is going to be something approximating a circle.

The numbers add up, because you can see it’s approximately 8.5 major cells across (about 0.17mm wide each) and it fits with the total diameter of the torus.

You can also see some subdividing of the contour to maintain an angle change between subsequent segments of less than acos(0.99), or approximately 8 degrees.

If I was a bit more rigourous with my inputs, I could be comparing this contour with the near ellipse shape I would expect the answer to be in order to unit test my torus-line slicing algorithm.

In the image below I have created 50 slices at various z-heights and plotted the normals in green so you can see the blob shape defining a sort of 3D volume made from all the slices together.

I’m wondering whether the DLL and python bindings which allow the above algorithms to be scripted would be a more worthwhile thing for people to use than our slice.exe application. This would require people to know Python, though. Unfortunately, most Python programmers are doing web things and not doing CADCAM.


  • 1. anders replies at 19th November 2011, 9:51 pm :

    The hackers who are likely to make any use of offset-ellipse or other push-cutter code, and/or waterline-toolpaths are mostly on Linux (and a majority possibly on Ubuntu). So a shared library (32 or 64 bit?) with python-bindings for Linux could maybe see some use.

    There seems to be a lot of activity around FreeCAD these days. And it has python scripting capability (get geometry in/out of the App/UI through python).

    I don’t think I ever fully understood your Weave approach. In your first image it looks very much like a quadtree? I am assuming this is a data structure for building a waterline-toolpath while calling the low-level push-cutter function? right?
    The push-cutter pushes a cutter along the X- or Y-axis into contact with a triangle, and returns the x/y-coordinate of the contact(s) ? right?

    Everyone knows the cylinder, ball, and cone shape are easy so you are focusing on the toroid. Contacting the vertices of the triangle, as well as the facet (plane containing triangle) is trivial, so again we focus on the hard case which is edge-contacts? right?

    Some context around your posts might help the casual reader 🙂

    Would you be interested in an open-source cutting simulation? I have done some work with an octree-model:

    keep up the good work!

  • 2. JT replies at 20th November 2011, 11:13 am :


Leave a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <blockquote cite=""> <code> <em> <strong>