PID calculations

I've seen calculations for PID in a microcontroller but I'm thinking something is missing.. or perhaps I'm misunderstanding something.

So if Derivative = current_error - previous_error then it's just effective for one cycle. It seems like it should be the change over a period of time, not necessarily one pass through the loop.

One way would be to have an array of error[xx] and take the difference in change over a period of time involving several of times through the loop.

Also, I've seen some PID that the I adjustment is in units of time.

This might not be a big deal if there is a real high resolution, but if you have a temperature control that is heating for a 5 degree error, chances are the derivative term isn't going to have much effect if it's calculated every millisecond. If it's calculated over a longer period, for example how much change in the last 10 minutes, it would be more meaningful.

I know a way to do this but I'm just looking for better ideas, perhaps more efficient memory usage.

RogerN

Reply to
RogerN
Loading thread data ...

You need to ping Tim Wescott who sometimes posts here - he's the guru.

Reply to
Stoob

Derivative is concerned with the error's rate of change, which given a time base your calculation does. Its primary use is to reduce overshoot in systems with a lot of lag, like an oven temperature control.

It's also the last thing to fool with if you're tuning the controller. For any fast acting loop, like flow or mass control, turn that damned derivative off. And if you see an oven approach setpoint then dip before it gets there, then oscillate gradually toward setpoint, cut it in half.

As a matter of fact, the best thing that ever happened to me for temperature loops, extruder barrels, that kind of thing, were auto-tuning controllers. I used discreet auto-tuning controllers, either Eurotherm or Omega, for barrel zones, just sent them setpoints. Auto tuning algorithms for use in the RSLogix type control software was coming out about the time I retired, but didn't work that well yet.

Fast, low lag loops were easy to tune. A little p, lots of i, and adjust either by factor of 2. Small changes are a waste of time. When you drive it to oscillation, cut that parameter in half. Or if you really don't want to oscillate the loop (really large motors, etc.), sneak up on it a little slower.

Pete Keillor

Reply to
Pete Keillor

Three is an excellent Wiki page on the subject.

formatting link

Reply to
Richard

What? Who? Huh?

Reply to
Tim Wescott

That depends on a number of factors, including but not limited to sampling rate, the amount of noise in the system, your desired settling time, and the settling time that you can actually achieve.

That's a BAD way to do it. It's what's known in the more esoteric corners of the trade as a non-minimum phase filter, which basically means that the filter has more delay than necessary for the amount of amplitude shaping vs. frequency. Delay is a Bad Thing in a control loop, and is to be avoided.

It would be perfectly meaningful if the system noise were low enough, and if there weren't any unexpected, fast paths from heater to thermostat.

You want a band-limited derivative term. The best way to do this is pretty simple, too (calculate this as one hunk-of-code each sample time):

derivative = (current_error - average_error);

average_error = average_error + k * (current_error - average_error);

Here "derivative" is the answer you want, "average_error" is a number that you carry from sample to sample (a so-called "state", like your integrator state), and k is a gain from 0 to 1 that determines the dynamics of the differentiator. The bigger k is the faster the derivative action, so the more noise it passes through and the more it helps fast settling. The smaller k, the less noise, and the less helpful the derivative action is when you're trying for high speeds.

If you need to mess with band-limited derivative terms then you really should be doing frequency-domain design at least, but you can sometimes make things work with seat of the pants tuning. As a rule of thumb, set k to (10) * (sampling interval) / (settling time), where you know the sampling interval and, the settling time is what you're trying to achieve. If you end up computing a k greater than 1, then you need to re- think your sampling interval or your desired settling time.

The link on my website to the article you want to read is currently broken: send me an email and I'll reply with a pdf.

Reply to
Tim Wescott

Or, try this:

formatting link
PhD.pdf

Reply to
Tim Wescott

It gets a bit sketchy in parts -- entire books could be (and have been!) written about PID controllers alone. But as Wikipedia articles go, I guess it's about average.

Reply to
Tim Wescott

Maybe I've been sleeping under a rock, didn't know this.

