Autor Tema: Vehículo autobalanceado tipo pendulo invertido  (Leído 22687 veces)

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

Desconectado alevq

  • PIC10
  • *
  • Mensajes: 7
Re: Vehículo autobalanceado tipo pendulo invertido
« Respuesta #15 en: 02 de Julio de 2013, 17:06:06 »
Antes que nada quiero felicitarte por la tarea emprendida se ve muy bien el proyecto seguiré el desarrollo del mismo.

Desconectado cristian_elect

  • PIC18
  • ****
  • Mensajes: 453
Re: Vehículo autobalanceado tipo pendulo invertido
« Respuesta #16 en: 02 de Julio de 2013, 19:12:58 »
Los japoneses siguen sacando nuevos producto el año pasado vi Honda U3-X.

Desconectado gab163

  • PIC16
  • ***
  • Mensajes: 111
Re: Vehículo autobalanceado tipo pendulo invertido
« Respuesta #17 en: 18 de Julio de 2013, 21:26:13 »
Bueno siguiendo con el proyecto acá les dejo unas imágenes de la tarjeta de control, se basa en un PIC16f1939 corriendo a 32MHz que se encarga de monitorear los sensores: gyro, acelerometro y encoders. Un dspic30f3010 a 30MIPS el cual estará leyendo los datos del 1939 por medio de la UART  con los cuales calculara la ley de control y la sacara por medio del modulo de control de motores el cual lo configure a un periodo 5Khz el cual sale por medio de optoacopladores hacia los drivers OSMC les dejo el primer prototipo estare probando todo en conjunto antes de montarle los drivers y los motores

Desconectado AKENAFAB

  • Colaborador
  • DsPIC30
  • *****
  • Mensajes: 3227
Re: Vehículo autobalanceado tipo pendulo invertido
« Respuesta #18 en: 19 de Julio de 2013, 00:20:46 »
Muy padre tu proyecto.

El pcb se ve genial!! 8)

Felicitaciones!! y esperamos mas detalles !! ((:-)) ((:-)) ((:-))

Desconectado willynovi

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 546
Re: Vehículo autobalanceado tipo pendulo invertido
« Respuesta #19 en: 19 de Julio de 2013, 06:50:49 »
Los japoneses siguen sacando nuevos producto el año pasado vi Honda U3-X.
Estas dos chicas me hicieron acordar a la pelicula Wall-e, si se populariza este aparatito o similares, en poco tiempo van a tener que hacerlos un poco mas resistentes para soportar los excesos de pesos de las personas.

Bueno siguiendo con el proyecto acá les dejo unas imágenes de la tarjeta de control, se basa en un PIC16f1939 corriendo a 32MHz que se encarga de monitorear los sensores: gyro, acelerometro y encoders. Un dspic30f3010 a 30MIPS el cual estará leyendo los datos del 1939 por medio de la UART  con los cuales calculara la ley de control y la sacara por medio del modulo de control de motores el cual lo configure a un periodo 5Khz el cual sale por medio de optoacopladores hacia los drivers OSMC les dejo el primer prototipo estare probando todo en conjunto antes de montarle los drivers y los motores

Muy linda la placa, segui para adelante con el proyecto que es muy desafiante  ;-)
Intento enseñarte a pescar, si solo quieres pescados, espera que un pescador te regale los suyos.

Desconectado gab163

  • PIC16
  • ***
  • Mensajes: 111
Re: Vehículo autobalanceado tipo pendulo invertido
« Respuesta #20 en: 30 de Julio de 2013, 18:11:08 »
Siguiendo con este cacharrito les comento que ya tengo lectura del ángulo usando el acelerometro en conjunto del gyro los sensores LSM303DLHC y L3GD20 respectivamente, realize una libreria para hacer las lecturas del eje que en mi caso como acomode la pcb es el eje Y les dejo la libreria por si alguien se anima a usarla y si se puede mejorarla pues sera mejor, el codigo es para CCS yo estoy usando el PIC16f1939 pero se puede ajustar a cualquiera. Las resistencias pull-up   para el bus de i2c  las tengo de 4.7Kohms.
Para usarla unicamente se llama a la función leer_angulo(); dando como argumento el tiempo de muestreo en ms
Código: [Seleccionar]
void main(){
float angulo;
int ts=20;
gyro_init();                              //inicialización de gyro
accel_init();                             //inicialización de acel
while(1){
angulo=leer_angulo(ts);
delay_ms(ts);
}
}

