Quote:
Originally Posted by lukevanoort
I don't see any complete PID implementations in that thread... I would recommend reading these two documents if you intend to code a PID loop: Matt Krass's whitepaper, and PID without a PhD. If you want to get a little more advanced you can search around the forum to find out how to go about writing generalized PID functions. (PID without a PhD actually uses a generalized function, but I don't think it talks about it specifically)
|
Sorry about that, wrong thread. Here's the correct one:
http://www.chiefdelphi.com/forums/sh...ad.php?t=55025
I have written an attempt at a generic PID function (rough draft of it at least).
Code:
typedef char bool;
#define false 0
#define true !false
/////////////////////////////
// PID info struct - state //
/////////////////////////////
typedef struct
{
int kpGain; /* Propotional gain */
int kiGain; /* Integral gain */
int kdGain; /* Derivative gain */
int previousError; // Previous cycles error */
int sumError; /* Sum of each cycles' error */
int errorTolerance; /* How small can the error be until we're done */
int iMax; /* Maximum integral output */
int iMin; /* Minimum integral output */
bool finished; /* Signifies if the desired target has been reached */
} PID;
void InitPID( PID* pid, int pGain, int iGain, int dGain, int imin, int imax, int et );
int PID( PID* pid, int error );
void InitPID( PID* pid, int pGain, int iGain, int dGain, int imax, int imin, int et )
{
pid->kpGain = pGain;
pid->kiGain = iGain;
pid->kdGain = dGain;
pid->iMin = imin;
pid->iMax = imax;
pid->errorTolerance = et;
pid->finished = false;
}
int PID( PID* pid, int error )
{
int P, I, D, errorDelta;
P = pid->kpGain * error;
pid->sumError += error;
if( pid->sumError > pid->iMax )
pid->sumError = pid->iMax;
else if( pid->sumError < pid->iMin )
pid->sumError = pid->iMin;
I = pid->kiGain * pid->sumError;
errorDelta = error - pid->previousError;
D = pid->kdGain * errorDelta;
if( errorDelta == 0 && error < pid->errorTolerance && error > -pid->errorTolerance )
pid->finished = true;
else
pid->finished = false;
pid->previousError = error;
return P + I - D;
}
My version would allow me to use a potentiometer with it, wouldn't? While the other one in the above thread could be used with motors and such?
Edit - I'm pretty confident it works, but I don't know for sure. I need to make a test case for it (I don't have access to the robot), but I don't know how to really. Does anyone know how to setup an example?