Design for Manufacturability.

While playing with the mini-lathe, mini-mill and 3d printer, I came across an interesting concept called design for manufacturability.

The essence of the problem is this: it’s not enough to design a thing: a computer, a hammer, a pencil, a power drill. You also need to design the object so that it can be manufactured: so that it can be moulded, milled, and assembled in an efficient way.

Here’s the thing: with every process used to make a thing, there are limits on the shape, size, and materials that are used in that manufacturing process. For example, consider plastic injected moulding. Typically two mold halves are pressed together, plastic is injected into the mold, the material cools, and the halves are separated and the molded part is pushed out.

Well, there are a couple of limits on what you can create using plastic injected molding. For example, you must use plastic. You also must design the part in such a way so that the part can slide out of the mold. This means the part must be, in a sense, pyramidal shape: when the half pulls apart it should pull in a way so that the surface doesn’t slide along an edge. It also means the part has to push out: holes must be parallel to the direction the mold halves pull apart.

There are other design limits on plastic injected molding. For example, element sizes cannot be too small or too thin; otherwise, the mold may not fully fill or the part may pull apart as the mold halves are separated.

There are limits on other manufacturing processes as well. 3D printing cannot print elements suspended in space; they must be “self-supporting” as the part is “sliced”. CNC milling can only remove so much material at a single pass. Sand casting results in components that must be milled or polished.

And each manufacturing process takes time, effort and equipment. So minimizing the number of manufacturing steps and components that must be assembled helps reduce costs and reduce material required to manufacture a thing.


This is quite a complex field and I cannot pretend to begin to understand it. I do have some experience with embedded design, however, and part of embedded design is determining ways to create the software necessary for your product which reduces the total component count on a circuit board: if you can use an embedded processor with built-in I/O ports and fit your application in the memory of that embedded processor, your (essentially) 1 chip design will be far cheaper to manufacture than a design which relies on a separate microprocessor, EPROM chip, RAM chip and discrete decoders and A/D encoders, each of which requires a separate chip.


And this brings me to something which irritates the crap out of me regarding user interface design and the current way we approach designing mobile user interfaces.

Have you seen a project where there seems to be a dozen custom views for every view controller or activity? Where every single button is independently coded, and then there is a lot of work trying to unify the color scheme because every control is a slightly different shade of blue?

This is because the UI designers who worked on that project are thinking like artists rather than like designers. They are thinking in terms of how to make things look nice, rather than designing a unified design. They are thinking about adding new pages without considering the previous pages, and considering how to lay out elements without considering previous elements–other than in the artistic sense.

They are not designing for manufacturability.


There is far more to consider when designing the user interface of an application beyond simply making the application look pretty.

You must consider how people interact with machines, including the limitations of how we interact with computers, including the limits on our short term memory or our limitations on recognizing patterns.

You must consider the problem set that the application must resolve. If you’re building an accounting application, you must understand how accounting works–and that requires a much deeper level of understanding than a casual user may have balancing their checkbook. (Meaning if you’re building an accounting application, you may wish to talk to a CPA.)

You must consider how the application will be put together. As a UI designer you don’t need to know how to write code, but you do need to understand how objects get reused: if you intend to have a button which means “submit”, using the exact same button (same color, same frame, same label) means the developer can use the exact same code to create the submit button even though it shows up in several places. If you have a feature which requires the user to enter their location and that feature is used in a handful of places, you may consider having a separate screen which allows the user to select their location–and reuse that screen everywhere a location is called for.

And that means rethinking how you design applications beyond just creating a collection of screens.

That means considering a unified design for layout, for colors, fonts, buttons, and all the other major components of your application. That means thinking less like a page designer and more like a branding designer: creating unified rules covering everything from color to font choices to spacing of key elements which can then be reused as new screens are required. And it means sticking to these rules once developed, and communicating those rules to your developers so they can build the components out of which the application is built.

