step.motion.line_follow

Line following using IR sensors.

This module provides steps for following lines using one or two IR sensors with PID-based steering control.

Two families of steps are available:

  1. Profiled line follow (FollowLine, FollowLineSingle, etc.) — built on LinearMotion for trapezoidal-profiled distance control along a single axis.

  2. Directional line follow (DirectionalFollowLine, StrafeFollowLine, etc.) — uses direct ChassisVelocity control with independent heading and strafe speed inputs, allowing line following while strafing, driving diagonally, or any combination.

All steps support composable StopCondition via the .until() builder method, enabling patterns like:

follow_line(left, right, speed=0.5).until(on_black(left) & on_black(right))
follow_line_single(sensor, speed=0.4).until(on_black(stop_sensor))

Classes

LineFollowConfig

Configuration for LineFollow step with two sensors.

LineSide

Which edge of the line to track with a single sensor.

SingleLineFollowConfig

Configuration for single-sensor line following.

LineFollow

Follow a line using two IR sensors with PID steering.

SingleSensorLineFollow

Follow a line edge using a single IR sensor with PID edge-tracking.

FollowLine

Follow a line using two IR sensors for steering.

FollowLineSingle

Follow a line edge using a single IR sensor.

DirectionalLineFollowConfig

Configuration for directional line following with two sensors.

DirectionalLineFollow

Follow a line with independent heading and strafe velocity components.

DirectionalSingleLineFollowConfig

Configuration for directional single-sensor line following.

DirectionalSingleLineFollow

Follow a line edge with independent heading and strafe velocity.

DirectionalFollowLine

Follow a line with independent heading and strafe speeds.

StrafeFollowLine

Follow a line forward, correcting position by strafing left/right.

StrafeFollowLineSingle

Follow a line edge forward, correcting position by strafing.

LateralFollowLine

Follow a line while strafing laterally, correcting with forward/backward motion.

LateralFollowLineSingle

Follow a line edge while strafing laterally.

DirectionalFollowLineSingle

Follow a line edge with a single sensor and independent heading/strafe speeds.

Module Contents

class step.motion.line_follow.LineFollowConfig

Configuration for LineFollow step with two sensors.

left_sensor: raccoon.sensor_ir.IRSensor
right_sensor: raccoon.sensor_ir.IRSensor
speed_scale: float
distance_cm: float | None = None
kp: float = 0.4
ki: float = 0.0
kd: float = 0.1
class step.motion.line_follow.LineSide(*args, **kwds)

Bases: enum.Enum

Which edge of the line to track with a single sensor.

LEFT = 'left'
RIGHT = 'right'
class step.motion.line_follow.SingleLineFollowConfig

Configuration for single-sensor line following.

The sensor tracks the edge of a line using PID control. side selects which edge: LEFT means the sensor approaches from the left (steers right when it sees black), RIGHT is the opposite.

sensor: raccoon.sensor_ir.IRSensor
speed_scale: float
distance_cm: float | None = None
side: LineSide
kp: float = 0.4
ki: float = 0.0
kd: float = 0.1
class step.motion.line_follow.LineFollow(config: LineFollowConfig, until: step.condition.StopCondition | None = None)

Bases: step.motion.motion_step.MotionStep

Follow a line using two IR sensors with PID steering.

Computes a steering error as the difference between the left and right sensors’ probabilityOfBlack() readings and feeds it through a PID controller. The PID output is applied as an angular velocity (omega) override on the underlying LinearMotion, which handles profiled distance control and odometry integration.

Supports distance-based termination, composable StopCondition via .until(), or both (whichever triggers first).

config
lower_to_segments() list

Lower this step into optimizer IR segments (list[Segment]).

Return None (the default) to remain OPAQUE to the path optimizer: it is then preserved verbatim as a barrier / side action and never transformed. Motion steps override this to return their segment(s).

on_start(robot: raccoon.robot.api.GenericRobot) None

Called once before the loop. Override to set up motion/velocity.

on_update(robot: raccoon.robot.api.GenericRobot, dt: float) bool

Called each cycle with dt in seconds. Return True when motion is complete.

class step.motion.line_follow.SingleSensorLineFollow(config: SingleLineFollowConfig, until: step.condition.StopCondition | None = None)

Bases: step.motion.motion_step.MotionStep

Follow a line edge using a single IR sensor with PID edge-tracking.

