J'ai une question très basique. Qu'est-ce que le filtre passe-bas et le filtre passe-haut en cas d'accéléromètre Android?
Lorsque je vois la sortie du capteur d'accéléromètre, je vois Si je n'utilise aucun filtre (cas: j'ai laissé mon téléphone portable inactif sur la table), j'obtiens la valeur z Axe + ve. Maintenant, si je pense qu'en utilisant la physique de base, cela me donne une valeur exacte (9,8 environ) pour les petits g, c'est-à-dire l'accélération due à la gravité.
Pour obtenir l'accélération linéaire, si j'ajoute une force au téléphone, cela changera la valeur de l'accéléromètre, mais ce sera g + a
que j'ai appliqué. Donc, pour obtenir a
pourquoi ne puis-je pas simplement soustraire directement la valeur que j'obtiens de l'accéléromètre?
Quelle est l'utilité?
Définition de base que je comprends pour le passe-bas: pour autoriser une valeur faible, passe-haut: pour autoriser une valeur élevée. S'il vous plaît, aidez-moi à le comprendre. Je suis confus avec ça.
Si vous regardez la documentation, vous verrez que SensorEvent renvoie un tableau qui représente le vecteur de toutes les forces. http://developer.Android.com/reference/Android/hardware/SensorEvent.html#values C'est ainsi que les composants de l'accélération se décomposent en chaque axe:
values[0] //acceleration on x axis
values[1] //acceleration on y axis
values[2] //acceleration on z axis
Vous devez trouver dans quelle direction la gravité opère, puis la décomposer en ses composants. L'amplitude de la force de gravité sera toujours de 9,8 mais la direction, et donc la façon dont elle se décompose en composants, changera. En supposant que nous pourrions obtenir la valeur de la gravité et stocker ce vecteur dans un tableau comme gravity[3]
:
gravity[0] //gravity x axis
gravity[1] //gravity y axis
gravity[2] //gravity z axis
L'accélération totale, T
, sur le téléphone est T = g + a
. Pour obtenir juste a
nous aurions besoin de a = T - g
:
linear_acceleration[0] = event.values[0] - gravity[0];
linear_acceleration[1] = event.values[1] - gravity[1];
linear_acceleration[2] = event.values[2] - gravity[2];
Remarquez comment cela calcule tout élément par élément car il s'agit d'une opération vectorielle.
La partie délicate est de trouver gravity
car il n'y a qu'un seul accéléromètre dans le téléphone qui mesure à la fois la gravité ET les autres forces en même temps. Nous avons 2 forces différentes que nous voulons trouver à partir d'un seul capteur. Si nous pouvions seulement examiner les forces à un moment isolé, nous ne serions pas en mesure d'extraire les informations. Cependant, nous obtenons des échantillons sur une plage de temps et en examinant comment les forces changent au fil du temps, nous pouvons extraire les informations.
Cela signifie que nous devons filtrer les résultats de cette source en fonction de la vitesse à laquelle ces forces changent. L'amplitude de l'accélération due à la gravité ne change pas rapidement car elle ne change pas du tout. La gravité est une force constante. Cependant, d'autres forces changeront avec le temps. Si nous filtrons les forces qui changent lentement comme la gravité en utilisant un filtre passe-haut, les forces restantes sont celles qui changent rapidement comme les forces appliquées au téléphone. C'est pourquoi le filtre passe-haut est utilisé.
Filtre passe-bas : passe les signaux basse fréquence et réduit l'amplitude des signaux avec des fréquences supérieures à la fréquence seuil
Filtre passe-haut : passe les signaux haute fréquence et réduit l'amplitude des signaux avec des fréquences inférieures à la fréquence seuil
Si vous regardez le documentation , il dit: "afin de mesurer l'accélération réelle de l'appareil, la contribution de la force de gravité doit être éliminée. Cette peut être obtenu en appliquant un filtre passe-haut . Inversement, un filtre passe-bas peut être utilisé pour isoler la force de gravité. "
Vous pouvez consulter ce tutoriel sur le filtrage passe-bas: http://www.raweng.com/blog/2013/05/28/applying-low-pass-filter-to-Android-sensors-readings/
En lisant les documents sur http://developer.Android.com/reference/Android/hardware/SensorEvent.html#values , vous pouvez voir que vous pouvez accéder à a valeurs sur tous les axes x, y, z en faisant:
values[0] - a on x axis
values[1] - a on y axis
values[2] - a on z axis
La sortie de l'accéléromètre inclut le bruit si vous soustrayez directement de ces valeurs qui incluent le bruit. Pour éliminer le bruit, il est nécessaire de mettre en œuvre des filtres passe-haut et passe-bas.
J'utilise généralement cette formule pour filtrer les données des données du capteur d'accélomètre sortant vers les données du capteur linéaire (comme le gyroscope). Utilisez-le si vous n'êtes pas sûr qu'il existe un capteur gyroscopique intégré.
private float[] values;
private float[] valuesN;
private float[] prev;
private float[] prevHF;
private boolean doHPF = false;
// ind - index of three dimensions (x, y, z)
private void makeHPFf() {
for (int ind = 0; ind < 3; ind++) {
valuesN[ind] = values[ind] * 0.002f * 9.8f;
if (doHPF)
values[ind] = valuesN[ind] - prev[ind] + (prevHF[ind] * 0.8f);
prev[ind] = valuesN[ind];
prevHF[ind] = values[ind];
}
if (!doHPF)
doHPF = true;
}