mohan-bee/gimbal-one-budget-pcb

A 4-layer STM32-based gimbal controller PCB with an onboard LSM6DS3TR-C IMU, three DRV8313 3-phase motor drivers, protected 3S battery input, 3.3 V buck regulation, and SWD/UART control interfaces.

Version
0.1.0
License
unset
Stars
0

routing/checked-routing.ts

import savedTraces from "./checked-traces.json"
import reference from "./reference-input.json"
import { pcb_trace } from "circuit-json"
import type { AutorouterConfig } from "@tscircuit/props"

// Preserve the manually reviewed route geometry. Five congested MCU vias use
// JLCPCB-supported 0.20 mm drills / 0.45 mm pads; the other vias stay larger.
// This replaces the solver only: core DRC and required-port checks still run.
const traces = pcb_trace.array().parse(savedTraces)
function canonical(value: unknown): string {
  if(typeof value === "number") return String(Math.round(value*1e6)/1e6)
  if(Array.isArray(value)) return `[${value.map(canonical).join(",")}]`
  if(value && typeof value === "object") return `{${Object.entries(value).filter(([,v])=>v!==undefined).sort(([a],[b])=>a.localeCompare(b)).map(([k,v])=>`${JSON.stringify(k)}:${canonical(v)}`).join(",")}}`
  return JSON.stringify(value)
}
export const checkedRouting: NonNullable<AutorouterConfig["algorithmFn"]> = async input => {
  const geometry = {bounds:input.bounds,connections:input.connections,obstacles:input.obstacles,layerCount:input.layerCount}
  if(canonical(geometry)!==canonical(reference)) throw new Error("Checked routing no longer matches PCB geometry or connectivity. Reroute and validate this revision before replacing routing/*.json.")
  const listeners = new Map<string,(event: unknown)=>void>()
  let stopped = false
  return {
    input, isRouting:false,
    on(event:string,callback:(event:unknown)=>void){listeners.set(event,callback)},
    start(){queueMicrotask(()=>{if(!stopped)listeners.get("complete")?.({type:"complete",traces:structuredClone(traces)})})},
    stop(){stopped=true},
    solveSync(){return structuredClone(traces)},
  }
}