imrishabh18/rp2040-motor-controller

A library of PCB component definitions covering MOSFETs, motor drivers, USB-PD control, sensors, current monitors, transistors, diodes, resistors, speakers, connectors, and mirrored bottom-side logos, with pin mappings, footprints, and 3D models.

Version
1.0.55
License
unset
Stars
5

scripts/refresh-top-capture.py

"""Update moved terminal ends from a fresh capture; retain all other copper."""
import json, math, runpy
from pathlib import Path
folder=Path('dist/top-assembly');path=folder/'route-plan.json'
plan=json.loads(path.read_text());srj=json.loads(Path('dist/pd-control/routing-input.json').read_text())
def points(input):
    return {p['pcb_port_id']:p for c in input['connections'] for p in c['pointsToConnect'] if p.get('pcb_port_id')}
old,new=points(plan['expectedInput']),points(srj)
assert set(old)==set(new),'Terminal identities changed; regenerate instead'
changed={id for id in old if math.hypot(old[id]['x']-new[id]['x'],old[id]['y']-new[id]['y'])>1e-6 or old[id].get('layer')!=new[id].get('layer')}
touched=set()
for trace in plan['traces']:
    for id in set(trace.get('connectsTo',[]))&changed:
        for p in [trace['route'][0],trace['route'][-1]]:
            if math.hypot(p['x']-old[id]['x'],p['y']-old[id]['y'])<1e-5:
                p.update(x=new[id]['x'],y=new[id]['y'],layer=new[id].get('layer',p.get('layer')))
                touched.add(trace['pcb_trace_id'])
changed_path=folder/'changed-routes.json'
changed_entries=json.loads(changed_path.read_text())
existing={e['id'] for e in changed_entries}
changed_entries += [{'id':id,'pins':[]} for id in sorted(touched-existing)]
changed_path.write_text(json.dumps(changed_entries,indent=2))
# A newly moved endpoint invalidates only that route's prior local-repair marker.
log=Path('reports/local-patch-repair.log')
if log.exists():
    lines=log.read_text().splitlines()
    log.write_text('\n'.join(line.replace('Routed ','Previously routed ',1) if any(line.startswith('Routed '+id+' ') for id in touched) else line for line in lines)+'\n')
print('Touched routes',sorted(touched))
plan['expectedInput']=srj;path.write_text(json.dumps(plan,indent=2))
(folder/'circuit.json').write_bytes(Path('dist/pd-control/unrouted.json').read_bytes())
check=runpy.run_path('scripts/find-top-pad-conflicts.py');plan=check['plan'];net=check['net']
changed_routes={e['id'] for e in json.loads((folder/'changed-routes.json').read_text())}
blocked=set(check['conflicts'])
traces={t['pcb_trace_id']:t for t in plan['traces']}
for id in ['top_assembly_267','top_assembly_272','top_assembly_273']:
    trace=traces[id];start=trace['route'][0];options=[]
    for other in plan['traces']:
        if other['pcb_trace_id'] in changed_routes|blocked or net(other)!=net(trace):continue
        for p in other['route']:
            if p['route_type']=='via':options.append((math.hypot(p['x']-start['x'],p['y']-start['y']),p,other['pcb_trace_id']))
    if options:
        _,p,backbone=min(options,key=lambda item:item[0]);trace['route'][-1]={'route_type':'wire','x':p['x'],'y':p['y'],'layer':'bottom','width':.15}
        print('Anchor branch',id,'to retained through via',backbone,p['x'],p['y'])
path.write_text(json.dumps(plan,indent=2))
print('Refreshed',len(changed),'moved terminals; candidate still requires routing checks')