ShiboSoftwareDev/nema8-20mm-dual-usbc-stepper-controller
BAT54C dual Schottky diode in a 3-pin SMD package, with two anodes and a shared cathode.
- Version
- 1.0.14
- License
- unset
- Stars
- 0
scripts/search-segment-detours.mjs
import fs from "node:fs"
import { runAllRoutingChecks } from "@tscircuit/checks"
let circuit = JSON.parse(
fs.readFileSync("dist/index/circuit.json", "utf8"),
).filter((element) => !String(element.type).endsWith("error"))
const samePoint = (point, x, y) =>
Math.abs(point.x - x) < 1e-5 && Math.abs(point.y - y) < 1e-5
const viaMoves = [
["source_net_30", 0.3165170373, 2.4681926742, 0.1165, 2.3682],
["source_net_26", -4.9635288614, 0.8009878988, -5.2635, 0.601],
["source_net_26", -1.0149987646, -4.722238758, -1.215, -4.7222],
["source_net_22", -5.975494, -3.367, -6.2755, -3.567],
["source_net_22", 1.9745212144, 2.375001, 1.6745, 2.875],
["source_net_21", 1.6, -3.9750010113, 1.6, -3.775],
]
const applyViaMove = (input, [connectionName, oldX, oldY, newX, newY]) => input.map((element) => {
if (element.type === "pcb_via" && element.pcb_trace_id?.startsWith(connectionName) &&
samePoint(element, oldX, oldY)) return { ...element, x: newX, y: newY }
if (element.type !== "pcb_trace" || element.connection_name !== connectionName) return element
return {
...element,
route: element.route.map((point) => samePoint(point, oldX, oldY)
? { ...point, x: newX, y: newY }
: point),
}
})
// The live build already contains the accepted via moves and trace detours.
if (false) for (const move of viaMoves) circuit = applyViaMove(circuit, move)
const shiftTraceWindow = (input, traceId, center, windowRadius, dx, dy) => input.map((element) => {
if (element.type !== "pcb_trace" || element.pcb_trace_id !== traceId) return element
const viaCoordinates = element.route
.filter((point) => point.route_type === "via")
.map((point) => [point.x, point.y])
let nearestIndex = -1
let nearestDistance = Infinity
element.route.forEach((point, index) => {
if (point.route_type !== "wire" || index === 0 || index === element.route.length - 1) return
if (viaCoordinates.some(([x, y]) => samePoint(point, x, y))) return
const distance = Math.hypot(point.x - center.x, point.y - center.y)
if (distance < nearestDistance) {
nearestIndex = index
nearestDistance = distance
}
})
if (nearestIndex < 0) return element
const anchor = element.route[nearestIndex]
return {
...element,
route: element.route.map((point, index) => {
if (point.route_type !== "wire" || index === 0 || index === element.route.length - 1) return point
if (viaCoordinates.some(([x, y]) => samePoint(point, x, y))) return point
const distance = Math.hypot(point.x - anchor.x, point.y - anchor.y)
return distance <= windowRadius ? { ...point, x: point.x + dx, y: point.y + dy } : point
}),
}
})
let errors = await runAllRoutingChecks(circuit)
console.log(`start\t${errors.length}`)
const deltas = [-0.3, -0.2, -0.1, -0.05, 0.05, 0.1, 0.2, 0.3]
for (let pass = 0; pass < 4; pass++) {
let improved = false
const traceErrors = errors.filter((error) => error.pcb_trace_id && error.center)
for (const error of traceErrors) {
let best = { count: errors.length, circuit, errors, detail: null }
for (const windowRadius of [0.01, 0.2, 0.45]) {
for (const dx of [0, ...deltas]) {
for (const dy of [0, ...deltas]) {
if (dx === 0 && dy === 0) continue
if (dx !== 0 && dy !== 0 && Math.abs(dx) !== Math.abs(dy)) continue
const candidate = shiftTraceWindow(
circuit,
error.pcb_trace_id,
error.center,
windowRadius,
dx,
dy,
)
let candidateErrors
try {
candidateErrors = await runAllRoutingChecks(candidate)
} catch {
continue
}
if (candidateErrors.length < best.count) {
best = {
count: candidateErrors.length,
circuit: candidate,
errors: candidateErrors,
detail: [error.pcb_trace_id, error.center.x, error.center.y, windowRadius, dx, dy],
}
}
}
}
}
if (best.count < errors.length) {
circuit = best.circuit
errors = best.errors
improved = true
console.log(`accept\t${best.count}\t${best.detail.join("\t")}`)
}
}
console.log(`pass\t${pass}\t${errors.length}`)
if (!improved) break
}
console.log(Object.entries(Object.groupBy(errors, (error) => error.type))
.map(([kind, group]) => `${kind}\t${group.length}`)
.join("\n"))
console.log(errors.map((error) => error.message).join("\n"))