Jump to content

Bug in NI PID VI?


DTaylor

Recommended Posts

I'm hoping that I'm just missing something here. I've known about this behavior for a while, but I didn't think it was problematic until today. In NI_PID_pid.lvlib:PID.vi, it appears that integrator anti-windup is implemented such that the accumulated error is set so that the sum of the integral and proportional action do not exceed the control limits, but that causes this (the high proportional gain and low integral gain are to demonstrate the behavior):

PID Bug.pngPID Bug Screenshot.png

Again, I hope I'm just overlooking something - it wouldn't be the first time.

 

PID Bug.vi

Link to comment

The problem with testing a PID is partially that you don't have the full setup, you are creating a control for your output, but you aren't adjusting the process variable with a simulated model of your environment.

Let me try to explain the best I can with my non-academic view of a PID.  So lets say you have a valve you want to control with a PID, and it will open and close and let in more or less water through a pipe.  So you create a PID and you want to test it without the hardware, which is what you have above.  But the problem is when you adjust that valve in the real world, your measured flow will actually change, and that new measured flow will go back into your PID, and then the PID will adjust the output control a little more, which opens and closes the valve more, which adjusts the amount of water flowing more, which is your simple feedback.  But in your simulation you are adjusting the value, but your flow being measured (PV) stays the same.  It is like the PID is closing the valve more and more, but the flow keeps coming, so the PID closes it more and more, but the flow keeps coming.  A better system is to model how the valve and flow relate to one another, and then have your PV going into your PID change, as your output of the PID changes.  

You have there a constant of 90 as your setpoint, telling the PID "I want you to be 90".  Then you have your PV (essentially the flow reading) set to 50 for 2 seconds, then 30 for 2 seconds then 50 for 2 seconds (if the comment is correct).  This means your measured flow in my example doesn't change for 2 seconds, so the PID is going to try to adjust the valve continually in the same direction.

If you want a good basic example, look at the General PID Simulator.vi by searching for it in the Help >> Find Examples (I searched for PID).  It has a simple model where there is a PID that sets an output, and then a plant simulator pretends to be the real world behavior.

Link to comment
4 hours ago, hooovahh said:

The problem with testing a PID is partially that you don't have the full setup, you are creating a control for your output, but you aren't adjusting the process variable with a simulated model of your environment.

Hoovah, thanks for the reply. I should have clarified what the unexpected behavior is. My intent was not to create any sort of realistic system, it was to demonstrate that I'm able to get the controller output to go negative despite the process variable being significantly below the setpoint. I would expect the controller to be continuously saturated high in this example because of the high proportional gain. You can actually get the same thing to happen in the General PID Simulator example by using the same gains I used in my example and changing the setpoint around.

Link to comment

Oh so sorry, yeah as I was writing that reply I did notice that with the PV so low I'd expect the MV to go really high.  The only thing I can say is that the PID sees that the PV went from a low number (30), to a higher number (50) instantaneously, and part of the PID is the derivative meaning predictive changes will occur, based on how quickly the value changes.  Even though the new PV is still below the setpoint, the PID sees this fast increase from 30 to 50, and predicts that the next time it is read it will be even higher, and thinks it needs to lower MV in response to that fast change.  Again not a PID expert, just what I've observed.  In the real world, your sensor shouldn't change that fast, in that short amount of time, and if it does, lowering the MV might be the right response, based on the PID values.

...Of course now that I look at your code again your "D" value is 0.  But by changing your "I" to 0 this behavior doesn't occur, so I'd suspect my reasoning is correct, but my specifics aren't.

Link to comment
5 hours ago, hooovahh said:

If you want a good basic example, look at the General PID Simulator.vi by searching for it in the Help >> Find Examples (I searched for PID).  It has a simple model where there is a PID that sets an output, and then a plant simulator pretends to be the real world behavior.

Here is an example of the same behavior inside the referenced example:PID Example.png

There are two things that I don't expect here that I believe are caused by the anti-windup implementation: The first is that the controller is initially saturated high, but backs off despite being far from the setpoint and having high proportional gain. The second is that upon lowering the setpoint, the controller output goes negative, despite the process variable having always been below the setpoint (and no derivative gain).

The integral gain in the above example was so low that it doesn't have much of an effect on this timescale. Setting the integral time to 0 turns off integration action and anti-windup in PID.vi, and this is what happens (and this response is close to what I would expect to see on a short timescale with a low integral gain, but with the absence of slowly accumulating integral action):PID Example 2.png

Link to comment
6 minutes ago, hooovahh said:

But by changing your "I" to 0 this behavior doesn't occur, so I'd suspect my reasoning is correct, but my specifics aren't.

That's because it turns off the integrator and what I think may be an incorrect anti-windup algorithm. You can see the special case for the 0 integral time inside the PID.vi.

Link to comment

I'd find it hard to believe such an old piece of documented code has a bug this big in it, but you are starting to convince me.  If you don't get any more help here I'd suggest making a post on the dark side (NI's forums) where their AE's monitor the boards closer, and may assign CARs.  They can also sometimes talk to the guy that implemented the feature or function and get better insite into why it might behave this way.

