How does the incremental form of the PID controller work?

Steven01

Member
Join Date
Oct 2015
Location
Prague
Posts
25
I have a question regarding the features of the so called incremental (velocity) form of the PID controller. As far as I understand this form in correct manner it can be described via this pseudocode


Code:
// increment of the action as a sum of the increment of the 
// P term with setpoint weighting:                                        dup = Kp * b * (r - r1) - Kp * (y - y1)), 
// I term with trapezoidal integration rule:                              dui = (Kp*T)/(2.0*Ti) * (e + e1),
// D term with filtering pole and protection against the derivative kick: dud = Td/(Nd*T + Td) * (ud1 - ud2) - (Kp*Td*Nd)/(Nd*T + Td)*(y - 2.0*y1 + y2)) 
// where 
// T  - execution period
// Kp - proportional gain
// b  - weighting factor (0 <= b <= 1)
// Ti - integration time constant
// Td - derivative time constant
// Nd - filtering pole position
// r  - reference value
// y  - controlled value
// e  - control error
// ud - derivative term
// 1  - value at time instant (k-1)
// 2  - value at time instant (k-2)  
du = dup + dui + dud

// current action as a sum of previous action and current increment of the action
u = u1 + du

// limitation of the action based on the actuator limits
if (u > u_max) {
    u = u_max
} else if (u < u_min) {
    u = u_min
}
// memory variables update
r1  = r
y2  = y1
y1  = y
e1  = e
u1  = u
ud2 = ud1
ud1 = ud


What I don't fully understand is behavior of this form in following scenario. Let's say I have this code in the feedback control loop and I do on-line changes of the controller parameters Kp and Ti (for the sake of simplicity suppose the D term isn't present). Now for whatever reason I set the Kp = 0.0 i.e. I effectively force the dup and the dui to be zero from that time instant. According to the above given pseudocode the action will remain at the previous value. In other
words the controller still produces some nonzero action. As far as my understanding is correct it seems to me that this behavior can be little bit misleading. Can anybody explain to me how does it work?
 
Whenever you differentiate an equation, you lose the information containing the original equation's starting position. It is why we need to add the "+c" when integrating, as we need to tell the indefinite integral where to start from (e.g. if we want to know how fast we are going after slowing down by 5kph, we need to know how fast we were going when we started).

In the case you describe, by setting the dependent form of the velocity PID Kp to 0 (it doesn't matter what you set Ti to, also Kp as a term should generally not be used in the dependent PID equation and instead should be Kc or similar, but I degress), the equation will indeed cease to provide meaningful updates. This is because the velocity form of the PID equation is derived by differentiating the standard form, and in differentiating we remove the constant, which is what the equation would have reverted to otherwise (this is the "+c" you get when you take an indefinite integral). In the the position form of the PID equation, no integrating happens so no integrating constant is defined, explicitly or implicitly, resulting in a zero output (or a defined non-zero output, if your bias is non-zero).

In essence, what you have found is a quirk of calculus. When you differentiate, you lose information. When you integrate to undo the differentiation (to get the controlled variable value from the velocity form of the PID equation), it is assumed that the output must be the previous value plus the change in output. The PID equation knows to initialize at an output of zero. Thus, when you force the change in output to never take a non-zero value, the true output will never change.

It is up to the implementation of the velocity PID equation to account for this, either by trusting the engineer to know this, by catching the potential error and setting an error flag, or by catching the error and forcing the output to zero.
 
Last edited:
In other words the controller still produces some nonzero action.
Correct.

As far as my understanding is correct it seems to me that this behavior can be little bit misleading.
How exactly?

Can anybody explain to me how does it work?
What exactly?

In order not to look unreasonably arrogant
Classic PI controller:
U_P (i):= kp (i) * Error (i)
U_I (i):= U_I (i - 1) + ki (i) * Error (i)* Δt
U_PI (i):= U_P (i) + U_I (i) = kp (i) * Error (i) + U_I (i - 1) + ki (i) * Error (i)* Δt

Once again. What exactly confuses you?

In essence, what you have found is a quirk of calculus.

What exactly did he find?
 
That's not a bug, that's a feature

1) What @JLand and @MaxK said.

2) Using a little algebra, you should be able to prove to yourself that the incremental (a.k.a. velocity) form of the PID is arithmetically identical to the absolute (a.k.a. positional) form (cf. page 2 here), with the caveat that the parameters (tuning and timing) are constant over time.

However, if the parameters do change, especially KP (or KC), then the two forms are no longer arithmetically identical, and all bets are off.

3) In this document, near the bottom of page 4, there is a section discussing Adaptive Gains that continues onto page 5.

The gist is that the incremental (velocity) form of the PID does not generate a bump in the proportional term when a discrete change is made to the KP (or KC) parameter; this is similar to the effect you are describing. If you are changing gains on the fly i.e. while the PID is in Auto mode, then this is a potential benefit to a PID implementation that uses the incremental form.

Another aspect of the incremental form is the simplicity of implementing bumpless transfer when changing the PID mode from Manual to Auto: on every loop update during which the PID is evaluated while in Manual mode, bumpless transfer is accomplished by simply copying the manually-assigned CV output value to the internal parameter CVN-1, the first term in the incremental equation, in anticipation that the PID might be in Auto mode at the next loop update (N).

Compare that to the machinations required to implement bumpless transfer in the absolute form while in Manual mode:

  • Calculate the Proportional term as if the PID were in Auto mode
    • E = PV - SP (or SP - PV)
    • Pterm = KP E
  • Subtract that Pterm from the manually assigned CV output value to get the internal integral term for bumpless transfer, in anticipation that the PID might be in Auto mode at the next loop update
    • Iterm = CV - Pterm
  • On top of that, there may be a further need to check the interaction of this bumpless transfer calculation against the CV output limits.
