ShiboSoftwareDev/nema8-20mm-usbc-pd-controller

A 20×20 mm four-layer USB‑C PD motor-controller PCB combining a CH32X035 MCU, TMC2209 stepper driver, protected power regulation, USB data/ESD protection, current sensing, and a four-pin motor connector.

Version
1.0.7
License
unset
Stars
0

scripts/evaluate-route-moves.mjs

import fs from "node:fs"

const inputPath = process.argv[2] ?? "dist/index/circuit.json"
const outputPath = process.argv[3] ?? "/private/tmp/route-candidate.circuit.json"
const moves = JSON.parse(process.env.ROUTE_MOVES ?? "[]")
const routeOverrides = JSON.parse(process.env.ROUTE_OVERRIDES ?? "{}")
const routePrefixes = JSON.parse(process.env.ROUTE_PREFIXES ?? "[]")
const removeVias = JSON.parse(process.env.ROUTE_REMOVE_VIAS ?? "[]")
const layerRemaps = JSON.parse(process.env.ROUTE_LAYER_REMAPS ?? "[]")
const circuit = JSON.parse(fs.readFileSync(inputPath, "utf8"))

for (const remap of layerRemaps) {
  const trace = circuit.find(
    (element) => element.type === "pcb_trace" && element.pcb_trace_id === remap.traceId,
  )
  if (!trace) continue
  trace.route = trace.route.map((point) => {
    if (point.route_type === "wire" && point.layer === remap.fromLayer) {
      return { ...point, layer: remap.toLayer }
    }
    if (point.route_type === "via") {
      return {
        ...point,
        from_layer: point.from_layer === remap.fromLayer ? remap.toLayer : point.from_layer,
        to_layer: point.to_layer === remap.fromLayer ? remap.toLayer : point.to_layer,
      }
    }
    return point
  })
}

for (const removal of removeVias) {
  const [x, y] = removal.at
  const epsilon = removal.epsilon ?? 0.02
  const trace = circuit.find(
    (element) => element.type === "pcb_trace" && element.pcb_trace_id === removal.traceId,
  )
  if (trace) trace.route = trace.route.filter((point) => !(point.route_type === "via" &&
    Math.abs(point.x - x) < epsilon && Math.abs(point.y - y) < epsilon))
  for (let index = circuit.length - 1; index >= 0; index--) {
    const element = circuit[index]
    if (element.type === "pcb_via" && element.pcb_trace_id === removal.traceId &&
      Math.abs(element.x - x) < epsilon && Math.abs(element.y - y) < epsilon) circuit.splice(index, 1)
  }
}

for (const element of circuit) {
  if (element.type !== "pcb_trace" || !routeOverrides[element.pcb_trace_id]) continue
  element.route = routeOverrides[element.pcb_trace_id]
}

for (const patch of routePrefixes) {
  const trace = circuit.find(
    (element) => element.type === "pcb_trace" && element.pcb_trace_id === patch.traceId,
  )
  if (trace) trace.route = [...patch.route, ...trace.route.slice(patch.keepFromIndex)]
}

const overriddenTraceIds = new Set(Object.keys(routeOverrides))
for (let index = circuit.length - 1; index >= 0; index--) {
  const element = circuit[index]
  if (element.type === "pcb_via" && overriddenTraceIds.has(element.pcb_trace_id)) {
    circuit.splice(index, 1)
  }
}

let nextViaId = 10000
for (const [traceId, route] of Object.entries(routeOverrides)) {
  for (const point of route) {
    if (point.route_type !== "via") continue
    circuit.push({
      type: "pcb_via",
      pcb_via_id: `pcb_via_eval_${nextViaId++}`,
      pcb_trace_id: traceId,
      x: point.x,
      y: point.y,
      hole_diameter: point.via_hole_diameter ?? 0.3,
      outer_diameter: point.via_diameter ?? 0.45,
      layers: ["top", "inner1", "inner2", "inner3", "inner4", "inner5", "inner6", "bottom"],
      from_layer: "top",
      to_layer: "bottom",
      subcircuit_id: "subcircuit_source_group_0",
    })
  }
}

for (const move of moves) {
  const [fromX, fromY] = move.from
  const [toX, toY] = move.to
  const epsilon = move.epsilon ?? 0.02
  for (const element of circuit) {
    if (element.type === "pcb_trace" && element.pcb_trace_id === move.traceId) {
      element.route = element.route.map((point) =>
        Math.abs(point.x - fromX) < epsilon && Math.abs(point.y - fromY) < epsilon
          ? { ...point, x: toX, y: toY }
          : point,
      )
    }
    if (
      element.type === "pcb_via" &&
      element.pcb_trace_id === move.traceId &&
      Math.abs(element.x - fromX) < epsilon &&
      Math.abs(element.y - fromY) < epsilon
    ) {
      element.x = toX
      element.y = toY
    }
  }
}

fs.writeFileSync(outputPath, `${JSON.stringify(circuit)}\n`)