Generic PID Function Requirments Discussion

Official FreeEMS vanilla firmware development, the heart and soul of the system!
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

Generic PID Function Requirments Discussion

Post by Fred »

As the title says, share your thoughts!

I know TheBigMacD and Abe and Gearhead are interested in this, share your thoughts on how to achieve a useful general purpose function.

As good ideas come out of the wash/arguments in here they can be added to the feature request :

http://freeems.aaronb.info/tracker/view.php?id=25
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
User avatar
BenFenner
LQFP144 - On Top Of The Game
Posts: 360
Joined: Wed Jul 09, 2008 3:15 pm

Re: Generic PID Function Requirments Discussion

Post by BenFenner »

There was a time when I didn't fully (or even partially) understand the basic PID control algorithm so I kept out of the previous thread. This time around I've got it fully under my belt I believe. From an outsider's point of view using the PID control for idle valve opening with MegaTune/VEMS I've found they put artificial limits into how much "I" can influence the outcome. My idle control valve (Nissan SR20) is the most finicky I've ever run across. It is absolutely non-linear (0-74 % DC seems linear, then 74-76% represents a giant difference in air, then 76-100% is linear again, but much steeper than 0-74%) and must work with two other passive idle controls (constant opening controlled by a screw and temp related opening for cold start/fast idle). This is something to keep in mind in and of itself.

About the partial limits on "I". Don't do what MegaTune/VEMS did is all I can say. In theory a 0 value for "P" and "D" and some value for "I" (like 1) should bring the system to equilibrium. It may take a long time, but it should. In MegaTune/VEMS there seemed to be a limit to the amount of control "I" had on the output. These limits could be widened by either increasing "I" (which also increased the speed of convergence to equilibrium, which could be bad) or increasing the "integral limits" anywhere from 0-255. This artificial limit on "I" makes it so that a small (but extremely useful) value of "I" such as 5 can not bring idle down, or up (depending) enough. The result being a nice smooth "catch" of the dropping rpm, and then a slow drop to the set idle rpm, only it won't ever get there. Instead of 850 rpm I'll see 1,000 or so. If I increase "I" it will get there, but the nice, slow idle drop turns into a fall that overshoots the target. This problem is compounded by the non-linear nature of my idle control. It's basically a perfect storm of idle ruining madness that I have to deal with. Finally I seem to have come across what Nissan must have used (at first I thought they couldn't possibly have used PID control at all) but am thwarted by MegaTune/VEMS's shortsightedness and apparent blindness of Nissan idle control valves.

Sorry for the ramble and all. I'll try to be of much more constructive help in the future. Right now I'm just calling things as I see them until I know better.
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

Re: Generic PID Function Requirments Discussion

Post by Fred »

You raise a good point here. (you often do)

There should probably be a mapping between airflow and pwm that is non linear. These other systems work on the basis that the valves are linear don't they? If the PID loop spat out an airflow and that mapped to a pwm figure it could improve your situation a lot. I'm not sure what you mean by these limits etc though.

Thanks!
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
thebigmacd
LQFP112 - Up with the play
Posts: 205
Joined: Thu Apr 10, 2008 5:51 pm

Re: Generic PID Function Requirments Discussion

Post by thebigmacd »

The issue with Megasquirt is the I term wasn't actually an I term, it was a P term. I believe they are fixing this for MS3.

As far as non-linearities, the loop for sure should be a hybrid of feed-forward and feed-back control. Good control should be approximated with an open-loop curve and adders for known additional loads. Then a simple PI controller can be used to fine tune it within a 100 rpm (or so) range.
Keith MacDonald
Control Engineering (Systems) Technologist
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

Re: Generic PID Function Requirments Discussion

Post by Fred »

If you see the tail end of the other thread you can see Kens words on the subject. He re wrote the whole thing :-)

Fred.
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
User avatar
BenFenner
LQFP144 - On Top Of The Game
Posts: 360
Joined: Wed Jul 09, 2008 3:15 pm

Re: Generic PID Function Requirments Discussion

Post by BenFenner »

Fred wrote:These other systems work on the basis that the valves are linear don't they?
I believe so.
Fred wrote:I'm not sure what you mean by these limits etc though.
I'll try and explain better below.
thebigmacd wrote:The issue with Megasquirt is the I term wasn't actually an I term, it was a P term. I believe they are fixing this for MS3.
I don't know about MegaSquirt, but maybe VEMS did the same thing? I'm doubtful though. See below.
thebigmacd wrote:As far as non-linearities, the loop for sure should be a hybrid of feed-forward and feed-back control. Good control should be approximated with an open-loop curve and adders for known additional loads. Then a simple PI controller can be used to fine tune it within a 100 rpm (or so) range.


I think I'll explain what I've seen here and it will touch on all the issues raised above.

