freeroute/docs/PORTING_PLAN.md
Ryan Malloy 0270137b9f Scaffold freeroute: Python port of the FreeRouting engine
Pure-Python PCB autorouter replacing the freerouting.jar step in kicad-mcp.
Contract is Specctra DSN in, SES out — a drop-in for the JAR so the toolchain
needs no JVM. Includes pyproject (uv/ruff/pytest, src-layout) and a porting
plan seeded for study of the upstream FreeRouting Java source.
2026-07-11 14:51:42 -06:00

61 lines
2.8 KiB
Markdown

# FreeRouting → Python porting plan
> Seed document. The routing agent expands this after studying the upstream
> Java source. Treat sections marked _(TBD from source study)_ as the first
> research deliverable.
## Ground truth: study the source
Port from the **actual FreeRouting Java source**, not from the Specctra spec
alone. The algorithm details (rip-up-and-retry ordering, cost functions,
45°/free-angle geometry, autoroute vs. optimize passes) live in the code.
```bash
# Cloned into ./reference (gitignored — we don't vendor GPL source into history)
git clone --depth 1 https://github.com/freerouting/freerouting reference/freerouting
```
Key upstream packages to map first (verify paths against the clone):
- `app/freerouting/designforms/specctra/` — DSN/SES read/write. This is the
I/O boundary we must match byte-compatibly enough for `kicad-cli` to import.
- `app/freerouting/autoroute/` — the maze/rip-up router core.
- `app/freerouting/board/` — the routing board data model (items, traces, vias,
nets, clearance matrix).
- `app/freerouting/geometry/planar/` — points, lines, tile shapes, the
45°/free-angle geometry primitives.
## The contract (fixed)
Input: Specctra `.dsn`. Output: Specctra `.ses`. `kicad-cli pcb export
specctra-dsn` produces the input; `kicad-cli pcb import specctra-ses` consumes
the output. Match that I/O and the rest of `kicad-mcp` is unchanged.
## Phased roadmap
1. **DSN parser** — tokenize + parse the S-expression DSN into a typed board
model (layers, components, padstacks, nets, keepouts, rules/clearances).
First concrete, fully-testable module. Round-trip fixtures from `kicad-cli`.
2. **SES writer** — emit a minimal valid session file KiCad imports cleanly,
starting with an empty/no-op route to prove the I/O loop end to end.
3. **Board model + geometry** — planar primitives and the item/net/clearance
model the router operates on. _(TBD from source study.)_
4. **Autorouter core** — maze routing with rip-up-and-retry. Start grid-based
Manhattan/45° for an MVP; converge toward FreeRouting's approach. _(TBD.)_
5. **Optimize pass** — via minimization, trace smoothing. _(TBD.)_
6. **CLI + kicad-mcp integration**`freeroute board.dsn -o board.ses`, then
swap it in behind `kicad_mcp/utils/freerouting_engine.py`'s JAR step.
## Validation strategy
For any `.dsn`, FreeRouting's JAR gives a reference `.ses`. Diff our output
against it (connectivity first — every ratsnest resolved — then geometry).
The JVM stays available as an oracle during development even though the
shipped product has no Java dependency.
## Conventions
`uv` for everything, src-layout, ruff, pytest. Author: Ryan Malloy. Keep
modules small and single-purpose. Tests alongside every parser/writer from
the first commit.