muythaibxr wrote:
I'll have to look, I think what happened is the MS folks are using
Alpha = KP
Beta = KI
Gama = KD
Or something like that, I have to look closer. But they are doing something way wrong.
No, this just shows that you didn't read the code carefully.
Great, let's get into symantics on the ONE part where I specifically qualified it with "I have to look closer".
Come ON here. I'm trying to get a handle on this, with a guy who seems to know some of the controller theory pretty well, specifically to avoid cluttering up the MS board with any under thought out conversation.
What we're doing is:
Alpha = Kp + Ki - Kd
And we're not doing Beta or Gamma...
So, you've applied a transform, then dropped a bunch of terms? You'll note the beta term specifically cancels out the additive effects of the Kp in the alpha term. It's a shortcut, and I think it breaks the way it's supposed to work.
which in turn boils down to:
Code: Select all
error = target - actual;
OUTPUT += Kp * error;
That's an integral.
No, it's not...
It's not an integral? Here's a thought experiment (which works really well in the limit the timing period is very short compared to the response, more on this later).
Let's use your numbers, ok?
So, for example, if I've got a current valve position of
60%, and my RPM is at 1600, and my target is 800, and my P term is set to 60, I'll get a delta for this iteration of -6 (assuming a valve closed of 0, and valve open of 100). That gives me a valve position of 54% now.
Ok, awesome.
OK so next iteration of the loop, I now have a valve position of 54%, and lets say RPM dropped to 1200, because the valve closed some on the last iteration..
Now you
have to be kidding me. Your motor was at 1600 rpm. That's 26 revolutions per second, or 37milliseconds per revolution. Now I forget if you run 200 ms loop time or 100, but either way, you expect me to believe in 5 revolutions you dropped 400 RPM, all from cracking a valve a couple percent? I can kill the ignition and my motor won't drop 400 revolutions per second.
I've watched my tach, and I can tell you that in 200 ms you'll be lucky to see the RPM change ... My target was likely 800 or 850 rpm in all this.
Ok, from my logs:
valve at 66%, rpm at 1030, time 2.198 seconds
valve at 57%, rpm at 913, time 2.854 seconds
valve still 57, rpm at 733, time 3.869 seconds.
Another case, RPM had been stable between 940 and 935 rpm for a few seconds.
Valve stable at 58%, RPM 935, time 79.2
valve closes linearly to 41% at time 80.5, RPM 924
valve stays at new position (41%), RPM drops to 788 at 81.2 seconds.
So, more like 194 (call it 200) rpm/second, or 40 rpm per loop.
Now, with a factor of ten removed, it reads
OK so next iteration of the loop, I now have a valve position of 54%, and lets say RPM dropped to 1540, because the valve closed some on the last iteration..
that gives us a delta of -3. or a new valve position of 51%, next time through, lets say the RPM is 1000, that gives us -1.5, or a new valve position of 49.5%...
Ok, this becomes
that gives us a delta of -6. or a new valve position of 48%, next time through, lets say the RPM is 1500, that gives us -5.5, or a new valve position of 42.5%...
The trend I'm seeing here is exactly what I'd expect from an integral only controller. The longer you're on one side of the target, the more the correction piles up, making your set point further and further from the correct value by the time you get to the steady state.
The error in a proportional control should stay at a fixed value, there should be an offset in the steady state.
Now I'm not arguing what you're doing can't work, I'm saying it's not a PID controller, it's just an equation that moves an output based on some input, and you might be able to make it work (and in this case, people have. Kudos).
The P-only controller you have will only work (as a P controller) in the case that your time steps are much much slower than the response of the system. You can compensate somewhat by making the P values very very small, then waiting for their integration to add up to what they should be, then using your integral term as a double integral hoping that function will overpower the P term in some way to integrate faster, a higher order term... But it's sloppy.
The basic point is, in a correct Z-transform (did you read that part, or just skim for something to argue with?), the older P contributions are subtracted back out. In a true PID controller without the transform, you never add them in.
You are not defining how much to move the output, you're defining the output directly with the P-term.
My questions now is how do I convince the MS guys they are wrong?
I am not convinced yet that you are doing it right. I'm not arguing that it isn't a good effort, and not that it doesn't work. I'm just saying I don't think it's a PID controller. I guess do the math, UN z-transform it, and you'll figure out what you're effectively doing.
One more take on this:
A cleaner, more mathematical way to look at it:
OUTPUT[0] = (Kp + Ki + Kd) * Error[0] - (Kp + 2 * Kd) * Error[1] + Kd * Error[2] + OUTPUT[1]
Here, Ki is not an integral *function*, it's a gain. Kd is also a constant, not a function.
In your code (Is it yours? I'm not assigning fault here, I just mean the MS-IIx code), you have the line:
pwmidle_error_sum += rpm_error;
And what you call Ki ends up being a constant times the above. But, if I understand the Z-transform math above, Ki is only the constant, so you're effectively double integrating again, as I've had the feeling all along.
I'm still floundering a bit here mathematically, but I don't yet see that I'm wrong. I do see several places in the MS-IIx version that don't really make sense to me, I think they are doing other things than intended in a true PID controller, z-transform or otherwise.