AnasSarkiz/muse-voice-remote

Muse Voice Remote — bare ESP32-S3R8, 155 TOP JLCPCB parts with real supplier CAD, native 3D assembly and GLB exports. Revised 17 mm case allocation; 0.30 mm via drill /0.45 mm pad. Checked prototype PCB; mechanical, RF and MUSE qualification pending.

Version
1.3.2
License
unset
Stars
0

scripts/seed-tight-fanout.py

#!/usr/bin/env python3
"""Add a geometry-checked off-pad escape where finite grids miss legal vias."""
import argparse,json,pathlib,os
helper=pathlib.Path(__file__).with_name('finish-unrouted.py');api={'__file__':str(helper)};exec(helper.read_text().split('\n# A FreeRouting pattern')[0],api)
from shapely.geometry import Point,box
from shapely.ops import nearest_points
from precise_path import visible_path
p=argparse.ArgumentParser();p.add_argument('reference');p.add_argument('pin');p.add_argument('--near',type=float,nargs=2);a=p.parse_args()
pbc=api['pcbnew'];path=api['path'];before=path.read_bytes();old=api['check']();board=pbc.LoadBoard(str(path));fs=list(board.GetFootprints());f=next(f for f in fs if f.GetReference()==a.reference);ps=list(f.Pads());pad=next(p for p in ps if p.GetNumber()==a.pin);net=pad.GetNetname();start=api['xy'](pad.GetPosition())
if any(v['type'] not in ['track_dangling','via_dangling'] for v in old['violations']):raise RuntimeError('Repair geometry before fanout')
occupied,drills=api['obstacles'](board,net);free=box(-32.25,-23.25,32.25,23.25).difference(occupied[0].context);regions=list(free.geoms) if free.geom_type=='MultiPolygon' else [free];region=next(r for r in regions if r.covers(Point(start)))
escapes=region.intersection(box(-32.25,-23.25,32.25,23.25).difference(drills.context).buffer(-.002))
if escapes.is_empty:raise RuntimeError(f'No legal off-pad through-via in the front region for {net}')
point=nearest_points(Point(a.near or start),escapes)[1];end=(point.x,point.y);points=visible_path(region,start,end)
for x,y in zip(points,points[1:]):
 track=pbc.PCB_TRACK(board);track.SetStart(api['vector'](x));track.SetEnd(api['vector'](y));track.SetLayer(pbc.F_Cu);track.SetWidth(pbc.FromMM(.15));track.SetNetCode(pad.GetNetCode());track.SetLocked(True);board.Add(track)
via=pbc.PCB_VIA(board);via.SetPosition(api['vector'](end));via.SetViaType(pbc.VIATYPE_THROUGH);via.SetLayerPair(pbc.F_Cu,pbc.B_Cu)
for layer in api['layers']:via.SetWidth(layer,pbc.FromMM(.45))
via.SetDrill(pbc.FromMM(.3));via.SetNetCode(pad.GetNetCode());via.SetLocked(True);board.Add(via);pbc.SaveBoard(str(path),board);after=api['check']()
if len(after['unconnected_items'])>len(old['unconnected_items']) or any(v['type'] not in ['track_dangling','via_dangling'] for v in after['violations']):path.write_bytes(before);raise RuntimeError('Native check rejected fanout; restored CAD')
report=api['root']/'docs/chip-fanout-repair.json';records=json.loads(report.read_text()) if report.exists() else []
records.append(dict(reference=a.reference,pin=a.pin,net=net,front_points_native_mm=points,via_native_mm=end,width_mm=.15,via_diameter_mm=.45,drill_mm=.3,off_pad=True,unconnected_pairs=len(after['unconnected_items']),status='geometry checked; general connection finishing required'))
report.write_text(json.dumps(records,indent=2)+'\n');print(f'Escaped {net}: {len(points)-1} top segments to legal off-pad via {end}',flush=True);os._exit(0)