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.41
- License
- unset
- Stars
- 3
routing/ground-pour-selection.ts
import selection from './ground-pour-selection.json';
/** Frozen pour selection for the validated fixed route plan.
* The independent copper audit records which pours belong to the connected
* ground network. The current core generates 25 connected pours, so this step
* removes none; it still fails closed if their geometry changes. No error record
* is filtered, and normal DRC runs after this check.
*/
export function canonicalPour(pour: any): string {
return JSON.stringify({layer:pour.layer,source_net_id:pour.source_net_id,shape:pour.brep_shape}, (_key,value)=>
typeof value==='number'?Math.round(value*1e7)/1e7:value);
}
export function selectConnectedGroundPours(json: any[], regions: Array<{geometry:any;keep:boolean}>) {
const pours=json.filter(e=>e.type==='pcb_copper_pour');
const expected=new Map(regions.map(r=>[canonicalPour(r.geometry),r.keep]));
if (pours.length!==regions.length || pours.some(p=>!expected.has(canonicalPour(p)))) {
throw new Error('Ground pour geometry changed. Regenerate and audit routing/ground-pour-selection.json.');
}
return pours.filter(p=>!expected.get(canonicalPour(p))).map(p=>p.pcb_copper_pour_id);
}
export function installGroundPourFinalization(board: any) {
if(!board || board.__groundPourSelectionInstalled)return;
board.__groundPourSelectionInstalled=true;
const original=board.doInitialPcbDesignRuleChecks.bind(board);
board.doInitialPcbDesignRuleChecks=()=>{
const db=board.root?.db;
// Placement-only CLI renders intentionally have no routed copper.
if(db && !board.root.pcbDisabled && !board.root.pcbRoutingDisabled) {
const remove=selectConnectedGroundPours(db.toArray(),selection.regions);
for(const id of remove)db.pcb_copper_pour.delete(id);
// Remove annotations that referred to removed geometry, not checks.
const deleted=new Set(remove);
for(const trace of db.pcb_trace.list()) {
if(trace.route.some((p:any)=>deleted.has(p.copper_pour_id))) {
db.pcb_trace.update(trace.pcb_trace_id,{route:trace.route.map((p:any)=>{
if(!deleted.has(p.copper_pour_id))return p;
const {copper_pour_id,is_inside_copper_pour,...point}=p;return point;
})});
}
}
}
return original();
};
}
