Go Down

Topic: Como utilizar MPU6050 con blender (Read 361 times) previous topic - next topic

ulises2012

Hola, estube revisando google y youtube, buscando info y obviamente codigo, para poder usar el acelerometro MPU6050 con arduino UNO con blender para poder mover de direccion en una animacion y utilizar gafas de realidad virtual, lo que pude encontrar fue esto http://robologs.net/2016/08/14/tutorial-de-realidad-virtual-con-arduino-y-blender-parte-1/
Pero no corresponde a este acelerometro, despues hay varios proyectos pero usan raspberry pi

Con que me puedan guiar un poco estare muy agradecido

surbyte

Es muy fácil modificar eso para que funcione con tu MPU, solo usando el demo dela librería MPU6050 convenientemente adaptado como esta en el ejemplo que pones en el link y ya

Esto debe respetarse
Code: [Select]
  Serial.print('1'); //Enviar el codigo de seguridad
   
  //Como queremos que el angulo se envie con 3 numeros antes
  //de la coma flotante, hay que ver cuantas cifras tiene.
  //Si tiene 1 cifra (es menor que 10) se escriben dos ceros
  //Si tiene 2 cifras (es menor que 100) se escribe un solo cero
  if(ejeX < 10)
  {
    Serial.print("00");
  }
  else if(ejeX < 100)
  {
    Serial.print("0");
  }
  Serial.print(ejeX); //Ahora si, escribir el angulo. Por defecto se escribira con dos cifras decimales.
   
   
  //Lo mismo con el eje Y...
  if (ejeY < 10)  {
     Serial.print("00");
  }
  if (ejeY < 100)  {
      Serial.print("0");
  }
  Serial.print(ejeY);
 
  //...y el eje Z!
  //
  if (ejeZ < 10)  {
     Serial.print("00");
  }
  if (ejeZ < 100)  { // esto esta mal
     Serial.print("0");
  }
  Serial.print(ejeZ);
   
  //Enviar el final de linea
  Serial.print("\n");


Agregué doble "00" cuando es menor que 10 porque asi tiene sentido.

Asi que se deben leer en 3 variables ejeX, ejeY, ejeZ los valores de tu MPU6050 y listo.
Toma un demo de la libreria MPU6050 y ya lo tienes

surbyte

Lo que buscas no son coordenadas X, Y, Z sino ángulos segun X, Y,Z
No veo en los códigos el angulo Z asi que tendré que darte la razón.


Ikkarus

Buenas!

Sé que no deberían revivirse temas del foro que lleven más de un mes sin actualizarse, pero dado que la pregunta es -relativamente- recente, he pensado que mi aportación podría ser útil en el supuesto caso de que no hayas resuelto aún tu duda.

No es posible crear un casco de realidad virtual con un MPU-6050 (de ahí que el código del tutorial de www.robologs.net utilice otra IMU). La razón es que el MPU-6050 es una IMU de 6DOF, lo cuál significa que sólo lleva Giroscopio y Acelerómetro y por tanto, sólo será capaz de medir los ejes X e Y con precisión. Para poder medir el eje Z (el paralelo al suelo) se necesita una IMU de 9DOF, que lleve magnetómetro.

Puedes utilizar otras IMUs como el MPU-9250 (personalmente no te la recomiendo, puesto que a mi me ha dado problemas) o el BNO055 (la del tutorial) que aunque no es precisamente barata, a mi me ha funcionado de coña para contruir mi casco.

¡Espero que esto te ayude!


surbyte


Quote
Sé que no deberían revivirse temas del foro que lleven más de un mes sin actualizarse,
No cometiste ninguna falta. Son 4 meses no 1 mes.
Y cuando eso pasa el sistema te pone un Warning. Asi que puedes continuar el tema sin problemas.
Respecto del casco porque no amplias la información?

Ikkarus

#5
Jan 13, 2017, 07:55 pm Last Edit: Jan 13, 2017, 08:13 pm by Ikkarus
No cometiste ninguna falta. Son 4 meses no 1 mes.
Vaya, pues no sé por qué pero estaba convencido de que era sólo un mes.


Respecto del casco porque no amplias la información?
Para construir un casco de realidad virtual sencillo, como el que supongo que quiere ulises2012, se necesitan conocer los 3 ángulos de rotación de la cabeza para pasarlos a Blender.