Aquí la librería IMU.h:
Código: [Seleccionar]
/*********************************************
 Libreria para leer IMU    
 Acelerometro y Magnetometro LSM303DHLHC
 Giroscopio L3GD20
 Ing. Gabriel Casarrubias Guerrero
 *********************************************/
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#include <MATH.h>
float olda=0;           //angulo en el instante anterior
//****************** Registros de configuración de acelerometro
#define escriacce        0x32       //dirección de escritura para acelerometro
#define lectacce         0x33       //dirección de lectura para acelerometro
#define REG1_A           0x20       //registro de configuración 1
#define REG2_A           0x21       //registro de configuración 2
#define REG3_A           0X22       //registro de configuración 3
#define REG4_A           0X23       //registro de configuración 4
#define REG5_A           0X24       //registro de configuración 5
#define REG6_A           0X25       //registro de configuración 6
//***************** Registros de configuración de magnetometro
#define magneton         0x3c       //dirección de magnetometro
#define LSM303_MR_REG_M  0x02
//******************* Registros de configuración de gyro
#define escrigiro        0xD6       //Dirección de escritura para giro
#define lectgiro         0xD7       //Dirección de lectura para giro
#define REG1_G           0x20       //registro de configuración 1
#define REG2_G           0x21       //registro de configuración 2
#define REG3_G           0X22       //registro de configuración 3
#define REG4_G           0X23       //registro de configuración 4
#define REG5_G           0X24       //registro de configuración 5
//******************* Registros de lectura para IMU acelerometro y gyro
#define OUT_X_L          0x28
#define OUT_X_H          0x29
#define OUT_Y_L          0x2A
#define OUT_Y_H          0x2B
#define OUT_Z_L          0x2C
#define OUT_Z_H          0x2D
//******************************************************************************
//**********Función para escribir un dato a los sensores************************
//  dirección=dirección del dispositivo
//  reg= registro al cual se escribe
//  valor= valor que se escribira
void escribir_dato(int direccion,int reg, int valor){
i2c_start();                        
i2c_write(direccion);
i2c_write(reg);
i2c_write(valor);
i2c_stop();
}
//******************** funciones manejo de acelerometro*************************
//funcion que inicializa el accelerometro;
void accel_init(){
escribir_dato(escriacce,REG1_A,0b01100111); //modo normal  a 200Hz
escribir_dato(escriacce,REG2_A,0);
escribir_dato(escriacce,REG3_A,0);
escribir_dato(escriacce,REG4_A,0b00001001);//actualización continua, justificado a la izquierda, rango de +-2g,high resolution
escribir_dato(escriacce,REG5_A,0);
escribir_dato(escriacce,REG6_A,0);
}
//funcion para leer el dato del accelerometro
//     reg= registro bajo que se leera
 int16 leer_accel(int8 reg){
 int16 dato;
 int Al,Ah;

i2c_start();
i2c_write(escriacce);
i2c_write(reg);
i2c_start();
i2c_write(lectacce);
Al=i2c_read(0);
i2c_stop();
//lectura registro alto
i2c_start();
i2c_write(escriacce);
i2c_write(reg+1);
i2c_start();
i2c_write(lectacce);
Ah=i2c_read(0);
i2c_stop();
dato=Ah;
dato=dato<<8;     //                Ah:Al
dato=dato+Al;    //dato de la forma AD:C0 donde el valor es AD:C y los primeeros 4 bits no cuentan
//entonces se recorre el dato a la derecha 4 bits.
dato=dato>>4;
return(dato);  //dato leido del acelerometro
}

