Autor Tema: MPU605; Cuadricoptero  (Leído 32888 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado tsk

  • PIC18
  • ****
  • Mensajes: 258
Re: MPU605; Cuadricoptero
« Respuesta #15 en: 30 de Enero de 2014, 14:07:13 »
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.

Citar
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)

Citar
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.

Desconectado albenegra

  • PIC10
  • *
  • Mensajes: 15
Re: MPU605; Cuadricoptero
« Respuesta #16 en: 01 de Febrero de 2014, 09:11:44 »
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!


Desconectado elgarbe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2178
Re: MPU605; Cuadricoptero
« Respuesta #17 en: 01 de Febrero de 2014, 10:31:53 »
¿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.!
-
Leonardo Garberoglio

Desconectado albenegra

  • PIC10
  • *
  • Mensajes: 15
Re: MPU605; Cuadricoptero
« Respuesta #18 en: 01 de Febrero de 2014, 11:55:55 »
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 ;)

Desconectado PCCM

  • PIC16
  • ***
  • Mensajes: 109
Re: MPU605; Cuadricoptero
« Respuesta #19 en: 02 de Febrero de 2014, 01:24:53 »
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.
« Última modificación: 02 de Febrero de 2014, 01:27:57 por PCCM »

Desconectado albenegra

  • PIC10
  • *
  • Mensajes: 15
Re: MPU605; Cuadricoptero
« Respuesta #20 en: 04 de Febrero de 2014, 08:28:51 »
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
Código: [Seleccionar]
#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;

Desconectado elgarbe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2178
Re: MPU605; Cuadricoptero
« Respuesta #21 en: 05 de Febrero de 2014, 15:22:29 »
bien ahí!!!!

videito?

Sds.
-
Leonardo Garberoglio

Desconectado albenegra

  • PIC10
  • *
  • Mensajes: 15
Re: MPU605; Cuadricoptero
« Respuesta #22 en: 06 de Febrero de 2014, 12:53:20 »


Y el nuevo codigo, con otros valores para el PID y un aumento considerable del rango para los motores

Código: [Seleccionar]
#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);
  */
 
}

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: MPU605; Cuadricoptero
« Respuesta #23 en: 06 de Febrero de 2014, 22:31:09 »
muy bueno, felicidades ((:-)) ((:-))
"Nada es imposible, no si puedes imaginarlo"

Desconectado elgarbe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2178
Re: MPU605; Cuadricoptero
« Respuesta #24 en: 06 de Febrero de 2014, 23:00:23 »
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!
-
Leonardo Garberoglio

Desconectado albenegra

  • PIC10
  • *
  • Mensajes: 15
Re: MPU605; Cuadricoptero
« Respuesta #25 en: 07 de Febrero de 2014, 12:39:24 »
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

Desconectado rivale

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1707
Re: MPU605; Cuadricoptero
« Respuesta #26 en: 07 de Febrero de 2014, 12:49:53 »
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


veo que tus valores de ki y kd son muy altos en comparacion con la kp

Código: C
  1. float kp=0.6;
  2. float ki=1.60;
  3. 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
"Nada es imposible, no si puedes imaginarlo"

Desconectado elgarbe

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2178
Re: MPU605; Cuadricoptero
« Respuesta #27 en: 07 de Febrero de 2014, 13:40:22 »
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


veo que tus valores de ki y kd son muy altos en comparacion con la kp

Código: C
  1. float kp=0.6;
  2. float ki=1.60;
  3. 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!
-
Leonardo Garberoglio

Desconectado albenegra

  • PIC10
  • *
  • Mensajes: 15
Re: MPU605; Cuadricoptero
« Respuesta #28 en: 10 de Febrero de 2014, 09:38:44 »
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.
« Última modificación: 10 de Febrero de 2014, 11:50:53 por albenegra »

Desconectado juanelete

  • PIC12
  • **
  • Mensajes: 74
Re: MPU605; Cuadricoptero
« Respuesta #29 en: 31 de Marzo de 2014, 14:08:48 »
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