J'ai environ 32 secondes de données d'accéléromètre d'un scénario de conduite de base sur des routes normales de 25 MPH, avec environ 7 nids de poule et un morceau de route accidenté. L'accéléromètre est monté sur le tableau de bord de ma voiture avec du ruban adhésif double face.
Problème: J'ai toutes les données bruyantes de l'accéléromètre et je dois trouver un moyen simple de détecter qu'un événement de nid-de-poule s'est produit. Vous trouverez ci-dessous plusieurs graphiques de données dans le domaine temporel et la FFT. L'accéléromètre mesure en GForce
Fondamentalement, je veux que mon arduino sache qu'un nid de poule s'est produit avec une assez grande précision et sans utiliser de mathématiques et de techniques de niveau supérieur.
L'accéléromètre échantillonné à 100 Hz a un simple filtre passe-bas RC 50 Hz sur l'axe Z
Here is the CSV data for the 32 seconds of accelerometer readings TIME, GFORCE format:
http://hamiltoncomputer.us/50HZLPFDATA.CSV
MISE À JOUR: Il s'agit de la bande passante RAW complète de l'accéléromètre 1000HZ échantillonné au taux d'échantillonnage le plus élevé que j'ai pu obtenir sur Arduino. Téléchargement direct de fichiers CSV: environ 112 secondes de données
http://hamiltoncomputer.us/RAWUNFILTEREDFULLBANDWIDTH500HZ.csv
La trace noire est des données d'accéléromètre RAW non filtrées: la trace bleue est filtrée par un filtre coupe-bande basé sur les fréquences extrêmes trouvées dans FFT, Dominate 2HZ et 12HZ.
L'événement de nid-de-poule ressemble à ceci dans le domaine temporel:
vous ne savez pas quel est le composant 10 à 15 Hz dans la FFT, est-ce le nid-de-poule réel, ou est-ce le saut de roue des roues contre la route, ou est-ce la fréquence de résonance de la voiture?
FFT:
semble que ce sont les événements réels des nids de poule, voici un HPF @ 13HZ Les caractéristiques dominantes des nids de poule semblent améliorées
Je veux pouvoir détecter et compter les nids de poule en temps réel
Il semble être contre-intuitif que la suspension devrait bouger beaucoup plus lentement qu'un 10 à 13 HZ qui provoquerait le mal des transports je crois
MISE À JOUR:
Selon les suggestions d'AngryEE, j'ai utilisé toute la bande passante de l'accéléromètre 1000HZ et la fréquence d'échantillonnage maximale que je pouvais obtenir sur l'arduino.
FFT:
voici un échantillon de données de l'événement de nid-de-poule et quelques bosses et le bruit de la route autour de lui:
Ajout du circuit détecteur d'enveloppe de diode, la sortie est la même ... L'accéléromètre produit toujours 0 à 3,3 Volts non négatifs ...
MISE À JOUR:
De nombreux essais routiers, je n'ai jamais dépassé 1,6G jusqu'à 45 MPH dans ma voiture sur l'axe Z, j'ai utilisé rand () pour générer une accélération pseudo-aléatoire Gforce.
Mon idée est que si je peux regarder des fenêtres de données de 1 à 3 secondes, je peux calculer le déplacement de l'axe Z, mais je m'inquiétais de la dérive de l'accéléromètre et des erreurs d'intégration. Je n'ai pas besoin d'être précis à 90% ici,> 70% serait bien, mais si je regarde le déplacement à une à trois secondes à la fois, serait-il possible de le faire en temps réel? De cette façon, je peux voir si le déplacement est supérieur à 1 pouce, 2 pouces, 5 pouces. Plus le déplacement était important, plus la bosse ou le nid de poule était rugueux:
Pouvez-vous vérifier si je fais cela correctement, j'ai essentiellement configuré sur mon bureau, en utilisant rand () pour générer une accélération aléatoire de -1,6 à 1,6 G, capturant 3 secondes de données @ un taux d'échantillonnage simulé de 50 Hz
Si comme vous exécutez * nix, j'utilise Sleep () à partir de Windows.h pour faire le retard de 20 ms, un taux d'échantillonnage de 50 Hz
Je voulais juste voir si le code vous convenait, je n'ai pas encore fait le tampon ciculaire, je suis un peu confus sur la façon de l'implémenter: le code commenté, vient de la classe sur laquelle je travaille , mais je ne le comprends pas encore à 100%. Un tampon circulaire permettrait de déplacer de façon contiguë des fenêtres de données non?
#include <cstdlib>
#include <iostream>
#include <iomanip>
#include <ctime> // USED BY RAND
#include <windows.h> // Used for delay
using namespace std;
#define SAMPLE_RATE 0.020 // Sample rate in Milliseconds
#define GRAVITYFT_SEC 32 // Gravity velocity 32 feet/sec
#define INCH_FOOT 12 // 12 inches in foot, from velocity to inch displacement calculation
int main(int argc, char *argv[])
{
srand((unsigned)time(0)); // SEED RAND() for simulation of Geforce Readings
// SIMULATING ACCELERATION READINGS INTO A CIRCULAR BUFFER
// circular_buffer Acceleration; // Create a new Circular buffer for Acceleration
// cb_init(&Acceleration, 150, 4); // Sampling @ 50HZ, 3 seconds of data = 150, size is float data of 4 bytes
//Simulate a sample run of Acceleration data using Rand()
// WE WILL BE SIMULATING "RANDOM" GEFORCE RATINGS using the rand() function constraining to -1.6 to 1.6 GFORCE
// These ratings are consistent with our road tests of apparently random vibration and Geforce readings not exceeding about 1.6 G's
float Gforce[150]; // Random Geforce for 3 second window of data
float velocity[150]; // Hold velocity information
float displacement[150]; // Hold Displacement information
float LO = -1.6; // Low GForce limit recorded from 6 road tests at different speeds
float HI = 1.6; // High GForce limit recorded from 6 road tests at different speeds
for(int i = 0; i < 150; i++) // 3 Second iwndow of random acceleration data
{
Gforce[i] = LO + (float)rand()/((float)RAND_MAX/(HI-LO)); // Borrowed from Stackexchange : http://stackoverflow.com/questions/686353/c-random-float
if( i == 0) // Initial values @ first Acceleration
{
velocity[i] = Gforce[i] * SAMPLE_RATE * GRAVITYFT_SEC; // Initial velocity
displacement[i] = velocity[i] * SAMPLE_RATE * INCH_FOOT; // Initial Displacement
}
else
{
velocity[i] = velocity[i-1] + (Gforce[i] * SAMPLE_RATE * GRAVITYFT_SEC); // Calculate running velocity into buffer
displacement[i] = displacement[i-1] +(velocity[i] * SAMPLE_RATE * INCH_FOOT); // Calculate running displacement into buffer
}
//cout << endl << Gforce[i]; // Debugging
//cb_push_back(&Acceleration, &Gforce[i]); // Push the GeForce into the circular buffer
Sleep(SAMPLE_RATE*1000); // 20mS delay simulates 50HZ sampling rate Sleep() expects number in mS already so * 1000
}
// PRINT RESULTS
for (int j = 0; j < 150; j++)
{
cout << setprecision (3) << Gforce[j] << "\t\t" << velocity[j] << "\t\t" << displacement[j] << endl;
}
// READ THE BUFFER
//cb_free(&Acceleration); // Pervent Memory leaks
system("PAUSE");
return EXIT_SUCCESS;
}
Exemple d'exécution:
GFORCE FT/SEC Inch Displacement Z axis
-0.882 -0.565 -0.136
0.199 -0.437 -0.24
-1.32 -1.29 -0.549
0.928 -0.691 -0.715
0.6 -0.307 -0.788
1.47 0.635 -0.636
0.849 1.18 -0.353
-0.247 1.02 -0.108
1.29 1.85 0.335
0.298 2.04 0.824
-1.04 1.37 1.15
1.1 2.08 1.65
1.52 3.05 2.38
0.078 3.1 3.12
-0.0125 3.09 3.87
1.24 3.88 4.8
0.845 4.42 5.86
0.25 4.58 6.96
0.0463 4.61 8.06
1.37 5.49 9.38
-0.15 5.39 10.7
0.947 6 12.1
1.18 6.75 13.7
-0.791 6.25 15.2
-1.43 5.33 16.5
-1.58 4.32 17.5
1.52 5.29 18.8
-0.208 5.16 20.1
1.36 6.03 21.5
-0.294 5.84 22.9
1.22 6.62 24.5
1.14 7.35 26.3
1.01 8 28.2
0.284 8.18 30.1
1.18 8.93 32.3
-1.43 8.02 34.2
-0.167 7.91 36.1
1.14 8.64 38.2
-1.4 7.74 40
-1.49 6.79 41.7
-0.926 6.2 43.2
-0.575 5.83 44.6
0.978 6.46 46.1
-0.909 5.87 47.5
1.46 6.81 49.2
0.353 7.04 50.8
-1.12 6.32 52.4
-1.12 5.6 53.7
-0.141 5.51 55
0.463 5.8 56.4
-1.1 5.1 57.6
0.591 5.48 59
0.0912 5.54 60.3
-0.47 5.23 61.5
-0.437 4.96 62.7
0.734 5.42 64
-0.343 5.21 65.3
0.836 5.74 66.7
-1.11 5.03 67.9
-0.771 4.54 69
-0.783 4.04 69.9
-0.501 3.72 70.8
-0.569 3.35 71.6
0.765 3.84 72.5
0.568 4.21 73.5
-1.45 3.28 74.3
0.391 3.53 75.2
0.339 3.75 76.1
0.797 4.26 77.1
1.3 5.09 78.3
0.237 5.24 79.6
1.52 6.21 81.1
0.314 6.41 82.6
0.369 6.65 84.2
-0.598 6.26 85.7
-0.905 5.68 87.1
-0.732 5.22 88.3
-1.47 4.27 89.4
0.828 4.8 90.5
0.261 4.97 91.7
0.0473 5 92.9
1.53 5.98 94.3
1.24 6.77 96
-0.0228 6.76 97.6
-0.0453 6.73 99.2
-1.07 6.04 101
-0.345 5.82 102
0.652 6.24 104
1.37 7.12 105
1.15 7.85 107
0.0238 7.87 109
1.43 8.79 111
1.08 9.48 113
1.53 10.5 116
-0.709 10 118
-0.811 9.48 121
-1.06 8.8 123
-1.22 8.02 125
-1.4 7.13 126
0.129 7.21 128
0.199 7.34 130
-0.182 7.22 132
0.135 7.31 133
0.885 7.87 135
0.678 8.31 137
0.922 8.9 139
-1.54 7.91 141
-1.16 7.16 143
-0.632 6.76 145
1.3 7.59 146
-0.67 7.16 148
0.124 7.24 150
-1.19 6.48 151
-0.728 6.01 153
1.22 6.79 154
-1.33 5.94 156
-0.402 5.69 157
-0.532 5.35 159
1.27 6.16 160
0.323 6.37 162
0.428 6.64 163
0.414 6.91 165
-0.614 6.51 166
1.37 7.39 168
0.449 7.68 170
0.55 8.03 172
1.33 8.88 174
-1.2 8.11 176
-0.641 7.7 178
-1.59 6.69 179
1.02 7.34 181
-0.86 6.79 183
-1.55 5.79 184
-0.515 5.46 186
0.352 5.69 187
0.824 6.22 188
1.14 6.94 190
-1.03 6.29 192
-1.13 5.56 193
0.139 5.65 194
0.293 5.84 196
1.08 6.53 197
-1.23 5.75 199
-1.1 5.04 200
-1.17 4.29 201
-0.8 3.78 202
-0.905 3.2 203
-0.0769 3.15 203
-0.323 2.95 204
-0.0186 2.93 205
Press any key to continue . . .