Trailblazer Robotics
Unit 4 · Week 7

Proportional Control (the P in PID)

Stop snapping at full power. Slow down as you approach the target.

You'll learn

The big idea

Imagine you're trying to park a car exactly 10 feet from a wall. If you drive at full speed until 10 feet then slam the brakes, you'll skid past the line. That's bang-bang control. Instead: the closer you get, the slower you drive. That's proportional control.

Error

error = target − current

If your goal is 1000 motor degrees and you've traveled 200, error = 800. Far from the goal → high error → drive fast. As you approach, error shrinks → motor power shrinks → smooth landing.

power time bang-bang (overshoots) proportional (smooth)

P-controlled turn

// Turn to a target heading using only the P term
void turnTo(double targetHeading) {
  const double kP = 0.6;   // tune this

  while (true) {
    double error = targetHeading - Gyro.rotation(degrees);
    if (fabs(error) < 1.0) break;             // close enough

    double power = kP * error;                 // proportional
    if (power >  60) power =  60;              // clamp so we don't fly
    if (power < -60) power = -60;

    LeftMotor.spin(forward,  power, percent);
    RightMotor.spin(reverse, power, percent);
    wait(20, msec);
  }
  LeftMotor.stop();
  RightMotor.stop();
}

Tuning kP

Start with kP = 0.1, double it until you see overshoot, then back off slightly. This is the same tuning process pros use.

Why this is a big deal: proportional control is the foundation of every fancy autonomous routine. PID, motion profiles, path following, all built on this idea. Get comfortable here before moving on.

Try it

Write a P-controlled driveTo(distanceInches) that uses the average of the two motor encoders. Test with different kP values. What happens at kP = 5?

Curated references

Coding Challenge

Perfect 180° turn, no overshoot

Write a P-controlled turn that gets the robot to face exactly 180° from its starting heading without overshooting or oscillating.

No solution is given for this challenge.

Find the Bug

Two programs with intentional errors. Spot the bug.

Problem 7A
This P-controlled turn looks correct. Instead of turning to 90°, the robot spins back and forth forever. Why?
void turnTo(double targetHeading) {
  double kP = 5.0;

  while (true) {
    double error = targetHeading - Gyro.rotation(degrees);
    if (fabs(error) < 1.0) break;

    double power = kP * error;
    LeftMotor.spin(forward,  power, percent);
    RightMotor.spin(reverse, power, percent);
    wait(20, msec);
  }
  LeftMotor.stop();
  RightMotor.stop();
}
Problem 7B
This loop runs forever. The robot keeps turning, even after it passes the target. Why doesn't the break trigger?
void turnTo(double targetHeading) {
  double kP = 0.6;

  while (true) {
    double error = targetHeading - Gyro.rotation(degrees);
    if (error < 1.0) break;

    double power = kP * error;
    LeftMotor.spin(forward,  power, percent);
    RightMotor.spin(reverse, power, percent);
    wait(20, msec);
  }
  LeftMotor.stop();
  RightMotor.stop();
}
← Week 6 Next: Full PID →