master
Name Last commit message Last updated
astra ESC demo: placement video (Fable and Astra), Astra's numbers, the honest wall-clock comparison · John Lauer 24d ago
clean ESC placement fixture: machine pins and contacts stay in place and locked (molecule interface) · John Lauer 24d ago
fable ESC demo: headline time is the wall clock from the prompt to the delivered result; charts, tables, stats and Astra prompts updated · John Lauer 23d ago
esc-g431-placement-fixture.json ESC G431 placement demo fixtures: unplaced and unrouted copies (clean variants without zones and board graphics), fixture tool, batch executor · John Lauer 24d ago
esc-g431-unplaced.kicad_pcb ESC G431 placement demo fixtures: unplaced and unrouted copies (clean variants without zones and board graphics), fixture tool, batch executor · John Lauer 24d ago
esc-g431-unrouted.kicad_pcb ESC G431 placement demo fixtures: unplaced and unrouted copies (clean variants without zones and board graphics), fixture tool, batch executor · John Lauer 24d ago
place_live.py ESC G431 placement demo fixtures: unplaced and unrouted copies (clean variants without zones and board graphics), fixture tool, batch executor · John Lauer 24d ago
README.md ESC G431 placement demo fixtures: unplaced and unrouted copies (clean variants without zones and board graphics), fixture tool, batch executor · John Lauer 24d ago

Placement demo fixture: the Adom ESC G431, unplaced and unrouted

Two copies of the public Adom ESC G431 board (ESC: G431 rev 2.0.1, 149 footprints, 4 copper layers, 64 x 74 mm, KiCad 10 file format (version 20260206)), made by tools/make_placement_fixture.py from the routed, placed original. They are the exercise for the placement verbs (kicad_placement_state, kicad_move_footprint, kicad_placement_validate, SKILL.md "Placement") and then for the routing verbs.

File What Size
esc-g431-unplaced.kicad_pcb Every footprint parked in a grid to the right of the outline, rotation 0, side kept; no copper; zones kept without fills 779 KB
esc-g431-unrouted.kicad_pcb The original placement; only the copper and the fills stripped 780 KB
esc-g431-placement-fixture.json The tool's summary for both copies

The numbers

  • Outline (Edge.Cuts box): x 104 to 168, y 58 to 132 mm.
  • Parking grid (unplaced copy): x 173 to 244.87, y 58 to 140.83 mm; 149 footprints in rows sorted by reference, 2 mm apart, starting 5 mm right of the outline. Every one is at rotation 0 and outside the outline; none collides with another (the bridge's courtyard check and KiCad's DRC both say zero overlaps).
  • Removed from both copies: 434 segments, 384 vias, 0 arcs, 57 zone fills (filled_polygon), 66 teardrop zones. Kept: the 49 user zones (pours on GND, +VBAT, +3V3, +5V, the phase nets), every footprint, every graphic, the setup block, the groups.
  • Everything else is byte for byte the source, CRLF line endings included: the tool parses the file with a span-keeping s-expression tokenizer and rewrites only the nodes that change. A parked footprint gets a new (at X Y); because KiCad stores pad and text angles as absolute values, each child angle is rewritten relative to the footprint's old rotation so the part looks the same at rotation 0.

Teardrop zones are KiCad's generated copper around pads and vias. They belong to the copper that was removed, so they go with it (pass --keep-teardrops to keep them).

What KiCad says about them

service-kicad pcb drc (KiCad 10.0.2) on both copies loads them without complaint:

Copy Errors Unconnected courtyards_overlap Notes
unplaced 13 271 0 six malformed_courtyard (Q1 to Q6, the source library's open courtyard shapes) and seven clearance errors between pads inside U2's own footprint; both are in the source board too
unrouted 14 271 1 the same, plus the source board's own TP2 against C28 courtyard overlap

271 unconnected items is the ratsnest to route once the parts are placed. The bridge's own parser reads both copies back with 149 footprints, zero segments, zero vias and 49 zones (rust/crates/kicad-core/tests/placement_fixture.rs).

Using it

  1. Copy esc-g431-unplaced.kicad_pcb somewhere the desktop's KiCad can open it (the project file is not needed; sibling .kicad_pro and .kicad_dru files are picked up by the DRC snapshot when present).
  2. Open it in the PCB editor with the IPC API server on (kicad_ipc_api {"enable":true}, relaunch), or start from the file: the read-only placement verbs answer from disk.
  3. kicad_placement_state {"filePath": ...}: 149 footprints, all parked, the ratsnest total around 4.2 m (the placed original measures about 1.5 m by the same estimate).
  4. Place with kicad_move_footprint, one part or cluster per call, following the recipe in SKILL.md. Each call is one native Undo step.
  5. kicad_placement_validate until placed is true and parked is empty, then route (kicad_autoroute engine ai, kicad_route_net) on what is now the unrouted board.

Rebuilding

python3 tools/make_placement_fixture.py --self-test
python3 tools/make_placement_fixture.py path/to/esc-g431.kicad_pcb --out demo/placement

Any placed .kicad_pcb with an Edge.Cuts outline works; the tool refuses a board without one, since there is nowhere to park relative to.