I messed with this a bit in college, and have been reading up on it some recently having no end of issues with the MegaSquirt's impersonation of the PID controller. I remember never having serious trouble setting one up before, but suddenly they are the worst thing I've ever used. Z-transform is french for "boot in your neither regions". Just ask Jean, he's from Canada, he probably knows French.
thebigmacd wrote:
Now, in discrete space which is what our microprocessors operate in, this can be greatly simplified by using only the current and previous error sample and not maintaining a sum. I won't go there quite yet.
I'm curious, why is this easier? Something like:
Int_Term = Previous_Error + Ki * Current_Error
verses
Int_Term += Ki * Current_Error
thebigmacd wrote:
For PI control, OUT = Kp*err + Ki*sum_err
Ok, just to be very clear here.... You didn't mean
OUT += Kp*err + Ki*sum_err
This is driving me SO batty. The way I wrote it is how the MS does it. They say it makes sense, but I don't buy it!
If you have a simple P controller, it integrates.
If I'm approaching my target, my output gets bigger not smaller, ensuring massive overshoot.
The other way to look at it is this:
AbeFM wrote:PID controller theory
Note: This section describes the ideal parallel or non-interacting form of the PID controller. For other forms please see the Section "Alternative notation and PID forms".
The PID control scheme is named after its three correcting terms, whose sum constitutes the manipulated variable (MV). Hence:
where Pout, Iout, and Dout are the contributions to the output from the PID controller from each of the three terms, as defined below.
Proportional term
The proportional term makes a change to the output that is proportional to the current error value. The proportional response can be adjusted by multiplying the error by a constant Kp, called the proportional gain.
The proportional term is given by:
Where
* Pout: Proportional output
* Kp: Proportional Gain, a tuning parameter
* e: Error = SP − PV
* t: Time or instantaneous time (the present)
I guess I don't know what this "z-transform" thing is. But using wiki's terms:
However, using the '+=', you get something differnet, and for discussion, let's again drop the I, D terms:
MV(t) = MV(t-1) + Kp*E(t) + Ki (=0) + Kd(=0)
MV(t) = MV(t-1) + Kp*E(t)
MV(t) = MV(t-2) + Kp*E(t-1) + kp*E(t)
MV(t) = (Sum over i = 0 to t) Kp*E(t)
MV(t) = kp * (Sum over i = 0 to t) E(t)
That looks an aweful lot like:
which, to my mind, makes it the integral term. For that matter, the I term becomes a double integral, and the D term cancels since it's the integral of a derivative (or think about adding something with a different sign every time? Sorta a stretch there).
Anyway, I'm going to go try it on the bench, but I must be missing something really big in this "z-transform" thing, because the P term should be timescale insensitive to first order.
More there than I needed, but you end up with, towards the end, an infinite sum over time.
What does all this mean? It means when your idle is low, or your boost is low, your control valve continues to open even as you approach the target. It ensures you'll never get into the 'steady offset' case where a purely proportional controller should be.
And it ensures that tuning it is an utterly black art. The recommendation of the folks who wrote that code:
If you half the time period, completely retune the controller, there is no way to just adjust the values to get the same response.
A TRUE PID controller would mean you either wouldn't change anything (absolute time reference) or you would leave Kp alone, and only half/double the Ki and Kp terms if you only considered time in loop-execution steps.
I guess the intelligent thing to do is to recompile my own version of the code with the proper math in there, tweak all the constants and scale factors (of numbers like 100,000) they put in to make it function, and see how it goes.
As it is, it would minimally need a lot of prediction. Of course, since the control doesn't go negative, I'd have to define a 'neutral' position, I think. So instead of OUT = sum(error_terms), it would be like OUT = sum(error_terms) + 50%, though really were it me, I'd choose that number to be the steady state number that works (28% for me), but I think I'm making this more complicated than it needs to be.
Or, I'm terribly misunderstanding something.