Observe released router 715036e1 in frozen common harness

This commit is contained in:
2026-09-24 18:53:15 -07:00
parent 3ea0e23b70
commit 4fb3cdc721
+9 -166
View File
@@ -846,19 +846,15 @@ fn route_edge(
.enumerate()
{
let incoming = points.iter().rev().find(|&&p| p != start).copied();
// Only the final leg has a known continuation. Intermediate
// authored pins must not inherit the target's terminal direction.
let outgoing = (index == pins.len()).then_some(b.point);
let path =
fast_path(start, end, &space, &occupied, incoming, outgoing).or_else(|| {
if !search {
return None;
}
let (path, hit_limit) =
grid_path(start, end, &space, &occupied, incoming, outgoing, budget);
exhausted |= hit_limit;
path
});
let path = fast_path(start, end, &space, &occupied, incoming).or_else(|| {
if !search {
return None;
}
let (path, hit_limit) =
grid_path(start, end, &space, &occupied, incoming, budget);
exhausted |= hit_limit;
path
});
let Some(path) = path else {
failed = true;
break;
@@ -1055,7 +1051,6 @@ fn fast_path(
space: &RoutingSpace<'_>,
previous: &[Segment],
incoming: Option<Position>,
outgoing: Option<Position>,
) -> Option<Vec<Position>> {
let obstacles = space.obstacles;
if obstacles
@@ -1075,9 +1070,6 @@ fn fast_path(
incoming
.zip(path.get(1))
.map_or(0.0, |(before, &after)| turn_cost(before, start, after))
+ outgoing
.zip(path.len().checked_sub(2).and_then(|i| path.get(i)))
.map_or(0.0, |(after, &before)| turn_cost(before, end, after))
};
let estimate = |path: &[Position]| base_cost(path) + join(path);
candidates.sort_by(|a, b| estimate(a).total_cmp(&estimate(b)));
@@ -1149,14 +1141,12 @@ impl Ord for QueueItem {
}
}
#[allow(clippy::too_many_arguments)]
fn grid_path(
start: Position,
end: Position,
space: &RoutingSpace<'_>,
previous: &[Segment],
incoming: Option<Position>,
outgoing: Option<Position>,
budget: &mut usize,
) -> (Option<Vec<Position>>, bool) {
let obstacles = space.obstacles;
@@ -1247,10 +1237,6 @@ fn grid_path(
let cost = current.cost
+ manhattan(a, b)
+ before.map_or(0.0, |before| turn_cost(before, a, b))
// Charge before queueing the target so competing arrival
// directions are compared by their complete terminal cost.
+ outgoing.filter(|_| next == last)
.map_or(0.0, |after| turn_cost(a, b, after))
+ crossing_cost(a, b, previous);
if cost >= costs[state] {
continue;
@@ -1605,146 +1591,3 @@ impl BoundsBuilder {
}
}
}
#[cfg(test)]
mod terminal_join_tests {
use super::*;
fn complete_cost(
path: &[Position],
before: Position,
after: Position,
occupied: &[Segment],
) -> f32 {
let mut complete = vec![before];
complete.extend_from_slice(path);
complete.push(after);
path_cost(&complete, occupied)
}
#[test]
fn terminal_join_prefers_equal_bend_witness_without_shared_trunk() {
// Four orientations prevent an accidental horizontal/right-only fix.
for orientation in 0..4 {
let transform = |p: Position| match orientation {
0 => p,
1 => pos(-p.x, p.y),
2 => pos(p.y, p.x),
_ => pos(-p.y, -p.x),
};
let start = transform(pos(0.0, 0.0));
let end = transform(pos(46.0, 180.0));
let before = transform(pos(-18.0, 0.0));
let after = transform(pos(64.0, 180.0));
let occupied = vec![Segment {
a: start,
b: transform(pos(46.0, 0.0)),
count: 1,
}];
let space = RoutingSpace::new(&[]);
let witness = vec![start, transform(pos(0.0, 180.0)), end];
// Length262 + two turns48 =310. The other complete L path has
// the same bends/length but pays46*0.12=5.52 in shared-run cost.
assert!((complete_cost(&witness, before, after, &occupied) - 310.0).abs() < EPSILON);
let fast = fast_path(start, end, &space, &occupied, Some(before), Some(after)).unwrap();
assert_eq!(fast, witness);
assert!((complete_cost(&fast, before, after, &occupied) - 310.0).abs() < EPSILON);
// Exercise grid directly; public routing's valid fast path would
// otherwise hide a target-state ordering regression in grid search.
let mut budget = VIEW_SEARCH_BUDGET;
let (grid, exhausted) = grid_path(
start,
end,
&space,
&occupied,
Some(before),
Some(after),
&mut budget,
);
assert!(!exhausted);
let grid = grid.unwrap();
assert_eq!(grid, witness);
assert!((complete_cost(&grid, before, after, &occupied) - 310.0).abs() < EPSILON);
}
}
#[test]
fn unspecified_continuation_keeps_intermediate_leg_choice() {
let start = pos(0.0, 0.0);
let pin = pos(46.0, 180.0);
let before = pos(-18.0, 0.0);
let occupied = vec![Segment {
a: start,
b: pos(46.0, 0.0),
count: 1,
}];
let space = RoutingSpace::new(&[]);
let witness = vec![start, pos(46.0, 0.0), pin];
let fast = fast_path(start, pin, &space, &occupied, Some(before), None).unwrap();
assert_eq!(fast, witness);
// An intermediate authored pin has no known outgoing continuation:
// length226 + one turn24 + shared5.52 =255.52 for this leg.
assert!((path_cost(&fast, &occupied) - 255.52).abs() < EPSILON);
let mut budget = VIEW_SEARCH_BUDGET;
let (grid, exhausted) = grid_path(
start,
pin,
&space,
&occupied,
Some(before),
None,
&mut budget,
);
assert!(!exhausted);
assert_eq!(grid.unwrap(), witness);
}
#[test]
fn straight_and_degenerate_terminal_legs_remain_exact() {
let space = RoutingSpace::new(&[]);
let start = pos(0.0, 0.0);
let end = pos(46.0, 0.0);
for after in [pos(64.0, 0.0), pos(28.0, 0.0)] {
let before = pos(-18.0, 0.0);
let fast = fast_path(start, end, &space, &[], Some(before), Some(after)).unwrap();
let expected = if after.x > end.x { 82.0 } else { 130.0 };
assert!((complete_cost(&fast, before, after, &[]) - expected).abs() < EPSILON);
let mut budget = VIEW_SEARCH_BUDGET;
let (grid, exhausted) = grid_path(
start,
end,
&space,
&[],
Some(before),
Some(after),
&mut budget,
);
assert!(!exhausted);
assert_eq!(grid.unwrap(), fast);
}
assert_eq!(
fast_path(
start,
start,
&space,
&[],
Some(pos(-18.0, 0.0)),
Some(pos(18.0, 0.0))
)
.unwrap(),
vec![start]
);
let mut budget = VIEW_SEARCH_BUDGET;
let (grid, exhausted) = grid_path(
start,
start,
&space,
&[],
Some(pos(-18.0, 0.0)),
Some(pos(18.0, 0.0)),
&mut budget,
);
assert!(!exhausted);
assert_eq!(grid.unwrap(), vec![start]);
}
}