Write SES coordinates in resolution units, as FreeRouting does
SES lengths and coordinates were written in the DSN's unit while the session declared (resolution um 10), so readers that follow FreeRouting's SesWriter (KiCad's importer, mckicad's ses_apply) placed every track at a tenth of its size. The JAR, run on the same DSN, writes F1 at 65000 where freeroute wrote 6500. Scale every length by the resolution factor: placements, via padstack shapes, wire widths and points, and vias. Rotations stay as they are. The router tests compared SES output against DSN pad positions and so had the same mistake built in; they now derive the expected values through ses_scale.
This commit is contained in:
@@ -68,10 +68,10 @@ def test_placement_echoes_components(board):
|
||||
comps = placement.children("component")
|
||||
names = [c.values()[0].text for c in comps]
|
||||
assert names == ["MiniQFN-6", "0603"]
|
||||
# U1 place: coords rounded to int, side, rotation
|
||||
# U1 place: coords in resolution units (um x10), side, rotation (unscaled)
|
||||
u1 = comps[0].child("place")
|
||||
vals = [v.text for v in u1.values()]
|
||||
assert vals == ["U1", "75000", "-45000", "front", "90"]
|
||||
assert vals == ["U1", "750000", "-450000", "front", "90"]
|
||||
|
||||
|
||||
def test_library_out_echoes_via_padstack(board):
|
||||
@@ -107,21 +107,22 @@ def test_routed_wire_path_and_via(board, routed):
|
||||
wire = child(net_a, "wire")
|
||||
path = child(wire, "path")
|
||||
pvals = [v.text for v in path.values()]
|
||||
# (path <layer> <width> x1 y1 x2 y2)
|
||||
assert pvals == ["Top", "200", "0", "0", "1000", "-500"]
|
||||
# (path <layer> <width> x1 y1 x2 y2), DSN um scaled to resolution units (x10)
|
||||
assert pvals == ["Top", "2000", "0", "0", "10000", "-5000"]
|
||||
|
||||
via = child(net_a, "via")
|
||||
vvals = [v.text for v in via.values()]
|
||||
assert vvals == ["Via[0-1]_600:300_um", "1000", "-500"]
|
||||
assert vvals == ["Via[0-1]_600:300_um", "10000", "-5000"]
|
||||
|
||||
|
||||
def test_coordinates_are_integers(board):
|
||||
result = RoutingResult()
|
||||
result.add_wire("NET_A", RoutedWire(layer="Top", width=199.6, coords=[0.4, -0.4, 2.5, 3.5]))
|
||||
result.add_wire("NET_A", RoutedWire(layer="Top", width=19.96, coords=[0.04, -0.04, 0.25, 0.35]))
|
||||
routes = child(parse(write_ses(board, result)), "routes")
|
||||
path = child(child(child(routes, "network_out").children("net")[0], "wire"), "path")
|
||||
pvals = [v.text for v in path.values()]
|
||||
# width 199.6 -> 200; coords 0.4->0, -0.4->0, 2.5->3, 3.5->4 (round half up)
|
||||
# scaled x10 first: width 199.6 -> 200; coords 0.4->0, -0.4->0, 2.5->3, 3.5->4
|
||||
# (round half up)
|
||||
assert pvals == ["Top", "200", "0", "0", "3", "4"]
|
||||
assert all("." not in v for v in pvals)
|
||||
|
||||
@@ -137,3 +138,25 @@ def test_round_trip_from_empty_board_fixture():
|
||||
assert top.values()[0].text == "freeroute-empty.ses"
|
||||
# empty board has no placements -> placement scope has no components
|
||||
assert child(top, "placement").children("component") == []
|
||||
|
||||
|
||||
# --- SES coordinate units ---------------------------------------------------
|
||||
# FreeRouting's SesWriter writes coordinates in resolution units, and KiCad's
|
||||
# importer and mckicad's ses_apply read them that way. On 2026-09-26 freeroute
|
||||
# was found writing DSN units instead, so every routed board came back 10x small.
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("resolution", "unit", "expected"),
|
||||
[
|
||||
("(resolution um 10)", "(unit um)", 10.0), # kicad-cli / pcbnew DSN
|
||||
("(resolution mil 1000)", "(unit mil)", 1000.0),
|
||||
("(resolution um 10)", "(unit mm)", 10000.0), # unit differs from resolution unit
|
||||
],
|
||||
)
|
||||
def test_ses_scale(resolution, unit, expected):
|
||||
from freeroute.dsn import parse_dsn
|
||||
from freeroute.ses.writer import ses_scale
|
||||
|
||||
dsn = parse_dsn(f"(pcb t (parser) {resolution} {unit} (structure) (placement) (library) (network))")
|
||||
assert ses_scale(dsn) == pytest.approx(expected)
|
||||
|
||||
Reference in New Issue
Block a user