velocidad studio permisos medir luz hacer giroscopio con como acelerometro android filter accelerometer kalman-filter

studio - Cómo detectar el andar con el acelerómetro de Android.



permisos acelerometro android (5)

EDIT: No creo que sea lo suficientemente preciso, ya que cuando camina normalmente la aceleración promedio sería cercana a 0. Lo más que podría hacer es medir la aceleración cuando alguien comienza a caminar o se detiene (pero como dijo, es difícil filtrarla desde el dispositivo movido por alguien parado en un lugar)

Entonces ... lo que escribí antes, probablemente no funcionaría de todos modos:

Puede "predecir" si el usuario se está moviendo descartando cuando el usuario no se está moviendo (es obvio), y las dos primeras opciones que me vienen a la mente son:
Compruebe si el teléfono está "oculto", usando el sensor de proximidad y de luz (opcional). Este método es menos preciso pero más sencillo.
Controlando la continuidad del movimiento, si el teléfono se está moviendo por más de ... 10 segundos y el movimiento no es despreciable, entonces considera que está caminando. Sé que tampoco está hecho, pero es difícil usar cualquier tipo de posicionamiento, por cierto ... ¿por qué no solo usas el LocationManager ?

Estoy escribiendo una aplicación y mi objetivo es detectar cuando un usuario está caminando. Estoy usando un filtro de Kalman como este:

float kFilteringFactor=0.6f; gravity[0] = (accelerometer_values[0] * kFilteringFactor) + (gravity[0] * (1.0f - kFilteringFactor)); gravity[1] = (accelerometer_values[1] * kFilteringFactor) + (gravity[1] * (1.0f - kFilteringFactor)); gravity[2] = (accelerometer_values[2] * kFilteringFactor) + (gravity[2] * (1.0f - kFilteringFactor)); linear_acceleration[0] = (accelerometer_values[0] - gravity[0]); linear_acceleration[1] = (accelerometer_values[1] - gravity[1]); linear_acceleration[2] = (accelerometer_values[2] - gravity[2]); float magnitude = 0.0f; magnitude = (float)Math.sqrt(linear_acceleration[0]*linear_acceleration[0]+linear_acceleration[1]*linear_acceleration[1]+linear_acceleration[2]*linear_acceleration[2]); magnitude = Math.abs(magnitude); if(magnitude>0.2) //walking

La gravedad de la matriz [] se inicializa con 0s.

Puedo detectar si un usuario está caminando o no (mirando el valor de la magnitud del vector de aceleración), pero mi problema es que cuando un usuario no está caminando y mueve los teléfonos, parece que está caminando.

¿Estoy usando el filtro correcto?

¿Es correcto observar solo la magnitud del vector o tengo que mirar los valores individuales?


Google proporciona una API para esta llamada DetectedActivity que se puede obtener utilizando ActivityRecognitionApi . Se puede acceder a esos documentos here y here .

DetectedActivity tiene el método public int getType() para obtener la actividad actual del usuario y también public int getConfidence() que devuelve un valor de 0 a 100. Cuanto mayor sea el valor devuelto por getConfidence() , más certeza getConfidence() la API. El usuario está realizando la actividad devuelta.

Aquí hay un resumen constante de lo que devuelve getType() :

  • int IN_VEHICLE El dispositivo está en un vehículo, como un automóvil.
  • int ON_BICYCLE El dispositivo está en una bicicleta.
  • int ON_FOOT El dispositivo está en un usuario que está caminando o corriendo.
  • int RUNNING El dispositivo está en un usuario que se está ejecutando.
  • int STILL El dispositivo todavía está (no se mueve).
  • int TILTING El ángulo del dispositivo en relación con la gravedad cambió significativamente.
  • int UNKNOWN No se puede detectar la actividad actual.
  • int WALKING El dispositivo está en un usuario que está caminando.

Intente detectar las oscilaciones hacia arriba y hacia abajo, las oscilaciones hacia adelante y hacia atrás y la frecuencia de cada una y asegúrese de que estén alineadas dentro de los límites en promedio, ya que detectaría la marcha y específicamente el estilo de marcha de esa persona, que debería permanecer relativamente constante durante varios pasos a la vez. Para calificar como móvil. Mientras las últimas 3 oscilaciones se alineen dentro de la razón, entonces concluya que la caminata está ocurriendo siempre y cuando esto también sea cierto:

Se mide la aceleración horizontal y se actualiza un valor de velocidad con ella. La velocidad se desplazará con el tiempo, pero es necesario mantener un promedio móvil de velocidad suavizado durante el tiempo de un paso, y siempre que no se desvíe más que la mitad de la velocidad de caminar por cada 3 oscilaciones, entonces está caminando, pero solo si inicialmente se elevó a la velocidad de caminar dentro de poco tiempo, es decir, medio segundo o 2 oscilaciones, tal vez.
Todo eso debería cubrirlo. Por supuesto, un poco de ai ayudaría a hacer las cosas más simples o complejas, pero sorprendentemente precisas si consideras todo esto como entradas a una NN. Es decir preprocesamiento.


Mi primera intuición sería realizar un análisis FFT en el historial del sensor y ver qué frecuencias tienen magnitudes altas al caminar.

Esencialmente, ver cómo "suena" el andar, tratar las entradas del sensor del acelerómetro como un micrófono y ver las frecuencias que son altas cuando se camina (en otras palabras, a qué frecuencia está ocurriendo la mayor aceleración).

Supongo que estaría buscando una gran magnitud en una frecuencia baja (como la frecuencia de pasos) o tal vez en otra cosa. Sería interesante ver los datos.

Mi conjetura es que ejecuta la FFT y busca que la magnitud en alguna frecuencia sea mayor que algún umbral, o la diferencia entre las magnitudes de dos de las frecuencias es más que cierta cantidad. Una vez más, los datos reales determinarán cómo intenta detectarlo.


Para la detección de la marcha, uso el derivado aplicado a la señal suavizada del acelerómetro. Cuando la derivada es mayor que el valor de umbral, puedo sugerir que fue un paso. Pero supongo que no es la mejor práctica, además, solo funciona cuando el teléfono se coloca en el bolsillo de un pantalón.

El siguiente código se utilizó en esta aplicación https://play.google.com/store/apps/details?id=com.tartakynov.robotnoise

@Override public void onSensorChanged(SensorEvent event) { if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER){ return; } final float z = smooth(event.values[2]); // scalar kalman filter if (Math.abs(z - mLastZ) > LEG_THRSHOLD_AMPLITUDE) { mInactivityCount = 0; int currentActivity = (z > mLastZ) ? LEG_MOVEMENT_FORWARD : LEG_MOVEMENT_BACKWARD; if (currentActivity != mLastActivity){ mLastActivity = currentActivity; notifyListeners(currentActivity); } } else { if (mInactivityCount > LEG_THRSHOLD_INACTIVITY) { if (mLastActivity != LEG_MOVEMENT_NONE){ mLastActivity = LEG_MOVEMENT_NONE; notifyListeners(LEG_MOVEMENT_NONE); } } else { mInactivityCount++; } } mLastZ = z; }