← Engineering

Engineering

Unit Tests for Hardware

August 15, 2026

Cycloidal gear designed as a Hardware-as-Code project

Cycloidal gear designed as a Hardware-as-Code project

"Hardware as code" usually gets pitched as a filing improvement: your CAD lives in git, you get diffs instead of files named bracket_v14_FINAL_reallyfinal.step. That's real, but it undersells the actual capability: once geometry is parametric, an invariant you write down gets checked against every input, not just the one you happened to look at.

A concrete example. We were adding a position encoder to a cycloidal gearbox—a magnetic ring bonded into the output flange, read by a sensor on the housing lid. The obvious move was to grow a "roller pin circle" parameter to make room for it. That parameter, though, wasn't just the roller pin circle—it was also the cycloidal disc's own output hole circle. Growing it pushed the disc's holes through its own lobed rim. The render showed it immediately: a visibly broken gear.

The fix wasn't just nudging the number back. We wrote the actual relationship down as a standing check—an output hole may never sit outside the disc's own profile—against the same closed-form math the geometry uses:

def test_disc_output_holes_stay_inside_disc_rim(...):
    hole_outer_edge = output_hole_circle_diameter / 2 + output_hole_diameter / 2
    available = disc_min_boundary_radius - eccentricity
    assert hole_outer_edge < available

That test immediately failed on a second, unrelated input: a larger output-coupling size, a perfectly reasonable customer request, broke the exact same rule. That configuration had been quietly exporting broken geometry the whole time—nobody had rendered it, so nobody had seen it. The test didn't need a picture. It just needed the rule.

To be clear, however, unit tests are not a magic wand. Later the same day, we tried to cancel a rotating imbalance in the gearbox by adding a second, counter-rotating disc, and wrote a kinematic simulation asserting the two discs stayed synchronized with the roller pins. It passed. It was wrong—the simulation assumed a disc's mounting angle and its meshing angle could be set independently, which they can't. What caught the mistake was a rendered exploded view, where the second disc's holes were plainly off from its own lobes.

Put together, the two failures point at the same lesson from opposite directions. A render catches what's in front of you; it says nothing about the input you didn't try. A test catches every input you specified, but only as correctly as you specified it—a wrong model produces a confident, wrong pass. Neither one is the safety net on its own. The actual capability hardware-as-code adds isn't replacing the render with the test. It's being able to hold both at once: look at the part, and also write down what has to stay true about it no matter what someone sets the parameters to.