I've been fighting a buzzing at stop in my Galilmc.com controlled AMC servo amps and DC servos. 9 out of 10 times the servo will stop smoothly, the tenth it will oscilate about 1 or 2 encoder counts so rapidly it makes a buzzing noise.

Adding the low pass filter to PID helped (see below for manual description) but i ended up reducing P,I and D by huge amounts to stop it. Now the system is sluggish. FWIW, Galil has servo tuning software to automatically tune your system. that worked for many years till this issue popped up.

Comments?

Karl

PL FUNCTION: Pole DESCRIPTION: The PL command adds a low-pass filter in series with the PID compensation. The digital transfer function of the filter is (1 - n) / (Z - n) and the equivalent continuous filter is A/(S+A) where A is the filter cutoff frequency: A=(1/T) ln (1 / n) rad/sec and T is the sample time. To convert from the desired crossover (-3 dB) frequency in Hertz to the value given to PL, use the following formula:

where: n is the argument given to PL

1,000,000) fc is the crossover frequency in Hertz

n 0 0.2 0.4 0.6 0.8 0.999

Reply to
Karl Townsend

I don't necessarily agree that it's a bad way because you can look up how much time since the last change, for example using slow 100ms loop times and a 1 degree change in temperature, at the instant of the change, rate was 1 degree per 100ms, this would trigger a strong response, next loop, one deg per 200ms, next would be 1 degree in 300ms... and so on, decaying every loop until further change. I think this would be similar to difference in average error. I like the average error calculation you showed me because it does (nearly?) the same thing without the array of previous error data.

Thanks Tim, I figured you'd have a better way of doing what I'm wanting to do. There is a huge relative speed difference in applications, for example changing a room temperature at 1 degree per minute is fast but a motor moving at 1 encoder count per minute would be very slow for a 500 line encoder. The calculations I have seen before is amount of changer per time period and what I thought would be more useful is amount of time per change, or low rates of change.

Interesting demonstration on YouTube: Raffaello D'Andrea_ The astounding athletic power of quadcopters

Thanks!

RogerN

Reply to
RogerN

Well, if what you want to do is find a fascinating array of subtle and not- so-subtle pitfalls, then by all means give it a whirl.

I forgot to mention that if you're really going to sample at 1kHz and close a loop with a settling time of a minute, then your 'k' value is going to be damned small -- like on the order of 1/6000.

This, in turn, means that you are exposed to your "average_error" term not having enough precision to keep track of changes. If your current_error is good to 12 bits, then your current_error * k must be good to 25 bits or so. That's barely within the ability of a single-precision floating point number to keep track. Even if you're only measuring temperatures with 8- bit ADCs, you're beyond the ability to keep track with 16-bit integers.

With modern processors, at a 1kHz sampling rate, you can take care of this by using double-precision floating point numbers (with something like a 53- bit mantissa). If you're using an older processor, using 32-bit numbers and playing lots of scaling games will work.

Speaking of subtle pitfalls.

Reply to
Tim Wescott

I thought it was very helpful. At least I learnt what PID was for. :)

Reply to
Richard

BINGO!

I'M SURE THIS IS IT. Only ran this machine ten years now with this problem. Never adjusted this pot.

Karl

Reply to
Karl Townsend

I get to be overly picky, because it's in my field.

I'm sure that quantum mechanics scoff at Wikipedia's quantum mechanics articles.

Reply to
Tim Wescott

I didn't like my idea because of the memory usage and processing of the array on every loop, but I don't think it would necessarily be bad due to responsiveness because you can respond strongly to the results of the last loop, I like your way with the average error much better though, less processing and less memory usage.

But here's some reasoning that I feel is valid, though it wouldn't necessarily demand a large array. Lets say the application was a room temperature control and the maximum rate of change was no more than 1 degree per minute. So if it used the change for the last minute or so, it could give the strongest response needed for the rate of change, any faster rates of change would just be from noisy readings.

Another weird thought I had was using the reading array data to calculate mean and standard deviation to have weak response to ~ +/- 3 sigma and stronger response to readings representing real change. If I used something like that in a R/C helicopter gyroscope, the noise level could also be an indication of out of balance blades, vibration levels that would be more harmful the the model and the controls. Of course not responding to noise would also reduce battery drain and wear on the servos.