Targets probabilityOfBlack() = 0.5 (the line edge) as the setpoint. The side configuration flips the error sign to select left vs. right edge tracking. The PID output overrides the angular velocity on the underlying LinearMotion, which handles profiled distance control and odometry integration.

Supports distance-based termination, composable StopCondition via .until(), or both (whichever triggers first).

config
lower_to_segments() list

Lower this step into optimizer IR segments (list[Segment]).

Return None (the default) to remain OPAQUE to the path optimizer: it is then preserved verbatim as a barrier / side action and never transformed. Motion steps override this to return their segment(s).

on_start(robot: raccoon.robot.api.GenericRobot) None

Called once before the loop. Override to set up motion/velocity.

on_update(robot: raccoon.robot.api.GenericRobot, dt: float) bool

Called each cycle with dt in seconds. Return True when motion is complete.

class step.motion.line_follow.FollowLine(left_sensor: raccoon.sensor_ir.IRSensor, right_sensor: raccoon.sensor_ir.IRSensor, distance_cm: float | None = None, speed: float = 0.5, kp: float = 0.4, ki: float = 0.0, kd: float = 0.1, until: step.condition.StopCondition | None = None)

Bases: LineFollow

Follow a line using two IR sensors for steering.

Drives forward while a PID controller steers the robot to keep it centered on a line. The error signal is the difference between the left and right sensors’ probabilityOfBlack() readings. A positive error (left sees more black) steers the robot back toward center. The underlying LinearMotion handles profiled velocity control and odometry-based distance tracking, while the PID output overrides the heading command as an angular velocity (omega).

Supports distance-based termination, composable StopCondition via .until(), or both (whichever triggers first). At least one of distance_cm or until must be provided.

Both sensors must be calibrated (white/black thresholds set) before use.

Parameters:
  • left_sensor – Left IR sensor instance, positioned to the left of the line.

  • right_sensor – Right IR sensor instance, positioned to the right of the line.

  • distance_cm – Distance to follow in centimeters. The step finishes when this distance has been traveled according to odometry. Optional if until is provided.

  • speed – Fraction of max velocity (0.0–1.0). Lower speeds give the PID more time to correct but are slower overall. Default 0.5.

  • kp – Proportional gain for steering PID. Higher values produce sharper corrections. Default 0.75.

  • ki – Integral gain for steering PID. Typically left at 0.0 unless there is a persistent drift. Default 0.0.

  • kd – Derivative gain for steering PID. Damps oscillation around the line. Default 0.5.

  • until – Composable stop condition (e.g., on_black(left) & on_black(right)). Can also be chained via the .until() builder method.

Returns:

A FollowLine step configured for line following.

Example:

from raccoon.step.motion import FollowLine
from raccoon.step.condition import on_black

# Follow a line for 80 cm at half speed
follow_line(left_sensor=left, right_sensor=right, distance_cm=80, speed=0.5)

# Follow until both sensors see black (intersection)
follow_line(left, right, speed=0.5).until(on_black(left) & on_black(right))

# Distance + early termination
follow_line(left, right, distance_cm=100, speed=0.5).until(on_black(third))
class step.motion.line_follow.FollowLineSingle(sensor: raccoon.sensor_ir.IRSensor, distance_cm: float | None = None, speed: float = 0.5, side: LineSide = LineSide.LEFT, kp: float = 0.4, ki: float = 0.0, kd: float = 0.1, until: step.condition.StopCondition | None = None)

Bases: SingleSensorLineFollow

Follow a line edge using a single IR sensor.

The sensor tracks the boundary between the line and the background, where probabilityOfBlack() is approximately 0.5. The PID controller drives the error (reading - 0.5) toward zero, keeping the sensor positioned right on the edge. The side parameter controls which edge: LEFT means the sensor is to the left of the line (steers right when it sees black), and RIGHT is the opposite.

This variant is useful when only one sensor is available, or when the line is too narrow for two sensors. The underlying LinearMotion handles profiled velocity and odometry-based distance tracking.

Supports distance-based termination, composable StopCondition via .until(), or both (whichever triggers first). At least one of distance_cm or until must be provided.

The sensor must be calibrated (white/black thresholds set) before use.

