Trailblazer Robotics
Unit 4 · Week 8

Distance PID (kP only)

A practical P-controller using the distance sensor. The same idea pros use, scaled to middle-school complexity.

You'll learn

Think of it like: Parking a car in front of a garage door. Far from the door, you press the gas. Closer, you ease off. Right at the line, you stop. A P-controller is the same idea, but the robot does it with math 25 times a second.

The P-controller, in plain English

Every loop, the robot asks: how far am I from where I want to be? That's the error. Multiply that error by a small number called kP, and you get the motor speed. Big error means fast. Small error means slow. Zero error means stop.

error  = target - currentDistance;
output = kP * error;

That is the whole controller. Two lines. The rest is just safety: clamping the output so the motor doesn't try to spin at 500%, and exiting when you arrive.

Distance PID: kP only (matches the reference PDF)

This is a faithful C++ version of the block / Python example from your Coding Examples folder. Same logic, same variables (target, error, output, kp), same flow.

#include "vex.h"
// using namespace vex;  (auto-included by VEXcode IQ)

brain    Brain;
motor    Motor1     = motor(PORT1, false);
distance Distance2  = distance(PORT2);

// Drive forward until you are `target` mm from a wall (P-controller)
void DriveDistance(double target) {
  Motor1.spin(forward);
  double kp     = 0.4;
  double error  = target - Distance2.objectDistance(mm);
  double output = 0;

  while (error > 0) {
    error  = target - Distance2.objectDistance(mm);
    output = kp * error;

    // clamp output between -100 and +100
    if      (output >  100) output =  100;
    else if (output < -100) output = -100;

    Motor1.setVelocity(output, percent);
    wait(0.04, seconds);
  }
  Motor1.stop();
}

int main() {
  DriveDistance(200);   // stop when 200 mm from the wall
}
Why we keep it to kP only: middle-school distance-sensor controllers almost never need integral or derivative terms. The distance sensor already gives a clean reading, and kP alone produces smooth, predictable behavior. Adding I and D is more code to tune and more places to introduce bugs. Start simple. Add complexity only when a real problem demands it.

Tuning kP

The "right" kP depends on your robot's weight, gearing, and wheel grip. Start at 0.4, then nudge up or down based on what you see.

What I and D would add (concept only)

You don't need these for the kP version. Read this so you know what the letters mean.

I: Integral

Adds up the error over time. If kP alone isn't enough to push through friction, the integral term slowly builds and gives the motor an extra nudge. Useful when the robot stalls a few mm short of the target.

Think of it like: a stubborn person leaning harder on a stuck door the longer it refuses to open.

D: Derivative

Watches how fast the error is changing. If the robot is sprinting toward the target, the D term applies the brakes early so it doesn't overshoot.

Think of it like: seeing a red light from a block away and easing onto the brake pedal early instead of slamming it at the last second.

You can graduate to full PID later. Right now, kP-only does the job for almost every IQ task.

Try it

Run the example. Print error and output to the Brain screen every loop. Watch what happens to the values as the robot approaches the target. You'll see error shrink, output shrink, motor slow down. That's the controller working.

Curated references

Coding Challenge

Wall holder

Use the distance sensor and a kP controller to hold the robot exactly 250 mm from a wall. If you push the robot back, it should drive forward to recover. If you pull it forward, it should reverse to recover. Hold the position for 5 seconds.

No solution is given for this challenge.

Find the Bug

Two distance-PID programs that look right but aren't. Spot the bug.

Problem 8A
This robot should stop when it is 200 mm from the wall. Instead, it speeds up and crashes. Why?
void DriveDistance(double target) {
  Motor1.spin(forward);
  double kp     = 0.4;
  double error  = target - Distance2.objectDistance(mm);
  double output = 0;

  while (error > 0) {
    error  = target - Distance2.objectDistance(mm);
    output = kp * error;
    Motor1.setVelocity(output, percent);
    wait(0.04, seconds);
  }
  Motor1.stop();
}
Problem 8B
This version clamps the output, but the robot still never stops. The while-loop runs forever. Why?
void DriveDistance(double target) {
  Motor1.spin(forward);
  double kp     = 0.4;
  double error  = target - Distance2.objectDistance(mm);
  double output = 0;

  while (error > 0) {
    output = kp * error;
    if      (output >  100) output =  100;
    else if (output < -100) output = -100;
    Motor1.setVelocity(output, percent);
    wait(0.04, seconds);
  }
  Motor1.stop();
}
← Week 7 Next: Odometry →