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
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
On 23-Sep-14 10:23 AM, RogerN wrote:

You need to ping Tim Wescott who sometimes posts here - he's the guru.
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload

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
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
On Tue, 23 Sep 2014 13:41:18 +0800, Stoob wrote:

What? Who? Huh?
--

Tim Wescott
Wescott Design Services
  Click to see the full signature.
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload

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
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
On Tue, 23 Sep 2014 19:20:17 -0500, Karl Townsend wrote:

<< user's manual excerpt snipped >>
The low-pass filter and reduced gains sound an awful lot like a bandaid, not a solution.
If it worked for years and now it doesn't, then something has worn or broken, or something got "upgraded", or it's been doing it all along and you only just now noticed. Control systems only work as well as the plants that they're driving -- they can't do magic if something is worn or broken.
What's attached to the servo motors? If it's a ballscrew or some bolted- up assembly, my first guess would be that over time slop has developed in the system that allows the motor to wiggle a bit before it comes on to the load. I base this both on the fact that it used to work and doesn't now, and the fact that backlash and slop can be a position-dependent thing.
It could also be something electrical -- a broken ground connection between the Galil board and a motor, or a power supply whose capacitors have dried out and allow motor current to couple in to the supply voltage, or worn-out brushes on a motor.
Either that or you've added something with a bit of spring, or you've taken off some bracing that lets the motors or their loads "twang" a bit. Resonances like that can be death to a stable control system.
So as tedious and pointless as it sounds, you may want to go over whatever backlash adjustment you have, loosen and re-tighten all mounting bolts, check for loose bearings, reverse any "improvements" you made about the time the singing started, check operation with a different power supply (or hang an oscilloscope off the power supply and see what happens to the power rail when it's "singing"), and all that due diligence stuff.
For a while I was viewed as a sorcerer by the FLIR Systems service department, because nine times out of ten I could fix a control system problem just by having them replace one magic bearing. Then I confessed that you had to disassemble most of the bolted joints in the assembly to get to the bearing, and in the process of reassembly you tightened them all to spec, with Loctite. After that I got summoned to service a lot less often, but the problems they presented me with were a lot more challenging.
(You couldn't just say "tighten all the bolts", because that made no sense to them. So they'd tighten what they could reach and claim to have done them all. But replacing a bearing -- that's real.)
(Soon after, the jerks upstairs decided that engineers shouldn't be allowed to talk to service, and visa-versa. I hate big companies.)
Keep in mind that I'm shooting in the dark here, because I know almost nothing about your setup. But you know that something has changed; now you just need to figure out what it is, and change it back.
--
www.wescottdesign.com

Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload

BINGO!
I'M SURE THIS IS IT. Only ran this machine ten years now with this problem. Never adjusted this pot.
Karl
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
On 9/22/2014 9:23 PM, RogerN wrote:

Three is an excellent Wiki page on the subject.
http://en.wikipedia.org/wiki/PID_controller
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
On Tue, 23 Sep 2014 07:37:36 -0500, Richard wrote:

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.
--

Tim Wescott
Wescott Design Services
  Click to see the full signature.
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
On 9/23/2014 6:51 PM, Tim Wescott wrote:

I thought it was very helpful. At least I learnt what PID was for. :)
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
On Tue, 23 Sep 2014 22:43:50 -0500, Richard wrote:

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.
--

Tim Wescott
Wescott Design Services
  Click to see the full signature.
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
On Mon, 22 Sep 2014 21:23:51 -0500, RogerN wrote:

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.
--

Tim Wescott
Wescott Design Services
  Click to see the full signature.
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
On Tue, 23 Sep 2014 14:45:33 -0500, Tim Wescott wrote:

Or, try this: http://igor.chudov.com/manuals/Servo-Tuning/PID-without-a- PhD.pdf
--

Tim Wescott
Wescott Design Services
  Click to see the full signature.
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
"Tim Wescott" wrote in message

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
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
On Tue, 23 Sep 2014 20:22:38 -0500, RogerN wrote:

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.

<< snip >>

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.
--

Tim Wescott
Wescott Design Services
  Click to see the full signature.
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
"Tim Wescott" wrote in message <snip>

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.
<< snip >>

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
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
On Thu, 25 Sep 2014 18:08:34 -0500, RogerN wrote:

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:
<https://drive.google.com/file/d/0B5lSHlBBxGvjNExnWm5ZYXZwN0E/edit? usp=sharing>
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:
http://wescottdesign.com/articles/zTransform/z-transforms.html

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.

<< snip >>

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.
--
www.wescottdesign.com

Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload

Polytechforum.com is a website by engineers for engineers. It is not affiliated with any of manufacturers or vendors discussed here. All logos and trade names are the property of their respective owners.