Fin-Ray compliant gripper Blade_v4_final.stl generated 2026-08-21 01:56 TPU

Blade v4

The long-jaw Fin-Ray blade, rebuilt from operator field-test feedback. Mesh checks all pass and the root failure that killed v3 is fixed. One dimension is still blank on purpose — nobody has measured it yet, and guessing it would be worse than leaving it at zero.

Geometry passes every check

Re-verified 2026-08-21: connected shells = 1, watertight, manifold, consistently wound, zero degenerate faces, signed volume 29,424 mm³. check_ribs.py on the toothless body gives rib pitch 4.06 mm, compliance 0.8×, outlier 1.59×, largest cavity 60.7 mm² — all pass.

!

Two things are still unmeasured — and both need hardware

1. HOLE_DX = 0. The mounting holes should shift inward laterally, but by how much has never been measured. The field-test doc says explicitly not to invent a number, so it sits at zero until someone measures it. Everything else about the part is final.

2. Jaw opening with the sleeve fitted. The TPU sleeve adds 9.34 mm past the grip face on each blade, so a closed pair loses 18.68 mm of opening. Whether a 90 mm cup still fits has not been confirmed. gripper_range.py answers it, but that script drives the real gripper motor — it cannot be settled from files.

Connected shells
1
the acceptance bar — one solid body
Height
89.4 mm
z −33.98 → 55.44
Mounting hole
Ø2.80
was Ø2.5 — too tight to drive into TPU
Hole edge margin
0.850 mm
the floor for TPU — cannot go lower

01 — Views

Rendered from the shipping mesh

These are rendered directly from Blade_v4_final.stl, not from the source script — so what you see is what prints.

02 — What changed from v3

Three fixes, all traceable to something that actually went wrong

The friction texture moved into the body

v3 built texture by sweeping the body along X, subtracting to get a skin, then intersecting with a rib array. That path produced 40 loose shells, then 3, then two zero-area triangles, then 4 non-manifold edges — and finally the plane it depended on turned out to cut straight through the grip face itself. The whole boolean-skin mechanism is deleted; texture is generated parametrically in the body now.

The old-hole plugs sit at the right height

The blade inherits Ø3.39 holes at z=−30.485. v3 plugged them at the new hole height −31.735 — 1.25 mm off, so an r=2.2 plug missed the top rim of an r=1.695 hole and left a 3.37 × 1.55 crescent gap in section. Plugs now use the old holes' own height.

The root is solid again

27.70 mm of continuous material at z=−26, up from 7.47 mm before the fix. This is the load path from the ribs into the mount; v3 was hollow where it needed to be solid.

Two defects mesh-checking cannot see

Both were hit on 2026-08-21. A texture band can be silently clipped away while the script still "has" it — caught by comparing vertex counts per 5 mm z-band, body vs toothed. And a hairline gap passes watertightness — caught by slicing at y=0 and listing every closed loop under 6×6 mm. check_mesh.py alone is not sufficient.

03 — Measured state

Every number below came from the file, not an estimate

ItemValueStatus
Connected shells1✓ pass
Watertight / manifold / winding / slivers✓ all pass
Signed volume29,424 mm³✓ pass
Rib pitch4.06 mm✓ pass
Compliance0.8×✓ pass
Largest cavity60.7 mm²✓ pass
Mounting holesØ2.80 × 2✓ z=−31.737, 10.0 mm apart
Hole edge margin0.850 mm✓ at the TPU floor
Old holes plugged✓ no residue in section
y=0 small closed loops3✓ 2 holes + 1 design cavity
Tip thickness @ z=55.21.13 mm✓ sharp
Root solid @ z=−2627.70 mm✓ was 7.47 mm
Lateral hole offset HOLE_DX0! unmeasured
Jaw opening with sleeve−18.68 mm! unverified vs 90 mm cup

04 — To finish it

Measure HOLE_DX, then rebuild

Hold the two blades inner-face to inner-face, measure the outside-to-outside span across the feet, and compare against the original part keeping the centre fixed — that back-solves the hole position. Put the number into HOLE_DX in generate_v4_finish.scad and re-run the third build step. Nothing else changes.

StepCommand
1 · body, no teethopenscad -D TEETH=false -o Blade_v4_body.stl generate_blade_arcsweep.scad
2 · body with teethopenscad -D TEETH=true -o Blade_v4_teeth.stl generate_blade_arcsweep.scad
3 · drill → finalopenscad -o Blade_v4_final.stl generate_v4_finish.scad

Order matters. check_ribs.py runs on the toothless body, not the final part — running it on the finished mesh reads the teeth as rib geometry and reports nonsense.