The PID idle control for VEMS took me a long time to figure out, but here's the deal. First you tune the PWM table which is about 10 spots of temp versus PWM value (direct DC % to idle valve). (This is what thebigmacd is talking about above when he says good control should be approximated with an open-loop curve.) Something like this:

[-60] --> [90]
[-40] --> [88]
[-20] --> [86]
[0.0] --> [84]
[15] --> [82]
[30] --> [80]
[45] --> [78]
[60] --> [76]
[75] --> [50]

The idea is that you get this as close as possible to the behavior you'd like. This is important because this is the base value the PID controller in VEMS starts with once idle is enacted. So if you close the throttle at 45 degrees the idle % DC value starts at 78 and then PID takes over adjusting that as it sees fit. If you close the throttle at high rpms, idle turns on and sees that rpms are way, way off so PID will drop the DC % value to a very low number which seems counter intuitive, because to "catch" the falling rpm you'd want something even higher than the 78 you started with. But I digress....

I had a year under my belt dealing with this idle control, and just finally realized that the idle solenoid was not linear. After sleeping on it I came up with a plan. I'd set all the PWM values to something high:

[-60] --> [85]
[-40] --> [85]
[-20] --> [85]
[0.0] --> [85]
[15] --> [85]
[30] --> [85]
[45] --> [85]
[60] --> [85]
[75] --> [85]

And I wouldn't give any authority to "P" which changes things much too fast and at the worst times for use in idle if you ask me.
I decided to start with "I" and was quickly rewarded with a great "catch" of idle because even while fully warmed up idle % DC would start off at 85 (which was good for about 1,400 rpm) and then "I" slowly worked it's magic bringing down the idle % DC value with a corresponding slow drop in idle until about 1,000 rpms and maybe a % DC value of 60.

Uhhh... wait a minute. Why did it stop going down? My target was 850 rpm.

From everything I've read about PID control it should adjust until the target (850 rpm) is reached.

Here's the window. Ignore the current values of everything actually. Imagine P = 0, I= 5, D = 0 and "integral decrease/increase limit" is set at 255 (highest).

Image

This allows for a deviation of about 25 % DC from the initial PWM value designated in the table. Lower the "integral decrease/increase limit" values and things get worse, only allowing for less than 25 % DC change depending on the value. You get the idea.

Yes, you can make "I" higher than 5 and it will bring things further than 25 % DC deviation, but it will act much too fast to allow the good "catch" of falling idle, etc. etc. etc.

Does that make it any clearer?


Once understood, Nissan's idle control valve being non linear makes a lot of sense. You can use the lower 75% as a fine tune mechanism to keep warm idle solidly in check. This however doesn't give enough air for cold/fast idle so the top 25% is used for that where only coarse tuning is really necessary. Additionally, as the % DC falls across the threshold from lots of air to a little bit of air you get a crisp, distinguishable drop in idle quickly (idle "catches" then drops to 850 rpm quickly, with purpose) with the tiniest drop in actual % DC value, and this tiny drop is all that's needed, and all that will be provided by a small "I" value. It would work so perfectly if VEMS would just allow the PID control to keep on truckin' instead of limiting things artificially (they may have been worried about the run-a-way "I" value which I've read needs preventing, but I digress again).

In conclusion, it just seems that the writers of the PID control never anticipated an "I" control, and only ever considered a "P" control, a "PI" control, or a "PID" control. A non-linear idle control valve seems to take advantage of a strictly "I" control. My advice is to keep this in mind when writing and testing the PID code. Even a value of 1 for "I" should get the system under control (if slowly).
Attachments
VEMS PID idle control
VEMS PID idle control
User avatar
AbeFM
Post Whore!
Posts: 629
Joined: Sat Feb 16, 2008 12:11 am
Location: Sunny San Diego
Contact:

Re: Generic PID Function Requirments Discussion

Post by AbeFM »

The thing he was trying to say, to keep in mind, is that the MS's idle is a really bad example of a PID controller, because while they listed "P" "I", and "D", they didn't at all stand for proportional, integral, and derivative. They all had odd effects due to some near-integration of all their variables. It was a badly botched execution based on short cuts and a lack of understanding, and they argued it to the death how they were right, refused any help in fixing it, then after several people had gone off to make custom hardware or software, they then released out of the blue a "fixed" version.

Needless to say, they pissed off at least one person in doing this. :-)

The code I wrote did just that, I had a baseline curve for default opening without the help of the PID, which was pretty much going to get me very near the idle I wanted. The "P" term is excellent, but easy to overuse. The I term was really fast I found.

As to requirements, for a general PID control loop.

There's some things I'd like to know when I, as a function, am called.

How many bits is my output?
How many bits are my variables?
Am I on a hardware PWM, a faked (soft-) PWM, or a true analog output?
How important am I - i.e. how often do I get to run? How much time can I take from the CPU?
Is there an emergency shut off state? Rigid limits of some sort (500<idle <2000, boost<280kpa)

