Freesteel Blog » Machining

Thursday, June 26th, 2014 at 4:52 pm - - Adaptive

Just some notes on the serious work that’s still going on. This whole thing was supposed to take a couple of months. It’s run 6 months beyond the time I expected it to already because I had no idea how hard it would be. But this shouldn’t matter in the long-run as the code will probably be in service for 60 years if it works.

At the moment Adaptive Clearing doesn’t do any fancy links. If it can’t go nearly directly through the partially cleared pocket, it rolls off and does a retract to a roll-on to the next starting point. This doesn’t look great. Also, when we re-order the passes for better efficiency, we shred all the links that are any good and need another way of recreating them.

I’ve been meaning to write up something about how we re-order the passes for a year, because it’s a really simple trick. It’s unfortunate that it exposes this re-linking problem, so you don’t get the benefit.

I’ve disabled all the smoothing features that were getting in the way. The first priority is to make a path from the start to the end that avoids the uncut stock using the A-star algorithm which operates within the model of the area. This is how it currently looks:
engagementfulllink

We’re going to get lots of questions about how it passes on the “wrong” side of the previously cut path. The diagram below should explain why it is correct.
engagementcutwrong

The real problem is that my linking path is going round the wrong side of the roll-off arc. It then has to back-track to find its way to its linking destination. Note how it zig-zags through the cells because re-smoothing is disabled.
engagementlinksarc

The problem is that the cutting cycle skips out sections when there is almost nothing left to cut. But my re-linking motions spots this material and tries to avoid it. Since there’s not enough room to get round the arc on one side, it goes round the wrong way.
engagementlinks

This small diagram shows how there is a lot less material there than it seems.
engagementcutshort

But still, it’s non-zero, and I don’t want to include a tolerance here. So I’m going to try and barge through the start of the linking motion and splice it in some way. Not sure how to code it yet. Things keep growing more and more layers of unexpected complexity. That’s how it goes.

Monday, May 12th, 2014 at 7:32 pm - - Machining 1 Comment »

Most CADCAM systems have about half a dozen 2D polygon offsetting algorithms somewhere about inside them. None of them work very well because the trickiness of the problem is notoriously easy to underestimate. The naive method is to offset each line segment perpendicularly sideways and then insert an arc where the angle between two adjacent lines is convex, or otherwise trim them back when the angle is concave, like so:

This seems attractive because it’s going to work whenever the offset distance is very small. Once you offset further than half the minimum distance between any two vertices, then you start to get multiple self-intersections, some of which involve intersections with the inserted arcs. A little bit of thought and you’ll see that this quickly enters a quagmire and you’ll be debugging it for the next 20 years. This is not an exaggeration.

An alternative method is to use Voronoi diagrams. These are great if you want to offset the same polygon by numerous different values, for example if you are producing some offset area clearing passes. The API into such algorithms (if you’ve got one) is daunting, and it’s going to be very time-consuming to add features such as allowing offset to be on only one side.

When all else fails, there’s my machining method, where we repurpose one of the waterline machining algorithms to give the answer that we want. Here we imagine converting the contour we would like to offset into a vertical wall of rectangles, and then we run a flat-bottomed cutter against it. My weave sub-sampling waterline algorithm delivers the structure shown in cyan with a contour going all the way round it on both sides.

Now the trick is to break the contour so it gives only the right hand side (the yellow curve). We have filters for tracing out partial waterline contours based on the contact angle with the tool-tip — for example producing z-constant toolpaths only where the tool is in contact with the surface at greater than 75degrees so they only appear on the walls.

So we could fake this by tilting the vertical wall to one side so that on the upper side the tool tip makes contact with a slope at an angle of less than 75degrees, and on the undercut side the tool shaft hits the top edge giving an effective slope of 90degrees.
But this gets messy. It’s better to add in a special toolpath filtering case that simply works for this application and sets the flags to filter out the toolpath when the contact direction either on the left hand side of the contour, or in contact with one of the end-points of the contour if the contour is not closed.

