2012-04-21 11 views
5

Digamos que el iPhone se coloca sobre una mesa plana. Me gustaría determinar el ángulo del plano de la mesa, donde un ángulo de 0 significaría que la mesa es exactamente perpendicular al vector de gravedad. Estoy usando la siguiente fórmula:Obtener el plano del dispositivo en relación con el plano de tierra con el acelerómetro

radians = atanf (z/sqrt (x^2 + y^2) 

en el .h

double  accelerationXAverage; 
double  accelerationYAverage; 
double  accelerationZAverage; 

double  accelerationXSum; 
double  accelerationYSum; 
double  accelerationZSum; 
int   readingsCount; 

en el .m

#define kThresholdMovementHigh 0.05 

- (void)accelerometer:(UIAccelerometer *)accelerometer 
     didAccelerate:(UIAcceleration *)acceleration 
{ 
    // did device move a lot? if so, reset sums 
    if (fabsf(acceleration.x - accelerationXAverage) > kThresholdMovementHigh || 
     fabsf(acceleration.y - accelerationYAverage) > kThresholdMovementHigh || 
     fabsf(acceleration.z - accelerationZAverage) > kThresholdMovementHigh ) 
    { 
     NSLog(@"deviceDidMove a lot"); 
     accelerationXSum = acceleration.x; 
     accelerationYSum = acceleration.y; 
     accelerationZSum = acceleration.z; 
     readingsCount = 1; 
    } 

    else 
    { 
     // because the device is at rest, we can take an average of readings 
     accelerationXSum += acceleration.x; 
     accelerationYSum += acceleration.y; 
     accelerationZSum += acceleration.z; 
     readingsCount ++;   
    } 

    accelerationXAverage = accelerationXSum/readingsCount; 
    accelerationYAverage = accelerationYSum/readingsCount; 
    accelerationZAverage = accelerationZSum/readingsCount; 

    float angle = RadiansToDegrees(atanf(accelerationZAverage/sqrtf(pow(accelerationXAverage, 2) + pow(accelerationYAverage, 2)))) + 90; 

    labelAngle.text = [NSString stringWithFormat:@"%.2f°", angle]; 
} 

estoy filtrar el ruido promediando las lecturas del acelerómetro. El intervalo de actualización del acelerómetro es 1/60, y por ahora mientras experimento, dejé que el dispositivo se asentara durante 10 segundos (por lo que es un promedio de 600 lecturas).

Esta fórmula parece funcionar, me da ángulos sobre lo que esperaría. Sin embargo, también estoy esperando que si pruebo esto con el dispositivo girado a una posición estática diferente mientras estoy plano sobre la mesa, debería obtener la misma respuesta (causa relativa al vector de gravedad, el ángulo no ha cambiado) . Sin embargo, eso no es lo que obtengo cuando lo pruebo. Los ángulos varían en un par de grados.

Estoy usando la fórmula correcta? ¿Por qué el ángulo sería diferente para diferentes ubicaciones en la misma mesa? ¿Es solo el margen de error?

He añadido una imagen (desde http://gotoandplay.freeblog.hu/) para asegurarme de que estoy hablando del mismo eje x- y-. enter image description here

+0

obtengo un error en kThresholdMovementHigh. ¿Qué es esto? – srinadh

+0

kThresholdMovementHigh es solo una constante. Debajo del umbral está el "ruido", es decir, el movimiento que desea ignorar. Por encima del umbral se trata de un movimiento que desea procesar como movimiento deliberado por parte del usuario. He actualizado mi pregunta para incluir mi #define. Deberá determinar qué es lo óptimo para su aplicación. –

Respuesta

3

Su enfoque y fórmula son correctos.

Las x, y y z son relativas al dispositivo. Teóricamente, el ángulo debe ser el mismo independientemente de la posición angular del dispositivo en la parte superior de la mesa. Sin embargo, hay varios factores que contribuyen a la precisión aquí, incluido el cálculo arctan en un ángulo tan pequeño. Sugiero que lo pruebes con la inclinación de la mesa (no horizontal al suelo). Diga mantenga su mesa a un ángulo de 30 grados del suelo y pruébelo. Supongo que tu x, y, z están todos en el doble

+0

Gracias por la sugerencia. Lo intenté con una inclinación mayor. La diferencia absoluta es aproximadamente la misma (~ 1 grado) aunque, como un error porcentual, es menos significativo con una mayor inclinación. Tenía x, y, z como flotadores; Cambié al doble. –

+0

Después de experimentar un poco más, creo que solo es un margen de error. Hice varias pruebas con el iPhone en la misma posición, y el ángulo varió 0.5 grados. (¡Debería haber comprobado la precisión en primer lugar!). Tienes razón, la falta de precisión es mucho más notable con las matemáticas en pequeños ángulos. –

Cuestiones relacionadas