step.motion.path.ir =================== .. py:module:: step.motion.path.ir .. autoapi-nested-parse:: Intermediate representation for the motion path pipeline. Compiler passes operate on ``list[PathNode]``: - ``Segment`` — one motion primitive (linear / turn / arc / follow_line / spline). - ``SideAction`` — a non-motion step pinned to a transition point. - ``None`` — placeholder for a deferred step resolved at runtime. These types are intentionally pure data — they hold no robot reference and no runtime state. Anything stateful (current motion, world tracker) lives in the executor / middleware layer. Attributes ---------- .. autoapisummary:: step.motion.path.ir.SENTINEL_DISTANCE_M step.motion.path.ir.PathNode Classes ------- .. autoapisummary:: step.motion.path.ir.Segment step.motion.path.ir.SideAction Module Contents --------------- .. py:data:: SENTINEL_DISTANCE_M :type: float :value: 100.0 .. py:class:: Segment One motion primitive extracted from a Step into the pipeline IR. Field semantics depend on ``kind``: - ``"linear"`` — ``axis``, ``sign``, ``distance_m``, ``speed_scale``, optional ``heading_deg`` and ``condition``. - ``"turn"`` — ``sign``, ``angle_rad``, ``speed_scale``, optional ``condition``. - ``"arc"`` — ``radius_m``, ``arc_angle_rad``, ``speed_scale``, ``lateral``. - ``"crab_arc"`` — ``radius_m``, ``arc_angle_rad``, ``speed_scale`` plus ``crab_from`` / ``crab_to`` (body-frame unit velocity directions at entry / exit). A constant-heading 90° corner blend for a holonomic base: the body velocity vector rotates from ``crab_from`` to ``crab_to`` over a quarter circle WITHOUT rotating the heading. Driven by a Python adapter (no warm-start unless profiled). Used by ``cut_corners`` for ``forward↔strafe`` corners. - ``"follow_line"`` — same shape as ``"linear"`` plus ``opaque_step`` (the original LineFollow step). Adapter delegates lifecycle to the step's ``on_start``/``on_update``. - ``"spline"`` — ``opaque_step`` (the SplinePath step). No warm-start. - ``"diagonal"`` — ``opaque_step`` (the DriveAngle step) plus the known body-frame displacement ``forward_m`` / ``left_m`` and ``distance_m``. Same opaque shape as a step; the travel direction is decoupled from the held heading. No warm-start. .. py:attribute:: kind :type: str .. py:attribute:: axis :type: raccoon.motion.LinearAxis | None :value: None .. py:attribute:: sign :type: float :value: 1.0 .. py:attribute:: distance_m :type: float | None :value: None .. py:attribute:: speed_scale :type: float :value: 1.0 .. py:attribute:: heading_deg :type: float | None :value: None .. py:attribute:: target_heading_rad :type: float | None :value: None .. py:attribute:: angle_rad :type: float | None :value: None .. py:attribute:: radius_m :type: float | None :value: None .. py:attribute:: arc_angle_rad :type: float | None :value: None .. py:attribute:: lateral :type: bool :value: False .. py:attribute:: crab_from :type: tuple[float, float] | None :value: None .. py:attribute:: crab_to :type: tuple[float, float] | None :value: None .. py:attribute:: forward_m :type: float | None :value: None .. py:attribute:: left_m :type: float | None :value: None .. py:attribute:: condition :type: step.condition.StopCondition | None :value: None .. py:attribute:: has_known_endpoint :type: bool :value: True .. py:attribute:: entry_speed_mps :type: float | None :value: None .. py:attribute:: exit_speed_mps :type: float | None :value: None .. py:attribute:: opaque_step :type: step.Step | None :value: None .. py:class:: SideAction A non-motion step pinned to a transition point in the path. ``is_background=True`` → fired as an asyncio task and not awaited inline. ``is_background=False`` → awaited inline before the next segment starts. ``ephemeral=True`` marks a background task SCOPED to a parallel() spine — a non-spine branch of ``parallel(motion_spine, branch)``. It runs concurrently with the spine but is JOINED at the next transition point (when the spine ends), preserving parallel()'s await-all semantics instead of leaking past its scope (which would, e.g., hold a servo while a later step tries to use it). A plain ``background()`` step is non-ephemeral — it persists until the path ends. Only meaningful together with ``is_background``. .. py:attribute:: step :type: step.Step .. py:attribute:: is_background :type: bool .. py:attribute:: ephemeral :type: bool :value: False .. py:data:: PathNode