The disadvantage of this method is that your offset contour is made up of hundreds of little line segments that only approximate the offset with regards to the endpoints of straight sections and linearizations of the arcs. But does this matter? Graphically it looks exactly the same. It might be good enough — especially if we don’t have to debug it for the next 20 years.

If I was starting this fresh and not trying to get it done in a day, I could encode which line segment or vertex each point of the offset shape was offset from, and then try to rejoin sequences of segments into the same line or arc where they came from the same entity. Then, after that, for segments that jump the gap between a offset point from entity A to a offset point from entity B, I’d extend the two offset passes to the true intersection between A and B. This would be robust almost all the time. And it would be fail-safe because wherever there was a problem it would fall back to the approximate offset — which is almost always going to be better than crashing or giving a properly screwed up result.

Saturday, April 26th, 2014 at 7:50 am - - Machining 2 Comments »

A mere 9 years after we first tried to use our own mini-machine tool — which Martin wants to make sure everyone understands he did get working (shortly before it broke) — it’s been brought out of the cupboard and fitted with some proper electronics in the form of an Arduino controller by the DoESLiverpool Italian intern, and is showing signs of life.


The part of this kit that gave me the most surprise was the GRBL G-code parser code that ran on the Arduino. Look at the amount of software crammed onto that thing! Watch out Hurco and Heidenhain, your days are numbered. Soon all your industrial equipment will be deader than a Vax VMS.

My favourite function in the GRBL code is report_realtime_status() which prints a line of the form

<idle WPos:10.999,-0.5,9.1>

Yes, it’s the current position of the tool while it is running.

I immediately wrote a threading Python program to drip tool motions into the Arduino interspersed with the “?” command to invoke this realtime status to find out where the position currently had got to. Eventually this could become the principle behind a combined probing, cutting and dynamically feed-backing CAM system — something that cannot be implemented on industrial machines today due to their batch-work nature and one-way post-processing valve filter. For more, see earlier post on the feedback in the cnc drive configuration.

While writing an internal rant about why it’s okay to machine triangles, when some CAM systems claim to be “more accurate” because they locate their cutter positions against the analytic geometric surfaces themselves, I came to an important observation: the point nodes of the toolpath as defined in the G-code file are of no significance to the total cutting process, which continues along the straight lines between the nodes. All these cutting positions on the lines between are never on the accurate surface, so getting the zero dimensional finite set of node positions exactly right doesn’t make a difference.

Wednesday, March 26th, 2014 at 12:29 pm - - Machining

Trying to get this surface triangulation distraction closed down today. The proposition was to see whether I could repurpose my toolpath strategy code and apply it to the problem of triangulating trimmed NURBS surfaces. After all, trimmed NURBS surfaces exist on a 2D parametric domain (like the 3-axis drive plane), and the trimming curve is very much like a machining boundary. You have to know that something like the constant scallop routine is actually modelling a surface that is repeatedly being eroded away, because the toolpaths you see are in fact the boundary outline of that surface.

One of the common triangulation results I kept getting looks like a nice Afghan carpet pattern, like this:

triangulationcarpet

I have an explanation. This happens when maxHdiffFibre is too small.

The surface is divided up into cells, and the sides of each cell has at least length/maxHdiffFibre extra points inserted along them. The convex polygonal area of each cell is then triangulated by lopping off the sharpest corners repeatedly, until you have an 8-sided shape that still has points along the top and bottom sides because they were the longest to begin with, so these are joined up. The outer boundary is the trimming curve, so one side of over-sampled cell is trimmed away leaving three sides that have too many points which need to be joined up in the best way they can. Then, at the corners of the trimming curve, the cells are subdivided to get smaller and smaller complete rectangular cells which are small enough not to be over-sampled.

I don’t think anyone else in the world misuses a 3-axis toolpath algorithm to make a triangulated surface, so this type of buggy behavior is unique.

