Skip to content

Custom autorouter post-processing creates via overlap at U_MCU pin5 without targeted validation #2058

Description

@seveibar

Summary

On tscircuit/spi-display-webcam-interceptor, tsci check reports a via from the U_BUF.pin7 -> U_MCU.pin6 route overlapping the adjacent U_MCU.pin5 pad/trace, even though the custom capacity-router input sets allowViaInPad: false.

The evidence indicates this is not the raw capacity solver choosing a via-in-pad location. The invalid location is introduced by the caller's post-routing transform after solver.getOutputSimpleRouteJson() returns. This issue is filed here because the failure occurs at the custom autorouter output boundary and the board already has an autorouter fixture/report; it may ultimately belong in core/output validation.

Reproduction

Board: https://github.com/tscircuit/spi-display-webcam-interceptor/tree/7c17e38d7e2fcdfc178b16614b13ce2b0da4c813

git clone https://github.com/tscircuit/spi-display-webcam-interceptor.git
cd spi-display-webcam-interceptor
git checkout 7c17e38d7e2fcdfc178b16614b13ce2b0da4c813
bun install
npx tsci check

Versions in the project:

  • tscircuit: ^0.0.2285
  • @tscircuit/capacity-autorouter: 0.0.785

Relevant existing autorouting input/report for this 87-connection ESP32-P4 phase:

Actual DRC errors

PCB trace trace[.U_BUF > port.pin9, .U_MCU > port.pin5] overlaps with pcb_via "pcb_via[#pcb_via_119]" (accidental contact)

Pad pcb_port[.U_MCU > .GPIO5] and trace trace[.U_BUF > port.pin7, .U_MCU > port.pin6] are too close (clearance: 0.05mm, minimum: 0.1mm)

pcb_via_119 belongs to source_trace_34 (U_BUF.pin7 -> U_MCU.pin6), while the overlapping neighboring route is source_trace_33 (U_BUF.pin9 -> U_MCU.pin5).

Final Circuit JSON geometry:

Object Center Copper geometry
U_MCU.pin5 / GPIO5 (-2.99999, 5.975102) top rectangular pad 0.6500114 x 0.1500124 mm
U_MCU.pin6 / GPIO6 (-2.99999, 5.62509) top rectangular pad 0.6500114 x 0.1500124 mm
pcb_via_119 on source_trace_34 (-2.8, 5.8) 0.6 mm outer diameter, 0.3 mm drill

Why it happens

Both the custom autorouter group and the AutoroutingPipelineSolver input explicitly set allowViaInPad: false.

After routing completes, however, the board calls normalizeToPlatedThroughVias(solver.getOutputSimpleRouteJson().traces). For source_trace_34, this transform finds the first MCU-side via and shifts the via plus coincident route points by -0.6 mm on X:

https://github.com/tscircuit/spi-display-webcam-interceptor/blob/7c17e38d7e2fcdfc178b16614b13ce2b0da4c813/index.circuit.tsx#L412-L442

The final via is at X -2.8, so its solver-returned X coordinate was approximately -2.2 before this transform. Moving it left by 0.6 mm places its copper inside the neighboring pin 5 pad and also creates the second pad-to-trace clearance error. The solver cannot account for an obstacle violation introduced after its output is returned.

Expected behavior / design question

At minimum this should be much easier to diagnose at the custom autorouter boundary. Possible directions:

  1. Validate custom algorithmFn output against pads, traces, obstacles, and allowViaInPad before accepting it.
  2. Expose/reuse an autorouter output validation helper that callers can run after route post-processing.
  3. Have core emit a targeted error that identifies the returned connection and invalid via before conversion to Circuit JSON.

The immediate board fix is to remove this coordinate mutation and let the solver route the connection. The framework-level question is whether invalid geometry returned by custom output post-processing should be rejected or diagnosed by tscircuit-autorouter, or by tscircuit core when it consumes the custom router result.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions