TODOPIC
Mecatrónica => UAV => Mensaje iniciado por: albenegra en 22 de Enero de 2014, 15:08:04
-
Muy buenas a todos, es mi primer post pero este foro me a ayudado muchisimas veces.
Estoy montando un cuadricoptero en arduino y tengo un MPU6050, necesito ayuda me veo en un tunel sin salida.
Se leer los valores, se que tengo que hacer un filtro KALMAN (duda: para los 3 ejes o solo X e Y) y despues el PID que es donde me pierdo se para que sirve pero ni se hacerle ni encuentro un codigo mas o menos apto y nose como atacar a las ESC despues.
Mis motores son de 1200Kv y las ESC hasta 25A nose si necesitais mas datos. este es nuestro bichillo :-/
El codigo KALMAN que e probado:
https://github.com/TKJElectronics/Example-Sketch-for-IMU-including-Kalman-filter/tree/master/IMU6DOF/MPU6050
Si almenos me podeis ayudar con algo en plan mira con los valores del kalman haces tal en el PID y despues lo que sea aunque sea poca cosa :undecided:
gracias de antemano :)
PD: Espero no haber incumplido ninguna norma en el post jeje
-
Hola Albenegra!
Te recomiendo que utilices el Filtro Complementario en lugar del Kalman y es muy simple de implementar http://web.mit.edu/scolton/www/filter.pdf (http://web.mit.edu/scolton/www/filter.pdf)
Hay mucha información al respecto en la web, por ejemplo http://robottini.altervista.org/kalman-filter-vs-complementary-filter (http://robottini.altervista.org/kalman-filter-vs-complementary-filter)
El filtro Kalman y el complementario sirven para "unir" las informaciones del giro y el acelerometro, para el eje yaw solo tienes el giro y por lo tanto no necesitas el filtro.
El pid es lo más difícil de implementar en un quad y sobre todo lo más difícil de de ajustar. En la web hay mucho código especialmente para Arduino, por ejemplo http://aeroquad.com/content.php (http://aeroquad.com/content.php)
Los ESC se controlan como un servo, necesitaras un pic con 4 pwm.
Saludos
Miquel
-
Lo de las ESC esta mas o menos controlado.
¿Se podria decir que la funcion del PID es como una especie de joystick autonomo?
Voy a mirar a fondo las webs que me has puesto, aunque ya e buscado por mil lados tambien jaja
muchas gracias miquel!
-
En principio te recomiendo leer el post sobre acelerómetro y el de giróscopos en este mismo sub foro. Ahí explico más o menos para que sirve cada uno, como se usa y la necesidad de fusionar los datos.
Es casi imposible que puedas desarrollar un sistema de control completo, implementarlo y que funcione. A no ser que tengas mucha experiencia.
Yo estoy en el mismo camino, pero estoy organizado de la siguiente forma:
1° Leer los datos de los sensores (acelerómetro, giróscopo y magnetómetro). En tu caso no tienes magnetómetro.
2° Probar algoritmos de fusion de datos, ya sea kalman, filtro complementario u otros.
3° Controlar 1 ESC con 1 motor, haciendo un PWM sobre la entrada del ESC.
4° Montar 1 motor con 1 hélice en un brazo que pivotee en un extremo para tratar de mantenerlo de forma horizontal.
5° Implementar un PID que reciba como entrada el ángulo del brazo deseado y en funcion de las constantes del PID, de los sensores y de la respuesta del brazo module el PWM para variar la velocidad del motor y que este gire el ángulo deseado.
6° Montar 2 motores uno en cada extremo de uno de los brazos del quad y poner un pibot en el centro.
7° Implementar el PID sobre los dos motores para equilibrar el brazo o hacerlo girar a gusto.
8° Leer los comandos del transmisor de radio control, leyendo las salidas del receptor.
9° Comandar el angulo de giro del brazo con solo 2 motores con el radio control.
10° Implementar un algoritmo tipo DCM que permita saber con exactitud la rotacion respecto de la tierra que tiene el Quad.
11° Armar el quad completo y probar todo eso.
Como veras hay como mínimo 11 pasos para mí antes de poder probar algo. En tu caso me parece que te entusiasmaste un poco y te adelantaste unos cuantos pasos... Yo voy a seguir publicando los avances de mi controladora. Tambien puedes revisar estos links:
https://sites.google.com/site/kuadricoptero/home
https://sites.google.com/site/mikuadricoptero/home
http://www.starlino.com/quadcopter_acc_gyro.html
Cualquier duda estamos por aquí para ayudate!
Saludos
-
Algo asi es lo que buscaba, mil gracias.
Debo tenerlo montado en cosa de 1 mes al menos que suba y baje crees que se puede o estoy jodido jaja por eso creo que intente ir tan de golpe, me lo tomare con mas calma y seguire los consejos que me dais
Un saludo ! :)
-
Si le dedicas muchas horas diarias y solo tiene que levantar y bajar y tienes buenos conocimientos en programación podrías obtener algo...
Ya tienes seleccionado el micro que usará? el distema de radio control? si querés publicá lo que tenes y vemos si te podemos ayudar.
Saludos!
-
Miguel y leonardo ya te dijeron todo, podria aportar a tu pregunta de que tienes razón de que el PID sería como un joyistick autónomo, la sintonización por prueba y error te simplificará mucho el tiempo.He intenta como te dicen, el filtro complementario ya que para la aplicación del quad es mas que suficiente y lo aplicarías solo para los ejes X e Y, ya que para el eje Z necesitarías otro sensor(como dice leonardo, el magnetómetro) ya que el gyro solo te puede dar errores exagerados después de varios minutos.
Saludos, y espero que sigas compartiendo tu proyecto.
-
Muchas gracias a todos enserio :)
Tenemos (somos dos es un proyecto de clase) el modulo de RF joystick y dos pulsadores mas o menos controlados con una placa de fabricacion propia que hemos echo hoy, falta cargar el bootloader y ver que funciona. Ya hemos mandado datos.
En la parte del cuadricoptero; Hoy hemos construido un balancin para probar codigo y demas giroscopio-ESC en cuanto tenga datos yo posteo ;)
Aunque contamos con la ayuda de los profesores no son expertos en este tema en concreto y lo malo, solo podemos trabajar en clase aunque son 6h.
Un saludo a todos ;-)
-
Hola, quería comentarte que he adquirido una placa de prueba con el MPU6050 asi que si necesitas que probemos algo me avisas.
Recuerda que si quieres poner el código que estas testeando siempre es bienvenido!
Saludos!
-
He probado algo sencillo con el PID y bueno no a sido algo muy ideal pero a sido un comienzo.
Cuando tengo un codigo mas o menos funcional hos lo pondre sin dudarlo porque de momento voy un poco lento jeje
Otra cosa, hasta que punto me sirve un modulo RF para mi cuadricoptero esque todo el mundo usa mandos comerciales :?
Que tal te a ido con la nueva adquisicion elgarbe
-
Este es el mejor codigo que tengo hasta ahora, los palores PID estan sin ajustar pero la verdad estabiliza 'bien'
Esta echo apartir del codigo para el filtro KALMAN que encontre jeje
Os pasare un video con este codigo en el cuadricoptero 8)
#include <PID_v1.h>
#include <Wire.h>
#include "Kalman.h" // Source: https://github.com/TKJElectronics/KalmanFilter
#include <Servo.h>
#define PINMOTOR 8 //pin conectado al ESC
#define MAXIMOPWM 160
#define MINIMOPWM 30
#define PINMOTOR2 9
Kalman kalmanX; // Create the Kalman instances
Kalman kalmanY;
float inverOutput;
int X;
/* Motor Data */
int pulsoMotor = 30;
int pulsoMotor2 = 30;
Servo myservo;
Servo myservo2;
byte recibiendoByte ;
boolean iniciado = false;
boolean carga = false;
/* PID Data */
double Setpoint, Input, Output; //Define Variables we'll be connecting to
PID myPID(&Input, &Output, &Setpoint,1,5,1, DIRECT); //Specify the links and initial tuning parameters
/* IMU Data */
int16_t accX, accY, accZ;
int16_t gyroX, gyroY, gyroZ;
double accXangle, accYangle; // Angle calculate using the accelerometer
double gyroXangle, gyroYangle; // Angle calculate using the gyro
double compAngleX, compAngleY; // Calculate the angle using a complementary filter
double kalAngleX, kalAngleY; // Calculate the angle using a Kalman filter
uint32_t timer;
uint8_t i2cData[14]; // Buffer for I2C data
void setup() {
Serial.begin(115200);
Setpoint = 180;
myservo.attach(PINMOTOR); // inicializo el ESC
myservo2.attach(PINMOTOR2);
Serial.println(" Comienzo del test"); //
Serial.println (" Pulsar 'A' para arrancar \n Cuando escuche el pitido de confirmación");
while ( iniciado==false ){
myservo.write(0);
myservo2.write(0); // Armado
recibiendoByte = Serial.read(); // Leemos el Byte recibido
if (recibiendoByte == 65 || recibiendoByte ==97) { // A o a Mayusculas o minusculas
iniciado=true;
}
}
Serial.println (" Pulsar 'C' para cargar");
while ( carga==false ){
myservo.write(30); // Armado
myservo2.write(30);
recibiendoByte = Serial.read(); // Leemos el Byte recibido
if (recibiendoByte == 67 || recibiendoByte ==99) { // A o a Mayusculas o minusculas
carga=true;
}
}
//turn the PID on
myPID.SetMode(AUTOMATIC);
// myPID.SetOutputLimits(90,179);
myPID.SetSampleTime(50);
Wire.begin();
TWBR = ((F_CPU / 400000L) - 16) / 2; // Set I2C frequency to 400kHz
i2cData[0] = 7; // Set the sample rate to 1000Hz - 8kHz/(7+1) = 1000Hz
i2cData[1] = 0x00; // Disable FSYNC and set 260 Hz Acc filtering, 256 Hz Gyro filtering, 8 KHz sampling
i2cData[2] = 0x00; // Set Gyro Full Scale Range to ±250deg/s
i2cData[3] = 0x00; // Set Accelerometer Full Scale Range to ±2g
while (i2cWrite(0x19, i2cData, 4, false)); // Write to all four registers at once
while (i2cWrite(0x6B, 0x01, true)); // PLL with X axis gyroscope reference and disable sleep mode
while (i2cRead(0x75, i2cData, 1));
if (i2cData[0] != 0x68) { // Read "WHO_AM_I" register
Serial.print(F("Error reading sensor"));
while (1);
}
delay(100); // Wait for sensor to stabilize
/* Set kalman and gyro starting angle */
while (i2cRead(0x3B, i2cData, 6));
accX = ((i2cData[0] << 8) | i2cData[1]);
accY = ((i2cData[2] << 8) | i2cData[3]);
accZ = ((i2cData[4] << 8) | i2cData[5]);
// atan2 outputs the value of -π to π (radians) - see http://en.wikipedia.org/wiki/Atan2
// We then convert it to 0 to 2π and then from radians to degrees
accYangle = (atan2(accX, accZ) + PI) * RAD_TO_DEG;
accXangle = (atan2(accY, accZ) + PI) * RAD_TO_DEG;
kalmanX.setAngle(accXangle); // Set starting angle
kalmanY.setAngle(accYangle);
gyroXangle = accXangle;
gyroYangle = accYangle;
compAngleX = accXangle;
compAngleY = accYangle;
timer = micros();
}
void loop() {
/* Update all the values */
while (i2cRead(0x3B, i2cData, 14));
accX = ((i2cData[0] << 8) | i2cData[1]);
accY = ((i2cData[2] << 8) | i2cData[3]);
accZ = ((i2cData[4] << 8) | i2cData[5]);
gyroX = ((i2cData[8] << 8) | i2cData[9]);
gyroY = ((i2cData[10] << 8) | i2cData[11]);
gyroZ = ((i2cData[12] << 8) | i2cData[13]);
// atan2 outputs the value of -π to π (radians) - see http://en.wikipedia.org/wiki/Atan2
// We then convert it to 0 to 2π and then from radians to degrees
accXangle = (atan2(accY, accZ) + PI) * RAD_TO_DEG;
accYangle = (atan2(accX, accZ) + PI) * RAD_TO_DEG;
double gyroXrate = (double)gyroX / 131.0;
double gyroYrate = -((double)gyroY / 131.0);
gyroXangle += gyroXrate * ((double)(micros() - timer) / 1000000); // Calculate gyro angle without any filter
gyroYangle += gyroYrate * ((double)(micros() - timer) / 1000000);
//gyroXangle += kalmanX.getRate()*((double)(micros()-timer)/1000000); // Calculate gyro angle using the unbiased rate
//gyroYangle += kalmanY.getRate()*((double)(micros()-timer)/1000000);
compAngleX = (0.93 * (compAngleX + (gyroXrate * (double)(micros() - timer) / 1000000))) + (0.07 * accXangle); // Calculate the angle using a Complimentary filter
compAngleY = (0.93 * (compAngleY + (gyroYrate * (double)(micros() - timer) / 1000000))) + (0.07 * accYangle);
kalAngleX = kalmanX.getAngle(accXangle, gyroXrate, (double)(micros() - timer) / 1000000); // Calculate the angle using a Kalman filter
kalAngleY = kalmanY.getAngle(accYangle, gyroYrate, (double)(micros() - timer) / 1000000);
timer = micros();
/* Print Data */
#if 0 // Set to 1 to activate
Serial.print(accX); Serial.print("\t");
Serial.print(accY); Serial.print("\t");
Serial.print(accZ); Serial.print("\t");
Serial.print(gyroX); Serial.print("\t");
Serial.print(gyroY); Serial.print("\t");
Serial.print(gyroZ); Serial.print("\t");
#endif
//Serial.print(accXangle); Serial.print("\t");
//Serial.print(gyroXangle); Serial.print("\t");
//Serial.print(compAngleX); Serial.print("\t");
Serial.print(kalAngleX); Serial.print("\t");
Serial.print("\t");
//Serial.print(accYangle); Serial.print("\t");
//Serial.print(gyroYangle); Serial.print("\t");
//Serial.print(compAngleY); Serial.print("\t");
//Serial.print(kalAngleY); Serial.print("\t");
Serial.print("\r\n");
delay(1);
// PID
Input = kalAngleX;
myPID.Compute();
pulsoMotor2= map (Output,0,255,90,94);
pulsoMotor= 184 - pulsoMotor2 ;
myservo.write(pulsoMotor);
myservo2.write(pulsoMotor2);
delay(250);
Serial.print("Velocidad del pulso-1-> ");
Serial.println (pulsoMotor);
Serial.print("PID 11111 --> ");
Serial.println (inverOutput);
Serial.print("Velocidad del pulso-2-> ");
Serial.println (pulsoMotor2);
Serial.print("PID 22222 --> ");
Serial.println (Output);
}
-
Muy bueno!
tendrás las librerías de tus #includes?
Saludos!
-
Estan incluidas el codigo compila y funciona fisicamente.
Si te refieres a que te las pase puedo pasartelas sin problema :)
-
Claro, entiendo, lo que te decía es si quieres compartirlas con nosotros :mrgreen:
Sds.
-
Las del MPU son estas:
https://github.com/TKJElectronics/Example-Sketch-for-IMU-including-Kalman-filter/tree/master/IMU6DOF/MPU6050
PID:
https://github.com/br3ttb/Arduino-PID-Library/zipball/master
Y las librerias servo.h y wire.h vienen en arduino
Saludos y espero haberte ayudado :-)
Por cierto, creo que el MPU6050 acumula errores, pero aun ni o he observado ni nada
-
Hola albanegra, tal vez te interesen algunos cursos
https://www.coursera.org/course/conrob (Control of Mobile Robots) te da muy buenos tips de lo que se tiene que hacer para pasar de la teoría a la práctica y los pasos extra que debes de tomar encuenta. Acaba de iniciar el 20 de Enero, y dura sólo 7 semanas, realmente no es mucho tiempo.
About the Course
This course investigates how to make mobile robots move in effective, safe, and predictable ways. The basic tool for achieving this is "control theory", which deals with the question of how dynamical systems, i.e., systems whose behaviors change over time, can be effectively influenced. In the course, these two domains - controls and robotics - will be interleaved and we will go from the basics of control theory, via robotic examples of increasing complexity - all the way to the research frontier. The course will focus on mobile robots as the target application and problems that will be covered include (1) how to make (teams of) wheeled ground robots avoid collisions while reaching target locations, (2) how to make aerial, quadrotor robots follow paths in the presence of severe disturbances, and (3) how to locomotive bipedal, humanoid robots.
While the main focus of this course is theory, it is important to be able to map the theory onto an actual physical platform. As such, the course will provide detailed instructions on how to build a mobile robot from scratch as an optional part of the course. In addition, an introduction into microcontrollers, mechatronics, and electronics will be given so that, by the end of the course, the controllers developed in the course can run on an actual mobile robot.
The course will also feature optional programming assignments, which will focus on implementing the controllers developed in this course for a mobile robot. A MATLAB-based simulator will be available run controllers from the programming assignments on a simulated robot or on the mobile robot built in this course. As a result of support from MathWorks, a downloadable license for MATLAB and course recommended toolboxes will be available for the duration of the MOOC.
De igual forma en edx.org el 17 de Febrero va iniciar otro: https://www.edx.org/course/ethx/ethx-amrx-autonomous-mobile-robots-1342 (Autonomous Mobile Robots)
Introduction to Autonomous Mobile Robots – basic concepts and algorithms for locomotion, perception, and intelligent navigation.
About this Course
Robots are rapidly evolving from factory workhorses, which are physically bound to their work-cells, to increasingly complex machines capable of performing challenging tasks in our daily environment. The objective of this course is to provide the basic concepts and algorithms required to develop mobile robots that act autonomously in complex environments. The main emphasis is put on mobile robot locomotion and kinematics, environment perception, probabilistic map based localization and mapping, and motion planning. This lecture closely follows the textbook Introduction to Autonomous Mobile Robots by Roland Siegwart, Illah Nourbakhsh, Davide Scaramuzza, The MIT Press, second edition 2011
Incluso te podrían ser de gran ayuda los siguientes.
https://www.udacity.com/course/cs271
https://www.udacity.com/course/cs373
Simpre es bueno contar con una variedad de puntos de vista e ideas.
-
Muchas gracias por molestarte y tu ayuda pero no me da tiempo a aprenderlo en un curso online, en un mes termino :S
He revisado el link que me paso miquel sobre aeroquad (mas de una vez XD) y sinceramente, no me e enterado de nada (Demasiado complejo desde mi punto de vista).
Elgarbe, te sirvieron de algo los links que te pase
¿Que me podeis contar sobre el DMR? Informare sobre nuevos progresos o atascos que tenga
saludos!
-
¿Que me podeis contar sobre el DMR? Informare sobre nuevos progresos o atascos que tenga
DMR?
Los link me sirvieron, pero ODIO arduino, así que no lo puedo probar. Pero la info está buena.
Viste mi post sobre la lectura del RC? ahora estoy escribiendo sobre el manejo de los motores a travez de los ESC, eso es más simple...
Sds.!
-
DMP * es del MPU6050 si no me equivoco
¿Porque lo odias? Todo un trimestre programando en ensamblador y cojer arduino es como para tontos pero la comodidad es bienvenida jaja
Verle seguro. leerlo a conciencia no, lo are ;)
-
jajaja ese "ODIO" fue con sentimiento.
El DMP del mpu6050 utiliza el filtro de Mahony para obtener la orientación del sistema en cuaterniones, sería bueno que lo pruebes ya que te ahorrarías muchas lineas de código y tiempo en tu microcontrolador. ya que del sensor solo lees directamente los cuaterniones osea todo el algoritmo procesado.
La ventaja como dije antes es el ahorro en espacio y tiempo en el microcontrolador, la desventaja es que no puedes modificar el filtro, por lo tanto no puedes configurarlo para que lo fusione con el magnetómetro que te dan como opción para que lo configures como dispositivo adicional.(a menos que entiendas el significado de esas matrices de memoria y actualización)
Por ejemplo aqui hay un codigo en arduino:
https://github.com/bzerk/MPU6050_DMP_6_axis_demo_/blob/master/MPU6050_DMP_6_axis_demo_.pde
Saludos.
-
Buenas jefes !
Si tengo tiempo probare el DMP no lo dudes.
He mejorado mi codigo y ahora estabiliza incluso con el cable del arduino conectado en el medio, aunque no es 100% estable.
Hay un valor que no acabo de tener claro; SetSampleTime(); Le he variado entre 500 y 5 notando la diferencia pero nose si entre 5 y 50 sera muy significativo.
Determina la frecuencia con la que evalúa el algoritmo PID. El valor predeterminado es 200 ms.
El codigo de lo que e echo
#include <PID_v1.h>
#include <Wire.h>
#include "Kalman.h" // Source: https://github.com/TKJElectronics/KalmanFilter
#include <Servo.h>
#define PINMOTOR 8 //pin conectado al ESC, en este caso CH_5 en ARDUPILOT corresponde al pin 8
#define MAXIMOPWM 160 // Son grados Podia llegar hasta 180,paramas seguridad lo dejo bajo
#define MINIMOPWM 30 // por si acaso empezar con un valor inferior, mi motor no arranca hasta 65
#define PINMOTOR2 9
Kalman kalmanX; // Create the Kalman instances
Kalman kalmanY;
float inverOutput;
boolean e=false;
float kp=0.9;
float ki=3.6;
float kd=0.2;
/* Motor Data */
int pulsoMotor = 30;
int pulsoMotor2 = 30;
Servo myservo; // creamos el motor como elemento en la libreria
Servo myservo2;
byte recibiendoByte ;
boolean iniciado = false;
boolean carga = false;
/* PID Data */
double Setpoint, Input, Output; //Define Variables we'll be connecting to
PID myPID(&Input, &Output, &Setpoint,kp,ki,kd, DIRECT); //Specify the links and initial tuning parameters
/* IMU Data */
int16_t accX, accY, accZ;
int16_t gyroX, gyroY, gyroZ;
double accXangle, accYangle; // Angle calculate using the accelerometer
double temp; // Temperature
double gyroXangle, gyroYangle; // Angle calculate using the gyro
double compAngleX, compAngleY; // Calculate the angle using a complementary filter
double kalAngleX, kalAngleY; // Calculate the angle using a Kalman filter
uint32_t timer;
uint8_t i2cData[14]; // Buffer for I2C data
void setup() {
Serial.begin(115200);
Setpoint = 180;
myservo.attach(PINMOTOR); // inicializo el ESC en el pin determinado
myservo2.attach(PINMOTOR2);
Serial.println(" Comienzo del test"); //
Serial.println (" Pulsar 'A' para arrancar \n Cuando escuche el pitido de confirmación");
while ( iniciado==false ){
myservo.write(0);
myservo2.write(0); // Armado
recibiendoByte = Serial.read(); // Leemos el Byte recibido
if (recibiendoByte == 65 || recibiendoByte ==97) { // A o a Mayusculas o minusculas
iniciado=true;
}
}
Serial.println (" Pulsar 'C' para cargar");
while ( carga==false ){
myservo.write(30); // Armado
myservo2.write(30);
recibiendoByte = Serial.read(); // Leemos el Byte recibido
if (recibiendoByte == 67 || recibiendoByte ==99) { // C o c Mayusculas o minusculas
carga=true;
}
}
//turn the PID on
myPID.SetMode(AUTOMATIC);
// myPID.SetOutputLimits(90,179);
myPID.SetSampleTime(10);
Wire.begin();
TWBR = ((F_CPU / 400000L) - 16) / 2; // Set I2C frequency to 400kHz
i2cData[0] = 7; // Set the sample rate to 1000Hz - 8kHz/(7+1) = 1000Hz
i2cData[1] = 0x00; // Disable FSYNC and set 260 Hz Acc filtering, 256 Hz Gyro filtering, 8 KHz sampling
i2cData[2] = 0x00; // Set Gyro Full Scale Range to ±250deg/s
i2cData[3] = 0x00; // Set Accelerometer Full Scale Range to ±2g
while (i2cWrite(0x19, i2cData, 4, false)); // Write to all four registers at once
while (i2cWrite(0x6B, 0x01, true)); // PLL with X axis gyroscope reference and disable sleep mode
while (i2cRead(0x75, i2cData, 1));
if (i2cData[0] != 0x68) { // Read "WHO_AM_I" register
Serial.print(F("Error reading sensor"));
while (1);
}
delay(100); // Wait for sensor to stabilize
/* Set kalman and gyro starting angle */
while (i2cRead(0x3B, i2cData, 6));
accX = ((i2cData[0] << 8) | i2cData[1]);
accY = ((i2cData[2] << 8) | i2cData[3]);
accZ = ((i2cData[4] << 8) | i2cData[5]);
// atan2 outputs the value of -π to π (radians) - see http://en.wikipedia.org/wiki/Atan2
// We then convert it to 0 to 2π and then from radians to degrees
accYangle = (atan2(accX, accZ) + PI) * RAD_TO_DEG;
accXangle = (atan2(accY, accZ) + PI) * RAD_TO_DEG;
kalmanX.setAngle(accXangle); // Set starting angle
kalmanY.setAngle(accYangle);
gyroXangle = accXangle;
gyroYangle = accYangle;
compAngleX = accXangle;
compAngleY = accYangle;
timer = micros();
}
void loop() {
/* Update all the values */
while (i2cRead(0x3B, i2cData, 14));
accX = ((i2cData[0] << 8) | i2cData[1]);
accY = ((i2cData[2] << 8) | i2cData[3]);
accZ = ((i2cData[4] << 8) | i2cData[5]);
gyroX = ((i2cData[8] << 8) | i2cData[9]);
gyroY = ((i2cData[10] << 8) | i2cData[11]);
gyroZ = ((i2cData[12] << 8) | i2cData[13]);
// atan2 outputs the value of -π to π (radians) - see http://en.wikipedia.org/wiki/Atan2
// We then convert it to 0 to 2π and then from radians to degrees
accXangle = (atan2(accY, accZ) + PI) * RAD_TO_DEG;
accYangle = (atan2(accX, accZ) + PI) * RAD_TO_DEG;
double gyroXrate = (double)gyroX / 131.0;
double gyroYrate = -((double)gyroY / 131.0);
gyroXangle += gyroXrate * ((double)(micros() - timer) / 1000000); // Calculate gyro angle without any filter
gyroYangle += gyroYrate * ((double)(micros() - timer) / 1000000);
//gyroXangle += kalmanX.getRate()*((double)(micros()-timer)/1000000); // Calculate gyro angle using the unbiased rate
//gyroYangle += kalmanY.getRate()*((double)(micros()-timer)/1000000);
compAngleX = (0.93 * (compAngleX + (gyroXrate * (double)(micros() - timer) / 1000000))) + (0.07 * accXangle); // Calculate the angle using a Complimentary filter
compAngleY = (0.93 * (compAngleY + (gyroYrate * (double)(micros() - timer) / 1000000))) + (0.07 * accYangle);
kalAngleX = kalmanX.getAngle(accXangle, gyroXrate, (double)(micros() - timer) / 1000000); // Calculate the angle using a Kalman filter
kalAngleY = kalmanY.getAngle(accYangle, gyroYrate, (double)(micros() - timer) / 1000000);
timer = micros();
/* Print Data */
#if 0 // Set to 1 to activate
Serial.print(accX); Serial.print("\t");
Serial.print(accY); Serial.print("\t");
Serial.print(accZ); Serial.print("\t");
Serial.print(gyroX); Serial.print("\t");
Serial.print(gyroY); Serial.print("\t");
Serial.print(gyroZ); Serial.print("\t");
#endif
//Serial.print(accXangle); Serial.print("\t");
//Serial.print(gyroXangle); Serial.print("\t");
//Serial.print(compAngleX); Serial.print("\t");
//Serial.print(kalAngleX); Serial.print("\t");
//Serial.print("\t");
//Serial.print(accYangle); Serial.print("\t");
//Serial.print(gyroYangle); Serial.print("\t");
//Serial.print(compAngleY); Serial.print("\t");
//Serial.print(kalAngleY); Serial.print("\t");
//Serial.print("\r\n");
//modificar valores
recibiendoByte = Serial.read();
if(recibiendoByte == 112){ // p minuscula
kp= kp - 0.1;
Serial.print (" kp - ");
Serial.println (kp);
}
if(recibiendoByte == 80){ // P mayuscula
kp = kp + 0.1;
Serial.print (" kp + ");
Serial.println (kp);
}
if(recibiendoByte == 105){ // i minuscula
ki = ki - 0.1;
Serial.print (" ki - ");
Serial.println (ki);
}
if(recibiendoByte == 73){ // I mayuscula
ki = ki + 0.1;
Serial.print (" ki + ");
Serial.println (ki);
}
if(recibiendoByte == 100){ // d minuscula
kd = kd - 0.1;
Serial.print (" kd - ");
Serial.println (kd);
}
if(recibiendoByte == 68){ // D mayuscula
kd = kd + 0.1;
Serial.print (" kd + ");
Serial.println (kd);
}
//codigo parada de motores
if(recibiendoByte == 115){ // s -> parada
Serial.print ("entrado");
myservo.write(30);
myservo2.write(30);
e = false;
while ( e==false ){
recibiendoByte = Serial.read(); // Leemos el Byte recibido
if (recibiendoByte == 67 || recibiendoByte ==99) { // C o c Mayusculas o minusculas
e=true;
}
}
}
// PID
Input = kalAngleX;
myPID.Compute();
pulsoMotor2= map (Output,0,255,94,98);
pulsoMotor= 192 - pulsoMotor2 ;
myservo.write(pulsoMotor);
myservo2.write(pulsoMotor2);
/*delay(250);
Serial.print("Velocidad del pulso-1-> ");
Serial.println (pulsoMotor);
Serial.print("PID 11111 --> ");
Serial.println (inverOutput);
Serial.print("Velocidad del pulso-2-> ");
Serial.println (pulsoMotor2);
Serial.print("PID 22222 --> ");
Serial.println (Output);
*/
}
de momento han quedado asi los valores
float kp=0.9;
float ki=3.6;
float kd=0.2;
-
bien ahí!!!!
videito?
Sds.
-
Y el nuevo codigo, con otros valores para el PID y un aumento considerable del rango para los motores
#include <PID_v1.h>
#include <Wire.h>
#include "Kalman.h" // Source: https://github.com/TKJElectronics/KalmanFilter
#include <Servo.h>
#define PINMOTOR 8 //pin conectado al ESC, en este caso CH_5 en ARDUPILOT corresponde al pin 8
#define MAXIMOPWM 160 // Son grados Podia llegar hasta 180,paramas seguridad lo dejo bajo
#define MINIMOPWM 30 // por si acaso empezar con un valor inferior, mi motor no arranca hasta 65
#define PINMOTOR2 9
Kalman kalmanX; // Create the Kalman instances
Kalman kalmanY;
float inverOutput;
boolean e=false;
float kp=0.6;
float ki=1.60;
float kd=1;
/* Motor Data */
int pulsoMotor = 30;
int pulsoMotor2 = 30;
Servo myservo; // creamos el motor como elemento en la libreria
Servo myservo2;
byte recibiendoByte ;
boolean iniciado = false;
boolean carga = false;
/* PID Data */
double Setpoint, Input, Output; //Define Variables we'll be connecting to
PID myPID(&Input, &Output, &Setpoint,kp,ki,kd, DIRECT); //Specify the links and initial tuning parameters
/* IMU Data */
int16_t accX, accY, accZ;
int16_t gyroX, gyroY, gyroZ;
double accXangle, accYangle; // Angle calculate using the accelerometer
double temp; // Temperature
double gyroXangle, gyroYangle; // Angle calculate using the gyro
double compAngleX, compAngleY; // Calculate the angle using a complementary filter
double kalAngleX, kalAngleY; // Calculate the angle using a Kalman filter
uint32_t timer;
uint8_t i2cData[14]; // Buffer for I2C data
void setup() {
Serial.begin(115200);
Setpoint = 180;
myservo.attach(PINMOTOR); // inicializo el ESC en el pin determinado
myservo2.attach(PINMOTOR2);
Serial.println(" Comienzo del test"); //
Serial.println (" Pulsar 'A' para arrancar \n Cuando escuche el pitido de confirmación");
while ( iniciado==false ){
myservo.write(0);
myservo2.write(0); // Armado
recibiendoByte = Serial.read(); // Leemos el Byte recibido
if (recibiendoByte == 65 || recibiendoByte ==97) { // A o a Mayusculas o minusculas
iniciado=true;
}
}
Serial.println (" Pulsar 'C' para cargar");
while ( carga==false ){
myservo.write(30); // Armado
myservo2.write(30);
recibiendoByte = Serial.read(); // Leemos el Byte recibido
if (recibiendoByte == 67 || recibiendoByte ==99) { // C o c Mayusculas o minusculas
carga=true;
}
}
//turn the PID on
myPID.SetMode(AUTOMATIC);
// myPID.SetOutputLimits(90,179);
myPID.SetSampleTime(20);
Wire.begin();
TWBR = ((F_CPU / 400000L) - 16) / 2; // Set I2C frequency to 400kHz
i2cData[0] = 7; // Set the sample rate to 1000Hz - 8kHz/(7+1) = 1000Hz
i2cData[1] = 0x00; // Disable FSYNC and set 260 Hz Acc filtering, 256 Hz Gyro filtering, 8 KHz sampling
i2cData[2] = 0x00; // Set Gyro Full Scale Range to ±250deg/s
i2cData[3] = 0x00; // Set Accelerometer Full Scale Range to ±2g
while (i2cWrite(0x19, i2cData, 4, false)); // Write to all four registers at once
while (i2cWrite(0x6B, 0x01, true)); // PLL with X axis gyroscope reference and disable sleep mode
while (i2cRead(0x75, i2cData, 1));
if (i2cData[0] != 0x68) { // Read "WHO_AM_I" register
Serial.print(F("Error reading sensor"));
while (1);
}
delay(100); // Wait for sensor to stabilize
/* Set kalman and gyro starting angle */
while (i2cRead(0x3B, i2cData, 6));
accX = ((i2cData[0] << 8) | i2cData[1]);
accY = ((i2cData[2] << 8) | i2cData[3]);
accZ = ((i2cData[4] << 8) | i2cData[5]);
// atan2 outputs the value of -π to π (radians) - see http://en.wikipedia.org/wiki/Atan2
// We then convert it to 0 to 2π and then from radians to degrees
accYangle = (atan2(accX, accZ) + PI) * RAD_TO_DEG;
accXangle = (atan2(accY, accZ) + PI) * RAD_TO_DEG;
kalmanX.setAngle(accXangle); // Set starting angle
kalmanY.setAngle(accYangle);
gyroXangle = accXangle;
gyroYangle = accYangle;
compAngleX = accXangle;
compAngleY = accYangle;
timer = micros();
}
void loop() {
/* Update all the values */
while (i2cRead(0x3B, i2cData, 14));
accX = ((i2cData[0] << 8) | i2cData[1]);
accY = ((i2cData[2] << 8) | i2cData[3]);
accZ = ((i2cData[4] << 8) | i2cData[5]);
gyroX = ((i2cData[8] << 8) | i2cData[9]);
gyroY = ((i2cData[10] << 8) | i2cData[11]);
gyroZ = ((i2cData[12] << 8) | i2cData[13]);
// atan2 outputs the value of -π to π (radians) - see http://en.wikipedia.org/wiki/Atan2
// We then convert it to 0 to 2π and then from radians to degrees
accXangle = (atan2(accY, accZ) + PI) * RAD_TO_DEG;
accYangle = (atan2(accX, accZ) + PI) * RAD_TO_DEG;
double gyroXrate = (double)gyroX / 131.0;
double gyroYrate = -((double)gyroY / 131.0);
gyroXangle += gyroXrate * ((double)(micros() - timer) / 1000000); // Calculate gyro angle without any filter
gyroYangle += gyroYrate * ((double)(micros() - timer) / 1000000);
//gyroXangle += kalmanX.getRate()*((double)(micros()-timer)/1000000); // Calculate gyro angle using the unbiased rate
//gyroYangle += kalmanY.getRate()*((double)(micros()-timer)/1000000);
compAngleX = (0.93 * (compAngleX + (gyroXrate * (double)(micros() - timer) / 1000000))) + (0.07 * accXangle); // Calculate the angle using a Complimentary filter
compAngleY = (0.93 * (compAngleY + (gyroYrate * (double)(micros() - timer) / 1000000))) + (0.07 * accYangle);
kalAngleX = kalmanX.getAngle(accXangle, gyroXrate, (double)(micros() - timer) / 1000000); // Calculate the angle using a Kalman filter
kalAngleY = kalmanY.getAngle(accYangle, gyroYrate, (double)(micros() - timer) / 1000000);
timer = micros();
/* Print Data */
#if 0 // Set to 1 to activate
Serial.print(accX); Serial.print("\t");
Serial.print(accY); Serial.print("\t");
Serial.print(accZ); Serial.print("\t");
Serial.print(gyroX); Serial.print("\t");
Serial.print(gyroY); Serial.print("\t");
Serial.print(gyroZ); Serial.print("\t");
#endif
//Serial.print(accXangle); Serial.print("\t");
//Serial.print(gyroXangle); Serial.print("\t");
//Serial.print(compAngleX); Serial.print("\t");
//Serial.println(kalAngleX); Serial.print("\t");
//Serial.print("\t");
//Serial.print(accYangle); Serial.print("\t");
//Serial.print(gyroYangle); Serial.print("\t");
//Serial.print(compAngleY); Serial.print("\t");
//Serial.print(kalAngleY); Serial.print("\t");
//Serial.print("\r\n");
//modificar valores
recibiendoByte = Serial.read();
if(recibiendoByte == 112){ // p minuscula
kp= kp - 0.1;
Serial.print (" kp - ");
Serial.println (kp);
}
if(recibiendoByte == 80){ // P mayuscula
kp = kp + 0.1;
Serial.print (" kp + ");
Serial.println (kp);
}
if(recibiendoByte == 105){ // i minuscula
ki = ki - 0.1;
Serial.print (" ki - ");
Serial.println (ki);
}
if(recibiendoByte == 73){ // I mayuscula
ki = ki + 0.1;
Serial.print (" ki + ");
Serial.println (ki);
}
if(recibiendoByte == 100){ // d minuscula
kd = kd - 0.1;
Serial.print (" kd - ");
Serial.println (kd);
}
if(recibiendoByte == 68){ // D mayuscula
kd = kd + 0.1;
Serial.print (" kd + ");
Serial.println (kd);
}
//codigo parada de motores
if(recibiendoByte == 115){ // s -> parada
Serial.print ("entrado");
myservo.write(30);
myservo2.write(30);
e = false;
while ( e==false ){
recibiendoByte = Serial.read(); // Leemos el Byte recibido
if (recibiendoByte == 67 || recibiendoByte ==99) { // C o c Mayusculas o minusculas
e=true;
}
}
}
// PID
// if ((kalAngleX > 178 ) && (kalAngleX < 182)) kalAngleX = 180; //Aumentar amplitud del setpoint
Input = kalAngleX;
myPID.Compute();
pulsoMotor2= map (Output,0,255,80,100);
pulsoMotor= 180 - pulsoMotor2 ;
myservo.write(pulsoMotor);
myservo2.write(pulsoMotor2);
/*delay(250);
Serial.print("Velocidad del pulso-1-> ");
Serial.println (pulsoMotor);
Serial.print("PID 11111 --> ");
Serial.println (inverOutput);
Serial.print("Velocidad del pulso-2-> ");
Serial.println (pulsoMotor2);
Serial.print("PID 22222 --> ");
Serial.println (Output);
*/
}
-
muy bueno, felicidades ((:-)) ((:-))
-
Excelente!
A eso me refería cuando te recomendaba probar en una plataforma primero. Incluso hay 2 motores que deberías apagar.
Para probar tus filtros y algoritmos lo que tendrías que hacer es poner como Set Point de tu PID 0° en el eje en que se puede mover. Tu algoritmo equilibrará y ese brazo del quad quedará horizontal.
Luego lo que podrías hacer es con el algoritmo funcionando colgar una pesita de unos 50-100 grs debajo de un motor para producir una "perturbacion". Tu algoritmo debería corregir esta situacion lo más rápido posible...
Muy buen abanse y esperamos más pruabas!
Saludos!
-
gracias jeje :)
Los motores verdes estan parados, en el video se esta aplicando solo al eje X.
¿Que parametro deberia variar para que corrija mas rapido? porque si le doy un golpe brusco estabiliza pero tarda un poco.
Y al arrancar da un tumbo fuerte, alguna idea o consejo :S
-
tal vez esta hoja de aplicación de microchip te sirva, ponen las instrucciones para calibrar un controlador PID para un péndulo invertido(que es parecido a el cuadracóptero)
http://ww1.microchip.com/downloads/en/AppNotes/00964A.pdf (http://ww1.microchip.com/downloads/en/AppNotes/00964A.pdf)
veo que tus valores de ki y kd son muy altos en comparacion con la kp
float kp=0.6;
float ki=1.60;
float kd=1;
te aconsejo que primero hagas el control únicamente con la kp, el sistema se vuelve estable con esto aunque puede tener un defasamiento, y posteriormente incrementes la Ki, esto hará que la respuesta de tu sistema llegue al valor que deseas pero te alenta la respuesta y finalmente incrementes la Kd, esta debe ser un valor pequeño(como una decima parte de kp), ya que aunque incrementa la velocidad de respuesta es muy sensible a ruido, en tu prueba no tienes muchas perturbaciones, pero cuando lo dejes libre veras que afectarán tu sistema
-
tal vez esta hoja de aplicación de microchip te sirva, ponen las instrucciones para calibrar un controlador PID para un péndulo invertido(que es parecido a el cuadracóptero)
http://ww1.microchip.com/downloads/en/AppNotes/00964A.pdf (http://ww1.microchip.com/downloads/en/AppNotes/00964A.pdf)
veo que tus valores de ki y kd son muy altos en comparacion con la kp
float kp=0.6;
float ki=1.60;
float kd=1;
te aconsejo que primero hagas el control únicamente con la kp, el sistema se vuelve estable con esto aunque puede tener un defasamiento, y posteriormente incrementes la Ki, esto hará que la respuesta de tu sistema llegue al valor que deseas pero te alenta la respuesta y finalmente incrementes la Kd, esta debe ser un valor pequeño(como una decima parte de kp), ya que aunque incrementa la velocidad de respuesta es muy sensible a ruido, en tu prueba no tienes muchas perturbaciones, pero cuando lo dejes libre veras que afectarán tu sistema
Totalmente de acuerdo, los valores que tienes puestos como constantes del PID son medios raros...
Te recomiendo leer un poquito sobre PID, sin profundizar demasiado, simplemente ver que corrige cada parámetro.
Como dice rivale, primer debes comenzar solo con Kp. Jugá un rato largo con diversos valores y pruebas. Es muy probable que se muy dificil conseguir que arrancando de 0 (con un brazo en el piso y el otro arriba) estabilice rápido y con los mismos parámetros funcione para corregir perturbaciones...
Una vez que el valor de Kp te gusta (ten en cuenta que solo con Kp no podrás conseguir que el brazo llegue a la posicion deseada, siempre habrá un error) empiezas a subir Ki. Esta es la ganancia integral del error. O sea que a medida que pasa el tiempo hay un termino en el PID que va integrando el error y contribuye con la salida. Lo que conseguiras con Ki es hacer que en el tiempo el sistema llegue al valor deseado. Kd podrías dejarlo en 0 sin problemas. Es mucho más dificil conseguir un valor que sirva ya que el efecto se ve en el transitorio, es decir que con Kd puedes evitar movimientos muy bruscos...
Ahora estoy por poner un post con la estabilizacion de un braso del quad con solo un motor... estoy trabajando en eso ahora... pero usetdes van muy bien!!! como andan de tiempo?
Saludos!
-
Buenas !
Hemos tenido problemas al incluir el codigo de RF, librerias y lio al juntar todo, pero ya esta solucionado.
Mañana recalibraremos el PID me fio bastante de vosotros y si no os inspiran confianza los valores que tengo sera por algo :P
He leido bastante, entre otras cosas esto http://flitetest.com/articles/p-i-and-sometimes-d-gains-in-a-nutshell
pero tu explicacion me a servido bastante; De tiempo nos quedan coosa de tres semanas.
EDITO: ¿Con que amplitud los motores trabajan mas agusto? Yo les doy 20º de rango nose si es suficiente.
-
Hola a tod@s
Hace tiempo me ronda por la cabeza hacer un aeroquad, no tanto por tener uno, que los hay muy baratos, sino por el reto que supone programar toda esa electrónica...,
bueno pues esta tarde casi sin pensarlo me ha dado un calenton y he comprado esto http://es.aliexpress.com/item/GY-87-10DOF-Module-MPU6050-HMC5883L-BMP180-Sensor-Free-Shipping-Dropshipping/915129505.html
la verdad es que por 8,5€ no he podido resistirme :lol:
Se trata de un modulo GY-87, que se compone de MPU6050 (gyroscopo y acelerómetro), HMC5883 (Compas magnético) y un BMP-180 (Barómetro). y comunicación mediante 12C
El problema es que ahora no encuentro el datasheet de este modulo, solo encuentro los componentes....
alguien podría decirme algún link o alguna información sobre este modulo. Gracias de antemano. :mrgreen:
Nota: No soy un ingenuo, se que es bastante complicado.
Tengo cierta experiencia programando PICS, leyendo tramas de Recepetores RC, manejando servos (o ESC) mediante PWM, leyendo dispositivos I2C, y he leído bastante sobre control PDI, filtros...etc
-
No es necesario que tengas el esquematico del modulo,ya que esas patas corresponden a los sensores , para su funcionamiento basico Vcc_in=3.3v, Fsync=0v, INTA es indiferente si lo conectas o no ya que puedes saber si se puede muestrear o no leyendo un registro al igual que el DRDY.
-
Hola, soy nuevo en el foro, soy estudiante de 5º semestre de mecatronica.
Ya, presentado quería comentarles que el semestre pasado para mi proyecto quise hacer un quadcopter (intento fallido), para lo que creía era suficiente mi experiencia BÁSICA en Arduino, y nula en control.
Leyendo el foro veo la razón de mi fracaso, pero quisiera aprender de estas cosas, aunque el profesor comprendió que no tenía conocimiento necesario y fue un poco laxo con esto, quisiera terminar el proyecto de manera independiente, para ello veo que necesito comprender PID y KALMAN (o algún otro filtro como DMP, el cual me habían recomendado). Por esto les pido ayuda a ustedes, de ser posible links de sitios donde pueda aprender, y no simplemente subir algo que encuentre en internet
Gracias :)
-
Hola!
Aqui tienes unos enlaces para empezar:
http://www.starlino.com/dcm_tutorial.html (http://www.starlino.com/dcm_tutorial.html)
http://bilgin.esme.org/BitsBytes/KalmanFilterforDummies.aspx (http://bilgin.esme.org/BitsBytes/KalmanFilterforDummies.aspx)
https://github.com/TKJElectronics/KalmanFilter (https://github.com/TKJElectronics/KalmanFilter)
https://github.com/TKJElectronics/Example-Sketch-for-IMU-including-Kalman-filter (https://github.com/TKJElectronics/Example-Sketch-for-IMU-including-Kalman-filter)
http://robottini.altervista.org/kalman-filter-vs-complementary-filter (http://robottini.altervista.org/kalman-filter-vs-complementary-filter)
https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050 (https://github.com/jrowberg/i2cdevlib/tree/master/Arduino/MPU6050)
http://www.x-firm.com/?page_id=193 (http://www.x-firm.com/?page_id=193)
Ya tienes tarea para unos dias!!!
Saludos desde Barcelona,
Miquel
-
Gracias, a estudiar se dijo, esperó estar pronto por acá mostrándoles o pidiéndoles ayuda :-) con uno que otro proyecto
-
puedes darte una vuelta por este hilo:
http://www.todopic.com.ar/foros/index.php?topic=12748.0 (http://www.todopic.com.ar/foros/index.php?topic=12748.0)
-
Saludos
Estoy trabajando en la lectura de una IMU MPU6050 en un cuadricoptero pegado a un tripode para que este no vuele y solo se pueda inclinar en los angulos X y Y
mi problema es que la vibración de los motores está afectando la medición del angulo
En estos momentos estoy usando la escala del gyroscopio y accelerometro en 500 */s y 4g que es la que menos variación me presenta. Ademas de usar un filtro complementario con relacion 0.98 para el gyroscopio y 0.2 para el acelerometro
otro problema es que es demasiado lento, es decir, cuando giro el cuadricoptero de 0 grados a un angulo de 15 grados por ejemplo, se demora casi 5-7 segundos en ir de 0 a 15 grados la grafica que estoy visualizando via RTDX
¿que escala del gyroscopio y acelerometro me recomiendan para que no le afecten tanto las vibraciones de los motores?
¿que me recomiendan para que la medición sea lo mas cercano al tiempo real?
¿podria dar mejores resultados si utilizo otro filtro como el Kalman, y en ese caso me podrian ayudar con eso?
PD: estoy usando simulink, con la libreria embedded coder y una targeta c2000 de texas instruments
-
Saludos
Estoy trabajando en la lectura de una IMU MPU6050 en un cuadricoptero pegado a un tripode para que este no vuele y solo se pueda inclinar en los angulos X y Y
mi problema es que la vibración de los motores está afectando la medición del angulo
En estos momentos estoy usando la escala del gyroscopio y accelerometro en 500 */s y 4g que es la que menos variación me presenta. Ademas de usar un filtro complementario con relacion 0.98 para el gyroscopio y 0.2 para el acelerometro
puede ser que sea .98 y .02?
otro problema es que es demasiado lento, es decir, cuando giro el cuadricoptero de 0 grados a un angulo de 15 grados por ejemplo, se demora casi 5-7 segundos en ir de 0 a 15 grados la grafica que estoy visualizando via RTDX
podes asegurar que no hay retrasos en la comunicacion y que ese es el tiempo que realmente le toma obtener el ángulo?.
¿que escala del gyroscopio y acelerometro me recomiendan para que no le afecten tanto las vibraciones de los motores?
¿que me recomiendan para que la medición sea lo mas cercano al tiempo real?
es una eleccion de compromiso entre filtrado y delay. Más filtro -> menos ruido pero más delay. Y a la inversa.
De todos modos me parece que si la relacion es .98 a .02 es muy poco acelerómetro, no probaste con algo como .9 a .1 o .8 a .2?
¿podria dar mejores resultados si utilizo otro filtro como el Kalman, y en ese caso me podrian ayudar con eso?
Si mejorará, pero yo no te puedo ayudar por que no lo he implementado nunca.
PD: estoy usando simulink, con la libreria embedded coder y una targeta c2000 de texas instruments
muy buena alternativa para el control. Podrías mostras lo que has hecho?
Saludos!
-
Saludos, solucione mi problema de ruido causado por la vibración de los motores
la MPU-6050 cuenta con un filtro pasa-bajas que se activa modificando el valor del registro 26 (26 en decimal)
redujo el ruido en un 95% masomenos... con eso fue mas facil implementar el filtro kalman en simulink para eliminar ese ruido pequeño que quedó, en simulink es muy facil, solo pones el bloque, ajustas Q y R en valores pequeños y funciona.
-
Hola muy buenas noches amigo es muy destacable tu estabilizacion en el eje x disculpa tengo un problema en el codigo I2c write me dice que no la he declarado tienes alguna idea que puede ser? te agradeceria mucho cualquier informacion
-
el filtro kalman de TKJ es bueno el unico problema que tengo es en el yaw no me filtra bien tengo un error de +/- 2º me gustaria saber si con el filtro complementario se tiene mejores resultados.