# The Arm — beauty variant + detachable base  ⭐ PRINT TARGET

6-servo desktop arm on Feetech **STS3215** servos. Cameron poses servos in Blender (GLB); the agent
regenerates connectors/base/URDF. **This is the build we print in the next ~4 days** (no gravity comp).

Viewer: `.../?file=two_servo_beauty.urdf` and `.../?file=two_servo_detach.urdf`

## Files
| File | Output |
|---|---|
| gen_two_servo.py | core LAYOUT→URDF+GLB+connectors (`read_layout`, `gen_urdf`, `gen_glb`) |
| apply_glb_layout.py | reads Blender GLB → rebuilds default variant (two_servo.urdf) |
| gen_beauty.py | → two_servo_beauty.urdf (the pretty arm we print) |
| gen_detach.py | → two_servo_detach.urdf + base_holder_detach.stl + fiducial_mount.stl |
| gen_curvy.py | curvy connectors (connector_beauty_*.stl) |
| fillet_holder.py / yoke_fillet.py | holder_fillet.stl / yoke_fillet.stl |

## Design decisions

### Connectors — how we made them smooth
1. **Perpendicular block**, not a triangular prism: take the holder face whose normal points at the yoke,
   extrude it to the yoke arm.
2. **Rounded by default** — `CONNECTOR_ROUND=7`mm rounded-rect cross-section (shapely).
3. **Curvy / waisted** (beauty) — loft through 16 sections with a waist pinch. `WAIST=0.30`;
   `WAIST_BY_CONN={3:0.425}` slims the fat connector_3 (its servo pair sits at an angle).
4. **Cross-section blend** — the section interpolates from the full **holder face → yoke-arm size (+1.5mm)**
   along the length, so it necks *into* the yoke instead of butt-capping over it. `_rrect()` keeps a fixed
   point count so lofted rings align.
5. **EXTRUDE_FRAC=0.5** — connector reaches only halfway toward the yoke (short, clean stubs).

### Fillets (never touch the servo fit)
- `holder_fillet` — round-the-box-then-carve, R=2.5. The servo cavity + 4 bolt holes are carved AFTER
  rounding, so fit/clearance is identical to the un-filleted holder.
- `yoke_fillet` — build123d fillet: **bold 4mm on the free arm** + 0.8mm elsewhere.
- Yoke arm stub shortened `link_len` 70→20→10→**5mm** (chunky 16×22 section, so still strong).

### Detachable fiducial base (gen_detach.py)
- Split at the **mount** (compact Part A). **Part A** `base_holder_detach.stl` = holder + base-mount +
  short shelf + **4 upward pins** (rounded lead-in tips). **Part B** `fiducial_mount.stl` = whole connector +
  fiducial board + 4 clearance holes.
- **Lap sits ABOVE the connector plane** → everything bottoms out flat at Y=-32 (nothing pokes below → robot
  sits flat). Part B drops straight down onto the pins; lift to detach. Tool-free, no screws.
- `CLEAR=0.35`mm pin clearance = the one print-tunable knob (dial after first fit).

## Structural notes (docs + struct_analysis.py / struct_beams.py)
- ~1.0 kg, 524 mm reach. **Shoulder output_1 = 52% of stall (1.63 N·m)** → run servos at **12 V** (at 7.4 V it
  is ~82% and will sag). Long connectors flex ~1.2° (~cm wobble); servo backlash ~similar. Parts are all
  strong (SF≥15) — the limits are torque + wobble, not breakage.

## Print list → arm_stls/
6× holder_fillet, 6× yoke_fillet, connector_beauty_1..5, base_holder_detach, fiducial_mount.