What got me thinking about this was Allen Bradley's PID control, I believe the motion control cards close the loop in the card itself, but the PID in the processor uses an I time and a D time instead of Ki and Kd. On a temperature controller or other slower systems, measurements would be more like a little change over a longer period of time instead of quite a bit of change in a short period of time.

I'm hoping to use the info in some temperature control applications as well as some R/C model stabilization applications. I bought some 3 axis gyro + 3 axis accelerometer modules from HobbyPartz for a reasonable price. I had the Arduino reading the data but I haven't done anything interesting with it yet. Thought I might start out by trying to get my boe-bot to operate on 2 wheels.

Thanks,

RogerN

Reply to
RogerN

I'm going to have to slide into discussing this in the frequency domain

-- sorry about that, but I don't know a different way to express it that doesn't boil down to BS and hand-waving. The thing that you're trying to avoid here is a control loop that, when a signal starts at any one point in the loop and goes all the way around, it comes back to the same point looking the same. If that happens, then your system will oscillate.

Doing stability analysis in the frequency domain is basically an exercise in making sure that for sine-wave signals, the condition holds that when the signal goes around the loop and back to the same point, it is either phase shifted, or smaller, or under some limited circumstances (and this is hard to get intuitively, but it's true) bigger.

The basic problem you struggle with in a derivative element in a PID filter is that the positive phase shift you get from differentiation is good, but gain at high frequencies is bad. You've got the "reduce gain at high frequencies" part covered with your scheme, but you're ignoring the effects of phase shift.

See here:

This is a type of plot called a Bode plot. It shows the gain and phase shift of two different differentiators as a function of frequency. Your proposed differentiator is in black, mine is in blue. To keep the math from getting awkward, I chose to average over one second at a sampling rate of 1kHz, rather than one minute -- this doesn't change the basic results, it just makes the plot easier to look at.

As a rule of thumb, figure that the differentiator is doing good as long as its phase is above +45 degrees. This is hard to pin down (it depends on what you're trying to control), but it'll serve to illustrate what I'm talking about. I jiggered the numbers on my differentiator so that it has the same gain and +45 degree crossing point as yours.

Now notice two differences between these differentiators: phase shift and maximum gain.

My differentiator never has a phase shift less than 0 degrees. This means in the worst case, at high frequencies my differentiator acts like a pure gain, nothing more. Your differentiator, on the other hand, has phase shift going all the way to -180 degrees. If your plant has enough gain at a frequency where your phase shift is high, your system will oscillate.

Your differentiator has about the same high frequency gain as mine on average, but it has about twice as much gain in the peaks. This extra gain, even in the absence of the excessive phase shift, could cause oscillation in certain cases. Add in the excess phase shift, and the potential for oscillation just gets worse.

The sum total of these two differences is that you just can't crank your differentiator up to the same gain that I can crank up mine, and maintain robust system stability. The fact that my differentiator is simpler to implement is just a bonus.

Here's an old and somewhat terse paper on using the frequency domain in control systems design, written with a software guy in mind:

formatting link

You're describing a nonlinear controller. It turns out that doing this sort of thing makes formal design and performance analysis much more difficult.

And, if your performance criterion is to reduce the root-mean-squared response to noise, it's not the best approach. Given a heavy-duty enough math background, you can prove that for a linear plant and Gaussian noise, that the best controller to achieve minimum RMS noise response is linear.

Your scheme will reduce the response to _sensor_ noise, but it'll make the craft less responsive to small wind gusts and other environmental upsets.

If your plant isn't very linear (no real-world plants are wholly linear), or if your performance criteria aren't to minimize RMS error, then the "best control is linear" proof is so many horse turds -- but the system will still be a pain to design for and analyze with the nonlinearities.

A lot of industrial control applications like to describe the PID controller in terms of the time constants of the PD and the PI portions of the controller. This isn't an inherently bad way to do it, but it's different from how I usually approach things.

The RC model stabilization stuff should be fun. If you start with quad copters, you can tether them to minimize crash damage while you're tuning.

Reply to
tim

PolyTech Forum website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.