# Iterative Technique for PID Controller Tuning

wrote:

You have got to be kidding. Actually you must be using guessing or using trial and error.

If I were to tune the system without an integrator the gains would be something like:
Kp .943951 Kd=0.66 Kdd=0.014854
This puts the response at 3 real poles at -2*PI*10. However, I can change where the poles are to match the desired response. The problem with 3 real poles at -2*PI*10 is that the output goes into saturation. I can change the response to what ever I want. When the output goes into saturation the second order response shows through.
I told you that this problem is rigged. First you must realize you need the second derivative. Second, the control output will go into saturation at +10 and -10 volts.
All of you that use trail and error would probably never consider a second derivative. Tim, it is time to respond or I will think there is no intelligent life here. The first question should be how do you use a second derivative gain when it is difficult enough to use a first derivative gain?
Peter Nachtwey
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Peter Nachtwey wrote:

I've been sick.
This is a good example of where you want to start your design exercise with a root locus plot. That'll tell you right off where those underdamped poles go with simple proportional gain, and why it is that you need not one, but two differentiators before you can even think about getting a significant speed increase out of the thing.
--

Tim Wescott
Wescott Design Services
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Peter Nachtwey wrote:

I'm not sure if you're drawing a distinction between the control guy and the system designer -- I was equating the two. You are correct, that to make the decision one must understand the plant fairly well.

I pour the source data for the plant Bode plot into a MathCad spread sheet or a SciLab script, and I tune the controller using a Nyquist plot to show total stability and a Bode plot to show the frequency domain behavior.

Certainly if you're going to have to shake the place apart to get meaningful data you aren't using the right technique, and ditto if you're trying to measure a closely coupled MIMO system. You can control the former with swept-sine methods by reducing your magnitudes and averaging longer for noise, but there are practical limits -- if you're doing damage and not getting good data, then you've obviously hit just such a limit. Obviously, you can't do much with the MIMO system -- in that case you need to use other methods of system identification.
The swept-sine method will more or less automatically compensate for such things as your different gains in different directions, by the way. If you look up "describing function analysis" of nonlinear systems you'll find that the swept-sine method is a direct measurement of the system describing function.
But I'm going to be the last guy to say that the swept sine method is _always_ the one to use -- I've just had very good success with it over the years, so it's the tool that's at the top of the box for me.

Not usually. Usually I try to get some sort of loop closure in place, however lame it may be, before I take measurements.
--

Tim Wescott
Wescott Design Services
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Peter Nachtwey wrote: -- snip a bunch --

I suspect the answer is that if you have a rough starting model you can use the gradient from that; while you'll miss your target gains every step of the way you only need a set of gradients that ends up with a process that converges quickly, not one that gets you there in one step. If you're really clever, you can probably use your updated data to refine the model at each step as well, to get better gradients.
--

Tim Wescott
Wescott Design Services
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
[...]

I tried this with canonical structure control:
F(s) = 1 / (0.0000844*s^3 + 0.0053*s^2 + 0.333*s)
Test carried out using PD^3 controller: http://home.arcor.de/janch/janch/_news/20070407-nachtwey / It only works if F(s) is identical with the real process.
See Page 2 (Seite 2) for definitions: http://home.arcor.de/janch/janch/_control/20070407-control-e /
--
eMail aktuell: snipped-for-privacy@nospam.arcornews.de
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
JCH wrote:

Why the third derivative? I tuned this using Bode plot techniques and came up with a second-derivative controller:
H_c = (3 + 3*s/(0.0005*s + 1) + 0.03*s^2/(0.0005*s + 1)^2)
This closes the loop nicely at 60Hz, with a 20dB gain margin and a 65 degree phase margin.
But it also makes my point about using idealized models: there is absolutely nothing in Peter's model to say that I can't close the loop so very high above the first resonant frequency, or for that matter why I can't close it at 10kHz. You almost have to throw away this information when you extract a system model, yet with measured frequency response data this would be immediately apparent.
I assume that if I tried this in real life I'd find either another resonance or a 1st-order low pass that would mess things up, and I'd have to back the tuning off to something like
H_c = (30 + 0.2*s/(0.0005*s + 1) + 0.01*s^2/(0.0005*s + 1)^2)
This puts the loop closure right about at the first resonance, which is only safe if you can really trust the resonance not to crawl around as the system ages or the operating point changes. The system also has a little hitch in it's get-along right around 8Hz or so, but that's to be expected.
--