//********funcion para convertir el dato del accelerometro a g
// dato= dato que se convertira
float convertirg(int16 dato){
float salida;
salida=(float)dato;
salida=salida*.001;           //resolucíon en +-2g=1mg/LSB
if(salida>=3.0)               //condición para detectar los negativos
salida=-(4.1-salida);
return(salida);              
}
//   funcion para convertir de g a grados
//   dato= dato a convertir
float caccelgrados(float dato){
float grados;
grados=asin(dato)*180/3.14158;   //dato=g*sen(Theta)  radianes para grados se multiplica por 180/pi
return(grados);
}
//funcion para convertir de g a radianes
//    dato=dato a convertir
float caccelradianes(float dato){
float grados;
grados=asin(dato);
return(grados);
}
//*******************  funciones manejo de gyroscopio***************************
// función para inicializar el gyro
void gyro_init(){
escribir_dato(escrigiro,REG1_G,0b10101111);
//escribir_dato(escrigiro,REG2_G,0b00000000);
//escribir_dato(escrigiro,REG3_G,0b00000000);
escribir_dato(escrigiro,REG4_G,0b00000001);
escribir_dato(escrigiro,REG5_G,0);
}
//función para leer el dato del giro
// reg= registro parte baja que se leera
int16 leer_gyro(int8 reg){
int16 dato;
int Al,Ah;
i2c_start();
i2c_write(escrigiro);
i2c_write(reg);
i2c_start();
i2c_write(lectgiro);
Al=i2c_read(0);
i2c_stop();
//lectura de registro parte alta
i2c_start();
i2c_write(escrigiro);
i2c_write(reg+1);
i2c_start();
i2c_write(lectgiro);
Ah=i2c_read(0);
i2c_stop();
dato=Ah;
dato=dato<<8;
dato=dato+Al;
dato=dato>>4;
//printf(lcd_putc,"\f Ah: %d+%d",Ah,Al);
return(dato);
}
//funcion para convertir a grados por segundo el dato del gyro
// dato=dato a convertir
float convertirdps(int16 dato){
float salida;
salida=(float)dato;
salida=salida*0.00875;  //resolucion en 250dps=8.75mdps/LSB
return(salida);              
}
//función que conjunta las mediciones para obtener una lectura corregida
// dato = dato en dps del gyro
// old= ángulo en un instante anterior
// tm= tiempo de muestreo
// Aacc= angulo del acelerometro
float cgyrogrados(float dato,float old,int tm,float Aacc){
float angulo;
float a=0.8;
angulo=((old+(dato*tm/1000))*a+(Aacc*(1-a)));// ángulo=(old+dato*ts)*a+Aacc*(1-a);
//donde a es el grado de confiabilidad del gyro con respecto al acelerometro dependiendo lo observado.
return(angulo);
}
//funcion que tenemos que llamar para leer el angulo en el eje Y para leer otro cambiar OUT_Y_L por OUT_X_L u OUT_Z_L
//tm= tiempo de muestreo para hacer la correción
float leer_angulo(int tm){
float Ya,Yg,Aya,Ayg;
int16 Yda,Ydg;
Yda=leer_accel(OUT_Y_L);         //lee el dato del acelerometro
Ydg=leer_gyro(OUT_Y_L);          //lee el dato del gyro
Ya=convertirg(Yda);              //convierte a g el dato del acelerometro
Yg=convertirdps(Ydg);            //convierte a º/s el dato del gyro
Aya=caccelgrados(Ya);            //convierte a º las g
Ayg=cgyrogrados(Yg,olda,tm,Aya); //convierte a º las dps corrigiendo con el angulo del accelerometro
olda=Ayg;                        //actualiza el instante anterior
return(Ayg);
}


« Última modificación: 30 de Julio de 2013, 18:13:19 por gab163 »

Desconectado PCCM

  • PIC16
  • ***
  • Mensajes: 109
Re: Vehículo autobalanceado tipo pendulo invertido
« Respuesta #21 en: 30 de Julio de 2013, 23:17:59 »
Interesante algoritmo:

Código: [Seleccionar]
angulo=((old+(dato*tm/1000))*a+(Aacc*(1-a)));
Tengo algunas dudas:

- Tu giroscopio no tiene offset para corregir?.

- Cuanto demora en converger tu angulo(ante movimientos rápidos de cabeceo en tu aplicación)?

