Quadcopter PID

Hola, a todo, estoy haciendo un proyecto de un quadcopter, mi problema es que no estabiliza muy bien, si se inclina aumenta la potencia pero la proporción de aumento no es muy buena ya que amplia mucho la velocidad y acaba desestabilizando el otro lado. mi código es este:

//pid declaracion
PID myPID(&Inputpid, &Output, &Setpoint,1,0,0, DIRECT);
//power variable de potencia
Setpoint = power;

//PID
//el roll mide el angulo de inclinacion desde 0 a +-90
Inputpid = roll;
myPID.Compute();

//incremento de los motores
if(Output > Setpoint)
{
//lado 2
inc = (Output - Setpoint)/3;
inc2 = (Output - Setpoint)/2;
p1 = power - inc;
p2 = power - inc;
p3 = inc2 + power;
p4 = inc2 + power;
}
else if (Output <= Setpoint)
{
//inc lado1
inc = (Setpoint - Output)/3;
inc2 = (Setpoint - Output)/2;
p1 = power + inc2;
p2 = power + inc2;
p3 = power - inc;
p4 = power - inc;
}
motor1.write(p1);
motor2.write(p2);
motor3.write(p3);
motor4.write(p4);

Alguna idea, puede ser los parámetros del PID?

¿Has trabajado alguna vez con un PID?
¿Has practicado con ejemplos sencillos antes de ponerte con esto?
¿Por qué haces Setpoint = power;?
¿A qué motores corresponden p1, p2, p3 y p4?
¿Por qué para calcular "inc" divides para 3 y para "inc2" divides para 2?

Aún con todas estas dudas creo que estás usando la salida del PID como si fuera un dato de un sensor o el ángulo de inclinación del quadcopter. Así no funciona un PID.

Hola cheyenne, antes de ponerme con esto he visto los ejemplos de PID introduciendo algún valor, introduzco un valor X y el PID me devuelve la corrección del error que presenta ese valor, visto esos ejemplo me meto con esto por ver si es mas fácil la estabilización ya que introduciendo algún dato el PID me devolverán a la salida un valor para compensar ese valor.

Uso Setpoint = power para que la salida del pid devuelva un valor que sea la diferencia osea el error que tiene la estabilización y me devuelva un valor para incrementar la potencia de los motores.

Como solo estoy probando el Roll de quadcopter establezco dos lados, osea que dos motores dependiendo de la inclinación aumentaran su potencia para equilibrar el quadcopter, y como puede ser que los motores no todos tendran la misma potencia dependiendo de lo que se valla a hacer, por ejemplo girarlo sobre su propio eje, o cualquier otro movimiento establezco las variables p1,p2,p3,p4 que haran referencia a la potencia de cada motor, cada uno de ellas con su correspondiente numero de motor.

Lo de los incrementos divido por dos y por tres, por hacer una prueba reduciendo el incremento y que no fuese tan brusco el cambio, al principio no dividia la variable inc, y tampoco existia inc2, pero al ver que sucedia eso probe con un valor mas pequeño al incrementar y por eso divido.

Este es mi codigo basico:

//pid declaracion
PID myPID(&Inputpid, &Output, &Setpoint,1,0,0, DIRECT);
//power variable de potencia
Setpoint = power;

//PID
//el roll mide el angulo de inclinacion desde 0 a +-90
Inputpid = roll;
myPID.Compute();

//incremento de los motores
if(Output > Setpoint)
{
//lado 2
inc = Output - Setpoint;

p1 = power;
p2 = power;
p3 = power + inc;
p4 = power + inc;
}
else if (Output <= Setpoint)
{
//inc lado1
inc = Setpoint - Output;

p1 = power + inc;
p2 = power + inc;
p3 = power;
p4 = power;
}
motor1.write(p1);
motor2.write(p2);
motor3.write(p3);
motor4.write(p4);

Un ejemplo de lo que hace este código es que si sitúas tu setpoint = power y el valor de power es 40 por ejemplo, cuando haya una inclinación X la salida del PID devuelva Y va a incrementar la potencia de los dos motores del lado que esta descompensado en la diferencia de la velocidad y lo que ha devuelto el PID osea si era 40 - Y = inc , por lo cual un lado del quadcopter tendrá el valor de los motores igual a power + inc y otro a power, a medida que se este estabilizando ira disminuyendo ese incremento y quedara estabilizado.Pero el resultado como sale en el vídeo demuestra que no, que es demasiada potencia y acaba por desequilibrar el otro lado.

Por ultimo no uso el PID como la salida de un sensor, intento que el PID me devuelva la corrección de un error de equilibrio y aplique esa salida como incremento de la potencia de los motores, si es verdad que dependiendo de esa salida aplico el incremento en un lado o en otro, que puede ser que me equivoque ya que al PID se le indica el valor deseado y yo le indico como valor la velocidad estable del quadcopter por lo cual, ahí puede estar uno de los problemas, ya que no va a ser estable con la velocidad de los motores iguales porque puede haber una descompensacion de peso en un lado y deben tener una potencia mayor para estabilizarlo, pero entonces como introduciendo un valor deseado de estabilidad por ejemplo quiero que este a un valor 0 en el eje X, para que este estable tendría que indicar en vez de la potencia el angulo de inclinación para que devuelva la corrección de ese angulo de inclinación, y con ese valor ya aplicar una potencia de incremento para los motores descompensados?