Link to comment
5 minutes ago, hooovahh said:

I'd find it hard to believe such an old piece of documented code has a bug this big in it, but you are starting to convince me.  If you don't get any more help here I'd suggest making a post on the dark side (NI's forums) where their AE's monitor the boards closer, and may assign CARs.  They can also sometimes talk to the guy that implemented the feature or function and get better insite into why it might behave this way.

That's good advice. I've cross posted this on the NI forums, but with the better example you led me to: http://forums.ni.com/t5/LabVIEW/Bug-in-NI-PID-VI/td-p/3557560. Thanks for the help!

Link to comment
28 minutes ago, infinitenothing said:

10 minutes is a really long I. I ran a simulation of your gains in the General PID simulation but I wired a constant dt to simulate it running faster and it does eventually converge. The other MV perturbations are just a consequence of Kp*(PV-SP) changing.

Thanks for the response. The long Ti in my example is so that the integrator action is minimal. My issue is not with the lack of accumulation or convergence, it's that the anti-windup is causing output states that I don't think should happen. My Kp is 10 in the example, PV is never greater than 10, and SP is never less than 60.

10 * (60 - 10) = 500

I don't see a reason why the MV should ever be anything but saturated high at 100.

Edited by DTaylor
I had an exclamation point after 500, but realized that could be interpreted as the factorial operator.
Link to comment

I see. You can look at the subVI to see mathematically what's happening right? It's preloading your integral. The qualitative answer is going to be more subjective and involve some hand waving but it's trying to gently take control to better handle the case where you start with your PV close to the SP and don't want the integral debt. In the case of the General PID Simulator, it's doing the right thing by going down—the stable control point is around 40% MV.

Edited by infinitenothing
Link to comment
8 minutes ago, infinitenothing said:

I see. You can look at the subVI to see mathematically what's happening right? It's preloading your integral.

Yes, and I think that that's a strange way of implementing anti-windup - perhaps strange enough to call it a bug.

8 minutes ago, infinitenothing said:

it's trying to gently take control to better handle the case where you start with your PV close to the SP and don't want the integral debt.

The anti-windup implementation I expect would be to just not accumulate in the positive direction when saturated high or negative direction when saturated low, not to set the error to whatever will bring the control output in-bounds.

12 minutes ago, infinitenothing said:

In the case of the General PID Simulator, it's doing the right thing by going down—the stable control point is around 40% MV.

I think you are referring to the second screenshot I posted. I think the second screenshot is correct and expected behavior, and that the first should look more like it on a short timescale given the long integral time.

Link to comment
1 hour ago, hooovahh said:

I'd find it hard to believe such an old piece of documented code has a bug this big in it, but you are starting to convince me.

This is not necessarily old documented code. NI periodically "improves" the PID VIs, and I found a bug in one of them a couple years back: http://forums.ni.com/t5/LabVIEW/RT-PID-toolkit-does-not-match-standard-PID-toolkit-for-arrays/td-p/501080

Thank you for pointing out this problem. I just (last week) ran into what is probably the same issue - my process variable is well above the setpoint but sometimes the PID output still turns on.

Link to comment
50 minutes ago, DTaylor said:

Yes, and I think that that's a strange way of implementing anti-windup - perhaps strange enough to call it a bug.

The anti-windup implementation I expect would be to just not accumulate in the positive direction when saturated high or negative direction when saturated low, not to set the error to whatever will bring the control output in-bounds.

I think you are referring to the second screenshot I posted. I think the second screenshot is correct and expected behavior, and that the first should look more like it on a short timescale given the long integral time.

It looks like NI is using option 5 on the wiki page. You could implement #3 manually which maybe gets you closer to the second screenshot. You seem to like option #4. It would be interesting learning the pros and cons of 4 vs 5. Maybe an enum selector input would be a nice feature.

I was referring to the initial drop below 100 in the first screenshot. I was saying it was desirable for when your PV was close to your SP but you still needed output.

Edited by infinitenothing
Link to comment
40 minutes ago, infinitenothing said:

It looks like NI is using option 5 on the wiki page.

They are indeed - thanks for the external reference. I've found some more references to this method. It seems potentially problematic to me, but it seems there is precedent for it.

40 minutes ago, infinitenothing said:

You seem to like option #4

Not exactly. I'm not advocating for limiting the error accumulator, just stopping it in the appropriate direction when the controller is saturated high or low. It's the second method (clamping) listed here:

https://www.mathworks.com/help/simulink/examples/anti-windup-control-using-a-pid-controller.html

I'm not sure I'm allowed to link to Simulink documentation here. That may be an unforgivable LabVIEW sin.

46 minutes ago, infinitenothing said:

Maybe an enum selector input would be a nice feature

That's a good idea

Link to comment

This random person on stackoverflow says that being able to set the back-calculation coefficient is important:

" Back Calculation highly depends on the back calculation coefficient Kb. If you don't know how to actually calculate the parameter Kb don't use back-calculation. "

http://stackoverflow.com/questions/18654853/simulink-pid-controller-difference-between-back-calculation-and-clamping-for

I have no idea whether this is true or not, but the NI PID.vi effectively has a constant Kb of 1.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.