Tuning the PID Library

The guys over at ARM have ported the Arduino PID Library to work with their mbed platform. I'm mentioning this on the Arduino board because as part of the port they did a really nice writeup on PID tuning. Since the backend is the same, their procedure will work with the Arduino library as well.

Also since this is a thread about PID tuning, let me throw up some suggestions for Trial and Error Parameter Adjustment. If the math in the mbed method isn't working for you, use these rules of thumb to get the performance you want.

Parameters and what they do (sort of) P_Param: the bigger the number the harder the controller pushes. I_Param: the SMALLER the number (except for 0, which turns it off,) the more quickly the controller reacts to load changes, but the greater the risk of oscillations. D_Param: the bigger the number the more the controller dampens oscillations (to the point where performance can be hindered)

These are rules of thumb and aren't exactly what's going on inside the controller, but they should help when deciding which number to change and in which direction.

And lastly, if the second you enable the controller the output goes in the wrong direction and pegs at 0 or 100%, you've got the sign of the P_Param wrong. That is, if you've got a 3 in there, make it -3.

Nice... Thanks.

br3ttb,

I've been browsing the PID control threads on here, and I must say I am really impressed with your contributions.

We'll just have to get you a new job so you can write some auto-tune software for the Arduino. ;)

We’ll just have to get you a new job so you can write some auto-tune software for the Arduino.

Having dealt with various auto-tuners over the years, I’m not sure I would want to write one, even if my employment agreement allowed it. auto-tuners can be beat by a moderately informed human just about every time.

I hope this thread will turn into a tool for (moderately) informing people.

Im am working on reworking my controller for a near space balloon. It basically controls the spin on the payload as it goes up using fins. The basic pid controller works well when I give it a good input and have been very happy with it so far. The problem I am having is over shoot. With wind gusts, turbluance and other issues, I can almost instantly loose control and then I try to spin my self back to a specific direction. However, the balloon payload has signifigant rotational inertia so that over shoots can be severe and the time to dampen out is to long. Its not to bad at low altitudes, but above 30-40K ft, it can get really bad as the air gets really thin. Is this something I can use the bias for?

I was thinking I would need to adjust my bias based on the rotational speed on the payload and my altitude as I am attempting to reach my desired direction. So, if I see the payload is spinning to fast the bias would provide a way for me to back off the controls some and let the rotational inertia that has built up move me to the correct location. The only issue would then be stopping it.

I guess another way of looking at the problem is that my main PID input is the offset from the desired direction. However, I really need two inputs. The offset and the rotational speed which needs to be controlled as well. To rotational speed will most likely have a maximum value at which point I may need to brake and slow the rotational speed reguardless of the my current direction.

I have tried doing this by just looking at my rotational speed, and if it ever went above X deg/sec, just turn the fins in the oppisite direction and slow the spin down. But this just doesn't seem very elegant.

Any suggestions on a possible solution or controller design?

Ken

Can someone please explain what the heck the UNITS are on the PID parameters?

For example, the post above mentions the P parameter being set to "3". Well, 3 what? 3%? 3 Seconds? 3 %/second?

I think if I knew what the numbers meant, it would be a lot easier to tune, because right now, there's no way I can get even the most basic estimation of what magnitude could be appropriate for the system in question.

Is this something I can use the bias for?

I don't think you'd get good results with the FFBias. that's designed for situations where you have a repeatable disturbance that you can measure in advance. what I'd recommend trying is using the SetTunings(...) function to use more conservative tunings (smaller P_Param) at higher altitudes, or when you see the controller begin to act too aggressively. that being said, I have no experience with high altitude aerodynamics, so I may not be understanding the dynamics involved

Can someone please explain what the heck the UNITS are on the PID parameters?

pfft. just keep adjusting the numbers until something works. who cares about units?! ...just kidding. P_Param is %OutputSpan/%InputSpan (where % is calculated using the Input and Output Limits) I_Param and D_Param are both seconds

I have tried doing this by just looking at my rotational speed, and if it ever went above X deg/sec, just turn the fins in the oppisite direction and slow the spin down. But this just doesn't seem very elegant.

The limitation with PID is that it models first-order systems. Some systems (most?) just aren't first-order. Or are first-order until there is an outside disturbance (like a gust of wind).

In an ideal world, it would be simple and cheap to create an accurate mathematical model and then design a control strategy around that model. Until we get to an ideal world, it is sometimes necessary to get the gut involved. I have an example that I think is apt...

I worked on a test room for an air conditioning company. The goal was simple: maintain the temperture in the test room within 1 degree Fahrenheit; at ALL times. Under steady-state conditions, a well tuned PID loop did an excellent job. We could keep the temperature within 0.1 degrees! The problem came when the unit under test turned on. For small units, the temperature would rise quickly but stayed within 1 degree. For large units, the temperature would rise by several degrees and cause oscillations. We fiddled and tweaked the parameters to no avail. We even tried using a different set of parameters when the unit was running.

In a moment of desperation, I suggested we bump the output to compensate for the sudden in-rush of heat. I called it "spiking the output". It seemed like a ridiculous idea but we didn't have anything else to try. The idea is simple: turn off the PID loop, adjust the output by some amount, turn on the PID loop. Not only did it work, it work extremely well! For even the largest units, we could maintain 0.1 degree control.

The point is, sometimes you just have to go with what works. ;)

The point is, sometimes you just have to go with what works. ;)

Absolutely, the trick is knowing when to throw in the towel on a pid-only solution. It sounds like that's exactly what you did Coding Badly.

On several occasions I have gone to a customer site to fix a poorly performing PID loop and found a long set of pid overrides (Do this on startup BUT not if this, and also THIS, etc.) On most of those I was able to replace the entire thing with a more simple strategy as I suggested above.

But yeah, ultimately the goal is to make it work. Since generally the hobbyist is the only one who needs to really understand what's going on in the code, a little extra complexity is fine. If you're going to share your code it might take a while to explain all the conditionals and why you chose the values that you did.

In general I try to keep things as elegant and simple as possible, as I've learned that minimizes future "why the heck is it doing THAT?!" moments.

Thanks CodingBadly, So I guess one way I could do this is the following.

1) For normal operation, use the standard PID controller to control my direction of aim and just adjust the parameters based on elevation (every 10K ft or so) 2) As i monitor my spin rate, if I ever detect that my spin rate is greater than "X", then put controller in manual mode, take over control of the fins and brake the spin until its less than X. Then re-enable the PID controller.

I was hoping to "mix" the speed and direction into a single equation to give a magical answer, but as was pointed out, a PID controller of this type is first order control only. My controls theory classes were long ago and my differential equations classes are a distant memory. Plus the 80 hour debug weeks are leaving my desire to debug even more stuff at home less interesting :)

Ken

Thanks CodingBadly,

You are welcome! And a BIG thank you to br3ttb!

1) For normal operation, use the standard PID controller to control my direction of aim and just adjust the parameters based on elevation (every 10K ft or so)

That certainly seems reasonable.

By modeling the behaviour at different elevations (air at different pressures flowing over a fin is a fairly well researched subject) you may be able to develop something more accurate. For example: with the lower pressure at higher altitudes it seems reasonable that the fins will have to be at steeper angles to get the same effect. You may be able to simply multiple the PID output by an amount based on elevation.

2) As i monitor my spin rate, if I ever detect that my spin rate is greater than "X", then put controller in manual mode, take over control of the fins and brake the spin until its less than X. Then re-enable the PID controller.

You will very likely want to ensure the transition from manual to auto is "bumpless". br3ttb will have to advise you on how to do that.

I was hoping to "mix" the speed and direction into a single equation to give a magical answer, but as was pointed out, a PID controller of this type is first order control only.

How quickly can the fins respond to a command?

Can the fins be individually controlled?

How accurate is "am I spinning" system?

Do you mind providing pictures of the system?

my differential equations classes are a distant memory

Dittio.

My controls theory classes were long ago

If I had known my career path I would have added two classes to my curriculum: Controls Theory and Mind Reading. ;D

Plus the 80 hour debug weeks

Yikes!

I have 4 identical fins that I can control independantly They are connected directly to 4 servos so I can control them "instantly" They are conected to 4 sides of a 10" octagon tube. As the ballon raises at 1Kft/min I am getting enough airflow over the fins to control it pretty good. My data above 30K ft is not so good because of "other" system issues. This will be fixed on the next launch. http://www.youtube.com/watch?v=S3PTGpTgVww

The "am I spinning" comes from either a gyro which seems to sensitive(I need to filter this better, make a quick iir filter with 5-10 taps). I am also looking at the last 5-10 compass readings, doing a liniear curve fit and finding the slope of the line (finding the derivative of the readings). Since I am reading the compass 5-10 times a second, the delay isn't to bad.

Hope this helps. I just need to try all of these new updates and then see what I need to do next.

Ken

Hi PID tuners,

This seemed like appropriate place to get some input on a self-tuning control library for Arduino. I've been thrilled with what I've been able to do with Brett's PID library, and I recently took an adaptive control course, so time to share.

What my proposed library might do: -Perform a recursive least-squares fit of input/output data to a very simple moving-average (linear) model -Calculate state feedback gains for a deadbeat controller. If you're not familiar with a deadbeat controller, wikipedia has a synopsis. One particular benefit is you get zero steady-state error without having to use an integrator -Execute the deadbeat control

Here's the input I'd like on implementation details: -Would people want the system identification & feedback gain calculation separated from generating the control signal? -What sort of sampling rates are people using with Brett's PID controller? -Is anyone using control signals that are actually continuous and not on/off? My library will need to keep track of the control actually applied as best as possible, so my first idea is a function you'd call that says "I just turned the control signal to value X". I think I'd want actual on/off info if you're using PWM unless your PWM frequency is much faster than the base sampling frequency. -Would anyone have a problem reporting system output sampled in tight synchronization with system input? -In order to initially identify the system, the controller will send a step input to the system until it sees improvement in the parameter estimates. This would be an adjustable percentage of full actuation. Does anyone have strange constraints where this type of input would break things? -Does anyone have systems they know will never change, and would want to be able to save & recall the model parameters once they're identified (to avoid the above step stimulus every time)?

To get my RLS system ID algorithm to work with temperature control, I find that I need to average a bunch of samples, i.e. maybe 30sec of samples @ 2Hz become one sample point to the RLS algorithm. This is my rice cooker as the test system, and a 3-parameter model works fine.

I'd like to implement the control at a faster sampling rate, so my initial idea is to use a sliding-window average to calculate the control signal after every sample, but only update the model & gains once per bin.

I understand that it's fairly common for the RLS algorithm to run at a much slower rate than the control, but I want to give people flexibility on this. My intuition is that the library might be easiest to use if all these things are handled internally, but the parameters can be set externally. So in the end, you'd simply call one function to ask the library what your next control output should be, and another to tell it what the actual system input/output are.

And finally, current status: My RLS algorithm works with experimental data, and I've run a simulation of a 3-parameter model & deadbeat controller at the reduced sampling rate that works quite well with around 5% noise injected on the input. This is all in Matlab =)

eecharlie, an autotuner would be a huge benefit to users of the library.

if you publish it and it works (somewhat well) at the very least I'll include it in the PID front-end.

Brett

Good to hear. If you're volunteering PID frontend requests, I have a feature request: can you make it autorange the input & output? And, maybe, superimpose everything on the same graph with two y-axis scales?

If I get the self-tuner working, there will be some additional stuff worth plotting on separate graphs: parameter estimates, parameter estimate uncertainties, and the model-predicted output (or alternatively prediction error)

-Charlie

Charlie,

are you sure you didn't instruct the course?.

Do you know of a Control Theory for dummies text that you can point us to?.

With a Deadbeat Controller, can you avoid overshoot?. (eg. an incubators, where overshoot cannot be tolerated.)

Do you know of a Control Theory for dummies text that you can point us to?.

Control Systems Engineering by Norman S. Nise is a good undergraduate textbook. I don't remember how much Fourier Transform stuff it expects you to already know, but I think not much if any. It most likely does touch on deadbeat control and digital control systems in general.

With a Deadbeat Controller, can you avoid overshoot?.

Almost. Directly from Wikipedia: The deadbeat response has the following characteristics:

  1. Zero steady-state error.
  2. Minimum rise time.
  3. Minimum settling time.
  4. Less than 2% overshoot/undershoot.

The way I will write the code, it will be possible for you to design your own controller and edit the code so it replaces the gains that comprise the deadbeat controller. The textbook above will cover a few controller designs that can achieve no overshoot.