Closed bug report

Freerouting DSN: track width comes back at 0.187 mm below the 0.2 mm board minimum, approximated pads cause clearance errors, plane layers get signal routes

John Lauer · ·closed by John Lauer
needs-hardware-test

Measured on ConfRoomROG (KiCad 10.0.5, bridge 1.0.3) with the ESC G431 routing fixture (149 parts, 59 nets, GND plane on In1.Cu, +3V3 plane on In2.Cu): kicad_autoroute {engine:"freerouting", passes:40, job:true} routed all 59 nets in 229 s (18 passes, 1217 segments, 139 vias, applied as 59 undo steps), but kicad_routing_validate reported 202 errors and 7 unconnected:

  • 162 track_width: "board setup constraints min width 0.2000 mm; actual 0.1874 mm". The DSN writer emits the KiCad default 0.25 mm width, yet Freerouting lands 0.1874 mm segments, which points at a unit or resolution mismatch in the DSN rules block (0.1874 mm is 7.38 mil), or Freerouting's own default class overriding ours. The DSN we write should carry the board's minimum track width and clearance from the setup block and each netclass width, and the SES import should refuse or widen segments below the board minimum.
  • 12 clearance and 9 shorting_items against the custom-shape MOSFET pads (Q1..Q6 pads 1 and 5) and roundrect pads: the writer approximates these shapes (reported as approximatedPads) so Freerouting routes into the real pad's copper.
  • 4 hole_clearance, 9 solder_mask_bridge, 2 via_dangling.
  • The two inner layers carry planes but Freerouting still routed signal traces on In1.Cu and In2.Cu (visible in the take); a plane layer should be marked as such in the DSN so the router only drops vias into it.
  • 7 unconnected after the zones are refilled.

Expected: the DSN rules mirror the board (min width, min clearance, netclass widths, via sizes), custom pads are written as polygons, plane layers are reserved, and the reply's drc block leads with these numbers so the AI never reports a Freerouting result as clean. The full validate output is in demo/routing/esc/ on the page after the routing round.

2 Replies

John Lauer ·

Fixed in KiCad Bridge 1.0.12, shipped to insiders, but not yet proven on a live route: read this as shipped, not confirmed.

The DSN writer already floors the class width at the board minimum, so what came back was Freerouting's own answer being a hair thin (0.1874 mm against 0.2 mm). The applier now widens any returned wire up to its net class width before it lands, and reports the count per net as widened, so nothing lands thinner than the board allows and the reply says how much was corrected.

Unit test: dsn::tests::router_wire_thinner_than_the_class_is_widened_to_it sends a 0.1874 mm wire and a correct one through the applier and asserts only the thin one is widened.

What would close this: one kicad_autoroute {engine:"freerouting"} run on the ESC fixture followed by kicad_routing_validate reporting zero track_width errors. I am leaving it open until that run exists.

John Lauer ·

Verified on hardware and closing. Every item in this report was measured on ConfRoomROG (KiCad 10.0.5) against the same fixture as the original: the ESC G431 routing board, 149 parts, 59 nets, GND on In1.Cu, +3V3 on In2.Cu, kicad_autoroute {engine:"freerouting", passes:40}, then kicad_routing_validate. The fixture was pushed byte-identical from demo/routing/esc/esc-g431-fable-placed-planes.kicad_pcb (0 segments) for every run.

The headline: track width

track_width errors smallest track
Original run (1.0.3) 162 ("actual 0.1874 mm") 0.1874 mm
Every run from 1.0.17 0 0.2 mm, all 1,102 to 1,157 segments

Freerouting still hands back thin wires. 1.0.18 made the reply say so, and it says a lot: routed.widened was 86, 108 and 179 on the three later runs. Those wires are landed at the net class width, so none reach the board below the minimum.

Everything else this issue listed

Fixing the widths exposed the rest, so I did those too. Four runs, one change at a time:

Run all errors from routing shorts unconnected
Original (1.0.3) 202 ~188 9 7
A: 1.0.17, planes open, custom pads as anchor only 40 26 5 3
B: 1.0.18, planes reserved, anchor only 75 62 25 27
C: 1.0.19, planes reserved, custom pads as real copper 24 11 0 30
D: 1.0.19, planes open, custom pads as real copper 19 6 0 3

"From routing" means the violation involves a track or a via. The other 13 are inside footprints (pad-to-pad spacing on U2 and six malformed courtyards). Those were on the board before any routing, so they are not the router's to fix.

  • Custom pads (the shorts, 1.0.19). You were right, and it was worse than an approximation. A custom pad went into the DSN as its 1x1 mm ANCHOR only, dropping the drawn copper: on the MOSFETs that is a 4.75 x 4.61 mm drain tab. Freerouting routed /DRV_SHA straight across +VBAT because as far as it knew there was nothing there. Custom pads are now written as the convex hull of the anchor and every primitive (polygons and rects exactly, circles as circumscribed 16-gons, strokes widened by half their width). That is a superset of the real copper, so the router cannot cross it. Gate and drain pads no longer share one padstack just because their anchors are the same size. Shorts went 25 → 0 on B → C, and hole-clearance and solder-mask-bridge errors went to 0 with them.
  • Plane layers (1.0.18, default changed in 1.0.20). A layer KiCad declares power, or one whose copper zone covers at least half the board, can now go into the DSN as (type power): vias only, no signals. Outer layers never do, because parts sit there. But the data argued against making that the default. On this board, reserving both planes left 30 connections unrouted against 3, with the same clearance count. So reservePlanes defaults to false and is one argument away. The reply reports what leaving the planes open cost, as routed.segmentsOnPlaneLayers next to planeLayers, so an AI never presents a plane-cutting route as clean.
  • DSN rules. They already carried the board minimum (trackWidth 0.2, clearance 0.2, via 0.6/0.3) from the .kicad_pro in every run. The thin wires come from Freerouting, not from our rules block, which is why the fix is at import.

Still open, honestly

  • 6 clearance errors from routing in run D, all within 0.05 mm of the 0.2 mm rule, mostly around U2 pad 10 and U5 pad 6. They are real and small. Nothing in this issue explains them, so they get their own issue if they persist after the next route.
  • 3 unconnected, 1 net left unrouted by Freerouting in run D. The original had 7.

Code: rust/crates/kicad-core/src/dsn.rs (convex hull, custom primitives, plane detection) and crates/kicad-bridge/src/verbs_routing.rs (widened, reservePlanes, segmentsOnPlaneLayers). Unit tests: router_wire_thinner_than_the_class_is_widened_to_it, inner_plane_layers_are_reserved_as_power_and_outer_pours_are_not, and custom_pads_are_written_as_the_hull_of_their_real_copper (built on the MOSFET drain pad's real coordinates). 1.0.20 is on insiders.

John Lauer closed this ·

Log in to reply.