Page 1 of 1

PID

PostPosted: Fri Oct 08, 2010 9:08 am
by pizza
hi all, im new to PID control. is my PD code correct? i can't seem to balance the seesaw with any P or D gains. my pwm to ESCs is @ 50Hz. and my pid control loop is at 100Hz.

Code: Select all
//TPU refers to timer units which output PWM..TGRA is the on cycle register
rollControl()
{       
        roll=PIDroll(Kp,0,Kd);
        if(roll>0)     //left motor too powerful
        {
            if(TPU2.TGRA-roll<=585)
                TPU2.TGRA=585; //LIMIT MIN, wait for the opp motor to increase
            else
                TPU2.TGRA-=roll;
       
            if(TPU0.TGRA+roll>=700) //LIMIT MAX wait for the opp motor to decrease
                TPU0.TGRA=700;
            else
                TPU0.TGRA+=roll;
        }
        else if(roll<0)          //right motor too powerful
        {
            if(TPU2.TGRA-roll>=700)
                TPU2.TGRA=700; //LIMIT MAX, wait for the opp motor to increase
            else
                TPU2.TGRA-=roll;
         
             if(TPU0.TGRA+roll<=585)  //LIMIT MIN, wait for the opp motor to increase
                TPU0.TGRA=585;
            else
                TPU0.TGRA+=roll;
        }
}

//interpreted from wikipedia
float PIDroll(float Kp, float Ki, float Kd)
{
   float previous_error;
   previous_error = error_roll;
   
   //setpoint @ 0 degree to balance seesaw
   error_roll = 0 - kalman_roll;
   
   derivative_roll =  (error_roll-previous_error)*dt;  // dt=0.01; 100Hz            
   return (Kp*error_roll)-(Kd*derivative_roll);
}


Re: PID

PostPosted: Sat Oct 09, 2010 2:28 pm
by Tom
Hey Pizza,

You code is not correct. Please take a look at the gluon pid.c code :-)

Code: Select all
float PIDroll(float Kp, float Ki, float Kd)
{
   float previous_error;
   previous_error = error_roll;   // WRONG
     
   //setpoint @ 0 degree to balance seesaw
   error_roll = 0 - kalman_roll;
   
   derivative_roll =  (error_roll-previous_error)*dt;  // dt=0.01; 100Hz            WRONG derivative = dE/dt, thus / dt
   return (Kp*error_roll)-(Kd*derivative_roll);    // WRONG multiply with dt
}

Re: PID

PostPosted: Tue Oct 12, 2010 4:50 am
by pizza
hi tom thanks. oh no i posted reply but the post was lost.

i read your pid.c but there was no update of the d-state.

yup! i made a mistake, it should be /dt instead of *dt.
what's wrong with remembering previous error as a global variable, then finding d(error) =previous_error-error_roll?

is it possible to balance the see saw using only P gain?
no matter what P gain i tried, it just oscillate about and will never stop at 0degree.
shouldn't we limit the maximum pwm and minimum pwm to climb?


Tom wrote:Hey Pizza,

You code is not correct. Please take a look at the gluon pid.c code :-)

Code: Select all
float PIDroll(float Kp, float Ki, float Kd)
{
   float previous_error;
   previous_error = error_roll;   // WRONG
     
   //setpoint @ 0 degree to balance seesaw
   error_roll = 0 - kalman_roll;
   
   derivative_roll =  (error_roll-previous_error)*dt;  // dt=0.01; 100Hz            WRONG derivative = dE/dt, thus / dt
   return (Kp*error_roll)-(Kd*derivative_roll);    // WRONG multiply with dt
}