- con tu "a" de 0.8 no estas dependiendo mucho del acelerómetro, has hecho pruebas con tu carrito en movimiento o solo estaticamente girando?, ya que con ese valor de "a" el acelerometro aporta 1/5 de angulo en la corrección cada 20 ms, si acelera en linea recta sin cabecear solo en un pequeño instante(una muestra) el acel dará aprox supongamos 40 grados, lo cual aportará 40/5=8 grados el cual debería ser 0, ello no afecta en tu control?.

Desconectado gab163

  • PIC16
  • ***
  • Mensajes: 111
Re: Vehículo autobalanceado tipo pendulo invertido
« Respuesta #22 en: 31 de Julio de 2013, 00:43:18 »
Hola PCCM apenas termine el código esta mañana por lo cual no me ha dado tiempo de probar en movimiento en cuanto tenga mas avances los mostrare para ver si puedo responder tus preguntas, saludos

Desconectado miquel

  • PIC12
  • **
  • Mensajes: 69
Re: Vehículo autobalanceado tipo pendulo invertido
« Respuesta #23 en: 31 de Julio de 2013, 05:43:31 »
¡Hola PCCM!  En esta página encontraras más información de este algoritmo:

http://web.mit.edu/scolton/www/filter.pdf

Es mucho más simple que el filtro Kalman.

Saludos,

Miquel


Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: Vehículo autobalanceado tipo pendulo invertido
« Respuesta #24 en: 31 de Julio de 2013, 09:20:58 »
Se llama filtro complementario. Es un caso específico del filtro de Kalman. Hay mucha información en internet, pueden buscar en google como "complementary filter" ;)
Básicamente lo que hace es tomar las componentes de alta frecuencia del gyro, y las fusiona con las componentes de baja frecuencia del acelerómetro.
Saludos!!

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado gab163

  • PIC16
  • ***
  • Mensajes: 111
Re: Vehículo autobalanceado tipo pendulo invertido
« Respuesta #25 en: 31 de Julio de 2013, 20:22:58 »
Bueno he decidido usar el filtro de Kalman ya que es lo que nos enseñan y aparte de que mi compañero ya trabajo en esta parte por lo cual solo tuve que modificar algunas cosas pero es su libreria he aquí esta:
Como argumentos va primero la lectura del accelerometro en radianes y despues la del giroscopio en radianes/s, obtenemos el ángulo en radianes y para que funcione correctamente hay que modificar la Matriz Q y R y tambien depende del tiempo de muestro.

Código: [Seleccionar]
/*
***             Filtro de kalman
***             M.C. Jorge Bonales
********************************************************************************
*/
//**********************Variables que se actualizan*****************************
  //Matrz de covarianza P
  float P[2][2]={{100000,0},{0,100000}};

  //matriz inicial de los estados
  float x[2][2]={{0,0},{0,0}};
  
  //Ganancia de Kalman
  float K[2][1];
  float Pn[2][2];
  float Acel_K;
  float gyro_ant;
  int w=0;
  
  
 //******************************************************************************