Meanwhile, a correspondent of the blog took up the challenge of making an excellent triangulation of a cone. He did this by starting with the triangular lattice with rotational symmetry of order 6, and then cutting a pie slice out of it in order to join it together to form a cone. Because he didn’t have the power of Twistcodewiki to draw 3D geometry direct from Python in your browser, he implemented the picture of all the edges by exporting Postscript commands, and didn’t have the capability of drawing the triangles themselves in order to see the folds:

triconesurf

Twistcodewiki is great. I use it all the time, even though its light/shading features are crude and terrible, and the interface is almost non-existent. But the one thing it does is so important and unique that I can ignore the fact that it doesn’t do it very well. The same probably goes for a lot of software out there.

Tuesday, March 18th, 2014 at 1:54 pm - - Machining

I hadn’t worked on triangulating surfaces since the first version of machining strategist in 1994, but always thought I could do it better by distributing the triangles in a nice enough manners. It is true that the people who write surface triangulators in engineering CAD packages don’t in general try very hard, but I don’t think many folks realize that there is no right answer.

Suppose we have a smooth surface S, defined by a function from a subset of the plane to real space

  f: D ------> R3, where D is a subset of R2 
                  representing the set of points within a boundary B defined by:
  b: [0,1] ------> R2 where b(0) = b(1)

… roughly speaking.

We want to approximate this surface to the tolerance e with a set of connected triangles defined by triplets of points in R3-space:
T = { (p0, p1, p2) }

It would be nice if it had the following properties:

(more…)

Thursday, March 13th, 2014 at 7:41 pm - - Machining

The days and weeks are passing me by. I’ve got to stop doing this programming and get with something I’m interested in. I don’t think I’ve been outside of Liverpool since January.

Due to a surface triangulation crisis (the speed of machining operations being four times faster than the initial time it takes the CAD kernel to produce the triangles it needs to start work), I spent the last 10 days hacking up a trimmed NURBS surface triangulator and triangle flipper with Martin based on some of the machining algorithms. We pretend the trimming curves are machining boundaries and encode an XYZ point at each XY 3-axis sample point instead of just tool tip height.

relayfacets

The triangle flipping is a second component experiment I’d been meaning to try for a long time. Can you redistribute the triangles in a better way than simply along the UV parametric lines? Not sure I’ve got an answer yet, but it’s exhausting trying to find out. I’ll write it up later when I have the energy.

Meanwhile, in another part of the city, things are being built by real engineers. I’m looking forward to installing it in the office and making it work. Which is more than can be said about many of the programming projects I’ve put my hand to recently.

I’m also wasting time posting ideas onto the internal Autodesk idea database. Most are sinking like lead bricks into mud. It’s pearls before swine. The latest idea which everyone hates is to hold Simultaneous Satellite Tech Conferences in each region rather than wasting a shedload of carbon by flying all the techies to meet in a hotel in Canada for two days.

“Oh, but I find the in-person meetings are so important for building relationships,” they say. “This never happens with on-line meetings.”

No one seems to think that maybe it’s because on-line meetings generally last less than an hour, but when you travel half-way round the world to a meeting, the duration of the meeting is in practice like 20 to 40 hours long (with sleeping breaks).

Perhaps this extended time period is what’s important, eh?

I mean, look, if you teleported into your favourite tech conference for, let’s say, one hour and fifteen minutes before suddenly vanishing in a puff of smoke, you wouldn’t be able to build a lot of relationship experiences with the people there, would you? However, if you were trapped in an elevator for 10 hours, and all you had was your phone which you could use to call the person in stuck in the other shaft, you’d become friends for life with that individual.

It’s all in the mind. Use your imagination. A functioning virtual telepresence system should not involve booking the suite for an hour on a stupid meeting. Instead it should require being time-locked in a tank for 12 or 24 hours where the only communication line is routed via the office to which your business travel destination has been designated. You can phone home, but the phone call will literally need to be be directed into a physical acoustic coupler device in that office. You are there, with all the inconvenience of being stuck there, meaning that the place of least effort to communicate is there, and it will be rude and boring if the people in that office don’t pay attention and entertain you while you are stuck there. Maybe after the first six hours you will have dispensed with enough pleasantries and finally be talking about the things you need to be talking about, and building those bonds of friendship that take time to form. Glue and cement and gelatin all take time to set. Do you not think they same could be true for our frivolous minds?

