Commit Graph
4 Commits
Author SHA1 Message Date
rsp2k 0bee385e71 Add exact-geometry (orthogonal, DRC-clean) routing track
Adds route/exact_router.py: routes with the grid track's rip-up/multi-layer/
via topology search in orthogonal mode (axis-aligned segments -> exact IntBox
copper), then verifies clearance exactly against a ShapeSearchTree. A net
whose copper would come closer than the clearance to any accepted item is
dropped, so the emitted geometry is DRC-clean by construction; endpoints stay
exactly on pads and vias at real layer transitions.

GridRouter gains a non-breaking orthogonal option (4-connected). The pipeline
gains an engine= selector: 'grid' (default, unchanged, highest coverage) or
'exact' (DRC-verified). The grid MVP stays the fallback.

On the designed boards the exact track routes every net DRC-clean; on the
real KiCad board it matches the grid's connectivity (4/4 multi-pin nets) and
is DRC-clean where the grid MVP's widened centrelines are not. Deferred:
shove, and 45-degree/IntOctagon trace caps.

Tests: the exact router's output has no clearance violation (exact IntBox
check) on every fixture; endpoints on pads; traces orthogonal; crossing uses
a via; and a direct comparison showing the exact track is clean where the
grid MVP violates on the real board. Oracle-gated parity for engine='exact'.
2026-07-13 02:16:23 -06:00
rsp2k d44275f07b Add rip-up-and-retry to the maze router
Restructures the router so occupancy is tracked per connection, then adds
a rip-up-and-retry loop that recovers from bad greedy net orderings.

When a connection cannot reach its target through free space, a rip-up
search may pass through other nets' traces at an escalating penalty; the
router rips up the connections that path crosses (fully removing their
occupancy), routes the failing connection, and re-queues the ripped
connections. Passes iterate up to max_passes, keeping the best
(fewest-unrouted) result and stopping on full success or when a pass
changes nothing.

Thrash prevention: each connection may be ripped at most rip_cap times,
and the rip penalty escalates with a connection's rip count, so
repeatedly-ripped connections harden into walls. Fully deterministic
(sorted rip sets, connection-creation order, tuple-keyed A* — no RNG).

route()/route_dsn_board()/route_board() take rip_up and max_passes;
rip_up=False reproduces the previous greedy single-pass behaviour for
comparison. RouteResult now reports the unrouted connection count.
2026-07-12 13:38:40 -06:00
rsp2k 992bba82a0 Add multi-layer routing with vias
Extends the grid router with a layer axis: A* nodes are (col, row, layer),
in-plane moves stay on a layer, and a via move transitions between layers
at a cell for a configurable via_cost (so the router prefers one layer but
changes layers to get through). Occupancy is tracked per (cell, layer);
a through via must be clear on every signal layer and then blocks all of
them for other nets.

RouteResult now carries per-layer wire segments and per-net via locations.
The pipeline emits each segment on its layer and each via as
(via <padstack> x y), using the DSN's via padstack; wire and via
coordinates are converted from board units back to DSN units. route() and
route_dsn_board() take an optional layers= to restrict routing (e.g. a
single layer) for comparison.
2026-07-12 13:20:52 -06:00
rsp2k 89c0481ccc Add MVP grid maze router and DSN->SES routing pipeline
Implements a working autorouter and the Java-free replacement for the
freerouting.jar step: dsn_text -> parse_dsn -> build_board -> route ->
write_ses.

GridRouter is a single-layer A* maze search over a uniform occupancy
grid: a cell is blocked by another net's pad (inflated by clearance +
half trace width) or a keepout; each net's ratsnest is connected pin to
pin; a routed trace then blocks other nets. The cell path becomes a
trace polyline whose endpoints are the exact pin locations. Board-unit
paths are converted back to DSN units for the SES (wire (path ...))
scopes.

This is an MVP, not a port of FreeRouting's expansion-room maze:
free-space rooms, rip-up-and-retry, multi-layer via search, and shove
are deferred (they raise quality/coverage, not the connectivity
milestone). It reaches connectivity on boards whose nets route on one
layer without crossing.

Adds tests/dsn/fixtures/simple_2net.dsn (a guaranteed-routable 2-net
board). Invariant tests: both nets route, the emitted SES parses, every
trace stays on a valid layer and within the board outline, and every
routed net's trace endpoints sit exactly on its two pads. An oracle-gated
test asserts connectivity parity with the reference FreeRouting JAR on
the simple board.
2026-07-12 11:25:03 -06:00