improve heuristic
This commit is contained in:
parent
51d8ddca51
commit
6ec953b76e
2 changed files with 48 additions and 3 deletions
|
|
@ -41,3 +41,4 @@ class CostConfig:
|
|||
congestion_penalty: float = 10000.0
|
||||
bend_penalty: float = 250.0
|
||||
sbend_penalty: float = 500.0
|
||||
min_bend_radius: float = 50.0
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ from __future__ import annotations
|
|||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import numpy as np
|
||||
from inire.router.config import CostConfig
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
|
@ -41,6 +42,7 @@ class CostEvaluator:
|
|||
congestion_penalty: float = 10000.0,
|
||||
bend_penalty: float = 250.0,
|
||||
sbend_penalty: float = 500.0,
|
||||
min_bend_radius: float = 50.0,
|
||||
) -> None:
|
||||
"""
|
||||
Initialize the Cost Evaluator.
|
||||
|
|
@ -53,6 +55,7 @@ class CostEvaluator:
|
|||
congestion_penalty: Multiplier for path overlaps in negotiated congestion.
|
||||
bend_penalty: Base cost for 90-degree bends.
|
||||
sbend_penalty: Base cost for parametric S-bends.
|
||||
min_bend_radius: Minimum radius for 90-degree bends (used for alignment heuristic).
|
||||
"""
|
||||
self.collision_engine = collision_engine
|
||||
self.danger_map = danger_map
|
||||
|
|
@ -62,6 +65,7 @@ class CostEvaluator:
|
|||
congestion_penalty=congestion_penalty,
|
||||
bend_penalty=bend_penalty,
|
||||
sbend_penalty=sbend_penalty,
|
||||
min_bend_radius=min_bend_radius,
|
||||
)
|
||||
|
||||
# Use config values
|
||||
|
|
@ -90,10 +94,50 @@ class CostEvaluator:
|
|||
dy = abs(current.y - target.y)
|
||||
dist = dx + dy
|
||||
|
||||
bp = self.config.bend_penalty
|
||||
penalty = 0.0
|
||||
if abs(current.orientation - target.orientation) > 0.1:
|
||||
# Needs at least 1 bend
|
||||
penalty += 10.0 + self.config.bend_penalty * 0.1
|
||||
|
||||
# 1. Orientation Difference
|
||||
# diff in degrees, normalized to [0, 360)
|
||||
diff = abs(current.orientation - target.orientation) % 360
|
||||
if diff > 0.1:
|
||||
if abs(diff - 180) < 0.1:
|
||||
penalty += 2 * bp
|
||||
else: # 90 or 270 degree rotation
|
||||
penalty += 1 * bp
|
||||
|
||||
# 2. Side Check (Entry half-plane)
|
||||
target_rad = np.radians(target.orientation)
|
||||
# Vector from current to target
|
||||
v_dx = target.x - current.x
|
||||
v_dy = target.y - current.y
|
||||
# Projection of current->target onto target orientation vector
|
||||
# Should be positive if we are on the "entry" side of the port
|
||||
side_proj = v_dx * np.cos(target_rad) + v_dy * np.sin(target_rad)
|
||||
|
||||
# Perpendicular distance to the target's travel line
|
||||
perp_dist = abs(v_dx * np.sin(target_rad) - v_dy * np.cos(target_rad))
|
||||
min_radius = self.config.min_bend_radius
|
||||
|
||||
if side_proj < -0.1 or (side_proj < min_radius and perp_dist > 0.1):
|
||||
# Wrong side or too close to turn into port
|
||||
penalty += 2 * bp
|
||||
|
||||
# 3. Traveling Away
|
||||
curr_rad = np.radians(current.orientation)
|
||||
# Projection of current->target onto current orientation vector
|
||||
# Should be positive if we are moving towards the target's general location
|
||||
move_proj = v_dx * np.cos(curr_rad) + v_dy * np.sin(curr_rad)
|
||||
if move_proj < -0.1:
|
||||
# Traveling away from the port
|
||||
penalty += 2 * bp
|
||||
|
||||
# 4. Jog Alignment
|
||||
# If orientations match, check if we are on the same line (jog alignment)
|
||||
if diff < 0.1:
|
||||
if perp_dist > 0.1:
|
||||
# Same orientation but different jog coordinate needs 2 bends (S-turn)
|
||||
penalty += 2 * bp
|
||||
|
||||
return self.greedy_h_weight * (dist + penalty)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue