Discretization
The A* routing functions (add_route_astar and add_bundle_astar) don't
search the layout continuously — internally they project everything onto a
uniform grid and search over that. Two consequences for you as a user:
- Routes always step on grid lines. The router won't return a path finer than the grid pitch.
- Obstacles are taken cell-by-cell. A cell that any obstacle polygon touches is treated as fully blocked.
The grid_unit parameter (in dbu) controls how fine that grid is. There's a
trade-off:
- Coarser grids (larger
grid_unit) search faster, but can miss valid routes that thread through narrow gaps and produce more "boxy" paths around obstacles. - Finer grids (smaller
grid_unit) follow obstacles more accurately and squeeze through tighter spaces, but the search space grows fast — A* slows down quadratically with the grid pitch.
There's also a hard lower bound: grid_unit must be at most half the
bend radius. The router enforces this because the bend's geometry
needs at least two grid cells along each axis to be representable. A
useful starting point is somewhere in [radius / 20, radius / 4] —
this notebook shows the difference between the two ends of that range.
Imports
import gdsfactory as gf
from gdsfactory.gpdk import PDK
import gdsfactoryplus as gfp
dr = gfp.routing.doroutes
PDK.activate()
A Route at a Coarse Grid
Routing on field1 with grid_unit = 2500 dbu (2.5 µm — exactly half
the 5 µm bend radius, the coarsest the router will accept). The
search has limited freedom: every step has to be a multiple of 2.5 µm,
so the route can only make wide detours and the path looks blocky.
c = gf.Component()
ref = c << dr.pcells.field1()
dr.add_route_astar(
component=c,
start=ref.ports["o1"],
stop=ref.ports["o2"],
straight="straight",
bend={"component": "bend_euler", "settings": {"radius": 5}},
layers=["WG"],
grid_unit=2500,
)
dr.util.show_cell(c)
API key for organization 'GDSFactory' found.
Same Route at a Finer Grid
Same start, stop, and obstacles, with grid_unit = 250 dbu (0.25 µm —
a twentieth of the bend radius). The router has many more grid points
to work with, so the path can hug obstacles closely and take a more
compact route.
c = gf.Component()
ref = c << dr.pcells.field1()
dr.add_route_astar(
component=c,
start=ref.ports["o1"],
stop=ref.ports["o2"],
straight="straight",
bend={"component": "bend_euler", "settings": {"radius": 5}},
layers=["WG"],
grid_unit=250,
)
dr.util.show_cell(c)
API key for organization 'GDSFactory' found.