float k_filter(float acel_rad,float gyro_rad){
  
  //Tiempo de muestreo en ms
  const float Ts=.002;
  //Matriz de covarianza del ruido
  float Q[2][2]={{0.5,0},{0,0.5}};
    //Varianza R
  float R=.1;
     //Matriz A de la forma A=[1,-Ts;0,1]
  float A[2][2]={{1,-Ts},{0,1}};
    //Matriz B=[Ts;0]
  float B[2][1]  ={{Ts},{0}};
    //Matriz C
  float C[1][2]={{1,0}};
 //********************Etapa de predicción
         if (w==0){
         gyro_ant=gyro_rad;
         w=1;
         }
         else{
         //x(:,k)=A*x(:,k-1)+B*gyro_ant
         x[0][1]=x[0][0]+A[0][1]*x[1][0]+B[0][0]*gyro_ant;
         x[1][1]=A[1][1]*x[1][0];
                  
         Pn[0][0]=P[0][0]+A[0][1]*P[1][0]+(P[0][1]+A[0][1]*P[1][1])*A[0][1]+Q[0][0];
         Pn[0][1]=P[0][1]+A[0][1]*P[1][1];
         Pn[1][0]=Pn[0][1];
         Pn[1][1]=P[1][1]+Q[1][1];
        
         P[0][0]=Pn[0][0];
         P[0][1]=Pn[0][1];
         P[1][0]=Pn[1][0];
         P[1][1]=Pn[1][1];
         //*******************Etapa de corrección***********
         // Actualización de la ganancia de Kalman
         K[0][0]=P[0][0]/(P[0][0]+R);
         K[1][0]=P[1][0]/(P[0][0]+R);
        
         //Actualización del estado
         x[0][0]=x[0][1]+K[0][0]*(acel_rad-x[0][1]);
         x[1][0]=x[1][1]+K[1][0]*(acel_rad-x[0][1]);
        
         //Actualización de la covarianza del error de estimación
         Pn[0][0]=P[0][0]-K[0][0]*P[0][0];
         Pn[0][1]=P[0][1]-K[0][0]*P[0][1];
         Pn[1][0]=P[1][0]-K[1][0]*P[0][0];
         Pn[1][1]=P[1][1]-K[1][0]*P[0][1];
        
         P[0][0]=Pn[0][0];
         P[0][1]=Pn[0][1];
         P[1][0]=Pn[1][0];
         P[1][1]=Pn[1][1];
         }
         //regresar el valor del acelerometro
         Acel_K=x[0][0];
         gyro_ant=gyro_rad;
         return(Acel_K);
}

De igual manera estare armando las funciones para leer encoders y adc's para medir el nivel de baterias y la del calculo de la ley de control para poder ya probar todo en conjunto. en cuanto tenga algo lo subo.
« Última modificación: 31 de Julio de 2013, 20:25:44 por gab163 »

Desconectado PCCM

  • PIC16
  • ***
  • Mensajes: 109
Re: Vehículo autobalanceado tipo pendulo invertido
« Respuesta #26 en: 01 de Agosto de 2013, 17:34:58 »
Si, busqué lo del filtro complementario, como dice miguel y gera es una versión especifica del filtro kalman, además te consume mucho menos procesamiento que el de kalman. Sería interesante que pruebes los 2 algoritmos y muestres los resultados.

Tienes la ventaja de tener encoder para medir su aceleración aproximadamente en el mismo eje del acelerómetro.
Con ello puedes corregir la aceleración lineal que de dá el acelerómetro, ya que solo necesitas la aceleración de la gravedad.

O sino puedes hacer que tu covarianza de error en la medición(R) sea dinámica, osea a mayor aceleración captada por el encoder, aumentas el R para que la corrección no sea rápida.

Desconectado gera

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 2188
Re: Vehículo autobalanceado tipo pendulo invertido
« Respuesta #27 en: 02 de Agosto de 2013, 09:45:05 »
Sería interesante que pruebes los 2 algoritmos y muestres los resultados.

Yo hice esa prueba (ademas pueden encontrarse varios papers con la comparacion). El filtro de kalman tiene una respuesta mucho mejor y es menos sensible a las vibraciones. Sin embargo, como vos decis, consume mas recursos computacionales y es dificil dejarlo bien "tuneado". En la mayoria de las aplicaciones, el filtro complementario cumple los objetivos ;)

Saludos!

"conozco dos cosas infinitas: el universo y la estupidez humana. Y no estoy muy seguro del primero." A.Einstein

Desconectado aljndro.g

  • PIC10
  • *
  • Mensajes: 1
Re: Vehículo autobalanceado tipo pendulo invertido
« Respuesta #28 en: 09 de Agosto de 2013, 14:13:11 »
Hola Muy bueno tu proyecto solo tengo una duda como conseguiste la OSMC, yo soy ciudadano colombiano y necesito una para un proyecto con motores te agradeceria pronta ayuda :-/

Desconectado kain589

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 324
Re: Vehículo autobalanceado tipo pendulo invertido
« Respuesta #29 en: 10 de Agosto de 2013, 21:22:37 »
Pregunto aqui una duda que tengo por no abrir otro hilo,se podria hacer este robot con unos servos futaba,me gustaria intentarlo ya que tengo los sensores pero no quiero gastarme en motores ya que es paso previo a un quadcoptero y ahi me tendre que gastar en motores y demas
Saludos desde Córdoba, españa