Correcto lo último que indicas. Y las correcciones tienen que ser simétricas. Sobre un nivel de velocidad igual a los cuatro motores (que sí será el indicado por el mando trottle de la emisora, imagino que lo que llamas power) le sumarás la salida del PID a los dos motores de un lado y se lo restarás a los dos del otro lado.

Muchas gracias, hablando contigo me di cuenta del error y veo que tiene mas lógica trabajar así que de la forma inicial, ahora probare la modificación y ya publicare aquí si dio resultado o no.

me sigue pasando lo mismo, parece mas estable y no tan brusco los movimientos pero acaba haciendo lo mismo, he hecho otro vídeo y lo he subido, voy a intentar hacer pruebas con la configuración + del quad en vez de en X, y por otro lado alguna mejora del código. Tengo una duda del pid, por lo menos en mi caso, mi imu después de aplicar un filtro de kalman, me da valores entre +- 90 dependiendo del angulo de inclinación, si paso al pid el setpoint 0 y el input del valor que de el imu, el pid me dará como resultado lo mismo que si hiciese yo la operación de restar.

Ejemplo:
Si mi imu me da 10º de inclinación, es el pid dirá que para obtener el valor 0, la salida sera 10, esto es lo mismo que usar ese valor directamente para incrementar los valores del motor, para que uso un pid si es lo mismo que usar directamente ese valor, por lo menos en mi caso.En que me estoy equivocando?

Adjunto la imagen de mi Serial donde muestra los valores del Pitch|Roll|Output PID para el Roll solo en este caso|potencia del lado 1 | potencia del lado 2. Para este caso el valor de P es 2 por eso sale el doble del valor

Video

roll.jpg

Hola,

PID myPID(&Inputpid, &Output, &Setpoint,1,0,0, DIRECT);

Si te fijas bien, estas poniendo las ganancias Kp = 1, Ki = 0, Kd = 0, por lo tanto solo tienes accion proporcional y no integral ni derivativa. Lo normal es que hagas un modelo matematico del sistema y a partir de alli segun la respuesta deseada calcules esos 3 valores que es lo que te va a llevar a tener una respuesta rapida, con o sin oscilaciones y estable.

Como veo que no tienes los conocimientos para hacer el modelado, puedes empezar a cambiar esos valores por tanteo a ver si mejoras, o creo que en el github de esa libreria hay una opcion de autotuning que pudieses probar. O para empezar prueba con 1, 0.1, 0 ya que al colocar accion integral aseguras que el error se vaya a cero.

Ademas estoy viendo que consideras Output como la salida del sistema, la salida del sistema deberia ser Roll, y el Inputpid deberia ser Setpoint - Roll, Y Output es la salida del PID que deberia ir de alguna forma a la planta en tu caso los motores. Existe una opcion donde puedes indicar el valor maximo y minimo para Output. Es decir para mi el output deberia ser tu incremento.

Yo a futuro quiero hacer un Quadcopter pero aun no me he metido a estudiar las ecuaciones.

Saludos.

Muchas gracias por tu respuesta, cambiare los valores y tendré en cuenta lo que dices para ir haciendo pruebas y descartar los posibles fallos que tiene el equilibrado del quadcopter. Como hice antes después de los cambios mostrare el resultado a ver si da resultado.

Respecto a lo del la entrada y salida del sistema, yo intruduzco como Setpoint 0, que es lo que quiero conseguir, si paso como Setpoint el valor que me da el imu nunca voy a conseguir la estabilizacion ya que el punto de estabilizado es 0, y como entrada introduzco el valor actual del imu, si hago Setpoint - Roll, es lo mismo que si introduzco roll directamente ya que por ejemplo setpoint 0 - 10º de inclinacion es lo mismo que introducir 10 en la variable input, y output me da el incremento para los motores.

En la práctica, lo más sencillo es sacarte por serie: entrada, salida, la parte proporcional, derivativa e integral.
Dibujarla en tiempo real con KST, Stamplot, etc .
De esta forma, puedes ver y entender qué pasa y cúando. Ayuda mucho para el "tuning".

Por otro lado, yo me haría mi propio código para el PID. Por ejemplo, es muy útil que tus constantes Kp,Kd e Ki sean tablas. Por ejemplo, tener una tabla que Kp depende del error, es muy útil. Para entendernos, puedes hacer que cuando el error sea muy grande, tu acción proporcional sea grande y vaya disminuyendo cuando te acercas al setpoint para evitar oscilaciones.

Podrías hacerlo mucho más completo....Por ejemplo, imagina que controlas la posición de un alerón. Podrías hacer una constante que dependa de la velocidad del avión (ya que la fuerza aerodinámica generada sobre él es al cuadrado de la velocidad), por lo que tu "control" te daría más flexibilidad para que sea mayor la cte a mayor velocidad. Es sin más un ejemplo, para ver las diferentes posibilidades que puedes tener.

También es útil tener control total de cuando la parte integral empieza a actuar. Por ejemplo, cuando el error sea menor de XX cantidad. Y fijar cual es el valor máximo al que puede llegar dicha acción.

Puedes mirar un ejemplo muy sencillo aquí => Tinkering with Electronics...: Maqueta de control PID con Arduino

Saludos,

Igor

La librería PID, que ahora ya viene con el IDE, permite cambiar los parámetros kp, ki y kd en tiempo real. Por supuesto, aparte de esto, utilizar esta librería tiene sus pros y sus contras.