Learn Robotics
Module: Move Carefully

Tuning & Debugging

Practical techniques for tuning PID controllers, diagnosing motion problems, and making your robot move smoothly.

8 min read

Tuning & Debugging

You built a PID controller, picked some gains, and hit run. Your robot lurches forward, overshoots the target, wobbles, and eventually settles -- kind of. Or maybe it just vibrates in place. Now what?

This lesson is about the practical side: how to systematically tune PID gains, how to read the signs when something is wrong, and how to use logging and testing to prove your controller actually works.

Manual Tuning: The Step-by-Step Method

If you have no idea where to start, follow this sequence. It works for nearly every system.

Step 1. Set Kp = 0, Ki = 0, Kd = 0. The robot should not move.

Step 2. Increase Kp slowly. Command a step change (e.g., target speed jumps from 0 to 1.0 m/s). Watch the response:

  • Too low: the robot barely moves.
  • Good: the robot reaches the target quickly but overshoots a little.
  • Too high: the robot oscillates and never settles.

Stop when you see sustained oscillation (constant back-and-forth). Note this critical gain as Ku, then set Kp = 0.5 * Ku.

Step 3. If the robot settles close to the target but not exactly on it (steady-state error), increase Ki in small increments until the error disappears. Use the minimum Ki that works.

Step 4. If overshoot is a problem, increase Kd to add damping. Go slowly -- too much Kd amplifies sensor noise and causes jitter.

Tip

Most wheeled robots work well with just PI control (Kd = 0). Only add the D term if you see persistent overshoot that the P and I terms cannot solve alone.

Ziegler-Nichols: A Classic Starting Point

The Ziegler-Nichols method gives you a formula-based starting point. It is not magic -- you will still need to refine the results -- but it gets you in the right ballpark.

  1. Set Ki = 0 and Kd = 0.
  2. Increase Kp until the system oscillates continuously at a constant amplitude. This is the ultimate gain Ku.
  3. Measure the oscillation period Tu (seconds for one full cycle).
  4. Apply the formulas:
ControllerKpKiKd
P only0.5 * Ku00
PI0.45 * Ku1.2 * Kp / Tu0
PID0.6 * Ku2 * Kp / TuKp * Tu / 8

For example, if Ku = 4.0 and Tu = 0.4 s:

  • Kp = 0.6 * 4.0 = 2.4
  • Ki = 2 * 2.4 / 0.4 = 12.0
  • Kd = 2.4 * 0.4 / 8 = 0.12
Warning

Ziegler-Nichols was designed for slow industrial processes and often produces aggressive gains for fast mechanical systems. Treat the output as a starting point, then reduce Ki and Kd if the response is too aggressive.

Diagnosing Common Problems

When your robot misbehaves, the symptom tells you which gain to adjust.

SymptomLikely CauseFix
Oscillates around the targetKp too highLower Kp, or increase Kd to add damping
Overshoots then slowly settlesKp slightly too high, Kd too lowLower Kp or raise Kd
Settles below the target (steady-state error)Ki too low or zeroIncrease Ki gradually
Very slow to reach the targetKp too lowIncrease Kp
Jitters and twitches near the targetKd too high, amplifying sensor noiseLower Kd, or filter sensor data
Shoots forward after being stuckIntegral windupAdd anti-windup (clamp the integral term)
anti_windup_pid.py

Using Logs and Plots to Debug

Staring at a moving robot and guessing what is wrong is a losing strategy. Instead, log the data and plot it.

Record these values every control loop iteration:

  • Timestamp -- so you can see timing.
  • Target (setpoint) -- what you asked for.
  • Actual (measurement) -- what the sensor reported.
  • Error -- the difference.
  • P, I, D terms -- the individual contributions.
  • Total output -- what was sent to the motor.
logging_pid.py

Plot the CSV and look for these patterns:

  • Target vs. Actual diverging: your gains are too low overall.
  • Actual oscillating around Target: Kp too high or Kd too low.
  • I term growing without bound: you need anti-windup.
  • D term spiking wildly: sensor noise -- add a low-pass filter.
  • Actual never reaching Target: steady-state error, increase Ki.

A single plot of target vs. actual over time will tell you more in ten seconds than ten minutes of watching the robot.

Testing Strategies

Do not declare your controller "tuned" until you have tested it properly. Here are three tests every PID controller should pass.

1. Step Response Test

Command a sudden change in setpoint (e.g., target speed jumps from 0 to 1.0 m/s). Measure:

  • Rise time: how quickly the actual value reaches 90% of the target.
  • Overshoot: how far past the target the actual value goes (ideally under 10%).
  • Settling time: how long until the actual value stays within 2% of the target.

2. Tracking Test

Command a smoothly changing setpoint (e.g., a sine wave or ramp). Check that the actual value follows the target closely without lagging behind. Large tracking error means your gains are too low or your control loop is too slow.

3. Disturbance Rejection Test

While the robot is holding a steady setpoint, apply a disturbance -- push the robot, add weight, or change the surface. The controller should recover quickly. If it takes a long time to return to the target, increase Ki. If it oscillates after the disturbance, increase Kd or lower Kp.

What's Next?

You now have the complete toolkit for precise robot motion: closed-loop feedback, PID algorithms, motor control modes, velocity commands, and practical tuning and debugging techniques.

In Module 6, we shift from motion to perception -- how robots see and understand the world using cameras, lidar, and sensor fusion. Because even a perfectly tuned controller is useless if the robot does not know where it is going.

Got questions? Join the community

Discuss this lesson, get help, and connect with other learners on Discord.

Join Discord

Discussion

Sign in to join the discussion.