-
Notifications
You must be signed in to change notification settings - Fork 1
Description
I discovered a bug, where when I set the control range for example (50,100), the integrator is clamped to the minimum value even though I set the integral gain to zero!!
Therefore the pid gives strange values above the top limit of control range forever, as the integrator can't steer against it due to the fact that the integral gain is set to zero...
In the normal case, where the integral gain is non zero the missbehaviour is still in the background, but not that noticable. I am not an expert at pid, therefore I couldn't figure out the optimal solution in the code and therefore no PR sorry :(
But the behaviour as it is, the integrator clamped to the control range and then added together with the proportional part, which is multiplied with the error, that is again scaled to the !unit range! and this all together get's then scaled again to the control range seems pretty strange to me.
It makes up for huge values on the integrator at startup if the control range minimum is non zero!!
Peace of code I am refering to:
public double Next(double error, double elapsed)
{
double maximumStep;
lock (this._lock)
{
error = error.Clamp(this._errorRange).Scale(this._errorRange, this._unitRange);
this._integrator = (this._integrator + this._integralGain * error * elapsed).Clamp(this._controlRange);
maximumStep = (this._proportionalGain * error + this._integrator + this._derivativeGain * ((error - this._previousError) / elapsed)).Clamp(this._unitRange).Scale(this._unitRange, this._controlRange).ClampToMaximumStep(this._previousControl, this._maximumStep);
this._previousControl = maximumStep;
this._previousError = error;
}
return maximumStep;
}