It means thinking like the designers of the Google Material Design, except on a smaller and more limited scope: thinking how your application looks as an assembly of various elements, each of which were separately designed and assembled according to the rules you create.

It means not thinking about an application as just a collection of screens, but as a collection of designed components.

Designed for manufacturability.

My itty bitty little vice for holding itty bitty little parts.

I have a mill now, but I have the problem that I need to hold itty bitty little parts still while I drill holes into the side. (Sort of like this but much smaller–about 1/4″ outer diameter, 2mm inner diameter.)

So I made myself an itty bitty little vice for holding itty bitty little parts.

IMG 3028

Drink coaster for size.

Turning on a metal lathe

So I bought a bunch of brass and aluminum to go along with my metal working lathe, and today I tried to turn a plumb bob.

And here’s what I learned.

Bob

(1) Make sure you have all the parts in the box. I took delivery of a 4 jawed chuck, only to find the screws were missing. (I went ahead and simply ordered the replacement screws; the theory being that at some point I’ll lose the existing screws anyway.)

(2) You can achieve some amazing precision on these lathes. Even a cheap lathe can cut objects to a tolerance of perhaps 0.001 inches. However, you get these precisions only with a lot of effort and thinking about how you are going to cut the part. For example, it doesn’t matter if you have tools that are accurate to 0.0001 inches, if the metal you’re cutting deflects 0.1 inches in the middle.

(3) It is impossible with three jawed chuck (or even a four jawed chuck) to flip the part and turn the length and have it all work out. (See the line in the middle of my picture above? That’s where I tried to flip the part.) Instead, you should minimize the number of times you remove the part from the chuck–and if that means turning the part down the entire length and then cutting the piece as a last step, there you go.

(4) You can, however, face the part after you cut it.

(5) I also learned I suck at cutting the part off. But I bought one of these metal cutting band saws, so it’s moot anyway.

(6) The amount of effort to cut a thread is just absurd. I think I want to put together a tool which can be used to mount the threading tools and turn them using the threading feature of the lathe. The other option is to develop more upper body strength.

(7) Brass is damned pretty.

(8) Also, the auto-feed lever is damned cool. When you think the cut is smooth, reset the cutting tool to the same depth and take another pass–and you find more material gets cut off. Wash, rinse and repeat 3 times and you get a nice finish.

I made a whole bunch of mistakes this morning, but I’m starting to appreciate both the capabilities and limitations of the lathe. I have a bunch of aluminimum stock on order from these guys so I can practice some more, and I also have a milling machine on order which I intend to practice with as well.

Ultimately my goal is to build a clock–but before I start building a clock I need to learn how to use the tools.

Evidence based data

I just saw an ad in my inbox which describes how your mouse is slowing you down, and you need to switch to using a text editor/IDE which can be completely driven by the keyboard.

And it bugged me.

It bugs me the same way all the other Shiny New Things bugs me, the way they bug Uncle Bob.

Further, it bugs me because we have some concrete evidence that this simply is not true. Meaning we have concrete evidence that (a) selecting a menu item is faster than typing a command, (b) finding a menu item is faster than using a keyboard shortcut if you haven’t committed that keyboard shortcut to muscle memory, (c) it takes a nontrivial amount of time and effort to learn the keyboard shortcut, which means that while common commands will be committed to muscle memory quickly (i.e., cut, copy and paste), less common commands are faster found on a properly structured hierarchical menu.

But no-one gives a fuck about evidence-based data anymore.

Because it gets in the way of The Churn.™

And it gets in the way of a thousand developers trying to make a name for themselves by positioning themselves as the inventor of The Next New Shiny Thing.


So do us a favor: if you design user interfaces or are thinking of The Next New Shiny Thing, get Designing With The Mind In Mind and understand how and why our brains work the way they do.

And stop treating your users like “lusers” or like Stockholm syndrom sufferers, so badly tortured by your poor design that they engage in traumatic bonding through an “ongoing cycle of abuse in which the intermittent reinforcement of reward and punishment creates powerful emotional bonds that are resistant to change.”

