imrishabh18/rp2040-motor-controller

An RP2040-based NEMA17 stepper-motor controller with USB-C programming and PD motor-power negotiation, DRV8825 dual H-bridge drive, current/temperature telemetry, protected power filtering, status RGB LED, buzzer alarm, and optional magnetic encoder.

Version
1.0.42
License
unset
Stars
3

scripts/normalize-route-widths.py

"""Express Gerber segment-width changes at duplicate vertices for native DRC.

Use a freshly rendered circuit: core may reverse a saved trace. Preserve the
rendered direction and insert zero-length width transitions, leaving every
nonzero copper segment geometrically identical. Rebuild and recheck afterward.
"""
import json,sys,copy
from pathlib import Path
folder=Path(sys.argv[1] if len(sys.argv)>1 else 'dist/drc-fix')
plan=json.loads((folder/'route-plan.json').read_text())
built={e['pcb_trace_id']:e for e in json.loads((folder/'circuit.json').read_text()) if e['type']=='pcb_trace'}
count=0
for t in plan['traces']:
 r=copy.deepcopy(built[t['pcb_trace_id']]['route']);out=[]
 for i,p in enumerate(r):
  for k in ['start_pcb_port_id','end_pcb_port_id','is_inside_copper_pour','is_inside_pour','copper_pour_id']:p.pop(k,None)
  if i and p['route_type']==r[i-1]['route_type']=='wire' and p['layer']==r[i-1]['layer'] and p['width']!=r[i-1]['width'] and (p['x'],p['y'])!=(r[i-1]['x'],r[i-1]['y']):
   q=dict(p);q['width']=r[i-1]['width'];out.append(q);count+=1
  out.append(p)
 if len(out)>1 and out[-1]['route_type']==out[-2]['route_type']=='wire' and out[-1]['layer']==out[-2]['layer']:out[-1]['width']=out[-2]['width']
 # A zero-length width change immediately before a via has no exported
 # wire copper. Keep the incoming segment width at that layer transition.
 t['route']=[q for i,q in enumerate(out) if not (i>0 and i+1<len(out) and q['route_type']=='wire' and out[i-1]['route_type']=='wire' and out[i+1]['route_type']=='via' and q['layer']==out[i-1]['layer'] and (q['x'],q['y'])==(out[i-1]['x'],out[i-1]['y'])==(out[i+1]['x'],out[i+1]['y']))]
(folder/'route-plan.json').write_text(json.dumps(plan,indent=2)+'\n')
print('Inserted',count,'zero-length width transitions without changing copper')