2011-05-22 11 views
10

Usando solo el acelerómetro incorporado en el teléfono (Android), ¿cómo encontraría su velocidad?¿Cómo puedo encontrar la velocidad usando solo acelerómetros?

He estado jugando con las matemáticas de esto, pero cualquiera que sea la función que se presente tiende a conducir a un crecimiento exponencial de la velocidad. Estoy trabajando desde la suposición de que al inicio de la aplicación, el teléfono está paralizado. Esto definitivamente debería hacer que sea posible encontrar la velocidad (al menos aproximadamente).

Tengo un buen historial en física y matemáticas, así que no debería tener ninguna dificultad con ningún concepto aquí.

¿Cómo debo hacerlo?

+0

@Ignacio ¿Qué? La aceleración constante significa que la velocidad aumenta linealmente. – Imran

+0

¿Tiene alguna solución de trabajo? ¿Puede indicarme eso o compartir el código? – VenomVendor

+0

Hola, ¿alguna vez pensó en cerrar esta pregunta? –

Respuesta

1

v = Integral (a)?

general, sin embargo, pensaría que las imprecisiones en los acelerómetros harían esto muy dura

+0

Depende del tipo de imprecisiones. Usted podría calibrar por error lineal, ¿no? –

-2

Si el teléfono se encuentra en período inactivo, tiene aceleración cero, por lo que su velocidad es 0. Probablemente usted debe encontrar los datos de posición GPS y obtenga las muestras de tiempo asociadas y calcule la distancia de velocidad en el tiempo.

+0

Sí, la velocidad es 0 "al iniciarse la aplicación". Estoy calibrándolo desde este punto. –

+0

"Permanecer quieto" debería ser realmente fácil de detectar. Si la entrada del acelerómetro (use TYPE_LINEAR_ACCELERATION) es muy constante, probablemente el teléfono no se esté manejando. –

7

Primero, debe eliminar la aceleración debida a la gravedad de los datos del acelerómetro. Entonces solo se trata de integrar la aceleración para obtener la velocidad. No olvide que la aceleración y la velocidad son vectores apropiados, no escalares, y que también tendrá que rastrear la rotación del teléfono en el espacio para determinar correctamente la orientación del vector de aceleración con respecto al vector de velocidad calculado.

+0

puede explicar desde la perspectiva de codificación o señalar a un enlace donde puedo obtener más detalles al respecto. – VenomVendor

+3

El sensor TYPE_LINEAR_ACCELERATION le dará aceleración con la gravedad filtrada, por lo que es agradable. TYPE_ROTATION_VECTOR le dará la orientación del dispositivo como un cuaternario, que puede convertirse fácilmente en una matriz de rotación de 3x3. En cada segmento de tiempo, usa la matriz de rotación para convertir la aceleración en un vector en 3 espacios. Integre esto a lo largo del tiempo para obtener la aceleración (otro vector) e integre * ese * para obtener la posición relativa a la posición de inicio. (Todo esto supone que la velocidad inicial fue cero). Luego ve al bar y toma una pinta porque no hay esperanza con sensores baratos. –

7

Eso realmente dependerá de la aceleración y durante cuánto tiempo. Una aceleración suave y larga podría ser medible, pero cualquier incremento repentino en la aceleración, seguido de una velocidad constante, hará que sus mediciones sean bastante difíciles y propensas al error.

Suponiendo una aceleración constante, la fórmula es extremadamente simple: a = (V1-V0)/t. Entonces, conociendo el tiempo y la aceleración, y asumiendo V0 = 0, entonces V1 = a * t

En un mundo más real, probablemente no tendrá una aceleración constante, por lo que debe calcular Delta V para cada medición y agregando todos esos cambios en la velocidad para obtener la velocidad final. Siempre considere que no tendrá datos de aceleración continuos, por lo que esta es la forma más factible (es decir, datos reales frente a la teoría de la matemática integral).

En cualquier caso, incluso en el mejor escenario, terminará con un margen de error muy alto, por lo que no recomiendo este enfoque para cualquier aplicación que realmente dependa de las velocidades reales.

+5

En caso de que nadie lo haya notado, V1 = a * t! – erdomester

2

La integración de la aceleración para obtener velocidad es un problema inestable y su error divergerá después de unos segundos más o menos. Los acelerómetros del teléfono tampoco son muy precisos, lo que no ayuda, y algunos de ellos no le permiten distinguir entre la inclinación y la traducción fácilmente, en cuyo caso usted está realmente en problemas.

2

Los acelerómetros en un teléfono son bastante inútiles para tal tarea. Necesita acelerómetros de alta precisión con muy poca deriva, algo que va mucho más allá de lo que encontrará en un teléfono. En el mejor de los casos, puede obtener resultados útiles durante unos segundos, o si tiene mucha suerte durante un minuto o dos, después de lo cual los resultados pierden sentido.

Además, necesita tener un giroscopio de tres ejes que usaría para integrar la velocidad en la dirección correcta. Algunos teléfonos tienen giroscopios, pero son incluso más pobres que los acelerómetros en lo que respecta a la deriva y la precisión.

