step.motion.path.passes.corner_cut¶
Corner-cut pass — round a corner between two straight legs with an arc.
Two corner shapes are cut, both trimming cut_m from each straight leg:
Turn corner —
linear + turn + linear(the legs share an axis and direction; the heading rotates by the turn angle). Becomeslinear + arc + linearwithR = cut_m / tan(|θ| / 2). Works for forward AND strafe legs (astrafe + turn + strafecorner yields a lateral arc).Crab corner —
linear(Forward) + linear(Lateral)(or vice-versa) with NO turn between: a holonomic base changes travel direction by 90° WITHOUT rotating. Becomeslinear + crab_arc + linear— a constant-heading quarter circle of radiusR = cut_m(tan 45° = 1) that blends the body velocity from one leg’s direction into the other’s.
Only triples/pairs with known endpoints and no conditions are eligible.
SideAction and deferred-placeholder (None) entries act as barriers;
background / ephemeral parallel-branch side actions are skipped over (they run
concurrently with the motion) and re-emitted around the arc.
Classes¶
Compiler pass that rounds turn corners (arcs) and crab corners (crab arcs). |
Functions¶
|
Return |
|
Return |
|
Replace turn corners with arcs and crab corners with crab arcs. |
Module Contents¶
- step.motion.path.passes.corner_cut.try_corner_arc(lin1: step.motion.path.ir.Segment, turn: step.motion.path.ir.Segment, lin2: step.motion.path.ir.Segment, cut_m: float, cut_until: bool = False) tuple[step.motion.path.ir.Segment, step.motion.path.ir.Segment, step.motion.path.ir.Segment] | None¶
Return
(new_lin1, arc, new_lin2)for a turn corner, orNone.Geometry: cutting
cut_mfrom each leg at the corner requires an arc of radiusR = cut_m / tan(|θ| / 2). Both linears must be the same axis and direction (the heading rotates by the turn angle, so the path deflects by exactlyθ) and have enough distance to accommodate the cut. A pair of lateral (strafe) legs yields a lateral arc; forward legs a drive arc.The entry leg must be a known, trimmable distance. With
cut_untilthe EXIT leg may instead be a sensor-bounded.until()leg (kept untrimmed).
- step.motion.path.passes.corner_cut.try_crab_arc(lin1: step.motion.path.ir.Segment, lin2: step.motion.path.ir.Segment, cut_m: float, cut_until: bool = False) tuple[step.motion.path.ir.Segment, step.motion.path.ir.Segment, step.motion.path.ir.Segment] | None¶
Return
(new_lin1, crab_arc, new_lin2)for a crab corner, orNone.A crab corner is two perpendicular straight legs (one Forward, one Lateral) with NO turn between them: a holonomic base changes travel direction by 90° at constant heading. The fillet is a quarter circle of radius
R = cut_m / tan(45°) = cut_m; the executor’sCrabArcAdaptersweeps the body velocity fromlin1’s direction intolin2’s.The entry leg must be a known, trimmable distance. With
cut_untilthe EXIT leg may instead be a sensor-bounded.until()leg (kept untrimmed) — e.g.drive_backward(18) + strafe_left().until(over_line).
- step.motion.path.passes.corner_cut.run_corner_cut(nodes: list[step.motion.path.ir.PathNode | None], cut_m: float, cut_until: bool = False) list[step.motion.path.ir.PathNode | None]¶
Replace turn corners with arcs and crab corners with crab arcs.
At each position a
linear+turn+linearturn corner is tried first, then alinear+linearcrab corner. Non-blocking (background / ephemeral) side actions between the legs are skipped over for the match and re-emitted concurrently with the arc. Blocking side actions and deferred placeholders are barriers.With
cut_untilthe EXIT leg of a corner may be a sensor-bounded.until()leg (kept untrimmed, runs from the arc’s end until its condition). The entry leg always needs a known, trimmable distance.