step.motion.path.motion_factory

Motion factory — constructs a controller for one Segment.

The executor calls create_motion(robot, seg, is_last) and gets back an object with the uniform motion-controller interface:

motion.start() motion.start_warm(offset, velocity) motion.update(dt) motion.is_finished() motion.has_reached_distance() / .has_reached_angle() motion.get_filtered_velocity() motion.set_suppress_hard_stop(bool)

For linear / turn / arc kinds, this is the corresponding C++ LinearMotion / TurnMotion / ArcMotion class directly.

For follow_line / spline / diagonal kinds, the Python step is wrapped in an adapter that translates the MotionStep lifecycle (on_start, on_update(robot, dt)) to the uniform interface.

Attributes

OVERSHOOT_M

OVERSHOOT_RAD

Classes

LineFollowAdapter

Adapts a LineFollow/SingleSensorLineFollow step to the C++ motion API.

TurnHeadingAdapter

Adapts a TurnToHeading step to the C++ motion API.

DriveAngleAdapter

Adapts a DriveAngle (true diagonal) step to the C++ motion API.

CrabArcAdapter

Drives a constant-heading 90° corner blend (crab_arc).

SplineAdapter

Adapts a SplinePath step to the C++ motion API.

Functions

create_motion(robot, seg, is_last[, ...])

Construct a controller for the given segment kind.

Module Contents

step.motion.path.motion_factory.OVERSHOOT_M = 1.0
step.motion.path.motion_factory.OVERSHOOT_RAD = 3.0
class step.motion.path.motion_factory.LineFollowAdapter(step, robot: raccoon.robot.api.GenericRobot)

Adapts a LineFollow/SingleSensorLineFollow step to the C++ motion API.

Delegates to the step’s on_start/on_update lifecycle and forwards completion queries to the internal LinearMotion. Supports warm-start for seamless velocity hand-off from a preceding forward linear segment.

start() None
start_warm(offset: float, velocity: float) None
update(dt: float) None
is_finished() bool
has_reached_distance() bool
get_filtered_velocity() float
set_suppress_hard_stop(val: bool) None
class step.motion.path.motion_factory.TurnHeadingAdapter(step, robot: raccoon.robot.api.GenericRobot)

Adapts a TurnToHeading step to the C++ motion API.

Delegates to the step’s on_start/on_update lifecycle. The step resolves its absolute target heading (via the HeadingReferenceService) and builds its own TurnMotion at on_start, so this adapter only tracks completion. Turns never warm-start, so start_warm is a cold start.

start() None
start_warm(offset: float, velocity: float) None
update(dt: float) None
is_finished() bool
has_reached_angle() bool
get_filtered_velocity() float
set_suppress_hard_stop(val: bool) None
class step.motion.path.motion_factory.DriveAngleAdapter(step, robot: raccoon.robot.api.GenericRobot)

Adapts a DriveAngle (true diagonal) step to the C++ motion API.

Delegates to the step’s on_start/on_update lifecycle. The underlying DiagonalMotion has no guaranteed warm-start, so every transition into a diagonal uses a cold start.

start() None
start_warm(offset: float, velocity: float) None
update(dt: float) None
is_finished() bool
has_reached_distance() bool
get_filtered_velocity() float
set_suppress_hard_stop(val: bool) None
class step.motion.path.motion_factory.CrabArcAdapter(seg: step.motion.path.ir.Segment, robot: raccoon.robot.api.GenericRobot)

Drives a constant-heading 90° corner blend (crab_arc).

A holonomic base can round a forward↔strafe corner without rotating: the body-frame velocity vector is swept from the entry leg’s travel direction (crab_from) to the exit leg’s (crab_to) along a quarter circle of radius R = seg.radius_m, while a proportional controller holds the heading captured at start. Progress is the path length travelled (read from odometry); the arc angle is α = travelled / R and the blend completes at α = arc_angle_rad (π/2).

No C++ motion backs this — like DriveAngle it commands chassis velocity directly. It never relies on a trapezoidal profile, so a cold start and a profiled start_warm both simply begin commanding the blend at cruise (or the carried) speed; inflate is irrelevant.

start() None
start_warm(offset: float, velocity: float) None
update(dt: float) None
is_finished() bool
has_reached_distance() bool
get_filtered_velocity() float
set_suppress_hard_stop(val: bool) None
class step.motion.path.motion_factory.SplineAdapter(step, robot: raccoon.robot.api.GenericRobot)

Adapts a SplinePath step to the C++ motion API.

SplineMotion does not support warm-start; cross-type transitions to/from spline segments always use a cold start.

start() None
start_warm(offset: float, velocity: float) None
update(dt: float) None
is_finished() bool
has_reached_distance() bool
get_filtered_velocity() float
set_suppress_hard_stop(val: bool) None
step.motion.path.motion_factory.create_motion(robot: raccoon.robot.api.GenericRobot, seg: step.motion.path.ir.Segment, is_last: bool, current_world_heading_rad: float | None = None, inflate: bool | None = None)

Construct a controller for the given segment kind.

current_world_heading_rad is the absolute world heading at the moment the executor is about to start this segment, read from robot.localization.get_pose().heading. Used by linear segments that have no user-specified heading_deg and by absolute turn segments bridged from the Phase-5 plan IR. Ignored by arc and by the opaque follow_line / spline adapters (those steps fetch the heading themselves).

inflate controls profile-overshoot inflation: True cruises through the endpoint (only correct when the next segment warm-starts from this one), False decelerates to the real target (cross-type / blocked / last). Defaults (None) to not is_last for back-compat. The executor passes the look-ahead result so short moves before a direction change stop on target instead of overshooting.