step.motion.path.passes.corner_cut ================================== .. py:module:: step.motion.path.passes.corner_cut .. autoapi-nested-parse:: 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). Becomes ``linear + arc + linear`` with ``R = cut_m / tan(|θ| / 2)``. Works for forward AND strafe legs (a ``strafe + turn + strafe`` corner 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. Becomes ``linear + crab_arc + linear`` — a constant-heading quarter circle of radius ``R = 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 ------- .. autoapisummary:: step.motion.path.passes.corner_cut.CornerCutPass Functions --------- .. autoapisummary:: step.motion.path.passes.corner_cut.try_corner_arc step.motion.path.passes.corner_cut.try_crab_arc step.motion.path.passes.corner_cut.run_corner_cut Module Contents --------------- .. py:function:: 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, or ``None``. Geometry: cutting ``cut_m`` from each leg at the corner requires an arc of radius ``R = 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_until`` the EXIT leg may instead be a sensor-bounded ``.until()`` leg (kept untrimmed). .. py:function:: 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, or ``None``. 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's ``CrabArcAdapter`` sweeps the body velocity from ``lin1``'s direction into ``lin2``'s. The entry leg must be a known, trimmable distance. With ``cut_until`` the EXIT leg may instead be a sensor-bounded ``.until()`` leg (kept untrimmed) — e.g. ``drive_backward(18) + strafe_left().until(over_line)``. .. py:function:: 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+linear`` turn corner is tried first, then a ``linear+linear`` crab 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_until`` the 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. .. py:class:: CornerCutPass(cut_m: float, cut_until: bool = False) Compiler pass that rounds turn corners (arcs) and crab corners (crab arcs). .. py:attribute:: name :value: 'corner_cut' .. py:attribute:: cut_m .. py:attribute:: cut_until :value: False .. py:method:: run(nodes: list[step.motion.path.ir.PathNode | None]) -> list[step.motion.path.ir.PathNode | None]