Tim Wescott
Wescott Design Services
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>

You are right. A sharp look could have told me that the tird derivative isn't necessary: F(s) = 1 / (0.0000844*s^3 + 0.0053*s^2 + 0.333*s) ^^^^^^^^^
I also looked again at the output using the second derivative. There is no difference.
What about the example in http://home.arcor.de/janch/janch/_control/20070407-control-e /
--
eMail aktuell: snipped-for-privacy@nospam.arcornews.de
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
JCH wrote:

???. How can we tell?

This link doesn't show a step from 0 to 1. I see a sine wave.

I don't see the examples. In fact it isn't clear what you are doing. It looks like you are just inverting system constants and calling that a controller. What is F(s)?
Meanwhile I do understand what Pieter and Tim are doing. Here are some comparisons. ftp://ftp.deltacompsys.com/public/PDF/Mathcad%20-%20T1C1%20PD2D.pdf Pages 3-4 just show how I did the simulation. Students might like this. Page 5 The point to point response for my 3 poles at -2*PI*10 is plotted. The response is a critically damped response except for when the output is saturate. Then the under damped system shows its true self. Actually, if I were tuning this I would use an integrator too. Page 6 Open loop bode plot. I don't usually find these that interesting. Page 7 Zeros and Poles. Notice that poles are were I put them but as I said before, the zeros can go anywhere. In this case they cause the bobble. In the otherwise smooth response. One can use different gains in the forward path than the feed back path to smooth the response out. Page 8 The closed loop Bode plot. Pretty mellow compared to what is to come. Page 9 Pieter's tuning with the Kp at 2.8 and a low pass filter added. Actually it works well for only using the proportional gain but my customers wouldn't like it. Page 10 A closed loop Bode plot. It looks OK. A least it is safe you can see the resonance peak though. Page 11 Tim's open loop Bode plot. Weird looking but it works. Page 12 Tim closed loop Bode plot. Wow! That response is flat but as Tim hinted at above we can make the response as flat as we want on paper. Tim's response is not very realistic UNLESS one uses a Kalman filter or observer to provide smooth acceleration data. but since Tim does custom systems he can do that.
Over the years I have noticed that Tim must start with the zeros. His zeros are always real. The poles seem to be added to filter out the zeros. PID controllers always have two zeros and they are often not real. Page 14. The closed loop zero and pole locations. Tim, did you intend the zero and pole at about -1 to be there?
Let me know about any errors in the .pdf.
Peter Nachtwey
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Peter Nachtwey wrote:

In as much as I can tell by a quick read, the pdf looks correct.
I think my zeros are always real because when they aren't they stick out like a sore thumb in a Bode plot -- when I see the dip in a complex pair, I say "oops" and adjust things, unless I'm intentionally notching out a resonance such as I did in my second example controller.
And no, I didn't _intend_ for the zero and pole at about -1, but I did notice the dip in the Bode plot, which implies their existence.
--
Tim Wescott
Wescott Design Services
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Tim Wescott wrote:

Good, but you should check again. I tried to simulate the point to point response using your gains and it appears that to get the flat response that the output swings wildly. One can see that I had to reduced the sampling period from 0.001 seconds to 0.0001 to model the two poles. The first hint of trouble is that the coefficients in the numerator are very high. I now that in any practical system the change of only one count in the feedback would cause the output to saturate. As I said a couple times before. This problem is rigged but is actually close to what I work with. Moving a hydraulic actuator 1 inch in .1 seconds is very realistic. I am usually happy if the closed loop bandwidth of 3 to 5 Hz. There are few hydraulic systems have closed loop bandwidths of 10Hz.
I think the point here is that Bode plots provide clues as to how the system will work if it is an analog system. Digital systems tend to fall apart. Now I think about it I think I should have added an exp(-s*T) to simulate the ZOH to see how it ruins your flat response.
Tell us if you find any errors.
Peter Nachtwey
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Peter Nachtwey wrote:

Well, you're certainly pulling me away from my family this Easter!
Obviously, I was just playing Bode plot games in mathemagic land, without much consideration for the real world. It's comforting to know that you are closing the loop that far below the mechanical resonance.
If I can get time away from paying work I'm going to do the exercise in the same domain as I would were I doing this 'for real' -- I'm translating the continuous-time model to the z domain assuming a simple ZOH for the DAC, and I'll do my simulations with a limiter. What would your system limit the output to? +/- 1?
I think I'll try two things: one is the approach that I've been taking, of a P - double D, with the gains arranged to put a notch at 10Hz. The other thing I'm going to do, since I can close the loop below the resonance, is to put a regular notch right at 10Hz and see how high I can get the bandwidth with a following PD controller. There's another trick I've seen used on active controllers for gyros that intentionally puts a low-pass filter before the resonance; this modifies the phase shift enough to keep everything stable, while still giving snappy response. It looked Really Weird when I tried it, but it was the recommendation from the gyro company and it's worked like gangbusters for years.
--

Tim Wescott
Wescott Design Services
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Tim Wescott wrote:

Don't let me do that. The newsgroup will still be here tomorrow.

I am just trying to keep people 'honest' for a while.

When you are moving tons you must be safe. The three poles at -2*PI*10 result in a bandwidth of about 51% of 10Hz or about 5Hz if the zeros are ignored. Even this is aggressive for many of the system I get involved with. Also, in reality I don't do step changes in the SP. I have a smooth target generator and feed forwards so the closed loop control has very little to do. This keeps the control output out of saturation too.

I usually limit my output to +/- 10 for +/- 10 volts when I am dealing with our motion controller. When working with PLC PIDs I work with %CO like in the tank level thread.

It will be interesting to see what you come up with. I would look at making use of what you already have. You already have the zeros. Complex zeros can cancel the complex poles. The trouble is that the gains in the forward path are different than in the feedback path. This is not possible with most PLC PIDs. If is also beyond the capabilities of most people. Good motion controllers can do this though:)
Try this, change the closed loop transfer function in my example so the forward path Kd is multiplied by .6 and Kdd by .22. Note that my closed closed loop bode plot magnitude has no sign of the complex poles anymore. No notch filter required! Simple. ftp://ftp.deltacompsys.com/public/PDF/Mathcad%20-%20NoNotchRequired.pdf I admit I twiddled the fudge (.6 and .22 ) factors very quickly manually. One can calculate these coefficients exactly.
Peter Nachtwey
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
[...]

Canonical Structure Control (Regelungsnormalform)
1. PD^2 controller (B3=0)
A1 = 0.333 A2 = 0.0053 A3 = 0.0000844 B1 = 0.333 B2 = 0.0053 B3 = 0
Solution: Fig. 1
2. PD^3 controller (B3=0.0000844)
A1 = 0.333 A2 = 0.0053 A3 = 0.0000844 B1 = 0.333 B2 = 0.0053 B3 = 0.0000844
Solution: Fig. 2
See page 1 http://home.arcor.de/janch/janch/_news/20070408-nachtwey / and some mathematics in Page 2
Note to Tim: PD^2 (Fig. 1) works, but PD^3 (Fig. 3) is better.
--
eMail aktuell: snipped-for-privacy@nospam.arcornews.de
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
JCH wrote:

This still isn't clear. The coefficients in the numerator and the denominator are the same except in the PD^2 case you made B3 0. Also, these coefficients seem to be very simplistic.
A1 = 1/Gain A2 = Zeta/(Gain*Omega) why not 2*zeta/(Gain*Omega)? A3 = 1/(Gain*Omega^2) The same goes for the B coefficients.

The document explains how to implement a filter, but I don't see where it is closed loop. I don't see where the plant or actuator is represented in the document. In case I don't think you have made it as clear as I have in my .pdf exactly what you are doing.
I added my calculations for the PID gains using Ackermann's equations. Note that by changing the desired pole locations, all the gains are updated at once. ftp://ftp.deltacompsys.com/public/PDF/Mathcad%20-%20T1C1%20PD2D.pdf It is too bad it takes too much effort to write a program were the desired closed loop pole can be changed using a slider bar so that the result gains can be viewed..
I have to learn how to make a slider bar in Scilab.
Peter Nachtwey
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>