So at some point I decided I needed to set up a machine shop…

I’ve been making more and more things with the Form 2 printer, and I find making things quite addictive. I’ve worked some more on some gear design software for the Macintosh, and now I’m finding to make the thing I’d like to ultimately make, I need some odd-shaped parts that don’t quite fit in the printer or would be better made from other materials. (Simply buying 2mm by 100mm pins isn’t working out as well as I’d like, simply because sometimes I need different lengths or I need different shapes for the gears to properly rotate or to be properly moved or set.)

I’m not giving up on the 3D printed parts, of course, but being able to build custom cut arbors using metal for the 3d printed wheels (gears) to rotate on would be extremely helpful. And eventually doing all of this in brass and steel using the 3d printed parts as prototype shapes would be very cool.

So I ordered my first shop tool.

And it’s not what you’d expect.

I didn’t order a mini-lathe, though that is first on my list of things I want to buy. (And to be honest I’m on the fence as to if I buy a micro-lathe or something larger first. The advantage of the former: I’d be able to shape the small arbors and custom screws that I need to make my gadget with ease. The advantage of the latter: I’d be able to shape a full range of parts, including some larger components I’ll eventually want to build, including those brass gears. Eventually, of course, I’d want both.)

I didn’t order a mini-mill. (This would allow me to make many of the brackets and holders and supports my gadget will eventually need, though for the time being I can 3D print many of them.)

I didn’t even order a bandsaw, though I intend to order one when I order whatever lathe I intend to eventually get.

No, I bought one of these.


Now I’m sure you’re asking yourself “why the hell did you order a shop crane?”

Simple.

Did you see the shipping weight on some of the other gadgets that will eventually need to be positioned on my workbenches?

The HiTorque 8.5 x 20 Bench Lathe for example, has a shipping weight of 281 pounds; the machine itself is 220 pounds. Mills are worse: the Grizzly G0463 Mill/Drill has a crated weight of 445 pounds.

So the question becomes “how do you swing a 500 pound object and place it and attach it to a workbench” (rated at 3,000 pounds so we’re good there)?

Uh-huh.


Of course I’m relying on Home Depot to have the straps and hydraulic fluid which are necessary to run this crane.

One thing I plan to use this for–while I’m not using it to swing machines around the garage, of course–is to help hold stock metal in place for cutting in the bandsaw. Sure, it may be overkill for this use, but remember: a 3 inch diameter brass rod that is 48 inches long weighs 105 pounds. And frankly I’d rather swing that in place with a crane than lift it by hand. I’m not a young man anymore.

Machine #2

My second attempt at building a gear system.

Individual gears are 1mm pitch, 4mm thick gears, and the whole mechanism steps down from 6 rpm down to 1 revolution per day (with the 80-tooth gear I purchased off of SparkFun). (Without that gear, the last gear in the chain revolves 4 times per day.) This means the last gear in the chain actually is a pinion with a 1mm pitch gear connected to a 32p (32 teeth/diametrical inch pitch) tooth gear.

Things I learned:

I think 3mm is probably the thinnest practical gear I can print. (I’m sure I can print smaller.) Also, my height calculations are not dead on correct; I need to sort out why I have what appears to be about a 1 mm gap. (Though I suspect it’s the washers I’m using between layers; the washers measure only 0.5mm thick, and were advertised as 0.7mm. Five of those puppies with a 0.2mm error gives 1mm.

Meaning “depthing” is something I’m just going to have to do, no matter how well I think everything is measured.

IMG 4458

I also need to sort out how I’m going to disengage the gear train for adjusting the time. (Small battery-powered clocks seem to do the trick by overpowering the motor. OTOH, watches appear to use a mechanism which engages or disengages a clutch which then allows the time to be set by rotating the watch stem.) I’m inclined to use something simple, such as a pin which pulls up a set of gears and allows them to rotate freely. (I did a prototype of this here, though it’s poorly executed.)

Machine #1

Purchased one of these synchronous motors which rotate at 6 RPM. (A synchronized motor synchronizes against the line current, which is kept at an accurate 60hz rate to allow its use to synchronize against time keeping devices.)

Built my first gear machine using my gear generation software.

IMG 4456

This attaches to the synchronous motor using a specially designed 12 tooth 1mm pitch gear that attaches to the synchronous motor, and uses single-tooth counting gears to step down the rotation rate, so the last gear rotates at 1 revolution per day.

First attempt at designing a gear chain for a clock.

This helped me to resolve a number of bugs with the gear generation software, including bugs with the generation of certain gear shapes, and the generation of the STL files for the spacers that are used to hold the gears in place.

Observations on the FormLabs’ Form 2 printer.

Some observations on the FormLab’s Form 2 printer:

First, the resolution of the objects that are printed is simply amazing. I remember putting together the original Makerbot; this thing prints objects that are absolutely amazing compared to the extruded noodle of the original Makerbot print objects.

For example, I’m able to print 2 millimeter holes through a design and have them come out exactly 2 millimeters in size. I’m printing 32p gears; these are gears with 10 teeth per circumference inch and have them come out perfectly. (I tried the same thing with the original Makerbot; there is no way 32p gears could possibly have worked. Of course the current generation of Makerbots are light years ahead of the box of do-it-yourself wooden parts and gears of the original Makerbot printer.

Here are some parts I printed; they look imperfect because I roughly sanded them using 320 grit sand paper to see how well things would hold up to sanding. (You can get a much better result if you follow FormLab’s instructions.)

IMG 2825

I’m currently writing a Macintosh app which can be used to design gear chain mechanisms using spur gears; the mechanism is the top and bottom of a simple gear chain which performs a clock motion work, stacking two gears with a 12 to 1 ratio, so when one gear (attached to a minute hand) turns one full revolution, the other stacked gear (attached to an hour hand) would turn 1/2th of a revolution.

This is a test mechanism; ultimately I’m looking to design a clock, and I may write more about it in later posts.

The pins are 2mm by 25mm long pins; I was able to specify the holes to an amazing degree of accuracy. I was able to specify the holes in the corners of the frame to a 1/10th of a mm larger than the hole of a standard M3 screw. (Right now I’m waiting for some washers I ordered to insert between the gears.)

It’s stunning how great the quality of the parts printed are.


Of course this resolution and quality has a cost: time. The two frames that I printed to hold the gears (a test of the software that generates Delaunay triangles to triangulate the axle locations for my gears; the resulting frame was bigger than I wanted, so I need to tweak it) took 7 hours to print.

Yes, you read that right. Seven hours.

The four gears inside took around 4 hours to print.

But then, it makes sense. The Form 2 printer takes care to agitate and heat the resin to a consistent state; this allowed me to print some amazing items pretty much right out of the box. After each layer is printed (and each layer is 50 microns thick; about the thickness of a very thin piece of paper), the resin is agitated and the area cleared for the next layer. Needless to say for an object 3 inches tall, building up the part 50 microns at a time takes a while.

The resulting parts come out tacky. Even after bathing the parts in isopropyl alcohol for 20 minutes, the resin is not set or cured; you must allow the parts to finish curing–either in a UV light (mine is on order), or let the part rest for about a day.

Another thing to note is that while the results of using automatic scaffolding helps make the parts print correctly, sometimes with heavy objects the scaffolding can fail, causing print errors. (I tried printing a model of a manatee for my wife, only to have the flippers and head separate from the rest of the body, as the body was too heavy to hold rigid during printing. I fixed the model by gluing the pieces back together.)

Further, the automatic scaffolding algorithm can be a pain; you need to review the parts and edit the scaffolding locations. For example, the above photographed gears have a problem meshing; bits of the scaffolding got stuck between the teeth. So if you have surfaces that must be perfectly shaped and clean, you may need to edit how the scaffolding gets applied.


At some point when I get the gear design software working, I’ll publish a note here.

Constructing a cyclic polygon given the edge lengths.

So I have a problem: given the length of the edges L = {l0, l1, … lN} of an N-sided irregular polygon with N > 3, I need to construct the values for the radius R and the angles A = {a0, a1, … aN} such that the points P = { R, ai } form a closed polygon with the lengths given.

I searched through the internet and found all sorts of articles on the subject, but a day of searching and I was unable to find a way that I could construct the values R and A. I’m sure it’s out there, but I figured it’d be a good exercise to do it myself.

Based on my reading apparently there is no analytic solution to the problem–so I went ahead and built a simple algorithm to construct the values. The idea is outlined below.


Before we continue, we assume the longest length of our polygon is l0. We can rotate the edges of the polygon if this is not the case.

Observation 1: The vertices P = { p0, p1, … pN } of our cyclic polygon may be described by the values pi = ( R, ai ) in polar coordinates:

Circumpolar

By observation, the sum of the angles A is 360°.

Hypothesis 1: For any set of edge lengths L, there is only one set of values for R and A which create a cyclic polygon.

Sketch of proof: By construction.

Hypothesis 2: In constructing a polygon with lengths L, we have two cases for the centroid of the circumscribed circle that encompasses the polygon. Either the centroid is inside the polygon:

CenterInside

Or the centroid is outside the polygon.

CenterOutside

If the centroid of the circumscribed circle is outside the polygon, it is outside the edge with the largest length, and it is only outside one of the edges.

Sketch of proof: If the centroid of the circumscribed circle is outside of one of the edges, the edge has the property that the associated angle ai has an angle greater than 180°. If the centroid is outside two edges, this implies the sum of the angles exceeds 360°, violating Observation 1 above.

Hypothesis 3: The value of R must be greater than l0/2, where l0 is the length of the longest edge.

Sketch of proof: The lower bound of R is determined by an edge which passes directly through the center of the circle. If the edge does not pass through the center of the circle, then the diameter must be larger than the specified edge.

Observation 2: Given an edge in a circumscribed polygon with length li and a radius R, the angle associated with the edge ai can be calculated as:

NewImage

For an edge where the center of the circumscribed circle is outside the edge, the angle a is between 180° and 360°.

Sketch of proof: Law of cosines.


With these observations we could construct our polygon by searching for the proper value of R.

The essence of our algorithm is to search for a value R such that the following function is zero:

NewImage

One issue we need to deal with is calculating the angle on the longest line segment of our polygon. We can handle this case by starting with the angle a0; the idea is that we know a0 is in the range (0,360). From the angle a0 we can calculate r using the formula:

NewImage

Sketch of proof: Geometric observation.

We now can construct a function F(a) = Σai, by calculating the angles of all of the edges in our polygon for a proposed radius r, calculated using the value a as the angle a0. (If the angle is greater than 180°, this fits hypothesis 2 above.)

Hypothesis 5: The function F(a) is monotonic on the value a.

Sketch of proof: A geometric argument; as R increases, the angles decrease, while as R decreases, the angles increase. The increase or decrease in angles are monotonic, so the sum is monotonic. The function R relating to a is also monotonic.

Hypothesis 6: The function F(a) – 360 has one zero.

Sketch of proof: Trivial observation based on the above hypothesis.


We can now sketch the code which searches for the zero given a value a. We can use a number of computational methods to search for the zero of F(a) – 360; in our code below we use a simple binary subdivision search to search for a with 0 < a < 360°.


Preliminary functions

Given an object with the following declaration:

#define EPSILON		1e-6			/* A very small value. */

@interface KTCyclicPolygon ()
{
    NSInteger n;            // # edges
    NSInteger *edges;       // length of edge

    NSInteger ledge;        // index of maximum length edge
}

We can implement our algorithm by first, finding the edge that has the maximum length:

- (NSInteger)largestEdge
{
    NSInteger i = 0;
    NSInteger len = edges[0];

    for (NSInteger j = 1; j < n; ++j) {
        if (edges[j] > len) {
            len = edges[j];
            i = j;
        }
    }
    return i;
}

We need a way to calculate the angle of an edge given a radius:

- (double)angleAtIndex:(NSInteger)index radius:(double)r
{
    // Calculate a from observation 2

    double l = edges[index];
    double c = 1 - (l*l)/(2*r*r);
    return acos(c);         // output from 0 to M_PI
}

Then we can calculate f(a) above:

- (double)f:(double)a
{
    /*
     *  Calculate r from a.
     */

    double l = edges[ledge];
    double m = l / 2;
    double r = m / sin(a/2);

    /*
     *  Calculate the angles and sum from 1 to N
     */

    double sum = a;

    /*
     *  Sum the angles from 1 to N
     */

    for (NSInteger i = 0; i < n; ++i) {
        if (i == ledge) continue;
        sum += [self angleAtIndex:i radius:r];
    }

    /*
     *  Now subtract from our zero.
     *
     *      If the angle is small (meaning we selected too small a start angle)
     *  then this value will be negative. If we picked too large a start
     *  angle (meaning a was too big), then the sum will be large and the
     *  value will be positive.
     */

    return sum - 2*M_PI;                // Return value is angle gap to close.
}

At this point we can easily calculate a value a between 0 and 360°:

- (BOOL)calculateCyclicPolygon
{
    if (n <= 3) return NO;      // Need a 4 sided object or larger

    /*
     *  Step 1: Find the largest edge
     */

    ledge = [self largestEdge];

    /*
     *  Step 2: given a min/max value of 0, 360, find a between those values
     *  which approach our error
     */

    double mina = 0;
    double maxa = M_PI*2;
    double mida;

    for (;;) {
        mida = (mina + maxa)/2;

        double f = [self f:mida];

        if (fabs(f) < EPSILON) break;       // a solves our solution
        if (f < 0) {
            // Angle too small; we need a larger angle
            mina = mida;
        } else {
            // Angle too large; we need a smaller angle
            maxa = mida;
        }
    }

    double a = mida;                        // to within epsilon.

At this point the angle a has been found to within the error specified in our constant EPSILON.

We can validate the correctness of our algorithm by calculating the radius, and the angles for the rest of the items. We can then calculate the polar coordinates of each of the edges and compare the lengths with the stored edge lengths:

    double l = edges[ledge];
    double m = l / 2;
    double r = m / sin(a/2);

    double x = r;
    double y = 0;
    double angle = 0;
    for (NSInteger i = 0; i < n; ++i) {
        if (i == ledge) {
            angle += a;
        } else {
            angle += [self angleAtIndex:i radius:r];
        }
        double xn = cos(angle) * r;
        double yn = sin(angle) * r;

        double dx = xn - x;
        double dy = yn - y;
        double d = sqrt(dx * dx + dy * dy);

        printf("Vertex: %g %g\n",x,y);
        printf("  Edge %d: %d == %g\n",(int)i,(int)edges[i],d);

        x = xn;
        y = yn;
    }
    printf("Vertex: %g %g\n",x,y);
}

When run this will find the initial angle a which converges to our solution. Running with input values 1, 2, 3 and 4, we get the output:

Vertex: 2.0026 0
  Edge 0: 1 == 1
Vertex: 1.75293 0.96833
  Edge 1: 2 == 2
Vertex: 0.0408695 2.00219
  Edge 2: 3 == 3
Vertex: -1.9922 -0.203859
  Edge 3: 4 == 4
Vertex: 2.0026 -3.40378e-07

This shows our vertices define a closed cyclic polygon with edges of lengths 1, 2, 3 and 4–to within our error tolerance.