typedef struct pid_tag{
float kp; //proportional gain
float ki; //integral gain
float kd; //derivative gain
float in; //input value
float err[3]; //error history
float out[2]; //output history
float in_ref; //input reference
float out_max; //maximum acceptable value for the output
float out_min; //minimum acceptable value for the output
}pid_t;
float perform_pid(pid_t *p){
/*compute actual error*/
p->err[0] = p->in_ref - p->in;
/*start with the previous output*/
p->out[0] = p->out[1];
/*add proportional part*/
p->out[0] += p->kp * (p->err[0] - p->err[1]);
/*add integral part*/
p->out[0] += p->ki * ((p->err[0] + p->err[1]) / 2);
/*add derivative part*/
p->out[0] += p->kd * (p->err[0] - 2*p->err[1] + p->err[2]);
/*set up the output limits to avoid abnormal behavior*/
if(p->out[0] > p->out_max) p->out[0] = p->out_max;
else if(p->out[0] < p->out_min) p->out[0] = p->out_min;
/*update error history*/
p->err[2] = p->err[1];
p->err[1] = p->err[0];
p->err[0] = 0;
return p->out[0];
}
Obviously using the structure variables as floats might not meet the time requirements for you application. You can optimize the code using some other variable types.
References:
[1] Bräunl, Thomas, "Embedded Robotics: Mobile Robot Design and Applications with Embedded Systems", pp.56-61




No comments:
Post a Comment