step.motion.drive_until_impact

Drive straight until an obstacle is hit, recording how far the robot got.

Drives at constant velocity (no heading correction) and watches the IMU’s gravity-compensated linear acceleration for a collision spike, exactly like wall_align. The difference is the result: instead of settling flush against a wall, this step snapshots the odometer at start and stores the distance travelled at the moment of impact.

The point is collision-aware distancing. You drive forward expecting to reach some nominal distance, but a game piece may be in the way. When the bump fires early, step.impact_result.forward_cm tells you how far you actually got, so a following step can drive back exactly that far (minus a clearance) instead of a fixed amount.

Classes

ImpactResult

Outcome of a drive_until_impact() run.

DriveUntilImpact

Drive straight until a collision is detected, measuring the distance driven.

Functions

drive_until_impact_back([max_cm, clearance_cm, speed, ...])

Drive forward until impact, then reverse exactly as far as was driven.

Module Contents

class step.motion.drive_until_impact.ImpactResult

Outcome of a drive_until_impact() run.

impacted: bool

True if a collision spike stopped the step; False if it reached max_cm (or timed out) without hitting anything.

forward_cm: float

Distance the robot actually drove before stopping, in centimeters. Always positive regardless of drive direction. This is the value you feed back into a drive-back step.

accel_magnitude: float

XY linear-acceleration magnitude at impact in m/s² (0.0 if no bump was detected).

class step.motion.drive_until_impact.DriveUntilImpact(max_cm: float = 50.0, speed: float = 0.5, accel_threshold: float = 0.5, grace_period: float = 0.3, grace_distance_cm: float = 3.0, max_duration: float = 8.0, backward: bool = False)

Bases: step.motion.motion_step.MotionStep

Drive straight until a collision is detected, measuring the distance driven.

The robot drives at constant velocity with no heading correction while the IMU’s gravity-compensated horizontal acceleration is monitored. A spike above accel_threshold is treated as an impact: the step stops immediately and records how far it drove. If no impact occurs, the step stops cleanly once max_cm is reached (or after max_duration as a safety backstop).

Distance is measured relative to where this step started (the odometer is snapshotted in on_start), because motion steps no longer reset odometry. Detection only arms after an initial guard so the robot’s own launch acceleration isn’t mistaken for a collision: it stays disabled until BOTH grace_period seconds have elapsed AND the robot has driven at least grace_distance_cm clear of the start.

This factory drives in and stops on impact — use it when you only need the “stop when I hit something” behaviour. To reuse the measured distance (e.g. drive back exactly as far as you came), reach for drive_until_impact_back(), which captures the live step instance and wires up the drive-back for you. Reading impact_result off the value this factory returns does NOT work: the factory returns a builder that seq resolves into a fresh step instance, so the object you hold never runs and its impact_result stays None.

Prerequisites:

A working IMU (raccoon.hal.IMU) and odometry. Detection quality depends on accel_threshold being tuned above the cruise-noise floor on real hardware; the mock simulator does not model collision impacts, so the triggering can only be validated on the robot.

Parameters:
  • max_cm – Nominal distance to drive in centimeters if nothing is hit (default 50.0). Doubles as a safety cap on travel.

  • speed – Drive speed in m/s (default 0.5). Lower is gentler and makes the bump cleaner and less likely to shove the game piece.

  • accel_threshold – Minimum XY linear-acceleration magnitude in m/s² to classify as an impact (default 0.5). Lower = more sensitive but more prone to false triggers on rough surfaces.

  • grace_period – Seconds to ignore acceleration after starting, so the robot’s own acceleration doesn’t trigger detection (default 0.3).

  • grace_distance_cm – Centimeters the robot must drive clear of the start before impact detection arms (default 3.0). Guards against the launch lurch or an obstacle already touching the robot at rest triggering instantly. Combined with grace_period — both must be satisfied before detection is active.

  • max_duration – Safety timeout in seconds — the step finishes even if neither an impact nor max_cm is reached (default 8.0).

  • backward – Drive in reverse instead of forward (default False).

Returns:

A DriveUntilImpact step that drives in and stops on impact.

Example:

from raccoon.step.motion import drive_until_impact

# Nudge forward up to 30 cm, stopping the instant something is hit.
drive_until_impact(max_cm=30, speed=0.4)
impact_result: ImpactResult | None = None
on_start(robot: raccoon.robot.api.GenericRobot) None
on_update(robot: raccoon.robot.api.GenericRobot, dt: float) bool
step.motion.drive_until_impact.drive_until_impact_back(max_cm: float = 50.0, clearance_cm: float = 0.0, speed: float = 0.5, accel_threshold: float = 0.5, grace_period: float = 0.3, grace_distance_cm: float = 3.0, max_duration: float = 8.0)

Drive forward until impact, then reverse exactly as far as was driven.

Collision-aware distancing in one step. The robot drives forward up to max_cm, stopping early if it bumps a game piece (IMU acceleration spike). It then reverses by the distance it actually travelled, minus clearance_cm. Hit a piece at 22 cm and it backs out ~22 cm; reach the full max_cm untouched and it backs out that far — so the return leg always matches how far you really got.

Internally this constructs a live DriveUntilImpact instance, captures it in a closure, and appends a defer(...) that reads its impact_result at runtime to build the drive-back leg. This is the supported way to reuse the measured distance — see drive_until_impact() for why holding the plain factory’s return value does not work.

If the measured return distance rounds to zero (e.g. clearance_cm is larger than the distance driven), the drive-back leg is skipped.

Prerequisites:

A working IMU (raccoon.hal.IMU) and odometry. accel_threshold must be tuned above the cruise-noise floor on real hardware; the mock simulator does not model collision impacts, so the triggering can only be validated on the robot.

Parameters:
  • max_cm – Nominal forward distance in centimeters if nothing is hit (default 50.0). Doubles as a safety cap on travel.

  • clearance_cm – Centimeters to leave when returning — the drive-back is driven - clearance (default 0.0 = return to the exact start).

  • speed – Drive speed in m/s (default 0.5). Lower is gentler and makes the bump cleaner and less likely to shove the game piece.

  • accel_threshold – Minimum XY linear-acceleration magnitude in m/s² to classify as an impact (default 0.5).

  • grace_period – Seconds to ignore acceleration after starting, so the robot’s own acceleration doesn’t trigger detection (default 0.3).

  • grace_distance_cm – Centimeters the robot must drive clear of the start before impact detection arms (default 3.0), so the launch lurch doesn’t trigger instantly. Combined with grace_period.

  • max_duration – Safety timeout in seconds for the forward leg (default 8.0).

Returns:

drive-until-impact followed by a deferred drive-back.

Return type:

A seq step

Example:

from raccoon.step.motion import drive_until_impact_back

# Drive up to 40 cm forward; if a cube stops us early, back out just
# as far, leaving a 3 cm clearance.
drive_until_impact_back(max_cm=40, clearance_cm=3.0, speed=0.4)