Don't cost a pin stub for a route that ends on a plane

A plane end is marked with its zone, not a pin, so a route from a pad
outside the plane's outline crashed looking for the pin's location
(the flight-controller board's first placement).
This commit is contained in:
2026-09-28 19:55:07 -06:00
parent 019b043cd5
commit 245cd91c0e
2 changed files with 15 additions and 2 deletions
+3 -2
View File
@@ -451,10 +451,11 @@ class GridRouter:
g_score: dict[Node, float] = {}
came_from: dict[Node, Node] = {}
# a stub costs its length, so the nearest cell wins unless it is blocked
goal_stub = {n: self._stub_cost(p, n) for n, p in goals.items() if p is not None}
# a pin end costs its stub; a zone or plane end is entered normally
goal_stub = {n: self._stub_cost(p, n) for n, p in goals.items() if isinstance(p, Pin)}
for s in sorted(starts):
pin = starts[s]
g_score[s] = self._stub_cost(pin, s) if pin is not None else 0.0
g_score[s] = self._stub_cost(pin, s) if isinstance(pin, Pin) else 0.0
heapq.heappush(open_heap, (g_score[s] + self._h(s, goal_cell), s))
# Via footprints are checked lazily: a layer change goes on the heap as
+12
View File
@@ -202,6 +202,18 @@ def test_smd_pads_reach_an_inner_plane_by_their_own_via():
assert all(names[layer] in ("F.Cu", "B.Cu") for segs in result.result.wires.values() for layer, _ in segs)
def test_a_pad_outside_the_plane_routes_to_it():
# G1 sits left of a plane that covers only the right half, so its route
# has to reach the plane's cells: those ends are the plane, not a pin
dsn_text = _four_layer_dsn().replace(
"(plane GND (polygon In1.Cu 0 500 -500 29500 -500 29500 -29500 500 -29500 500 -500))",
"(plane GND (polygon In1.Cu 0 15000 -500 29500 -500 29500 -29500 15000 -29500 15000 -500))",
)
result, _scale, _names = route_dsn_board_exact(parse_dsn(dsn_text))
gnd = next(i + 1 for i, n in enumerate(parse_dsn(dsn_text).nets) if n.name == "GND")
assert gnd in result.result.routed_net_numbers
def test_a_through_hole_pad_inside_a_plane_needs_no_route():
from freeroute.route.grid_router import _connected_groups