more bend-related work
This commit is contained in:
parent
43a9a6cb3a
commit
556241bae3
4 changed files with 92 additions and 2 deletions
25
DOCS.md
25
DOCS.md
|
|
@ -51,3 +51,28 @@ The `CostEvaluator` defines the "goodness" of a path.
|
||||||
- **Coordinates**: Micrometers (µm).
|
- **Coordinates**: Micrometers (µm).
|
||||||
- **Grid Snapping**: The router internally operates on a **1nm** grid for final ports and a **1µm** lattice for expansion moves.
|
- **Grid Snapping**: The router internally operates on a **1nm** grid for final ports and a **1µm** lattice for expansion moves.
|
||||||
- **Search Space**: Assumptions are optimized for design areas up to **20mm x 20mm**.
|
- **Search Space**: Assumptions are optimized for design areas up to **20mm x 20mm**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Best Practices & Tuning Advice
|
||||||
|
|
||||||
|
### Speed vs. Optimality
|
||||||
|
The `greedy_h_weight` is your primary lever for search performance.
|
||||||
|
- **`1.0`**: Dijkstra-like behavior. Guarantees the shortest path but is very slow.
|
||||||
|
- **`1.1` to `1.2`**: Recommended range. Balances wire length with fast convergence.
|
||||||
|
- **`> 1.5`**: Extremely fast "greedy" search. May produce zig-zags or suboptimal detours.
|
||||||
|
|
||||||
|
### Avoiding "Zig-Zags"
|
||||||
|
If the router produces many small bends instead of a long straight line:
|
||||||
|
1. Increase `bend_penalty` (e.g., set to `100.0` or higher).
|
||||||
|
2. Ensure `straight_lengths` includes larger values like `25.0` or `100.0`.
|
||||||
|
3. Decrease `greedy_h_weight` closer to `1.0`.
|
||||||
|
|
||||||
|
### Handling Congestion
|
||||||
|
In multi-net designs, if nets are overlapping:
|
||||||
|
1. Increase `congestion_penalty` in `CostEvaluator`.
|
||||||
|
2. Increase `max_iterations` in `PathFinder`.
|
||||||
|
3. If a solution is still not found, check if the `clearance` is physically possible given the design's narrowest bottlenecks.
|
||||||
|
|
||||||
|
### S-Bend Usage
|
||||||
|
Parametric S-bends are triggered by the `sbend_offsets` list. If you need a specific lateral shift (e.g., 5.86µm for a 45° switchover), add it to `sbend_offsets`. The router will only use an S-bend if it can reach a state that is exactly on the lattice or the target.
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ from shapely.geometry import Polygon
|
||||||
from inire.geometry.collision import CollisionEngine
|
from inire.geometry.collision import CollisionEngine
|
||||||
from inire.geometry.primitives import Port
|
from inire.geometry.primitives import Port
|
||||||
from inire.router.astar import AStarRouter
|
from inire.router.astar import AStarRouter
|
||||||
from inire.router.config import CostConfig, RouterConfig
|
|
||||||
from inire.router.cost import CostEvaluator
|
from inire.router.cost import CostEvaluator
|
||||||
from inire.router.danger_map import DangerMap
|
from inire.router.danger_map import DangerMap
|
||||||
from inire.router.pathfinder import PathFinder
|
from inire.router.pathfinder import PathFinder
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
|
|
@ -1,7 +1,9 @@
|
||||||
|
import numpy as np
|
||||||
import pytest
|
import pytest
|
||||||
|
from shapely.geometry import Point
|
||||||
|
|
||||||
from inire.geometry.components import Bend90, SBend, Straight
|
from inire.geometry.components import Bend90, SBend, Straight
|
||||||
from inire.geometry.primitives import Port
|
from inire.geometry.primitives import Port, rotate_port, translate_port
|
||||||
|
|
||||||
|
|
||||||
def test_straight_generation() -> None:
|
def test_straight_generation() -> None:
|
||||||
|
|
@ -90,3 +92,67 @@ def test_sbend_collision_models() -> None:
|
||||||
|
|
||||||
res_arc = SBend.generate(start, offset, radius, width, collision_type="arc")
|
res_arc = SBend.generate(start, offset, radius, width, collision_type="arc")
|
||||||
assert res_bbox.geometry[0].area > res_arc.geometry[0].area
|
assert res_bbox.geometry[0].area > res_arc.geometry[0].area
|
||||||
|
|
||||||
|
|
||||||
|
def test_sbend_continuity() -> None:
|
||||||
|
# Verify SBend endpoints and continuity math
|
||||||
|
start = Port(10, 20, 90) # Starting facing up
|
||||||
|
offset = 4.0
|
||||||
|
radius = 20.0
|
||||||
|
width = 1.0
|
||||||
|
|
||||||
|
res = SBend.generate(start, offset, radius, width)
|
||||||
|
|
||||||
|
# Target orientation should be same as start
|
||||||
|
assert abs(res.end_port.orientation - 90.0) < 1e-6
|
||||||
|
|
||||||
|
# For a port at 90 deg, +offset is a shift in -x direction
|
||||||
|
assert abs(res.end_port.x - (10.0 - offset)) < 1e-6
|
||||||
|
|
||||||
|
# Geometry should be connected (unary_union results in 1 polygon)
|
||||||
|
assert len(res.geometry) == 1
|
||||||
|
assert res.geometry[0].is_valid
|
||||||
|
|
||||||
|
|
||||||
|
def test_arc_sagitta_precision() -> None:
|
||||||
|
# Verify that requested sagitta actually controls segment count
|
||||||
|
start = Port(0, 0, 0)
|
||||||
|
radius = 100.0 # Large radius to make sagitta significant
|
||||||
|
width = 2.0
|
||||||
|
|
||||||
|
# Coarse: 1um sagitta
|
||||||
|
res_coarse = Bend90.generate(start, radius, width, sagitta=1.0)
|
||||||
|
# Fine: 0.01um (10nm) sagitta
|
||||||
|
res_fine = Bend90.generate(start, radius, width, sagitta=0.01)
|
||||||
|
|
||||||
|
# Number of segments should be significantly higher for fine
|
||||||
|
# Exterior points = (segments + 1) * 2
|
||||||
|
pts_coarse = len(res_coarse.geometry[0].exterior.coords)
|
||||||
|
pts_fine = len(res_fine.geometry[0].exterior.coords)
|
||||||
|
|
||||||
|
assert pts_fine > pts_coarse * 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_component_transform_invariance() -> None:
|
||||||
|
# Verify that generating at (0,0) then transforming
|
||||||
|
# is same as generating at the transformed port.
|
||||||
|
start0 = Port(0, 0, 0)
|
||||||
|
radius = 10.0
|
||||||
|
width = 2.0
|
||||||
|
|
||||||
|
res0 = Bend90.generate(start0, radius, width, direction="CCW")
|
||||||
|
|
||||||
|
# Transform: Translate (10, 10) then Rotate 90
|
||||||
|
dx, dy = 10.0, 5.0
|
||||||
|
angle = 90.0
|
||||||
|
|
||||||
|
# 1. Transform the generated geometry
|
||||||
|
p_end_transformed = rotate_port(translate_port(res0.end_port, dx, dy), angle)
|
||||||
|
|
||||||
|
# 2. Generate at transformed start
|
||||||
|
start_transformed = rotate_port(translate_port(start0, dx, dy), angle)
|
||||||
|
res_transformed = Bend90.generate(start_transformed, radius, width, direction="CCW")
|
||||||
|
|
||||||
|
assert abs(res_transformed.end_port.x - p_end_transformed.x) < 1e-6
|
||||||
|
assert abs(res_transformed.end_port.y - p_end_transformed.y) < 1e-6
|
||||||
|
assert abs(res_transformed.end_port.orientation - p_end_transformed.orientation) < 1e-6
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue