lunes, 9 de noviembre de 2015

Horas y horas intentando calibrar el PID

Ya tenemos todas las partes funcionando, ahora tenemos que calibrar las ganancias del PID. Como vamos a ver esto no nos resulto una tarea fácil.
Para entender el funcionamiento de los PID, mostraremos el programa que utilizamos  (Que aún no esta en funcionamiento). Para la realización de este programa revisamos varios recursos en Internet y los modificamos para adaptarlo a nuestras necesidades.

El programa que controla los PID consta de 3 partes, la primera es donde declaramos las ganancias de cada PID:

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//GANANCIAS PID
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
float pid_p_gain_roll = 0.05 ;               //Ganancia roll Controlador P 
float pid_i_gain_roll = 0.003;              //Ganancia roll Controlador I 
float pid_d_gain_roll = 0.4;                //Ganancia roll Controlador D
int pid_max_roll = 30;                    //Máxima salida del controlador PID (+/-)

float pid_p_gain_pitch = pid_p_gain_roll;  //Ganancia pitch Controlador P.
float pid_i_gain_pitch = pid_i_gain_roll;  //Ganancia pitch Contorlador I.
float pid_d_gain_pitch = pid_d_gain_roll;  //Ganancia pitch Controlador D.
int pid_max_pitch = pid_max_roll;          //Máxima salida del controlador PID (+/-)

float pid_p_gain_yaw = 0.04;                //Ganancia yaw Controlador P
float pid_i_gain_yaw = 0.0002;               //Ganancia yaw Contorlador I.
float pid_d_gain_yaw = 0;                //Ganancia yaw Contorlador D.
int pid_max_yaw = 30;                     //Máxima salida del controlador PID (+/-)

En nuestro caso los motores se mueven entre un rango de 1 a 255, por lo que la máxima variación que puede realizar el PID la seteamos en el 15% aproximadamente, para que no efectué movimientos muy bruscos y tengamos un margen de control en la potencia.
Ademas podemos ver que la ganancia del PITCH y el ROLL son iguales y el YAW no necesita un controlador D.

Luego la aplicación de las correcciones en los motores:

calculate_pid();
 if (start == 2){                                                          //Los motores estan encendidos
    if (throttle > 220) throttle = 220;                                   //Dejamos margen de ganancia para el control de los motores
    motor1 = throttle - pid_output_pitch + pid_output_roll - pid_output_yaw; // (FRENTE DERECHA - CCW)
    motor2 = throttle + pid_output_pitch + pid_output_roll + pid_output_yaw; // (ATRAS DERECHA - CW)
    motor3 = throttle + pid_output_pitch - pid_output_roll - pid_output_yaw; // (ATRAS IZQUIERDA - CCW)
    motor4 = throttle - pid_output_pitch - pid_output_roll + pid_output_yaw; // (FRENTE IZQUIERDA - CW)
  
  
  }

Y la funcion del PID propiamente dicha:

void calculate_pid(){
  //Calculos Roll
  pid_error_temp = gyro_roll_input - pid_roll_setpoint;
  pid_i_mem_roll += pid_i_gain_roll * pid_error_temp;
  if(pid_i_mem_roll > pid_max_roll)pid_i_mem_roll = pid_max_roll;
  else if(pid_i_mem_roll < pid_max_roll * -1)pid_i_mem_roll = pid_max_roll * -1;
  
  pid_output_roll = pid_p_gain_roll * pid_error_temp + pid_i_mem_roll + pid_d_gain_roll * (pid_error_temp - pid_last_roll_d_error);
  if(pid_output_roll > pid_max_roll)pid_output_roll = pid_max_roll;
  else if(pid_output_roll < pid_max_roll * -1)pid_output_roll = pid_max_roll * -1;
  
  pid_last_roll_d_error = pid_error_temp;
  
  //Calculos PITCH
  pid_error_temp = gyro_pitch_input - pid_pitch_setpoint;
  pid_i_mem_pitch += pid_i_gain_pitch * pid_error_temp;
  if(pid_i_mem_pitch > pid_max_pitch)pid_i_mem_pitch = pid_max_pitch;
  else if(pid_i_mem_pitch < pid_max_pitch * -1)pid_i_mem_pitch = pid_max_pitch * -1;
  
  pid_output_pitch = pid_p_gain_pitch * pid_error_temp + pid_i_mem_pitch + pid_d_gain_pitch * (pid_error_temp - pid_last_pitch_d_error);
  if(pid_output_pitch > pid_max_pitch)pid_output_pitch = pid_max_pitch;
  else if(pid_output_pitch < pid_max_pitch * -1)pid_output_pitch = pid_max_pitch * -1;
    
  pid_last_pitch_d_error = pid_error_temp;
    
  //CALCULOS YAW
  pid_error_temp = gyro_yaw_input - pid_yaw_setpoint;
  pid_i_mem_yaw += pid_i_gain_yaw * pid_error_temp;
  if(pid_i_mem_yaw > pid_max_yaw)pid_i_mem_yaw = pid_max_yaw;
  else if(pid_i_mem_yaw < pid_max_yaw * -1)pid_i_mem_yaw = pid_max_yaw * -1;
  
  pid_output_yaw = pid_p_gain_yaw * pid_error_temp + pid_i_mem_yaw + pid_d_gain_yaw * (pid_error_temp - pid_last_yaw_d_error);
  if(pid_output_yaw > pid_max_yaw)pid_output_yaw = pid_max_yaw;
  else if(pid_output_yaw < pid_max_yaw * -1)pid_output_yaw = pid_max_yaw * -1;
    
  pid_last_yaw_d_error = pid_error_temp;


}

Traduciendo el Programa a un gráfico, cada PID básicamente lo que realiza es lo siguiente:



Lo primero que tenemos que probar es que funcione el PID, para esto realizamos cambios bruscos en los motores y vemos los cambios de velocidad. Ademas seteamos los valores para conseguir un sobre amortiguamiento, como vemos en los vídeos.




Viendo que el código del PID funciona bien, nos disponemos a calibrarlo. 
Vimos varios métodos en internet y no pudimos hacerlos funcionar, principalmente porque están pensados para drones mas grandes y no tan chicos como el nuestro. 
Otro tema a tener en cuenta es la ganancia, el rango de nuestros motores es de 1- 255 y manejados con una continua a través de un PWM.  Los motores Brushless se manejan con valores rangos en el orden de 1500 y ademas se manejan con pulsos de tiempos variables en el orden de los ms, por lo que las ganancias son totalmente distintas para nuestros motores.

Luego de muchas pruebas infructuosas detectamos algunos problemas que no nos permiten obtener un correcto funcionamiento de nuestro drone:

  • El rango de potencia disponible para el vuelo es muy chico, ya que recién puede despegarse del piso a un 70% de la velocidad de los motores, por lo que debemos optimizar el peso
  • Nuestra estructura esta muy desbalanceada, lo que produce muchos problemas para el control.
  • Algunos motores están desalineados.
  • Una de las etapas de potencia estaba con fallas, produciendo que un motor funcione mas lento.

Esto nos lleva a efectuar un replanteo de como realizar el proyecto.



No hay comentarios.:

Publicar un comentario