Tengo unos 32 segundos de datos de acelerómetro de un escenario de conducción básico de 25 MPH en carreteras normales junto con unos 7 baches y un tramo de carretera irregular. El acelerómetro está montado en el tablero de instrumentos de mi automóvil con cinta adhesiva de doble cara.
Problema: Tengo todos los datos que son ruidosos del acelerómetro, y necesito hacer una manera simple de detectar que ha ocurrido un evento de baches. A continuación hay varios gráficos de datos en el dominio del tiempo y FFT. El acelerómetro mide en GForce
Básicamente, quiero que mi arduino sepa que ha ocurrido un bache con bastante precisión y que no usa matemáticas y técnicas de nivel de posgrado.
El acelerómetro muestreado a 100 Hz tiene un simple FILTRO DE PASO BAJO RC DE 50 HZ EN EL EJE Z
Here is the CSV data for the 32 seconds of accelerometer readings TIME, GFORCE format:
http://hamiltoncomputer.us/50HZLPFDATA.CSV
ACTUALIZACIÓN: Este es el ancho de banda completo RAW del acelerómetro 1000HZ muestreado a la velocidad de muestreo más alta que pude obtener en Arduino. Descarga directa de archivos CSV: aproximadamente 112 segundos de datos
http://hamiltoncomputer.us/RAWUNFILteredFULLBANDWIDTH500HZ.csv
La traza negra es RAW sin filtrar datos del acelerómetro: la traza azul es filtrada por un filtro de detención de banda basado en las frecuencias extremas encontradas en FFT, Dominate 2HZ y 12HZ.
El evento de baches se ve así en el dominio del tiempo:
no estoy seguro de cuál es el componente de 10 a 15 HZ en el FFT, ¿es ese el bache real, o es el salto de las ruedas contra la carretera, o es la frecuencia de resonancia del automóvil?
FFT:
parece que son los eventos reales de baches, aquí hay un HPF @ 13HZ Las características dominantes de los baches parecen mejoradas
Quiero poder detectar y contar los baches en tiempo real
Parece ser contrario a la intuición, la suspensión debería moverse mucho más lento que un HZ de 10 a 13, lo que podría causar mareo.
ACTUALIZAR:
Según las sugerencias de AngryEE, utilicé el ancho de banda completo del acelerómetro 1000HZ y la velocidad de muestreo máxima que pude obtener en el arduino.
FFT:
Aquí hay una muestra de datos del evento de baches y algunos baches y ruido de la carretera a su alrededor:
Se agregó el circuito del detector de envoltura de diodo, la salida se ve igual ... El acelerómetro siempre emite 0 a 3.3Voltios no negativo ...
ACTUALIZAR:
De muchas pruebas en carretera, nunca excedí 1.6G de hasta 45 MPH en mi automóvil en el eje Z, usé rand () para generar una aceleración pseudoaleatoria de Gforce.
Mi idea es que si puedo ver ventanas de datos de 1 a 3 segundos, puedo calcular el desplazamiento del eje Z, pero estaba preocupado por la deriva del acelerómetro y los errores en la integración. No necesito ni siquiera un 90% de precisión aquí,> 70% sería bueno, pero si estoy viendo el desplazamiento de uno a tres segundos a la vez, ¿sería posible hacerlo en tiempo real? De esta manera puedo ver si el desplazamiento es mayor que como 1 pulgada, 2 pulgadas, 5 pulgadas. Cuanto mayor era el desplazamiento, más rugosa era la protuberancia o el bache:
¿Puede verificar si estoy haciendo esto correctamente? Básicamente lo configuré en mi escritorio, usando rand () para generar una aceleración aleatoria de -1.6 a 1.6 G, capturando 3 segundos de datos a una velocidad de muestreo simulada de 50 HZ
Si, como si ejecutaras * nix, estoy usando Sleep () desde Windows.h para hacer que la demora de 20 ms, la frecuencia de muestreo de 50 Hz
Solo quería ver si el código le parece correcto, todavía no hice el búfer cicular, estoy un poco confundido sobre cómo implementarlo: el código comentado es de la clase en la que estoy trabajando para ello , pero aún no lo entiendo al 100%. Un búfer circular permitiría mover contiguamente ventanas de datos, ¿verdad?
#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;
}
Ejecución de muestra:
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 . . .