Thread: PID question
View Single Post
  #6   Spotlight this post!  
Unread 10-01-2008, 17:01
bronxbomber92 bronxbomber92 is offline
Registered User
FRC #1551 (Grapes of Wrath)
Team Role: Programmer
 
Join Date: Jan 2007
Rookie Year: 2007
Location: Naples
Posts: 75
bronxbomber92 is an unknown quantity at this point
Re: PID question

Quote:
Originally Posted by lukevanoort View Post
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?

Last edited by bronxbomber92 : 10-01-2008 at 19:28.