Wednesday, February 26th, 2014 at 1:41 pm - - Adaptive 1 Comment »

Last year we got a chance to see SolidCAM’s iMachining and laughed at the way its progress bar jumped all over the place, from -14% to 200% and back again.

Then we looked at our own Adaptive Clearing strategy which we had just spent the past year making multicore — and noticed it did the same stupid thing!

How embarrassing.

You never notice yourself picking your own nose, but when someone else does it in your face, you realize it’s ugly.

Progress bars don’t get as much love and attention from the programmers as they ought to, given how much time the users have to stare at them. The users think it’s so normal for the progress bar to be absolutely wrong that it’s considered a sign of extreme naivety to think about complaining. They probably believe that we’d going to laugh at them if they raised the issue.

It turns out that the progress bar on multiple CPU processing is not hard to get right, but you do it differently to how you do it on a single-threaded process.

Let’s first think about what a progress bar is for. There are two different options. It could report the time remaining for the process to complete, or it could report the percentage of the process job that has been completed.

The time remaining might be the most useful information for organizing your life (is there enough time to grab lunch while this completes?), but there’s no way you’re going to get that information — even though it’s what everyone wants to know.

You will hear: “How many days till it’s done?” more often than “Are we at the 75% complete stage yet?” for a project — and that’s even before it’s over-run by a factor of two.

In fact, the only practical implementation for the time remaining is to run the whole job first, time it, and then set a count-down timer from that value when you run it again. It’ll make everything run twice as slow, but what’s the big deal?

(more…)

Tuesday, February 11th, 2014 at 5:43 pm - - Adaptive

Taking a break from all my other mindful notions to do some proper work on this stay-down linking job.

I have an A-star function that works on the underlying weave structure. The white zones refer to the weave which defines the interior of the contour, and the red zones are the places where it’s safe to go without colliding with the uncut stock.

astart0area
Most A-star algorithms involve one start point in each tile which spreads out to all sides of the tile. But in my implementation the paths from the sides of the tile are pulled from the receiving end, so it’s possible to have two start points in the same tile with two paths going through, as shown above.

(more…)

Friday, January 24th, 2014 at 6:07 pm - - Adaptive

Sometimes it’s a relief to be certain that I’m doing something which is exactly what I am paid to do. All the rest of the mouthing off comes for free. Though maybe it’s important to always question what you are paid to do, so you don’t wind up wasting everyone’s time doing something that’s actually pointless.

After having got the A* routing through the weave structure to work based on my unpatented subdividing model of a 2D area that forms the geometric basis of the adaptive clearing non-gouging motion algorithm, I noticed that it did not give enough sample points for a linking pass to be within tolerance. The route, which must avoid uncut stock, requires a greater sample rate than the basic weave cells. These cells were sampled to a resolution along the boundary contour so that it would be within tolerance, but it is insufficient to handle the uncut stock structures that exist in the interior space of this area partway through the clearing cycle.

There are two options to deal with this insufficiency of sampling. Either add in an additional sample rate system, or improve the basic underlying weave sampling structure.

(more…)

Tuesday, January 14th, 2014 at 6:47 pm - - Adaptive

A quick day’s work to make a multi-threading percentage progress handling object in Python that handles residuals.

Let’s start with the test code (which I wrote after the working code — take that TDD!):

class ACProgress:
    def __init__(self):
        self.sumprogress = 0
    def ReportProgress(self, lprogress):
        self.sumprogress += lprogress
        print "The progress is at:", (self.sumprogress *100), "percent"

def addprogress(a, n):
    for i in range(n):
        acprogress.ReportProgress(a/n)
        time.sleep(0.05)

acprogress = ACProgress()
addprogress(1.0, 25)

This prints numbers up to 100% in steps of 4%.

Now we want to do this in threads.

(more…)