I used the transfer function coefficients: Process F1(s) = 1 / (0.0000844*s^3 + 0.0053*s^2 + 0.333*s)
and compensated with Controller F2(s) = 0.0000844*s^3 + 0.0053*s^2 + 0.333*s
That is 100% 'time-compensated'.
Some detail:
Open loop: F(s) = F1(s)*F2(s) = 1
Regarding K1 and K2 factors different from 1 F(s) = K1*F1(s)*K2*F2(s)
Closed loop: F_closed(s) = 1 / (1 + 1/F(s)) = 1 / (1 + 1/(K1*K2))
Example K1 = 1 K2 = 1000
F_closed(s) = 1 / (1 + 1/1000) = 0.999
See details: http://home.arcor.de/janch/janch/_news/20070409-nachtwey /
Conclusion: Use a PD^3 instead of PID controller in your simulation program. For implementing in real life I suggest a PID^3 controller though I think the integral part is not necessary.
Note With the canonical structure control I just tested PD^2/PD^3 controller.
--
eMail aktuell: snipped-for-privacy@nospam.arcornews.de
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>

CORRECTION A2 = B2 = 0.0106

Process F1(s) = 1 / (0.0000844*s^3 + 0.0106*s^2 + 0.333*s) ^^^^^^

Controller F2(s) = 0.0000844*s^3 + 0.0106*s^2 + 0.333*s ^^^^^^

--
eMail aktuell: snipped-for-privacy@nospam.arcornews.de
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Newsbeitrag

I see what you are doing now. Wow, that is different. Simple.

I agree that the PID controller is not up to the task. I don't think a third derivative is needed. That would give you more gains than poles. The controller you call F2(s) isa a derivative, second derivative and third derivative controller. It would required a 3rd derivative state that the second order model doesn't have. Also, I don't see the proportional term. I don't see how this 3rd derivative can be practically implemented as a digital controller. Perhaps if we add an accelerometer and take the derivative of that to get the feedback values. Most people have a hard enough time calculating the first derivative. The third derivative will be very quantized and noisy.
I prefer to remove a power of s so the controller is a PD2D controller again. I would also modify the 0.01061 back to 0.001061 Controller F2(s) = K*(0.0000844*s^2 + 0.00106*s + 0.333) or F2(s)=(K/Gain)*(s^2/Omega^2+2*Zeta*s/Omega+1)
then the closed loop transfer function simplifies to T(s)=K/(s+K) and one can increase K to get the desired response. It is very safe given the model is correct.

You are right. In theory the integrator isn't necessary. Unfortunately in real life the actuator rarely gets to the set point unless the controller has a an integrator. I would actually use a PID2D controller. As pointed out earlier, two derivative gains are required and the integrator is necessary to get to set point. It is difficult enough to calculate a meaningful second derivative. Some advanced techniques are required for that. I will show your method with my modifications in an update of the .pdf later. I think the results will be good.
Peter Nachtwey
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>

Your statements are ok. The Problem is that we have a very nasty process transfer function.
It looks like http://home.arcor.de/janch/janch/_news/20070410-nachtway / Page 1
Having in mind the test target scheme I think it is difficult handling this task. I wouldn't use the normal feedback control.
I would prefer open loop F1(s)*F2(s) = 1 and correcting PV by an integrator: http://home.arcor.de/janch/janch/_news/20070410-nachtway / Page 2
Note A differential equation F2(s) of order 3 can be approximated into order 2 by using programs.
--
eMail aktuell: snipped-for-privacy@nospam.arcornews.de
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
JCH wrote:

I know the process is very nasty. I picked it because I wanted to make a point.
I tried my suggested improvement to your method. The closed loop Bode plot looks good but the digital simulation does not. See pages 19 to the end for my mods to your method. ftp://ftp.deltacompsys.com/public/NG/Mathcad%20-%20T1C1%20PD2D.pdf

If you look at the .PDF you can see that I can control this system easily. I must control these types of system every day.
Peter Nachtwey
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>

T(s) in your page 19 is classical 'feedback' control:
Your model T(s) = Kc / (s + Kc) = 1 / (s/Kc + 1) .... 
My model in feedback control would be T(s) = Kc / (1 + Kc) = 1 / (1/Kc + 1)
My suggestion: Classical 'feedforward' control with T(s) = 1 and I- or perhaps PI-feedback (let's say correction). (P)I-correction adjusts the system. 'Feedforward' control is regarded as stable (no feedback no oscillation).
Slight improvement by changing adder to multiplier: http://home.arcor.de/janch/janch/_news/20070411-nachtway / x3 will mainly be constant, hardly change.
Question:  What will happen if you use 1 in T(s) instead of s in your model?
--