Una IMU de 6-DOF (se lee 6 degrees of freedom/6 grados de libertad) es la unión de dos sensores: un Acelerómetro de 3 ejes (puede medir aceleraciones en el eje X,Y,Z) y un Giroscopio también de 3 ejes (mide la velocidad angular en los ejes X,Y,Z).

Ninguno de estos dos sensores mide directamente ángulos, y además ambos sensores dan sus medidas con un cierto error. El Acelerómetro es ruidoso y suceptible a golpes y movimientos, mientras que con el Giroscopio, como sus medidas se leen en intervalos discretos de tiempo, habrá un pequeño error en cada cálculo del ángulo que irá creciendo.

Para obtener el ángulo real, lo que se hace es implementar un filtro que "mezcla" las lecturas del acelerómetro y el giroscopio y eliminan el error. Por ejemplo, puede aplicarse un Filtro Complementario (http://robologs.net/2014/10/15/tutorial-de-arduino-y-mpu-6050/) que es bastante simple de entender.

El problema es que el Filtro Complementario no es capaz de detectar las variaciones en el eje Z de forma precisa. La solución podría ser utilizar sólo las lecturas del eje Z del giroscopio, pero se perdería precisión. Por tanto, una IMU de 6-DOF no nos sirve para construir un casco de RV.

La solución es utilizar una IMU de 9-DOF que además del Giroscopio y Acelerómetro lleve un magnetómetro (sensor de campo magnético, que puede utilizarse como "brújula") para saber cuál es el ángulo Z. Para ello se utilizan filtros más complejos para procesar las lecturas de los sensores, como el Filtro de Madgwick o el famoso Filtro de Kálman, entre otros.

No sé si esto amplia mi explicación lo suficiente.

¡Un saludo!

surbyte

No para mi. Eso ya lo sabía. 
Pero da algun enlace de como lo resolviste usando la IMU de 9-DOF y el código.
Lo demás esta bien pero hablo del aspecto práctico.
Yo estoy trabajando con Ulises por eso te lo pido.

Ikkarus

Básicamente, para construir mi casco seguí los pasos del tutorial del link que nos ha pasado ulises2012.

Inicialmente quise utilizar el MPU-9250, porque había trabajado con el MPU-6050 para hacer otros proyectos y me había dado muy buenos resultados. Pero me encontré con muchas dificultades a la hora de acceder a los valores del magnetómetro y filtrarlos, incluso con las funciones oficiales de la librería. Dada mi mala experiencia, no recomiendo esta IMU.

La solución fue utilizar la IMU BNO055 de Adafruit. Para hacerla funcionar utilicé el código del tutorial, con un par de variaciones a la hora de enviar los valores a Blender.

A no ser que se quiera programar la IMU desde cero, no hay que olvidarse de descargar las librerías del BNO055 para Arduino: esta y esta.


Este es el código para leer los ángulos que marca la IMU y enviarlos por Serial.

Code: [Select]

#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BNO055.h>
#include <utility/imumaths.h>
 
//Delay entre lecturas
#define BNO055_SAMPLERATE_DELAY_MS (15)
Adafruit_BNO055 bno = Adafruit_BNO055(55); //Crear el objeto IMU
 
void setup(void)
{
  Serial.begin(115200); //Activar el serial
  
  //Activar el sensor
  Serial.println("Activar sensor");
  bno.begin();
 
  //Delay de tres segundos para dar tiempo a calibrar el magnetometro
  delay(3000);
}
 
void loop(void)
{
  //Leer la IMU
  sensors_event_t event;
  bno.getEvent(&event);
 
  /*Los ejes estan girados: el X es el Y, el Y es el Z y el Z es el X
    Ademas, hay que sumar 90 para que el eje X,Y vaya de 0 a 180*/
  float ejeX = (float)event.orientation.y+90;
  float ejeY = (float)event.orientation.z+90;
  float ejeZ = (float)event.orientation.x;
  
  Serial.print('1'); //Enviar el codigo de seguridad
  
  //Como queremos que el angulo se envie con 3 numeros antes
  //de la coma flotante, hay que ver cuantas cifras tiene.
  //Si tiene 1 cifra (es menor que 10) se escriben dos ceros
  //Si tiene 2 cifras (es menor que 100) se escribe un solo cero
  if(ejeX < 10)
  {
    Serial.print("00");
  }
  else if(ejeX < 100)
  {
    Serial.print("0");
  }
  Serial.print(ejeX); //Ahora si, escribir el angulo. Por defecto se escribira con dos cifras decimales.
  
  
  //Lo mismo con el eje Y...
  if(ejeY < 10)
  {
    Serial.print("00");
  }
  else if(ejeY < 100)
  {
    Serial.print("0");
  }
  Serial.print(ejeY);
 
  //...y el eje Z!
  if(ejeZ < 10)
  {
    Serial.print("00");
  }
  else if(ejeZ < 100)
  {
    Serial.print("0");
  }
  Serial.print(ejeZ);
  
  //Enviar el final de linea
  Serial.print("\n");
  
  delay(BNO055_SAMPLERATE_DELAY_MS);
}


Como placa Arduino utilicé una Arduino Nano (ocupa menos espacio y por tanto es más fácil de pegar encima del casco RV) y el casco era este modelo, en blanco.

Dentro del casco metí una pantalla parecida a esta (pero de cinco pulgadas), conectada al ordenador.

Finalmente, hay que crear una escena con el motor de juegos de Blender (o cualquier otro motor como Unity o Unreal Engine) que lea el Serial de Arduino y decodifique el mensaje para extraer los tres ángulos, rotar la cámara y mostrar la escena en la pantalla del casco.

¡Espero que esto ayude! Si hay algo más, estaré por aquí.


surbyte

Traducción: (al menos para mi) entonces y no lo sabía el hecho de usar una IMU de 9-DF me quita lo engorroso de usar filtros KALMAN o cualquier otro para mantener las cosas estables? 
El sensor MPU-9250 funciona perfecto simplemente mostrando los datos crudos?


Ikkarus

Traducción: (al menos para mi) entonces y no lo sabía el hecho de usar una IMU de 9-DF me quita lo engorroso de usar filtros KALMAN o cualquier otro para mantener las cosas estables?
Creo que no me he explicado bien. El filtro (sea un del tipo que sea: Kalman, Madgwick) hay que usarlo con cualquier tipo de IMU.

Lo que quiero decir es que con una IMU de 6-DOF, como el MPU-6050, no puedes medir la rotación en el eje Z, porque no tienen magnetómetro. Trabajar con una IMU de 9-DOF (como el MPU-9250 o el BNO055) no te ahorrará trabajo, justo lo contrario, pero te permitirá medir bien la rotación en el eje Z que es lo que interesa para crear un casco de realidad virtual.

Por suerte, la mayoría de librerías para hacer funcionar IMUs ya tienen implementadas funciones que aplican estos filtros y te dan directamente el ángulo.


El sensor MPU-9250 funciona perfecto simplemente mostrando los datos crudos?
El sensor MPU-9250, como he dicho, a mí no me ha funcionado, por eso he utilizado el BNO055. No porque el MPU-9250 no sea adecuado (es una IMU de 9-DOF y por tanto en teoría serviría) sino porque tenido muchos problemas para leer el magnetómetro, pero puede que a vosotros no os pase.

Por otra parte, los datos "crudos" son los valores del Acelerómetro, Giroscopio y Magnetómetro, que no son ángulos. Hay que aplicarles algun tipo de filtro o algoritmo para combinarlos y extraer el ángulo.

No sé si ahora se entiende un poco mejor.

surbyte

#10
Jan 14, 2017, 05:38 pm Last Edit: Jan 14, 2017, 05:40 pm by surbyte


Si eso lo dijiste. Pero en tu código no veo filtro!!

Aunque no se si esto no involucra algo
Code: [Select]
  float ejeX = (float)event.orientation.y+90;
  float ejeY = (float)event.orientation.z+90;
  float ejeZ = (float)event.orientation.x;

Ikkarus

Exactamente, esto son los ángulos reales. Esta función aplica un filtro a los valores en bruto de los sensores de la IMU y te devuelve la orientación del aparato.

Ikkarus

Rectifico: la función bno.getEvent() es la que guarda la orientación dentro de 'event'. El fragmento de código que mencionas sólo copia los valores de la orientación de event dentro de las variables ejeX, ejeY e ejeZ.

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy