Home
Up
3 phase rotating magnetic field
Triplens
Lab reports
Measure an unknown inductor
Serial Port info
ASCII chart
DataSheets
PIC programmer from a JTAG3 cable
LogicPort
Intro to PID

 

 

Intro to PID

 

*This tutorial includes video demonstrations of key concepts.  Please read and watch!

Control.  We all want, we all need it.  This is a small introduction to a control system that I used to demonstrate concepts like steady state error, oscillation, Proportional and integral control.  There wont be any complex math, just some noodling around with a control system.  The system is very simple, a motor with feedback is attached to a disk with a spring attached.  As the disk turns, the spring is pulled and causes the motor to fight to move to any given position.  The entire purpose of this demonstration is to reach the target position as quickly as possible without any error in the long term.  Sounds easy?  Lets find out.

 P0003341.JPG (385865 bytes)P0003343.JPG (458496 bytes)

            First off, there is feedback on the motor.  Through the use of its quadrature encoder, we can determine the position of the motor shaft.  In this particular example, on revolution of the motor (before the gearbox) represents 12 position counts.  Clockwise rotation increments a counter, and counter clockwise rotation decrements the counter.  This allows us to determine the exact position of the motor at anytime.  The motor is attached to a 53 : 1 gearbox which multiplies our 12 counts per revolution of the motor shaft by 53, giving us 636 counts per revolution of the disk.  Just to give you an idea, that’s 360 degrees divided into 636 counts or .566 degrees per count.  That means for every increment or decrement of our position counter, our disk has rotated 0.566 degrees.  Not super fine resolution, but it will do.

 

            The motor is “homed” to its center position.  All other position commands will be issued relative to the “home” position.  For instance, if the home value was 100, and I wanted to rotate the shaft 11.32 degrees counterclockwise, I would tell the controller to put the motor at position 80.   does that make sense?  All positions are relative to the home position.  My implementation uses a 16 bit counter, and I initialize the home position to half the range of a 16 bit number or 32767.  This allows me to rotate in either direction about 32767 / 636 = 51.5 rotations.  Since I will not be rotating farther that 1 full revolution, this is more than adequate.  But like I was saying, since my home position is 32767, if I want to rotate 90 degrees clockwise, I would tell the controller to place the motor at 32767 + (90 degrees / 0.566 degrees per count) = 32767 + 159 = 32926.  I hope that makes sense, because everything else hinges upon understanding how position is being calculated.  The motor is homed by lining up the target indicator with the home mark, and issuing the home command in the terminal window.  This sets the current position of the motor to 32767.  the accuracy of the home position is entirely up to the operator (and the position of home for that matter), but from here on out, that is the only human intervention required.

 

            Once the motor is homed, we are ready to start experimenting.  But lets take a second to understand how the controller works.  The motors current position is updated whenever the motor moves, and it reflects the motors absolute position, regardless of what we want it to be.  It is by using this position that we will determine if we have reached our target position or not.  If you grabbed the motor shaft and gave it a quick turn after you had homed the motor, the current position of the motor would reflect that movement.  A target position is then set, and this is the place where we want the current position to be.  A control loop will look at the current position and the target position, and send power and direction signals as appropriate to the motor so that the target position and the actual position match.  That is the entire goal of our control loop.

 

            The simplest form of a control loop is the proportional control.  It works like this:  The actual position is compared to the target position, if the actual position is greater than the target position, the direction the motor should move is set to counterclockwise.  If the actual position is less than the target position, then the motor is told to rotate clockwise.  How much should we rotate?  Well, take the magnitude of the target position – actual position, and that should work (the sign of the result will set the direction, negative is counter clockwise, positive is clockwise).  For instance, lets say we had a PWM that accepted inputs from 0 (0% duty cycle or 0 power to the motor) all the way up to 100 (100% duty cycle or 100% power).  If our current position was 200, and our target was 150, we would set the direction to counterclockwise, and target - actual = -50, so we would apply 50% power to the motor.  As we got closer to the target, say the current position is 175 and target is still 150, the direction would be counterclockwise, but the power to the motor would be 175 – 150 = 25% power to the motor.  It is obvious to see, that as we got closer and closer to the target position, the power to the motor would decrease until the current position and the target position were exactly the same!  “WOO HOO!” You say, “that was easy!”  well lets give it a try.

 

I will tell the motor to move to target 1, using the very simple control loop that we just discussed.  Home, target 1 and target 2 can be seen as white lines on the black disk.  The LED panel to the right of the spring indicates the power going to the motor in 4 steps, like a bar graph display, and all the LEDS will turn off when the actual position and the target position are the same.  Home is the center mark, target 1 is to the right of home, and target 2 is to the left of home.  For the first demonstration I will leave the spring disconnected.

  nospring.wmv - 1.8 Mb

What happened?  well, it looked pretty good didn’t it!  The motor turned fairly quickly to t1 (target 1), and even though the LEDS didn’t go out, the motor came pretty close to reaching the target didn’t it!  Well, I would say we got it!  Wouldn’t you?  Well, just to be on the safe side, lets hook up the spring and see what happens.  Ok, spring connected, motor is homed, and here we go, set position to target 1.

pgain1.wmv - 1.8 Mb

Umm, that’s not good.  It’s not even close!  As the motor moves toward position 1, the spring begins to pull harder and harder on the shaft in the opposite direction.  At some point, the system reaches equilibrium and the force applied by the motor is equal to the force created by the spring.  But since the power going to the motor is directly related to the distance between the target and the actual position, there is a physical position at which the system reaches equilibrium.  If the motor were to turn closer to its target position, the power would be reduced (because the error between the actual and target positions got smaller)  and the spring would over power the motor and pull it backwards.  This would increase the power to the motor because the spring pulling the motor away from its target would increase the error, and thus the motor would get more power and pull the spring harder.  So its obvious to see, the system will reach a point when the error is sufficient to overcome the pull of the spring, but just barely.  Too close to the target, and the power goes down, too far away and the power goes up.  In the extreme case, if the motor (for some magical reason) were to actually reach the target position, the error would be zero, and the motor would turn off.  Then the spring would pull the motor back, and we would be right back where we started.  So you see, with a simple proportional controller, we will always be cursed with a long-term error.  The spring will prevent us from ever reaching the target, for if we ever did, the motor would turn off, and the spring would pull it away.  You have now been introduced to a rather devious problem.  Long-term error.  Its something a purely proportional controller cannot fix, but lets leave that for another day.  Lets introduce another twist to the simple proportional controller.  Proportional gain.

 

With a gain of 1, the error is directly turned into the power to the motor.  If the error is 25 counts, we supply 25% of full power to the motor.  If the error is 75 counts, we supply 75% of full power to the motor.  So it may or may not be obvious, but it takes a large amount of error to generate sufficient power to do much (25 counts at least).  What if we could make it respond a little quicker?  How about multiplying the error by a value so that 25 counts caused the output to be 100% of full power?  That would be a proportional gain.  We will multiply the proportional error by some number (the proportional gain) to generate the power to the motor.  So with a proportional gain of 10, an error of 1 count would result in 10% of the max power to the motor, and a error of 5 counts would result in 50% of the power going to the motor.  All right!  This sounds exciting!  We might be able to fix that huge and pesky long term error by cranking up the proportional gain!  Now if the motor is off by just a few counts, we will be supplying much more power to the motor, and thus the spring will be overcome until we get much closer to the target.  For example, in the first test, we had a proportional gain of 1, and the target was half way reached (large long term error), but in this next demonstration, we are going to have a gain of 10.

pgain10.wmv - 2.0 Mb

Much better!  The target was much closer, the long term error was reduced, but its still not perfect.  For most applications where a long term error is not a problem, this would be sufficient.  Simply turn up the gain until the error is within reasonable limits.  But wait!  There is a catch.  If we increase the gain too much, we may run into oscillation!  Watch this next demonstration where to proportional gain is turned up too high.

pgain35.wmv - 2.4 Mb

And if the command to return to home is issued, watch what happens.

 pgain35home.wmv - 0.7 Mb

Oscillation occurs because the error gain is set too high.  As the motor approaches the target, if the gain is set to say, 100 (in an extreme case) then even an error of 1 count results in 100% of max motor power being applied.  The Motor shoots right through the target position and out to the other side.  The motors direction is reversed, and an error of 1 count again supplies 100% of max power to the motor, causing it to shoot through the target again.  This process will repeat indefinitely.  This is oscillation.  The only way to tame oscillation is to turn the gain down, which may increase your long-term error beyond acceptable limits.

 

            Proportional control is sufficient for many applications, but it has 2 major pitfalls.  

1.) Long-term error:  When setting a target, it would be ideal if the target was actually met.

2.) High gains (which may be used to minimize long-term error) can cause oscillations.

 

Here are some more demonstrations of purely proportional control.  Watch for steady state error and oscillation.

pgainnoodle.wmv - 12.6 Mb

            We need a fix for the long-term error.  What we need is something that watches the system for a period of time, and determines what needs to be done.  For example, lets imagine our system with a proportional gain of 1.  After a few seconds, the system has stabilized and is in equilibrium, but it is obvious, that the actual position and the target position are not the same.  Imagine an observer who watches this error, realizes that more power is needed and applies it to the motor.  What if every second we took the error and added it to a running total of error.  If the error stayed constant over a period of time, the accumulator would gather a rather large sum of errors.  We know that the proportional control alone is not sufficient to get the actual position to match the target position, so what if we multiply the accumulated error by some gain (integral gain, because we are integrating the error over time) and add it to the proportional gain.  If the sum of the proportional and integral error is positive, we turn clockwise, and if it is negative, we turn counter clockwise.  Perhaps this is best understood if it is demonstrated.  We will set up the system with a proportional gain of 1 (which we all know is inadequate) but this time, we will add a small integral gain.  We will accumulate the error in an accumulator (130 times a second we will add the current error to the accumulator) and we will multiply it by a small value, like 0.001 (the integral gain).  This value (accumulator * integral gain) will be added to the proportional gain to produce the direction and percentage of power supplied to the motor.  Error * proportional gain + accumulator * integral gain, if the sum is negative, the direction will be counterclockwise, if the sum is positive, the direction will be clockwise.  The magnitude of the result will set the power to the motor.  For example, if we are currently at an actual position of 50, and our target is 100, with a  proportional gain of 1, we will supply 50% power to the motor.  But lets say that it has stayed this way for 10 seconds, and we have accumulated the error once every second, we would have an accumulated error of 500, lets say we have an integral gain of .01, then the power to the motor would be 50 counts (error) * 1 (proportional gain) + 500 (accumulator) * 0.01 (integral gain) or 50 + 5 = 55% power to the motor in a clockwise direction.  As more time goes on, the power continues to increase to the motor, causing it to move closer and closer to the target.  This causes the proportional term to become smaller and smaller, but as long as the target and actual position are not the same, the accumulator will continue to accumulate error and add power to the motor.  Eventually, the actual position and the target will match.  The proportional term will be zero at this point, and the accumulator will no longer be accumulating error (because the error added to the accumulator will be zero) but the previously accumulated error will still be there.  Lets say that the controller has been running for 100 seconds now, and has accumulated 7500 counts of error.  The power to the motor will be 0 counts (error) * 1 (proportional gain) + 7500 (accumulator) * 0.01 (integral gain) or 0% + 75% = 75%.  In our control system with the spring, it is easy to see that some power must be maintained to the motor to fight the spring, and with the integral added to the system, we have a way of supplying the right amount of power to the motor, even when we have reached our target.  So lets demonstrate:

pgain1Igain001.wmv - 7.4 Mb

            So you can physically observe the integral action fixing the long term error.  But what is with the incredibly long time it takes for it to reach the target? Well, the integral gain is set too low, and for that matter, the proportional gain is set too low as well.  It was obvious from the video above, that the proportional term only got us ˝ way there. The integral term had to take us the rest of the way, and for a slowly accumulating integral term, it was a long process (yes, it was accumulating 130 times a second, but it was being multiplied by a very small number, making it very slow to effect change in the motors position).  By the way, 10 minutes after I began the experiment in the video above, the target position had still not been reached.

 

            But just for laughs, lets find out what happens if we turn the proportional gain off, and use purely integral to reach our target.  We know that we are guaranteed to reach our target position, eventually, but what will it look like?  Lets find out.  Here is a purely integral controller with an integral gain of 0.01

  pgain0Igain01.wmv - 4.2 Mb

            Not too shabby.  A little slow, takes a little while to settle down, but over time, it would settle down (or at least oscillate slowly around our target, almost imperceptibly) and while that’s not perfect, it could be good enough.  Lets see what happens when we turn the integral gain up.

igainhigh.wmv - 3.5 Mb

            Well, that was too far.  But it should be apparent from the videos that integral terms will oscillate just as badly or worse than purely proportional controllers.  What are we to do?  Put them together!  That’s what!  So now lets find a proportional gain that does not oscillate but gets us close to the target quickly.  Lets say a gain of 12.  not too much, but not too little either.  Now lets find an integral gain that does not cause strong oscillations, but fixes our long term error quickly.  Say 0.0256.  lets see what that does for us.

tuning.wmv - 19.6 Mb

            Well, I noodled around with the integral and proportional values a little bit, and at the end of the video I had a proportional gain of 12 and an integral gain of 0.128 updating at 78 times a second.  It still needs a little tuning, but for educational reasons, I will leave that up to you.  Have fun, I hope you learned something, and please feel free to write me an email telling me if you liked it, hated it, or think something needs to be corrected.

 

This was just a simple introduction to the world of control systems.  There are many more things that I did not even mention, such as derivative action, integral windup and much more.  For more information, do a search for "PID without a PhD" and "PID control"

P0003349.JPG (427887 bytes)P0003350.JPG (557067 bytes)

send comments to :

 

 

Hit Counter