4) Bottom line: what you call "misleading," i.e. a bug, others may call a feature.
 
Last edited:
What exactly did he find?

I'd say stumbling across the consequence of differentiation losing information is a pretty neat find. Any real-world ramifications of calculus is fun, in my opinion. In using the velocity form of the PID equation, the output locks up when Kc is 0 instead of the output dropping to 0. It's too easy to become jaded and not see the interesting little quirks to the stuff we might see as banal because it's a daily occurrence for many of us.
 
The gist is that the incremental (velocity) form of the PID does not generate a bump in the proportional term when a discrete change is made to the KP (or KC) parameter;

I.e. if Error = 100, but constant = P-term is useless. Is it feature?
 
what does "but constant = P-term is useless." mean?

The closer the Error to its peak value, the less the ΔError. A kp changing at this moment will not lead to a change in CO. You consider this a bumpless transfer, i.e. pros. I consider this not the fulfillment the P-term main goal (error compensation here and now), i.e. cons.
Each of us is free to have our own point of view.

Steven01's question was:
Why if I set the Kp = 0.0 i.e. I effectively force the dup and the dui to be zero from that time instant controller still produces some nonzero action.
We answered the question:
Because this is normal (correct) functioning of a PI controller
 
The incremental form of PID starts with a normal integrator.
The proportional term is implemented by integrating the error in velocity.
The derivative term is implemented by integrating the error in acceleration.

A simple incremental PID is implement like this:
Code:
e(n-2) = e(n-1)
e(n-1) = e(n)
e(n) = r(n) - x(n)    # r is the SP and x is the PV
u(n) = u(n-1) + K0*e(n)+K1*e(n-1)+K2*e(n-2)
This is very efficient since it can be implemented with multiply and adds.
I used Tustin's approximation to convert the PID in the s domain to difference equation.
This is how a DSP or any CPU with a multiply and add instruction would execute the PID.
So what are K0, K1 and K2?
Code:
K0 = (1/4)*Ki*Δt+(1/2)*Kp+(1/Δt)*Kd
K1 = (1/2)*Ki*Δt-(2/Δt)*Kd
K2 = (1/4)*Ki*Δt-(1/2)*Kp+(1/Δt)*Kd
This code only needs to be executed once unless Ki, Kp or Kd change as drbitboy suggests could happen
This code also include a low pass filter to attempt to mitigate some sampling "noise"
I use min and max functions to limit the control output to +/-100%
u(n) = max(min(u(n-1) + K0*e(n)+K1*e(n-1)+K2*e(n-2),100)-100)
Simple and very efficient!
 
It's all about the bias

The closer the Error to its peak value, the less the ΔError. A kp changing at this moment will not lead to a change in CO.
I don't think so.

With the incremental (velocity) form of the PID equation, as long as KP is non-zero*, any non-zero ΔE (ΔError) between loop updates will lead to a change in CO**.

This is true even if KP was changed since the last loop update.

Of course, if KP is changed to 0, then yes, CO will be static, i.e. the PID instruction will assing CVN-1 to CVN for as long as that condition holds. In effect, CVN-1 becomes the "+c" of @Jland's excellent integration analogy; that could also be called the functional bias for the incremental form.

The behavior will be different with the absolute form of the PID equation: the starting point for the P-term KP E will be the sum of the PID bias parameter*** and the then-current integral accumulation term Σ(KP Δt E / TI), which sum is the functional bias for the absolute form; if KP is changed to 0 from a positive value, then

  • any non-zero P-term from the previous loop update will be lost (zeroed out),
  • the CV output will be assigned the value of that functional bias,
    • which value will be different than that of the previous loop update's CV output, assuming the P-term was non-zero,
  • and the functional bias will not change,
for all loop updates going forward until KP is no longer 0.

In summary, the primary difference between the absolute and increment forms of the PID equation is what constitutes the functional bias, or starting point value at each update, for the form:

  • <bias parameter> + Σ(KP Δt E / TI), for the absolute form
  • CVN-1, for the incremental form
and that difference is what determines the difference in behavior between the two forms, which difference comprises the genesis and subject of this thread, whether we consider that difference in behavior to be misleading, or a bug, or a feature, or a pro, or a con.

Again, the incremental form of the PID equation is mathematically identical to the absolute form of same, with the caveat that the parameters do not change. The premise of this thread does not maintain that caveat, so the difference in behavior should not be unexpected (good golly: talk about a tempest in a teapot ;)).

* or, more specifically, positive ;)
** at least mathematically i.e. ignoring integer roundoff to 0
*** I think the PID bias parameter has not been mentioned in this thread until now, other than once by @JLand, but it is really the key issue.
 
P.S. I am not saying anything fundamentally different than what was in @JLand's first post; I am only coming at the same issue, i.e. what constitutes the functional bias term for each form, from a different angle.
 

Similar Topics

I am trying to connect with a Schneider plc which has a firmware version only available in Somachine v4.2. In Machine expert After taking upload...
Replies
0
Views
112
They are installed in a control panel that was made in France and are intended for the termination of analog inputs. Each of the red capped...
Replies
4
Views
420
So, I'm really just trying to get some experience by practicing with arrays. I'm using studio 5000 v33. I have one rung with an XIC bit that's...
Replies
5
Views
233
I tried researching but I still don't quite get it. As far as I understood, it's used after a function is called in STL and then if the function...
Replies
1
Views
145
Back
Top Bottom