¿Los cálculos del ángulo giroscópico no son precisos?

Estoy usando este LISY300AL Gyro: Hoja de datos

Pero no puedo obtener un dato preciso ..

Aquí está mi cálculo:    

    sensitivity = 0.716454545;
    gyroAdc = analogRead(0);
    if(abs(gyroAdc - gyroZero) <= Threshold)
      gyroAdc = gyroZero;
    gyroRate = (gyroAdc-gyroZero)/sensitivity;
    gyroRotation=gyroRotation+gyroRate*dtime1/1000;
    gyroAngle = abs((gyroRotation - 360 * ceil(gyroRotation / 360))); // Round up between 0-360
    dtime = millis() - stime; // millis() is the milliseconds since my controller started
    stime = millis();

No obtengo un ángulo preciso, muevo mi objeto 90 grados pero el giroscopio se desvía demasiado, así que muestra algo más...

¿Quizás estoy haciendo algo mal? ¿O simplemente debería agregar un acelerómetro para hacerlo más preciso?

Respuestas (2)

No miré su hoja de datos, pero los giroscopios baratos (no 10s de 1000s de $) inherentemente obtienen una señal proporcional a la velocidad de giro. Para obtener ángulo, este debe estar integrado. Por lo tanto, cualquier error en la señal de tasa se acumula con el tiempo. Los giroscopios MEMS baratos tienen deriva y precisión, de modo que el ángulo no tiene sentido después de unos segundos.

Los giroscopios mecánicos reales funcionan con un principio totalmente diferente que mantiene el eje apuntando en la misma dirección. Por lo tanto, proporcionan salidas de ángulo real, no una tasa de cambio de ángulo, por lo que son más útiles para la navegación inercial.

Los acelerómetros pueden darte la magnitud del ángulo absoluto con respecto a la gravedad si sabes que el objeto no está acelerando de otra manera. Sin embargo, ese es solo un ángulo con respecto a abajo. No le ayudarán a determinar el ángulo de giro lateral, por ejemplo.

Gran explicación. Solo quería comentar que el chip LSM303 contiene un acelerómetro y un magnetómetro y podría ser útil para obtener tanto el cabeceo como el rumbo. Pololu tiene un buen módulo para Arduino.

Para evitar esta deriva en mi giroscopio, agregué declaraciones if para filtrar la deriva. Algo como esto:

if(abs(degrees(gyroRate[XAXIS]))>0.5) 
    rollAngle += degrees(gyroRate[XAXIS])*timeDiff/1000.00; 
if(abs(degrees(gyroRate[YAXIS]))>0.5) 
    pitchAngle += degrees(gyroRate[YAXIS])*timeDiff/1000.00; 
if(abs(degrees(gyroRate[ZAXIS]))>0.5) 
    yawAngle += degrees(gyroRate[ZAXIS])*timeDiff/1000.00;

Por lo tanto, cuando la velocidad del giroscopio es inferior a +/- 0,5 (desviación habitual de los giroscopios), no se actualizará el ángulo.