In this post I will discuss my genetic algorithm to tune a PID controller.

PID controllers are often used in robotics, especially to drive motors. In my case a want a PID controller that turns Sidbot (see previous posts for this robot) to desired headingd in the quickest possible way. The job of the PID controller is to specify the amount of motor power that is suited to turn the robot. One can imagine that the amount of power will be large when the robot is way off the desired heading. If the robot is exactly on the desired heading the motor must remain motionless, the amount of power must be 0. When the robot is close to the desired heading then the motors must receive little power, otherwise the robot could overshoot the desired heading without stopping. If the robot overshoots the power must be negative.

The PID controller works like this. It takes the difference between current heading and desired heading and calles this the error. The error is the basis for calculating the amount of power that needs to got to the motors. It not only takes the current error (Proportional), it also takes into account how big the error used to be (Integral) and how big it is likely to be (Derivative). It weights these three inputs with PID values and sums them. This is the amount of power that is send to the motors.

Finding good values for P, I and D can be a difficult thing. You might check wikipedia to read more about some of the methods that are used. I wanted to use a smart kind of trial and error method using the same principle that also drive evolution: Survival of the fittest. I took ten randomly chosen values for PID and tested them all. The best sets survived, the worst 50%were discarded. As there were only 5 sets left I copied these these to have one copy each. By chance these copies were a little bit different from their parent. Then I tested these ten sets again. This process was repeated over and over until a satisfactory set of parameters was found.

Below is a graph that’s shows the results of my experiment. It actually shows the PID values for the best set each time I tested the 10 sets. It also shows how much time it took to make a turn of 60 degrees. Remember my goal was to go to the end heading as quick as possible, so the lower this light blue line, the better the parameters.

So what does this graph tell you? In the last test the robot reached it’s goal in about 0.4 seconds. I don’t think it can do much faster due to physical limitations. The graph also shows that a fairly good set of parameters was found quickly, just after a few tests the turn was made within 4.2 seconds. (I must admit that I had some idea for a suitable range for the random generator that selected the initial PID parameters). It then took some time to find a set that was even better. After that changes to the PID values got smaller and the gain was also smaller. The optimum PID values were reached.

I might conclude that my experiment was successful. But the task of the PID controller was a simple one.

For those still here, these are the resulting values P=210.91 I=56.75 D=2 hI=0.65. hI is the fading speed of the Integral.

Hello,

this is really helpful! I’ve been having a hard time programming balancing bots using PIDs, and this approach looks great. But I was wondering how you determine which of the PID values give the best results (for deleting half of them)? Do you use the highest error or something? Anyway, this is a great resource.

thank you,

DiMastero

Well, this is the most difficult part. Also, there is not a single answer, you’ll have to find a solution that fits the task that you have in mind. In this case I defined succes as:

- having reached the desired heading exactly, and

- the PID value should be less than 4.

The first condition is quite obvious, the second is to make sure that the robot has stopped at the desired heading and is not overshooting it.

For a balancing robot I think success is a combination of being able to stand up for a long time and stability while standing up. The latter could be defined as a small value for oscillation (ie a small integral of the absolute error). You’ll have to combine these two aspects into one variable hat expresses success. This could be done by dividing stand up time by the integral, success =time/integral.

You should also be aware that in my experiment there was no need to reset the robot after every test. With a balancing robot I thing you’ll have to put it upright manually before every test. This approach may be very labor intensive then.

Pretty neat!

I wonder though, the final constants are not what is normally seen for a PID. Usually I is much smaller than P and D is much larger than P. For a P of 210 I would expect an I of something like 20~40 (not that far off the 57 you obtained). For the same P I would expect the D to be 1000 or more. The D of 2 looks to me like the controller is PI not PID since a D that small isn’t doing much.

Any idea what kinds of values for P, I and D you would get if you used standard methods of tuning? For example, find a P that oscillates then used the published tables to determine I and D values.

I’ve got a NXT PID page for line following at http://www.inpharmix.com/jps/PID_Controller_For_Lego_Mindstorms_Robots.html with a suitable Zieglerâ€“Nichols table for tuning. Be real interesting to see what values that approach gives.

Hi thanks for the reaction. As a matter of fact it was your page that got me interested in PID controllers.

The I and D factors are time dependent in reality. In my program I ignored this. (This doesn’t matter as long as the loop speed of the controller is constant.) I think this explains the odd I and D values. The I factor normally would be increased by P*dt. The D factor should by lastP/dt. As I ignored the effect of time my I value is much too big and the D value is much too small.

I think that an application like this requires a PD controller. Unlike a line follower it doesn’t try to maintain an equilibrium. It tries to reach a goal and is then finished. The I factor is great when a system is within a controllable range. It is a burden when the system is outside this range. I needed a kind of damping on the I so that it not grows to big. A clear indication that system is outside the controllable range for most of the time.

To Jim Sluka,

I am the new owner of a Lego Mindstorms, Revision 2.0 set and having many, many years of work experience in the instrumentation field, I enjoyed reading your webpage on the design of PID algorithms for the Legos.

Have you revised a .rbt file for use on the Revision 2.0 set and using the color sensor instead of the light sensor? Is this .rbt file available?

Ah, I see, yes the time interval matters and effects the I and D constants.

The integral can be a problem and you are right, often it is better to leave it out. And of course, it matters whether you want the error as small as possible at a given time or if you want the average error to be as small as possible. In the first case the integral can be a problem, in the second it is required.

I’ve found that considering common PIDs in the everyday world handy for deciding if the integral should be included. Consider an oven temperature controller. In cooking you actually want the tempXtime integral to be a particular value. If the door is opened and the oven’s temperature drops you want the temperature to overshoot when the door is closed. That keeps the timeXtemp integral constant. A car’s cruise control is often also done with a PID. In the case of a car’s speed though you never want to overshoot the set point (target vehicle speed). If you hit a hill and the speed drops you don’t want the car over-accelerating past the speed set point in it’s attempt to keep speedXtime constant, instead you want the system to dampen with no over shoot. In this case you can either leave the integral term out, or if it is used it is often useful to zero the integral every time the error is zero or every time the sign of the error changes. That’ll keep the integral term from forcing the system to overshoot but still retain the integral’s term ability to…

One nice thing about the integral term is that it will correct for very small errors (given enough time). Sometimes that is useful, particularly when the system is fairly stable to begin with. For line following, or balancing robot I suspect that random noise in the system pretty much keeps the PD controller busy enough that small tuning from the integral term isn’t all that useful.

Anyway, cool application of the genetic type algorithm for tuning and I’m going back and reading your cool earlier posts.

Thanks for the very informative addition!