Parameters:
  • sensor – The IR sensor instance used for edge tracking.

  • distance_cm – Distance to follow in centimeters. The step finishes when this distance has been traveled. Optional if until is provided.

  • speed – Fraction of max velocity (0.0–1.0). Default 0.5.

  • side – Which edge of the line to track. LineSide.LEFT (default) or LineSide.RIGHT.

  • kp – Proportional gain for steering PID. Default 1.0.

  • ki – Integral gain for steering PID. Default 0.0.

  • kd – Derivative gain for steering PID. Default 0.3.

  • until – Composable stop condition (e.g., on_black(stop_sensor)). Can also be chained via the .until() builder method.

Returns:

A FollowLineSingle step.

Example:

from raccoon.step.motion import FollowLineSingle, LineSide
from raccoon.step.condition import on_black

# Follow left edge for 60 cm
follow_line_single(sensor=front_ir, distance_cm=60, speed=0.4)

# Follow until stop sensor sees black
follow_line_single(front_ir, speed=0.4, side=LineSide.LEFT).until(on_black(stop))

# Distance + early termination with timeout
follow_line_single(front_ir, distance_cm=100).until(on_black(stop) | after_seconds(10))
class step.motion.line_follow.DirectionalLineFollowConfig

Configuration for directional line following with two sensors.

Allows independent heading (forward/backward) and strafe (left/right) speed components. The PID controller steers via angular velocity based on the difference between left and right sensor readings.

When lateral_correction is True, the PID output controls lateral velocity (vy) instead of angular velocity (wz), keeping the robot’s heading constant while correcting position by strafing. When forward_correction is True, the PID output controls forward velocity (vx), useful for following while the primary motion is lateral (vy).

left_sensor: raccoon.sensor_ir.IRSensor
right_sensor: raccoon.sensor_ir.IRSensor
heading_speed: float
strafe_speed: float
distance_cm: float | None = None
kp: float = 0.4
ki: float = 0.0
kd: float = 0.1
integral_max: float = 1.0
integral_min: float | None = None
lateral_correction: bool = False
forward_correction: bool = False
heading_hold: bool = True
correction_sign: float = 1.0
heading_deg: float | None = None
class step.motion.line_follow.DirectionalLineFollow(config: DirectionalLineFollowConfig, until: step.condition.StopCondition | None = None)

Bases: step.motion.motion_step.MotionStep

Follow a line with independent heading and strafe velocity components.

Uses direct ChassisVelocity control instead of LinearMotion, enabling line following while strafing, driving diagonally, or any combination. A PID controller computes angular velocity from the difference between the left and right sensors’ probabilityOfBlack() readings.

Distance is tracked via odometry as euclidean distance from the start position. Supports distance-based termination, composable StopCondition, or both.

config
lower_to_segments() list

Lower this step into optimizer IR segments (list[Segment]).

Return None (the default) to remain OPAQUE to the path optimizer: it is then preserved verbatim as a barrier / side action and never transformed. Motion steps override this to return their segment(s).

on_start(robot: raccoon.robot.api.GenericRobot) None

Called once before the loop. Override to set up motion/velocity.

on_update(robot: raccoon.robot.api.GenericRobot, dt: float) bool

Called each cycle with dt in seconds. Return True when motion is complete.

class step.motion.line_follow.DirectionalSingleLineFollowConfig

Configuration for directional single-sensor line following.

The sensor tracks the edge of a line using PID control while the robot moves with the given heading and strafe velocity components.

When lateral_correction is True, the PID output controls lateral velocity (vy) instead of angular velocity (wz), keeping the robot’s heading constant while correcting position by strafing. When forward_correction is True, the PID output controls forward velocity (vx), useful for following while the primary motion is lateral (vy).

sensor: raccoon.sensor_ir.IRSensor
heading_speed: float
strafe_speed: float
distance_cm: float | None = None
side: LineSide
kp: float = 0.4
ki: float = 0.0
kd: float = 0.1
integral_max: float = 1.0
integral_min: float | None = None
lateral_correction: bool = False
forward_correction: bool = False
heading_hold: bool = True
correction_sign: float = 1.0
heading_deg: float | None = None
class step.motion.line_follow.DirectionalSingleLineFollow(config: DirectionalSingleLineFollowConfig, until: step.condition.StopCondition | None = None)

Bases: step.motion.motion_step.MotionStep

Follow a line edge with independent heading and strafe velocity.

Targets probabilityOfBlack() = 0.5 (the line edge) as the setpoint. The side configuration flips the error sign to select left vs. right edge tracking. The PID output controls angular velocity while heading and strafe velocities are set directly via ChassisVelocity.

