<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.bespokerobotsociety.org/index.php?action=history&amp;feed=atom&amp;title=Behavior%3ALine_Following</id>
	<title>Behavior:Line Following - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.bespokerobotsociety.org/index.php?action=history&amp;feed=atom&amp;title=Behavior%3ALine_Following"/>
	<link rel="alternate" type="text/html" href="https://wiki.bespokerobotsociety.org/index.php?title=Behavior:Line_Following&amp;action=history"/>
	<updated>2026-04-25T11:26:46Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://wiki.bespokerobotsociety.org/index.php?title=Behavior:Line_Following&amp;diff=47&amp;oldid=prev</id>
		<title>John: Claude edited based on my notes, prompt, and SimpleBot code repository</title>
		<link rel="alternate" type="text/html" href="https://wiki.bespokerobotsociety.org/index.php?title=Behavior:Line_Following&amp;diff=47&amp;oldid=prev"/>
		<updated>2025-10-11T16:47:35Z</updated>

		<summary type="html">&lt;p&gt;Claude edited based on my notes, prompt, and SimpleBot code repository&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{Behavior&lt;br /&gt;
|name=Line Following&lt;br /&gt;
|requires=[[Capability:Line Sensing]], [[Capability:Differential Drive]]&lt;br /&gt;
|enables=[[Activity:Line Following]]&lt;br /&gt;
|difficulty=Beginner&lt;br /&gt;
|implementations=[[SimpleBot:Line Following Implementation]]&lt;br /&gt;
|status=Fully Documented&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Line Following&amp;#039;&amp;#039;&amp;#039; is a fundamental robotic behavior that enables a robot to autonomously track and follow a visible line on the ground. This behavior interprets data from line sensors (typically infrared reflectance sensors) to continuously adjust the robot&amp;#039;s steering and maintain alignment with the line path.&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Line-following behavior is one of the most common introductory robotics tasks, yet it scales from simple bang-bang control to sophisticated PID-based systems. The core principle remains constant: detect position relative to the line, and adjust motor speeds to correct any deviation.&lt;br /&gt;
&lt;br /&gt;
The behavior operates in a continuous sense-think-act loop:&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Sense&amp;#039;&amp;#039;&amp;#039;: Read reflectance values from line sensors&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Think&amp;#039;&amp;#039;&amp;#039;: Determine position relative to the line (on line, left of line, right of line, or lost)&lt;br /&gt;
# &amp;#039;&amp;#039;&amp;#039;Act&amp;#039;&amp;#039;&amp;#039;: Adjust motor speeds to steer back toward the line&lt;br /&gt;
&lt;br /&gt;
Line-following is typically used with high-contrast lines (black tape on white surface or vice versa), though the algorithms can be adapted for other visual markers.&lt;br /&gt;
&lt;br /&gt;
== Algorithm Variants by Sensor Count ==&lt;br /&gt;
&lt;br /&gt;
The complexity and performance of line-following behavior depends heavily on the number of sensors used. Each configuration has distinct trade-offs.&lt;br /&gt;
&lt;br /&gt;
=== One-Sensor Algorithm ===&lt;br /&gt;
&lt;br /&gt;
The simplest line-following approach uses a single sensor positioned at the robot&amp;#039;s front center.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Algorithm:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
loop forever:&lt;br /&gt;
    if sensor detects line:&lt;br /&gt;
        drive forward&lt;br /&gt;
    else:&lt;br /&gt;
        rotate in place (searching)&lt;br /&gt;
        wait until line is found again&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Pseudocode:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
while true:&lt;br /&gt;
    if read_sensor() == LINE_DETECTED:&lt;br /&gt;
        set_motors(FORWARD_SPEED, FORWARD_SPEED)&lt;br /&gt;
    else:&lt;br /&gt;
        // Lost the line - search by rotating&lt;br /&gt;
        set_motors(TURN_SPEED, -TURN_SPEED)  // Spin in place&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Pros:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Simplest hardware and code&lt;br /&gt;
* Minimal cost&lt;br /&gt;
* Good for teaching basic concepts&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Cons:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Jerky, inefficient motion (constant stop-and-turn)&lt;br /&gt;
* Cannot anticipate curves&lt;br /&gt;
* Very slow on anything but straight lines&lt;br /&gt;
* No way to determine which direction to correct&lt;br /&gt;
&lt;br /&gt;
=== Two-Sensor Algorithm ===&lt;br /&gt;
&lt;br /&gt;
Using two sensors positioned on either side of the line enables the robot to detect which direction it&amp;#039;s drifting and make appropriate corrections. &amp;#039;&amp;#039;&amp;#039;This is the approach used by SimpleBot.&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Algorithm:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
loop forever:&lt;br /&gt;
    read left_sensor and right_sensor&lt;br /&gt;
&lt;br /&gt;
    if both sensors on white (off line):&lt;br /&gt;
        drive straight - robot is centered on line&lt;br /&gt;
&lt;br /&gt;
    else if left_sensor on line (black):&lt;br /&gt;
        turn right - robot is drifting left&lt;br /&gt;
&lt;br /&gt;
    else if right_sensor on line (black):&lt;br /&gt;
        turn left - robot is drifting right&lt;br /&gt;
&lt;br /&gt;
    else if both sensors on line (black):&lt;br /&gt;
        intersection or completely lost&lt;br /&gt;
        execute special handling&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Pseudocode:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
const BASE_SPEED = 150&lt;br /&gt;
const TURN_SPEED = 100&lt;br /&gt;
&lt;br /&gt;
while true:&lt;br /&gt;
    left = read_left_sensor()&lt;br /&gt;
    right = read_right_sensor()&lt;br /&gt;
&lt;br /&gt;
    if left == WHITE and right == WHITE:&lt;br /&gt;
        // Centered on line - drive straight&lt;br /&gt;
        set_motors(BASE_SPEED, BASE_SPEED)&lt;br /&gt;
&lt;br /&gt;
    else if left == BLACK and right == WHITE:&lt;br /&gt;
        // Drifting left - turn right&lt;br /&gt;
        set_motors(BASE_SPEED, TURN_SPEED)&lt;br /&gt;
&lt;br /&gt;
    else if left == WHITE and right == BLACK:&lt;br /&gt;
        // Drifting right - turn left&lt;br /&gt;
        set_motors(TURN_SPEED, BASE_SPEED)&lt;br /&gt;
&lt;br /&gt;
    else if left == BLACK and right == BLACK:&lt;br /&gt;
        // Both on line - intersection or lost&lt;br /&gt;
        // Option 1: Stop and signal&lt;br /&gt;
        set_motors(0, 0)&lt;br /&gt;
        // Option 2: Drive straight through&lt;br /&gt;
        set_motors(BASE_SPEED, BASE_SPEED)&lt;br /&gt;
        // Option 3: Execute turn decision&lt;br /&gt;
        make_intersection_decision()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Pros:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Simple to understand and implement&lt;br /&gt;
* Directional correction (knows which way to turn)&lt;br /&gt;
* Smooth following on gentle curves&lt;br /&gt;
* Can detect intersections&lt;br /&gt;
* Good cost-to-performance ratio&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Cons:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Fixed correction amount (not proportional)&lt;br /&gt;
* Struggles with sharp curves&lt;br /&gt;
* Sensor spacing critical to performance&lt;br /&gt;
* Line width must match sensor spacing&lt;br /&gt;
&lt;br /&gt;
=== Three-Sensor Algorithm ===&lt;br /&gt;
&lt;br /&gt;
Three sensors (left, center, right) provide better tracking by distinguishing between centered, slightly off, and significantly off positions.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Algorithm:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
loop forever:&lt;br /&gt;
    read left_sensor, center_sensor, right_sensor&lt;br /&gt;
&lt;br /&gt;
    if center_sensor on line:&lt;br /&gt;
        drive fast and straight - perfectly centered&lt;br /&gt;
&lt;br /&gt;
    else if left_sensor on line:&lt;br /&gt;
        gentle turn right&lt;br /&gt;
&lt;br /&gt;
    else if right_sensor on line:&lt;br /&gt;
        gentle turn left&lt;br /&gt;
&lt;br /&gt;
    else if no sensors on line:&lt;br /&gt;
        execute lost-line recovery&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Pseudocode:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
const FAST_SPEED = 200&lt;br /&gt;
const NORMAL_SPEED = 150&lt;br /&gt;
const SLOW_SPEED = 100&lt;br /&gt;
&lt;br /&gt;
while true:&lt;br /&gt;
    left = read_left_sensor()&lt;br /&gt;
    center = read_center_sensor()&lt;br /&gt;
    right = read_right_sensor()&lt;br /&gt;
&lt;br /&gt;
    if center == BLACK:&lt;br /&gt;
        // Perfectly centered - drive fast&lt;br /&gt;
        set_motors(FAST_SPEED, FAST_SPEED)&lt;br /&gt;
&lt;br /&gt;
    else if left == BLACK:&lt;br /&gt;
        // Slightly left - gentle right turn&lt;br /&gt;
        set_motors(NORMAL_SPEED, SLOW_SPEED)&lt;br /&gt;
&lt;br /&gt;
    else if right == BLACK:&lt;br /&gt;
        // Slightly right - gentle left turn&lt;br /&gt;
        set_motors(SLOW_SPEED, NORMAL_SPEED)&lt;br /&gt;
&lt;br /&gt;
    else:&lt;br /&gt;
        // Lost line - slow search&lt;br /&gt;
        set_motors(SLOW_SPEED, -SLOW_SPEED)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Pros:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Better detection of centered position&lt;br /&gt;
* Can optimize speed (drive faster when centered)&lt;br /&gt;
* More graceful corrections&lt;br /&gt;
* Better lost-line detection&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Cons:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* More hardware complexity&lt;br /&gt;
* Still uses discrete corrections&lt;br /&gt;
* Cannot handle very sharp curves without slowing significantly&lt;br /&gt;
&lt;br /&gt;
=== Multi-Sensor Array (5-8 Sensors) ===&lt;br /&gt;
&lt;br /&gt;
High-performance line following uses an array of sensors to calculate a continuous &amp;quot;line position&amp;quot; value, enabling proportional control.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Algorithm:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
loop forever:&lt;br /&gt;
    read all sensors (s0, s1, s2, s3, s4, s5, s6, s7)&lt;br /&gt;
&lt;br /&gt;
    calculate line_position using weighted average:&lt;br /&gt;
        line_position = sum(sensor_value[i] * position_weight[i]) / sum(sensor_value[i])&lt;br /&gt;
&lt;br /&gt;
    calculate error = line_position - desired_position (0 = center)&lt;br /&gt;
&lt;br /&gt;
    apply PID control:&lt;br /&gt;
        correction = Kp * error + Ki * integral_error + Kd * derivative_error&lt;br /&gt;
&lt;br /&gt;
    adjust motors:&lt;br /&gt;
        left_motor = BASE_SPEED + correction&lt;br /&gt;
        right_motor = BASE_SPEED - correction&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Pseudocode:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
const BASE_SPEED = 180&lt;br /&gt;
const Kp = 0.8  // Proportional gain&lt;br /&gt;
const Ki = 0.01 // Integral gain&lt;br /&gt;
const Kd = 2.0  // Derivative gain&lt;br /&gt;
&lt;br /&gt;
integral_error = 0&lt;br /&gt;
last_error = 0&lt;br /&gt;
&lt;br /&gt;
while true:&lt;br /&gt;
    // Read sensor array (0 = white, 1000 = black)&lt;br /&gt;
    sensors = [read_sensor(0), read_sensor(1), ..., read_sensor(7)]&lt;br /&gt;
&lt;br /&gt;
    // Calculate weighted line position (-3.5 to +3.5 for 8 sensors)&lt;br /&gt;
    weighted_sum = 0&lt;br /&gt;
    total_activation = 0&lt;br /&gt;
&lt;br /&gt;
    for i in 0 to 7:&lt;br /&gt;
        weight = i - 3.5  // Position weights: -3.5, -2.5, -1.5, -0.5, 0.5, 1.5, 2.5, 3.5&lt;br /&gt;
        weighted_sum += sensors[i] * weight&lt;br /&gt;
        total_activation += sensors[i]&lt;br /&gt;
&lt;br /&gt;
    if total_activation &amp;gt; 0:&lt;br /&gt;
        line_position = weighted_sum / total_activation&lt;br /&gt;
    else:&lt;br /&gt;
        // Lost line - use last known position&lt;br /&gt;
        line_position = last_line_position&lt;br /&gt;
&lt;br /&gt;
    // PID control&lt;br /&gt;
    error = line_position  // Target is 0 (center)&lt;br /&gt;
    integral_error += error&lt;br /&gt;
    derivative_error = error - last_error&lt;br /&gt;
&lt;br /&gt;
    correction = Kp * error + Ki * integral_error + Kd * derivative_error&lt;br /&gt;
&lt;br /&gt;
    // Apply correction&lt;br /&gt;
    left_speed = BASE_SPEED + correction&lt;br /&gt;
    right_speed = BASE_SPEED - correction&lt;br /&gt;
&lt;br /&gt;
    set_motors(left_speed, right_speed)&lt;br /&gt;
&lt;br /&gt;
    last_error = error&lt;br /&gt;
    last_line_position = line_position&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Pros:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Smooth, precise tracking&lt;br /&gt;
* Proportional corrections (gentle curves vs. sharp turns)&lt;br /&gt;
* High speed capability&lt;br /&gt;
* Excellent on complex paths&lt;br /&gt;
* Can implement look-ahead strategies&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Cons:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* Significant hardware cost&lt;br /&gt;
* Complex algorithm and tuning&lt;br /&gt;
* Requires PID understanding&lt;br /&gt;
* Overkill for simple tasks&lt;br /&gt;
&lt;br /&gt;
== Tuning Parameters ==&lt;br /&gt;
&lt;br /&gt;
Successful line-following requires careful tuning of several parameters:&lt;br /&gt;
&lt;br /&gt;
=== Base Speed ===&lt;br /&gt;
The forward speed when driving straight or making corrections.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Too slow&amp;#039;&amp;#039;&amp;#039;: Robot is stable but inefficient; wastes time&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Too fast&amp;#039;&amp;#039;&amp;#039;: Robot overshoots corrections and oscillates&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Optimal&amp;#039;&amp;#039;&amp;#039;: As fast as possible while maintaining stable tracking&lt;br /&gt;
&lt;br /&gt;
Start with low speeds (50-100 motor units) and gradually increase until oscillation appears, then reduce by 20%.&lt;br /&gt;
&lt;br /&gt;
=== Turn Aggression ===&lt;br /&gt;
How sharply the robot corrects when off-line.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Too gentle&amp;#039;&amp;#039;&amp;#039;: Robot drifts off line before correction takes effect&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Too aggressive&amp;#039;&amp;#039;&amp;#039;: Robot oscillates or zigzags&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Optimal&amp;#039;&amp;#039;&amp;#039;: Smooth sinusoidal path that stays on line&lt;br /&gt;
&lt;br /&gt;
For differential corrections, the turn speed should be 50-70% of base speed.&lt;br /&gt;
&lt;br /&gt;
=== Sensor Spacing ===&lt;br /&gt;
Physical distance between sensors affects behavior.&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Narrow spacing&amp;#039;&amp;#039;&amp;#039;: More sensitive to small deviations; better on gentle curves; struggles on sharp turns&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Wide spacing&amp;#039;&amp;#039;&amp;#039;: Less sensitive; handles sharp turns; may miss gentle curves&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Optimal&amp;#039;&amp;#039;&amp;#039;: Spacing slightly wider than line width&lt;br /&gt;
&lt;br /&gt;
For a 20mm wide line, sensors should be 25-30mm apart.&lt;br /&gt;
&lt;br /&gt;
=== Sensor Threshold ===&lt;br /&gt;
The reflectance value that distinguishes line from background.&lt;br /&gt;
&lt;br /&gt;
* Calibrate in actual operating environment&lt;br /&gt;
* Use midpoint between average white and average black readings&lt;br /&gt;
* Implement hysteresis to prevent flickering at boundary&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Calibration procedure&lt;br /&gt;
white_value = read_sensor_on_white_surface()&lt;br /&gt;
black_value = read_sensor_on_black_line()&lt;br /&gt;
threshold = (white_value + black_value) / 2&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Common Challenges and Solutions ==&lt;br /&gt;
&lt;br /&gt;
=== Lost Line ===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Problem:&amp;#039;&amp;#039;&amp;#039; Robot loses the line completely (all sensors read white or all read black).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Solutions:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Memory-based recovery&amp;#039;&amp;#039;&amp;#039;: Remember last known direction and turn that way&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if line_lost():&lt;br /&gt;
    if last_correction == TURNING_LEFT:&lt;br /&gt;
        set_motors(-SEARCH_SPEED, SEARCH_SPEED)  // Continue left&lt;br /&gt;
    else:&lt;br /&gt;
        set_motors(SEARCH_SPEED, -SEARCH_SPEED)  // Continue right&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Spiral search&amp;#039;&amp;#039;&amp;#039;: Gradually expand search radius&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Timeout and stop&amp;#039;&amp;#039;&amp;#039;: If line not found within N seconds, halt and signal error&lt;br /&gt;
&lt;br /&gt;
=== Sharp Turns ===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Problem:&amp;#039;&amp;#039;&amp;#039; Robot cannot turn sharply enough to stay on line.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Solutions:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Detect sharp turn&amp;#039;&amp;#039;&amp;#039;: Multiple consecutive corrections in same direction&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Reduce speed&amp;#039;&amp;#039;&amp;#039;: Slow down when sharp turn detected&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
consecutive_turns_right += 1&lt;br /&gt;
if consecutive_turns_right &amp;gt; 5:&lt;br /&gt;
    base_speed = SLOW_SPEED  // Sharp curve detected&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Aggressive correction&amp;#039;&amp;#039;&amp;#039;: Increase turn speed or even stop one wheel&lt;br /&gt;
&lt;br /&gt;
=== Intersections ===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Problem:&amp;#039;&amp;#039;&amp;#039; Multiple possible paths (T-junction, cross, etc.).&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Solutions:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Detection&amp;#039;&amp;#039;&amp;#039;: Both sensors (or multiple sensors) detect line simultaneously&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Pre-programmed decisions&amp;#039;&amp;#039;&amp;#039;: Follow sequence of turns (left, right, straight, right...)&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
intersection_sequence = [LEFT, STRAIGHT, RIGHT, LEFT]&lt;br /&gt;
current_intersection = 0&lt;br /&gt;
&lt;br /&gt;
if detect_intersection():&lt;br /&gt;
    execute_turn(intersection_sequence[current_intersection])&lt;br /&gt;
    current_intersection += 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Marker-based navigation&amp;#039;&amp;#039;&amp;#039;: Use additional sensors to detect colored markers&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Default behavior&amp;#039;&amp;#039;&amp;#039;: Always go straight through intersections&lt;br /&gt;
&lt;br /&gt;
=== Line Width Variations ===&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Problem:&amp;#039;&amp;#039;&amp;#039; Line width changes along path.&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Solutions:&amp;#039;&amp;#039;&amp;#039;&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Calibration&amp;#039;&amp;#039;&amp;#039;: Test on actual track&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Adaptive thresholds&amp;#039;&amp;#039;&amp;#039;: Continuously recalibrate based on recent readings&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Edge detection&amp;#039;&amp;#039;&amp;#039;: Track line edge rather than center (more consistent)&lt;br /&gt;
&lt;br /&gt;
== Advanced Techniques ==&lt;br /&gt;
&lt;br /&gt;
=== PID Control ===&lt;br /&gt;
Proportional-Integral-Derivative control provides smooth, optimized tracking:&lt;br /&gt;
&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Proportional (P)&amp;#039;&amp;#039;&amp;#039;: Correction proportional to current error (distance from line)&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Integral (I)&amp;#039;&amp;#039;&amp;#039;: Corrects for persistent bias (e.g., one motor slightly faster)&lt;br /&gt;
* &amp;#039;&amp;#039;&amp;#039;Derivative (D)&amp;#039;&amp;#039;&amp;#039;: Dampens oscillation by responding to rate of change&lt;br /&gt;
&lt;br /&gt;
Start with P-only control (set I and D to zero), then add D to reduce oscillation, and finally add small I if steady-state error exists.&lt;br /&gt;
&lt;br /&gt;
=== Look-Ahead ===&lt;br /&gt;
With sensor arrays, use forward sensors to anticipate curves:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
if sensors[0] or sensors[1] active:&lt;br /&gt;
    // Sharp left turn coming&lt;br /&gt;
    reduce_speed()&lt;br /&gt;
    increase_left_correction()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Intersection Navigation ===&lt;br /&gt;
Sophisticated intersection handling:&lt;br /&gt;
&lt;br /&gt;
* Count intersections to determine position on known map&lt;br /&gt;
* Use timing to ensure robot fully enters intersection before turning&lt;br /&gt;
* Implement &amp;quot;intersection memory&amp;quot; to avoid counting same intersection twice&lt;br /&gt;
&lt;br /&gt;
=== Path Memory ===&lt;br /&gt;
Record successful paths and replay:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// Record mode&lt;br /&gt;
path = []&lt;br /&gt;
while running:&lt;br /&gt;
    sensor_state = read_sensors()&lt;br /&gt;
    motor_command = calculate_correction(sensor_state)&lt;br /&gt;
    path.append(motor_command)&lt;br /&gt;
    execute(motor_command)&lt;br /&gt;
&lt;br /&gt;
// Replay mode&lt;br /&gt;
for command in path:&lt;br /&gt;
    execute(command)&lt;br /&gt;
    delay(LOOP_TIME)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== SimpleBot Implementation ==&lt;br /&gt;
&lt;br /&gt;
SimpleBot uses the &amp;#039;&amp;#039;&amp;#039;two-sensor algorithm&amp;#039;&amp;#039;&amp;#039; with basic bang-bang control. The sensors are positioned 25mm apart, straddling a 20mm wide black line on a white surface.&lt;br /&gt;
&lt;br /&gt;
The implementation uses:&lt;br /&gt;
* Reflectance sensors with analog output&lt;br /&gt;
* Threshold-based line detection&lt;br /&gt;
* Four-state control logic (straight, left, right, lost)&lt;br /&gt;
* Simple lost-line recovery (continue last turn direction)&lt;br /&gt;
&lt;br /&gt;
For complete implementation details including circuit diagrams, calibration procedures, and code, see [[SimpleBot:Line Following Implementation]].&lt;br /&gt;
&lt;br /&gt;
== See Also ==&lt;br /&gt;
&lt;br /&gt;
* [[Capability:Line Sensing]] - Hardware and sensor technology&lt;br /&gt;
* [[Capability:Differential Drive]] - Motor control fundamentals&lt;br /&gt;
* [[Activity:Line Following]] - Using line following for navigation tasks&lt;br /&gt;
* [[SimpleBot:Line Following Implementation]] - Complete working example&lt;br /&gt;
* [[Behavior:PID Control]] - Advanced smooth control technique&lt;br /&gt;
&lt;br /&gt;
[[Category:Behavior]]&lt;br /&gt;
[[Category:Beginner Behavior]]&lt;/div&gt;</summary>
		<author><name>John</name></author>
	</entry>
</feed>