PID Control

Hi! I’m using your wheels and sensors on my line following robots at the competitions in Türkiye. Some of my robots were champions at some competitions. Now i want to use PID loop in my codes for more sensitive motor control. I’ve read your 3pi document about PID control but i couldnt find how to calculate constants like 1/20, 1/10000, and 3/2 at this code.

# int power_difference = proportional/20 + integral/10000 + derivative*3/2;

How can i find these constants for my robot?
Here is a video, one of my line follower robots, which is the winner of this competition at Bilkent University. My robot is the white robot before last one (@ 1:50).


Hello Diego,

There are ways to “calculate” the constants, but they are mathematically advanced and require a lot of data collection that is not easy to implement on a small robot. What I usually do is just play around with the constants, one at a time, manually adjusting them to optimize performance and using a lot of testing on a real track. Try to watch for overshooting (crossing the line multiple times before aligning with it, especially after coming out of a sharp turn), and for low- and high-frequency instabilities, which have different causes. You can start with the robot running at a low speed, where it will be easy to get it working well, then gradually increase the speed and see what you need to change to keep it working.

By the way, I almost never use an integral constant, since the effect would only be to slightly improve the centering of the robot on the line.



A few other things to consider in addition to what Paul recommended:

  1. I like to start with just the proportional term, P, at a low speed to get something that behaves reasonably. You can calculate a ballpark value for Kp by determining what line position value from your sensor should correspond to a maximum correction from your motors (i.e. at what point do you want one motor turning full speed while the other motor is stopped)? Pick a value for Kp that makes that happen.

For example, let’s say that your sensor returns line positions from 0 to 100, where 0 is full left and 100 is full right, and let’s say your motor speeds vary from -100 (full reverse) to 100 (full forward). To get a maximum correction, you want a motor differential of, say, -100 when your sensor reading is 0 and +100 when your sensor reading is 100:

correction = Kp * (line_position - 50) // ignore D for now
right_motor_speed = 100 - correction
left_motor_speed = 100 + correction

To convert appropriately from line sensor values to motor speeds as defined above, you can see that Kp should be around 2. If your line sensor values or motor speeds have different domains, then the ideal Kp will be different. The point is to pick a Kp that converts line sensor readings into motor speeds in a way that gives you just the right amount of responsiveness. Too much and you’ll overshoot on turns. Too little and you’ll lose the line on sharp turns.

  1. Once you have a good sense for Kp, try adding in the differential term, D. The key thing to note is that the Kd needs to be much bigger than Kp for it to have any effect on the correction computation. This is because Kd is being multiplied by the difference of two similar terms:

correction = Kp * line_position + Kd * (line_position - prev_line_position)

The difference is likely to be very small relative to the value of line_position itself. I recommend starting with Kd = 20 * Kp, but the actual value of Kd will depend on your particular implementation. For example, the faster your main loop runs, the bigger Kd should be.

  1. Make sure you have the signs right in your equation. If you have a sign error somewhere, your trial and error tests are likely to be very frustrating.

- Ben

Thanks for your answers. I will upload here my robots video when it is ready.

@Ben thanks for your reply. But i’ve a question too. You say “start with Kd=Kp*20” but in the example codes of 3pi PID algorithm it is like

# int power_difference = proportional/20 + integral/10000 + derivative*3/2;

Here Kd=3/2 and Kp =1/20. How did you calculated this? Is your PID loop slow?



I believe the 3pi example code’s PID constants are detuned on purpose so that people can improve them and learn PID tuning. The course in your video does not look particularly hard, except possibly the incline. I think you should be able to tune your PID constants so your robot is not noticeably overshooting the line when coming out of turns.

- Ryan

Yeah, the 3pi’s PID constants are deliberately not great. We didn’t think it would be as much fun for people if we just handed them optimal line-following code with no room for improvement.

- Ben