Supports distance-based and composable StopCondition-based termination.

config
lower_to_segments() list

Lower this step into optimizer IR segments (list[Segment]).

Return None (the default) to remain OPAQUE to the path optimizer: it is then preserved verbatim as a barrier / side action and never transformed. Motion steps override this to return their segment(s).

on_start(robot: raccoon.robot.api.GenericRobot) None

Called once before the loop. Override to set up motion/velocity.

on_update(robot: raccoon.robot.api.GenericRobot, dt: float) bool

Called each cycle with dt in seconds. Return True when motion is complete.

class step.motion.line_follow.DirectionalFollowLine(left_sensor: raccoon.sensor_ir.IRSensor, right_sensor: raccoon.sensor_ir.IRSensor, distance_cm: float | None = None, heading_speed: float = 0.0, strafe_speed: float = 0.0, kp: float = 0.4, ki: float = 0.0, kd: float = 0.1, until: step.condition.StopCondition | None = None)

Bases: DirectionalLineFollow

Follow a line with independent heading and strafe speeds.

Drive along a line using any combination of forward and lateral velocity while a PID controller steers the robot via angular velocity. The error signal is the difference between the left and right sensors’ probabilityOfBlack() readings. Distance is tracked via odometry as the euclidean distance from the start position.

Unlike FollowLine which only drives forward, this step accepts both heading_speed (forward/backward) and strafe_speed (left/right) as independent fractions of max velocity, enabling line following while strafing or driving diagonally.

Supports distance-based termination, composable StopCondition via .until(), or both (whichever triggers first). At least one of distance_cm or until must be provided.

Both sensors must be calibrated (white/black thresholds set) before use. Requires a mecanum or omni-wheel drivetrain if strafe_speed is nonzero.

Parameters:
  • left_sensor – Left IR sensor instance, positioned to the left of the line.

  • right_sensor – Right IR sensor instance, positioned to the right of the line.

  • distance_cm – Distance to follow in centimeters. The step finishes when this euclidean distance has been traveled. Optional if until is provided.

  • heading_speed – Forward/backward speed as a fraction of max velocity (-1.0 to 1.0). Positive = forward, negative = backward. Default 0.0.

  • strafe_speed – Lateral speed as a fraction of max velocity (-1.0 to 1.0). Positive = right, negative = left. Default 0.0.

  • kp – Proportional gain for steering PID. Default 0.75.

  • ki – Integral gain for steering PID. Default 0.0.

  • kd – Derivative gain for steering PID. Default 0.5.

  • until – Composable stop condition. Can also be chained via the .until() builder method.

Returns:

A DirectionalFollowLine step.

Example:

from raccoon.step.motion import DirectionalFollowLine
from raccoon.step.condition import on_black

# Strafe right while following a line for 50 cm
directional_follow_line(left, right, distance_cm=50, strafe_speed=0.5)

# Follow until both sensors see black
directional_follow_line(left, right, strafe_speed=0.4).until(on_black(left) & on_black(right))
class step.motion.line_follow.StrafeFollowLine(left_sensor: raccoon.sensor_ir.IRSensor, right_sensor: raccoon.sensor_ir.IRSensor, distance_cm: float | None = None, speed: float = 0.5, kp: float = 0.4, ki: float = 0.0, kd: float = 0.1, heading_deg: float | None = None, until: step.condition.StopCondition | None = None)

Bases: DirectionalLineFollow

Follow a line forward, correcting position by strafing left/right.

The robot drives forward at the given speed while a PID controller corrects lateral position using two sensors. Unlike FollowLine which steers by rotating, this step keeps the robot’s heading constant and corrects by strafing, which is useful when the robot must maintain a fixed orientation (e.g. to keep a side-mounted mechanism aligned).

Supports distance-based termination, composable StopCondition via .until(), or both (whichever triggers first). At least one of distance_cm or until must be provided.

Both sensors must be calibrated. Requires a mecanum or omni-wheel drivetrain.

Parameters:
  • left_sensor – Left IR sensor instance.

  • right_sensor – Right IR sensor instance.

  • distance_cm – Distance to follow in centimeters. Optional if until is provided.

  • speed – Forward speed as fraction of max velocity (0.0 to 1.0). Default 0.5. Use negative values to drive backward.

  • kp – Proportional gain for lateral PID. Default 0.75.

  • ki – Integral gain for lateral PID. Default 0.0.

  • kd – Derivative gain for lateral PID. Default 0.5.

  • heading_deg – Absolute heading to hold while correcting, in degrees from the mark_heading_reference() origin (CCW-positive, same convention as turn_to_heading_left and drive_forward(heading=…)). None (default) holds whatever heading the robot has when the step starts. Requires mark_heading_reference() earlier in the mission when set.

  • until – Composable stop condition. Can also be chained via the .until() builder method.