I would like to have the algorithm be time independent. I want to know how many seconds/ticks have gone by, so I can be called irregularly and not have how often you call the function alter the response to a given value of P (for instance, but it should hold for all terms). Also, I would like to be able to adjust values in real time, without rebooting or anything silly.

Also, should things be adaptive at all, adjust their own variables? Could it be smart enough to fix things? Is hybrid ok (a base map, plus a small PID based adjustment) - this last one I like.


Sigh, this is all I could remember from drunken brainstorming last night, but it's what I'd like to see for a requirements list. Instinctively, I feel the answers might be different from VVT control to boost control to traction control to idle, so I'd like to see these expressed in how the function is called.

Edit: Kudos on the DC adjust for inputs. I still want to see a simple 0-5V input which would tell it to add X amount of idle, could be useful in other situations. Perhaps boost cut on low pressure in water injection system.
Edit II: Integral deadband is interesting. I was playing with something like that, though I never got around to naming it. :-)
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

Re: Generic PID Function Requirments Discussion

Post by Fred »

8InchesFlacid wrote:There's some things I'd like to know when I, as a function, am called.
:-)
How many bits is my output?
I and O should probably be 16 each? perhaps 8 makes sense in places? I'm not sure.
How many bits are my variables?
If you mean working variables, double the I and O ones for overflow resistance.
Am I on a hardware PWM, a faked (soft-) PWM, or a true analog output?
Why do you care??? The point of such a function would be to be independent of such implementation details.
How important am I - i.e. how often do I get to run? How much time can I take from the CPU?
You don't care about this, optimise last! How often will be something decided or tunable and then taken care of by the scheduler.
Is there an emergency shut off state? Rigid limits of some sort (500<idle <2000, boost<280kpa)
Sounds like logic that should be external to this function.

Software blocks should have a single well defined purpose.
I would like to have the algorithm be time independent. I want to know how many seconds/ticks have gone by, so I can be called irregularly and not have how often you call the function alter the response to a given value of P (for instance, but it should hold for all terms).
Easy, the struct holds a time stamp (ore more) stored by the previous run taken from the RTC vars.
Also, I would like to be able to adjust values in real time, without rebooting or anything silly.
We have as much ram put aside for stuff like alone this as MS2 has total. You will definitely have this.
Also, should things be adaptive at all, adjust their own variables? Could it be smart enough to fix things? Is hybrid ok (a base map, plus a small PID based adjustment) - this last one I like.
KISS/Walk then run. Again, something outside of such a function. This function should be fairly pure and generic. All sorts of logic and tweaks can surround it and be specific to the task at hand etc.
Instinctively, I feel the answers might be different from VVT control to boost control to traction control to idle, so I'd like to see these expressed in how the function is called.
The point of this thread is to extract out the common ground and nail it together.
Edit: Kudos on the DC adjust for inputs. I still want to see a simple 0-5V input which would tell it to add X amount of idle, could be useful in other situations.
Definitely external logic/processing after the PID runs.

Fred.
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
User avatar
BenFenner
LQFP144 - On Top Of The Game
Posts: 360
Joined: Wed Jul 09, 2008 3:15 pm

Re: Generic PID Function Requirments Discussion

Post by BenFenner »

8InchesFlacid wrote:The thing he was trying to say, to keep in mind, is that the MS's idle is a really bad example of a PID controller, because while they listed "P" "I", and "D", they didn't at all stand for proportional, integral, and derivative.
You've got that right I guess, except for the fact that I'm not using MegaSquirt. From the looks of things, VEMS implemented "P", "I" and "D" properly (for the most part). I just believe some instances (all idle control if you ask me) could benefit from a pure "I" control (with large or no limits) which should be kept in mind when writing the general PID controller.

From the looks of it Abe (8InchesFlacid) was rockin' and rollin' on the generic PID algorithm in the other thread. It would seem it's basically finished, and does what it should do and does it well. No fluff, just pure PID control. Did he leave us? Is this why we're discussing this again?
User avatar
Fred
Moderator
Posts: 15431
Joined: Tue Jan 15, 2008 2:31 pm
Location: Home sweet home!
Contact:

Re: Generic PID Function Requirments Discussion

Post by Fred »

Abe was trying to implement proper PID in the MS code for his car, however his engine died and he got a dozen girl friends etc so he's been not so active on here for the last few months.

The stuff in the other thread was more of an integrated approach as opposed to an isolated and modular one. This thread was supposed to be more at the implementation level and what is required of the function as an interface in order to be generally useful.

The other code did not fulfil those things IMO, but I didn't take a close look.

We'll see what comes of it, but I have high hopes for this :-)

Fred.
DIYEFI.org - where Open Source means Open Source, and Free means Freedom
FreeEMS.org - the open source engine management system
FreeEMS dev diary and its comments thread and my turbo truck!
n00bs, do NOT PM or email tech questions! Use the forum!
The ever growing list of FreeEMS success stories!
Post Reply