Skip to content

Commit 6f1a4fd

Browse files
authored
Log instead of throw routing errors so best-effort route is drawn (#99)
1 parent 10fc5bb commit 6f1a4fd

File tree

3 files changed

+42
-32
lines changed

3 files changed

+42
-32
lines changed

src/paths/routes.jl

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ Last angle of a route, returns `r.α1`.
200200
reconcile!(path::Path, endpoint::Point, end_direction, rule::RouteRule, waypoints, waydirs;
201201
initialize_waydirs = false)
202202
203-
Ensure that `path` can be routed to `endpoint` at `end_direction` using `rule, waypoints, waydirs`, or throw an error.
203+
Ensure that `path` can be routed to `endpoint` at `end_direction` using `rule, waypoints, waydirs`, or log an error.
204204
205205
Does nothing for a generic `RouteRule`. Subtypes of `RouteRule` may implement specialized methods
206206
to do their own validation when `route!` is called.
@@ -234,9 +234,9 @@ function reconcile!(
234234
startdir = α1(path)
235235
= uconvert(°, rem(end_direction - startdir, 360°, RoundNearest))
236236

237-
isapprox((dα / α_bend), round(dα / α_bend), atol=1e-9) || error(
238-
"StraightAnd90 routing can only be used with start and end vectors on the same 4-point compass"
239-
)
237+
isapprox((dα / α_bend), round(dα / α_bend), atol=1e-9) ||
238+
@error "StraightAnd90 routing can only be used with start and end vectors on the same 4-point compass" _group =
239+
:route
240240

241241
i = 0
242242
while i < length(waypoints) + 1 # Waypoints may be added
@@ -252,9 +252,9 @@ function reconcile!(
252252
par = dx * dir_x + dy * dir_y
253253
perp = -dx * dir_y + dy * dir_x # perp > 0 requires +90° turn
254254

255-
par >= zero(par) || error(
256-
"StraightAnd90 routing cannot go backwards from $startpoint to $nextpoint. Try adding intermediate points."
257-
)
255+
par >= zero(par) ||
256+
@error "StraightAnd90 routing cannot go backwards from $startpoint to $nextpoint. Try adding intermediate points." _group =
257+
:route
258258

259259
sgn = isapprox(perp, zero(dx), atol=1e-6 * oneunit(dx)) ? 0 : sign(perp)
260260

@@ -263,9 +263,8 @@ function reconcile!(
263263
(abs(perp) >= rule.min_bend_radius || (abs(perp) rule.min_bend_radius)) &&
264264
(par >= rule.min_bend_radius || par rule.min_bend_radius)
265265
) ||
266-
error(
267-
"Required bend between $startpoint and $nextpoint is too sharp for single segment of StraightAnd90 routing"
268-
)
266+
@error "Required bend between $startpoint and $nextpoint is too sharp for single segment of StraightAnd90 routing" _group =
267+
:route
269268

270269
dα_01 = sgn * α_bend
271270
nextdir = startdir + dα_01 # direction after next turn
@@ -279,9 +278,8 @@ function reconcile!(
279278
elseif isapprox_angle(nextdir_target, startdir) && sgn != 0
280279
# Add an intermediate waypoint to snake to endpoint
281280
abs(perp) >= 2 * rule.min_bend_radius && par >= 2 * rule.min_bend_radius ||
282-
error(
283-
"Required bend between $startpoint and $((startpoint + nextpoint)/2) is too sharp for single segment of StraightAnd90 routing"
284-
)
281+
@error "Required bend between $startpoint and $((startpoint + nextpoint)/2) is too sharp for single segment of StraightAnd90 routing" _group =
282+
:route
285283
nextpoint = (startpoint + nextpoint) / 2
286284
insert!(waypoints, i, nextpoint)
287285
insert!(waydirs, i, nextdir)
@@ -306,9 +304,9 @@ function reconcile!(
306304
startdir = α1(path)
307305
= uconvert(°, rem(end_direction - startdir, 360°, RoundNearest))
308306

309-
isapprox((dα / α_bend), round(dα / α_bend), atol=1e-9) || error(
310-
"StraightAnd45 routing can only be used with start and end vectors on the same 8-point compass"
311-
)
307+
isapprox((dα / α_bend), round(dα / α_bend), atol=1e-9) ||
308+
@error "StraightAnd45 routing can only be used with start and end vectors on the same 8-point compass" _group =
309+
:route
312310

313311
i = 0
314312
while i < length(waypoints) + 1 # Waypoints may be added
@@ -324,9 +322,9 @@ function reconcile!(
324322
par = dx * dir_x + dy * dir_y
325323
perp = -dx * dir_y + dy * dir_x # perp > 0 requires +90° turn
326324

327-
par >= zero(par) || error(
328-
"StraightAnd45 routing cannot go backwards from $startpoint to $nextpoint. Try adding intermediate points."
329-
)
325+
par >= zero(par) ||
326+
@error "StraightAnd45 routing cannot go backwards from $startpoint to $nextpoint. Try adding intermediate points." _group =
327+
:route
330328

331329
sgn = isapprox(perp, zero(dx), atol=1e-6 * oneunit(dx)) ? 0 : sign(perp)
332330
dα_01 = sgn * α_bend
@@ -349,7 +347,8 @@ function reconcile!(
349347
d_diag = sqrt(2) * abs(perp) - d
350348
d_straight = abs(par) - abs(perp) - d
351349
d_diag > -1e-9 * oneunit(d) && d_straight > -1e-9 * oneunit(d) ||
352-
error("$nextpoint can't be reached from $startpoint with a 45° turn")
350+
@error "$nextpoint can't be reached from $startpoint with a 45° turn" _group =
351+
:route
353352
end
354353
# Otherwise, this is the endpoint or waydirs are initialized
355354
# If this is a snake, try to insert a waypoint
@@ -369,7 +368,8 @@ function reconcile!(
369368
d_diag = sqrt(2) * abs(perp / 2) - d
370369
d_straight = abs(par / 2) - abs(perp / 2) - d
371370
d_diag > -1e-9 * oneunit(d) && d_straight > -1e-9 * oneunit(d) ||
372-
error("Next point can't be reached with a pair of opposite 45° turns")
371+
@error "Next point can't be reached with a pair of opposite 45° turns" _group =
372+
:route
373373
# Add an intermediate waypoint to snake to endpoint
374374
# Pushing to waypoints won't cause confusion because this is the last iteration
375375
nextpoint = (startpoint + nextpoint) / 2
@@ -382,7 +382,8 @@ function reconcile!(
382382
# Check if double turn is possible
383383
abs(perp) < rule.min_bend_radius ||
384384
abs(par) < rule.min_bend_radius &&
385-
error("Next point can't be reached with a pair of 45° turns")
385+
@error "Next point can't be reached with a pair of 45° turns" _group =
386+
:route
386387
bend_r =
387388
max(rule.min_bend_radius, min(abs(perp), abs(par), rule.max_bend_radius))
388389

@@ -454,15 +455,15 @@ function route!(
454455
initialize_waydirs=initialize_waydirs
455456
)
456457
_route!(path, p_end, α_end, rule, sty, waypoints, waydirs)
457-
isapprox(rem(α1(path) - α_end, 360°, RoundNearest), 0, atol=1e-9) || error("""
458+
isapprox_angle(α1(path), α_end) || @error """
458459
Could not automatically route to destination with the correct arrival angle \
459460
(got $(α1(path)) instead of $α_end). Try adding or adjusting waypoints.\
460-
""")
461+
""" _group = :route
461462
pts = promote(p1(path), p_end)
462-
return isapprox(pts...; atol=atol) || error("""
463+
return isapprox(pts...; atol=atol) || @error """
463464
Could not automatically route to destination with the correct arrival point \
464465
(got $(p1(path)) instead of $p_end). Try adding or adjusting waypoints.\
465-
""")
466+
""" _group = :route
466467
end
467468

468469
"""
@@ -513,9 +514,10 @@ function route!(
513514
waydirs=Vector{typeof(1.0°)}(undef, length(waypoints))
514515
) where {S}
515516
sum(crr.leg_lengths) == length(waypoints) + 1 ||
516-
error("CompoundRouteRule leg lengths must match the number of waypoints + endpoint")
517+
@error "CompoundRouteRule leg lengths must match the number of waypoints + endpoint" _group =
518+
:route
517519
length(waydirs) == length(waypoints) ||
518-
error("CompoundRouteRule requires a direction for each waypoint")
520+
@error "CompoundRouteRule requires a direction for each waypoint" _group = :route
519521
leg_start = 1
520522
for (idx, leg_rule) in enumerate(crr.rules)
521523
if idx == length(crr.rules)

test/test_routes.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@
2626
α_start,
2727
α_end
2828
)
29-
@test_throws ErrorException pa = Path(r, sty)
29+
@test_logs (:error, r"Could not automatically route") match_mode = :any pa =
30+
Path(r, sty)
31+
@test length(pa) > 0 # Partial/best-effort route was drawn
3032

3133
r = Route(
3234
Paths.StraightAnd90(min_bend_radius=20, max_bend_radius=200),
@@ -35,7 +37,7 @@
3537
α_start,
3638
pi
3739
)
38-
@test_throws ErrorException (pa = Path(r, sty))
40+
@test_logs (:error, r"Could not automatically route") (pa = Path(r, sty))
3941

4042
r = Route(
4143
Paths.StraightAnd90(min_bend_radius=20, max_bend_radius=200),
@@ -126,7 +128,7 @@
126128
α_end,
127129
waypoints=waypoints
128130
)
129-
@test_throws ErrorException (pa = Path(r4, sty))
131+
@test_logs (:error, r"can't be reached") (pa = Path(r4, sty))
130132

131133
# Use StraightAnd45
132134
p_end = Point(200, 150)

test/test_schematicdriven.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,12 @@ end
215215
@test transformation(floorplan2, z_node2) == transformation(floorplan, z_node)
216216
@test transformation(floorplan2, xy_node2) == transformation(floorplan, xy_node)
217217

218+
# Reset matching hooks to something that returns original error
219+
SchematicDrivenLayout.matching_hook(t1::TestComponent, s::Symbol, ::TestComponent) =
220+
SchematicDrivenLayout.matching_hook(t1, s, Spacer())
221+
SchematicDrivenLayout.matching_hooks(t1::TestComponent, ::TestComponent) =
222+
SchematicDrivenLayout.matching_hooks(t1, Spacer())
223+
218224
@testset "Replace" begin
219225
append_x(tc, p) =
220226
TestComponent(name=(tc.name * "$(ustrip(mm, p.x))"), hooks=tc.hooks)
@@ -302,7 +308,7 @@ end
302308
@test SchematicDrivenLayout.max_level_logged(floorplan, :build) == Logging.Error
303309
@test contains(
304310
read(floorplan.logger.logname, String),
305-
"Failed to build RouteComponent"
311+
"Could not automatically route"
306312
)
307313
end
308314

0 commit comments

Comments
 (0)