Returns:

A StrafeFollowLine step configured for lateral correction.

Example:

from raccoon.step.motion import StrafeFollowLine
from raccoon.step.condition import on_black

# Follow a line for 40 cm, correcting via strafe
strafe_follow_line(left, right, distance_cm=40, speed=0.4)

# Follow until both sensors see black
strafe_follow_line(left, right, speed=0.4).until(on_black(left) & on_black(right))

# Hold the board-forward heading (0° from the marked reference)
strafe_follow_line(left, right, distance_cm=40, speed=0.4, heading_deg=0)
class step.motion.line_follow.StrafeFollowLineSingle(sensor: raccoon.sensor_ir.IRSensor, distance_cm: float | None = None, speed: float = 0.5, side: LineSide = LineSide.LEFT, kp: float = 0.4, ki: float = 0.0, kd: float = 0.1, heading_deg: float | None = None, until: step.condition.StopCondition | None = None)

Bases: DirectionalSingleLineFollow

Follow a line edge forward, correcting position by strafing.

The robot drives forward at the given speed while a PID controller corrects lateral position using a single sensor tracking the line edge. Unlike FollowLineSingle which steers by rotating, this step keeps the robot’s heading constant and corrects by strafing.

Supports distance-based termination, composable StopCondition via .until(), or both (whichever triggers first). At least one of distance_cm or until must be provided.

The sensor must be calibrated. Requires a mecanum or omni-wheel drivetrain.

Parameters:
  • sensor – IR sensor for edge tracking.

  • distance_cm – Distance to follow in centimeters. Optional if until is provided.

  • speed – Forward speed as fraction of max velocity (0.0 to 1.0). Default 0.5. Use negative values to drive backward.

  • side – Which edge of the line to track. Default LineSide.LEFT.

  • kp – Proportional gain for lateral PID. Default 1.0.

  • ki – Integral gain for lateral PID. Default 0.0.

  • kd – Derivative gain for lateral PID. Default 0.3.

  • heading_deg – Absolute heading to hold while correcting, in degrees from the mark_heading_reference() origin (CCW-positive). None (default) holds the heading captured at step start. Requires mark_heading_reference() earlier when set.

  • until – Composable stop condition. Can also be chained via the .until() builder method.

Returns:

A StrafeFollowLineSingle step configured for lateral correction.

Example:

from raccoon.step.motion import StrafeFollowLineSingle, LineSide
from raccoon.step.condition import on_black

# Follow a line edge for 40 cm, correcting via strafe
strafe_follow_line_single(front_ir, distance_cm=40, speed=0.4)

# Follow until stop sensor sees black
strafe_follow_line_single(front_ir, speed=0.4).until(on_black(stop))

# Hold 0° (board forward) while correcting on the strafe axis
strafe_follow_line_single(front_ir, distance_cm=40, speed=0.4, heading_deg=0)
class step.motion.line_follow.LateralFollowLine(left_sensor: raccoon.sensor_ir.IRSensor, right_sensor: raccoon.sensor_ir.IRSensor, distance_cm: float | None = None, speed: float = 0.5, kp: float = 0.4, ki: float = 0.0, kd: float = 0.1, heading_deg: float | None = None, until: step.condition.StopCondition | None = None)

Bases: DirectionalLineFollow

Follow a line while strafing laterally, correcting with forward/backward motion.

The robot moves primarily along vy (right for positive speed, left for negative speed) while a PID controller corrects cross-track error on vx. Heading is held constant with the heading PID. This is the lateral/omni counterpart to StrafeFollowLine, whose primary motion is forward and whose correction is lateral.

left_sensor and right_sensor are interpreted relative to the current lateral follow direction. When strafing right, the left sensor is the forward-side sensor and the right sensor is the rear-side sensor; when strafing left, that geometry is mirrored.

Supports distance-based termination, composable StopCondition via .until(), or both (whichever triggers first). At least one of distance_cm or until must be provided.

Parameters:
  • left_sensor – Sensor on the travel-left side of the line.

  • right_sensor – Sensor on the travel-right side of the line.

  • distance_cm – Lateral distance to follow in centimeters. Optional if until is provided.

  • speed – Lateral speed as a fraction of max velocity (-1.0 to 1.0). Positive strafes right, negative strafes left.

  • kp – Proportional gain for cross-track PID.

  • ki – Integral gain for cross-track PID.

  • kd – Derivative gain for cross-track PID.

  • heading_deg – Absolute heading to hold while strafing, in degrees from the mark_heading_reference() origin (CCW-positive). None (default) holds the heading captured at step start. Requires mark_heading_reference() earlier when set.

  • until – Composable stop condition. Can also be chained via the .until() builder method.

class step.motion.line_follow.LateralFollowLineSingle(sensor: raccoon.sensor_ir.IRSensor, distance_cm: float | None = None, speed: float = 0.5, side: LineSide = LineSide.LEFT, kp: float = 0.4, ki: float = 0.0, kd: float = 0.1, heading_deg: float | None = None, until: step.condition.StopCondition | None = None)

Bases: DirectionalSingleLineFollow

Follow a line edge while strafing laterally.

The robot moves primarily along vy (right for positive speed, left for negative speed) while a PID controller corrects the edge-tracking error on vx. LineSide.LEFT and LineSide.RIGHT are interpreted relative to the lateral follow direction, not the robot’s fixed front. That means the correction sign is mirrored automatically when speed is negative.

Supports distance-based termination, composable StopCondition via .until(), or both (whichever triggers first). At least one of distance_cm or until must be provided.

Parameters:
  • sensor – IR sensor for edge tracking.

  • distance_cm – Lateral distance to follow in centimeters. Optional if until is provided.

  • speed – Lateral speed as a fraction of max velocity (-1.0 to 1.0). Positive strafes right, negative strafes left.

  • side – Which edge of the line to track, relative to the lateral travel direction.

  • kp – Proportional gain for cross-track PID.

  • ki – Integral gain for cross-track PID.

  • kd – Derivative gain for cross-track PID.

  • heading_deg – Absolute heading to hold while strafing, in degrees from the mark_heading_reference() origin (CCW-positive). None (default) holds the heading captured at step start. Requires mark_heading_reference() earlier when set.

  • until – Composable stop condition. Can also be chained via the .until() builder method.

class step.motion.line_follow.DirectionalFollowLineSingle(sensor: raccoon.sensor_ir.IRSensor, distance_cm: float | None = None, heading_speed: float = 0.0, strafe_speed: float = 0.0, side: LineSide = LineSide.LEFT, kp: float = 0.4, ki: float = 0.0, kd: float = 0.1, until: step.condition.StopCondition | None = None)

Bases: DirectionalSingleLineFollow

Follow a line edge with a single sensor and independent heading/strafe speeds.

The sensor tracks the boundary between the line and the background, where probabilityOfBlack() is approximately 0.5. The side parameter selects which edge to track. The PID output controls angular velocity while heading and strafe velocities are set independently.

Supports distance-based termination, composable StopCondition via .until(), or both (whichever triggers first). At least one of distance_cm or until must be provided.

The sensor must be calibrated (white/black thresholds set) before use. Requires a mecanum or omni-wheel drivetrain if strafe_speed is nonzero.

Parameters:
  • sensor – IR sensor for edge tracking.

  • distance_cm – Distance to follow in centimeters. Optional if until is provided.

  • heading_speed – Forward/backward speed fraction (-1.0 to 1.0). Default 0.0.

  • strafe_speed – Lateral speed fraction (-1.0 to 1.0). Default 0.0.

  • side – Which edge of the line to track. Default LineSide.LEFT.

  • kp – Proportional gain for steering PID. Default 1.0.

  • ki – Integral gain for steering PID. Default 0.0.

  • kd – Derivative gain for steering PID. Default 0.3.

  • until – Composable stop condition. Can also be chained via the .until() builder method.

Returns:

A DirectionalFollowLineSingle step.

Example:

from raccoon.step.motion import DirectionalFollowLineSingle, LineSide
from raccoon.step.condition import on_black

# Strafe right while tracking the left edge for 50 cm
directional_follow_line_single(front_ir, distance_cm=50, strafe_speed=0.4)

# Follow until stop sensor sees black
directional_follow_line_single(front_ir, strafe_speed=0.4).until(on_black(stop))