seveibar/pd-dual-stepper-controller
Bottom-side PCB silkscreen artwork consisting of embedded mirrored TS Circuit SVG logos, with via-clearance-aware lower-board placement.
- Version
- 0.1.0
- License
- unset
- Stars
- 0
scripts/repair-missing-routes.py
"""Route one missing path per physical net; reimport the complete copper graph after each batch."""
import json,subprocess,sys
from pathlib import Path
folder=Path('work/repair');failed=json.load(open('reports/freerouting-import.json'))['failed'];requests={e['pcb_trace_id']:e for e in json.load(open('dist/revision/route-plan.json'))['traces']}
j=json.load(open('dist/dual/capture.json'));st={e['source_trace_id']:e for e in j if e['type']=='source_trace'}
from freerouting_geometry import root
gnd=root(next(e["source_net_id"] for e in j if e["type"]=="source_net" and e["name"]=="GND"))
seen=set();results=[]
for f in failed:
if f['net'] in seen or f['net']==gnd:continue
seen.add(f['net']);t=requests[f['trace']];p=json.loads((folder/'route-plan.json').read_text())
if any(x['pcb_trace_id']==t['pcb_trace_id'] for x in p['traces']):continue
p['traces'].append(t);(folder/'route-plan.json').write_text(json.dumps(p))
src=next((st[x] for x in t['connection_name'].split('__') if x in st),{})
width=.4 if src.get('min_trace_thickness',0)>=.8 else .15
args=[sys.executable,'scripts/route-local.py',str(folder),t['pcb_trace_id'],str(width),'--shorten','--report-dir=work/repair/reports']
if '--soft' in sys.argv:
protected=[]
for old in p['traces']:
oldname=next((st[c].get('name','') for c in old['connection_name'].split('__') if c in st),'')
if (oldname.startswith(('DRIVER_','M2_')) or oldname in ['PD_ENABLE_OUTPUT','PD_ENABLE_OUTPUT_M2']) and old['pcb_trace_id']!=t['pcb_trace_id']:protected.append(old['pcb_trace_id'])
args+=['--soft-routing','--protected='+','.join(protected)]
if width>=.4:args+=['--outer-only','--escape-width=.3','--escape-radius=1.5']
print('ROUTE',src.get('name'),t['pcb_trace_id'],flush=True)
proc=subprocess.run(args,stdout=subprocess.PIPE,stderr=subprocess.STDOUT,text=True);print(proc.stdout,flush=True)
if proc.returncode==0 and '--soft' in sys.argv:
displaced=set(json.load(open('work/repair/reports/local-route-blockers.json')))
latest=json.loads((folder/'route-plan.json').read_text());latest['traces']=[x for x in latest['traces'] if x['pcb_trace_id'] not in displaced];(folder/'route-plan.json').write_text(json.dumps(latest))
results.append({'trace':t['pcb_trace_id'],'returncode':proc.returncode,'output':proc.stdout})
if proc.returncode:(folder/'route-plan.json').write_text(json.dumps({**p,'traces':[x for x in p['traces'] if x['pcb_trace_id']!=t['pcb_trace_id']]}))
(folder/'repair-log.json').write_text(json.dumps(results,indent=2))