Una aplicación posiblemente útil sería usar los acelerómetros junto con los giroscopios o la brújula magnética para completar los datos faltantes del GPS. Cada vez que el GPS da una buena solución, uno restablecería las condiciones iniciales de posición, velocidad y orientación, y los acelerómetros proporcionarían los datos hasta la próxima corrección válida del GPS.

+0

Digamos que quiero obtener información de inclinación para controlar un juego. En ese escenario, podré hacer muchas suposiciones. Por ejemplo, puedo suponer que el usuario está sosteniendo el dispositivo de cierta manera. ¿No sería posible entonces suavizar los datos de forma que los cambios repentinos se destaquen y se vuelvan útiles como entrada al juego? –

4

No hay nada más que hacer que estar de acuerdo con los argumentos razonables presentados en todas las grandes respuestas anteriores, sin embargo, si eres del tipo pragmático como yo, necesito encontrar una solución que funcione de alguna manera.

Sufrí un problema similar al suyo y decidí hacer mi propia solución después de no encontrar ningún en línea. Solo necesitaba una entrada de "inclinación" simple para controlar un juego, por lo que esta solución probablemente NO funcionará para necesidades más complejas, sin embargo, decidí compartirla en caso de que otros buscaran algo similar.

NOTA: I have pasted my entire code here, y es gratis para cualquier uso.

Básicamente lo que hago en mi código es buscar el sensor del acelerómetro. Si no se encuentra, la retroalimentación de inclinación se desactivará. Si el sensor acelerómetro está presente, busco el sensor de campo magnético, y si está presente, obtengo mi ángulo de inclinación de la manera recomendada combinando datos de acelerómetro y campo magnético.

public TiltSensor(Context c) { 
    man = (SensorManager) c.getSystemService(Context.SENSOR_SERVICE); 
    mag_sensor = man.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); 
    acc_sensor = man.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 
    has_mag = man.registerListener(this, mag_sensor, delay); 
    has_acc = man.registerListener(this, acc_sensor, delay); 
    if (has_acc) { 
     tiltAvailble = true; 
     if (has_mag) { 
      Log.d("TiltCalc", "Using accelerometer + compass."); 
     } 
     else { 
      Log.d("TiltCalc", "Using only accelerometer."); 
     } 
    } 
    else { 
     tiltAvailble = false; 
     Log.d("TiltCalc", "No acceptable hardware found, tilt not available."); 
     //No use in having listeners registered 
     pause(); 
    } 
} 

Si sin embargo, sólo el sensor de acelerómetro estaba presente, I caer de nuevo a la acumulación de la aceleración, que se amortigua de forma continua (multiplicado por 0,99) para eliminar cualquier deriva. Para mis necesidades de inclinación simple, esto funciona muy bien.

@Override 
public void onSensorChanged(SensorEvent e) { 
    final float[] vals = e.values; 
    final int type = e.sensor.getType(); 
    switch (type) { 
     case (Sensor.TYPE_ACCELEROMETER): { 
      needsRecalc = true; 
      if (!has_mag) { 
       System.arraycopy(accelerometer, 0, old_acc, 0, 3); 
      } 
      System.arraycopy(vals, 0, accelerometer, 0, 3); 
      if (!has_mag) { 
       for (int i = 0; i < 3; i++) { 
        //Accumulate changes 
        final float sensitivity = 0.08f; 
        dampened_acc[i] += (accelerometer[i] - old_acc[i]) * sensitivity; 
        //Even out drift over time 
        dampened_acc[i] *= 0.99; 
       } 
      } 
     } 
      break; 
     case (Sensor.TYPE_MAGNETIC_FIELD): { 
      needsRecalc = true; 
      System.arraycopy(vals, 0, magnetic_field, 0, 3); 
     } 
      break; 
    } 
} 

En conclusión Me limitaré a repetir que esto probablemente no es "correcta" de ninguna manera, sino que simplemente funciona como una entrada simple de un juego. Para usar este código simplemente hago algo como lo siguiente (sí las constantes mágicas son malas mkay):

Ship ship = mShipLayer.getShip(); 
mTiltSensor.getTilt(vals); 
float deltaY = -vals[1] * 2;//1 is the index of the axis we are after 
float offset = ((deltaY - (deltaY/1.5f))); 
if (null != ship) { 
    ship.setOffset(offset); 
} 

Enjoi!

2

Gravity va a destruir todas sus medidas. El teléfono, en modo parado, experimenta una alta aceleración constante hacia arriba (sí, ARRIBA). Un acelerómetro no puede distinguir entre aceleración y gravedad (técnicamente, son lo mismo), por lo que llegaría a velocidades extremadamente altas después de unos segundos. Si nunca inclina su acelerómetro aunque sea levemente, entonces simplemente puede restar el arrastre gravitatorio constante del eje z (o el que apunta hacia arriba o hacia abajo), pero eso es bastante improbable.

Básicamente, tienes que usar un complicado sistema de giroscopio/magnetómetro y un acelerómetro para calcular la dirección exacta de la gravedad y luego restar la aceleración.

+0

Sensor Fusion puede filtrar eso por usted. Simplemente use el sensor TYPE_LINEAR_ACCELERATION. –

Cuestiones relacionadas