Ich habe Beschleunigungsmesserdaten für ein grundlegendes Fahrszenario von 25 MPH auf normalen Straßen im Wert von 32 Sekunden zusammen mit etwa 7 Schlaglöchern und einem unebenen Straßenabschnitt. Der Beschleunigungsmesser ist mit doppelseitigem Klebeband am Armaturenbrett meines Autos angebracht.
Problem: Ich habe alle Daten, die vom Beschleunigungsmesser verrauscht sind, und ich muss auf einfache Weise feststellen, dass ein Schlaglochereignis aufgetreten ist. Nachfolgend sind einige Diagramme von Daten in Zeitdomäne und FFT aufgeführt. Der Beschleunigungsmesser misst in GForce
Grundsätzlich möchte ich, dass mein Arduino weiß, dass ein Schlagloch mit ziemlich großer Genauigkeit aufgetreten ist und keine Mathematik und Techniken auf Hochschulniveau verwendet.
Der bei 100 Hz abgetastete Beschleunigungsmesser verfügt über einen einfachen 50-Hz-RC-LOW-PASS-Filter auf der Z-Achse
Here is the CSV data for the 32 seconds of accelerometer readings TIME, GFORCE format:
http://hamiltoncomputer.us/50HZLPFDATA.CSV
UPDATE: Dies ist die RAW-Bandbreite des Beschleunigungsmessers 1000 Hz, abgetastet mit der höchsten Abtastrate, die ich auf Arduino bekommen konnte. Direkter Download der CSV-Datei: Ungefähr 112 Sekunden Daten
http://hamiltoncomputer.us/RAWUNFILTEREDFULLBANDWIDTH500HZ.csv
Schwarze Spur ist RAW-ungefilterte Beschleunigungsmesserdaten: Die blaue Spur wird von einem Bandsperrfilter basierend auf den Extremfrequenzen von FFT, Dominate 2HZ und 12HZ gefiltert.
Das Schlaglochereignis sieht im Zeitbereich so aus:
Sie sind sich nicht sicher, welche 10 bis 15 Hz-Komponente in der FFT enthalten ist, ist dies das eigentliche Schlagloch, oder ist es der Radsprung der Räder gegen die Straße, oder ist es die Resonanzfrequenz des Autos?
FFT:
Es scheint, als ob es sich um die tatsächlichen Schlaglochereignisse handelt. Hier ist ein HPF bei 13 Hz. Die dominanten Merkmale der Schlaglöcher scheinen verstärkt zu sein
Ich möchte Schlaglöcher in Echtzeit erkennen und zählen können
Es scheint kontraintuitiv zu sein, dass sich die Federung viel langsamer als 10 bis 13 Hz bewegen sollte, was meiner Meinung nach Reisekrankheit verursachen würde
AKTUALISIEREN:
Gemäß den Vorschlägen von AngryEE habe ich die volle Bandbreite des Beschleunigungsmessers 1000 Hz und die maximale Abtastrate verwendet, die ich auf dem Arduino erreichen konnte.
FFT:
Hier ist ein Beispiel von Daten des Schlaglochereignisses und einiger Unebenheiten und Straßengeräusche:
Die Diodenhüllkurvendetektorschaltung wurde hinzugefügt, der Ausgang sieht gleich aus ... Der Beschleunigungsmesser gibt immer 0 bis 3,3 Volt aus, nicht negativ ...
AKTUALISIEREN:
Bei vielen Straßentests habe ich 1,6 G bis zu 45 MPH in meinem Auto auf der Z-Achse nie überschritten. Ich habe rand () verwendet, um eine pseudozufällige Gforce-Beschleunigung zu generieren.
Meine Idee ist, wenn ich Datenfenster von 1 bis 3 Sekunden betrachten kann, die Verschiebung der Z-Achse berechnen kann, aber ich war besorgt über die Drift des Beschleunigungsmessers und über Fehler bei der Integration. Ich muss hier nicht einmal 90% genau sein,> 70% wären nett, aber wenn ich die Verschiebung mit ein bis drei Sekunden auf einmal betrachte, wäre das in Echtzeit möglich? Auf diese Weise kann ich sehen, ob der Versatz größer als 1 Zoll, 2 Zoll, 5 Zoll ist. Je größer die Verschiebung, desto rauer war die Erhebung oder das Schlagloch:
Kannst du überprüfen, ob ich das richtig mache? Ich habe es im Grunde genommen auf meinem Desktop eingerichtet und benutze rand (), um eine zufällige Beschleunigung von -1,6 auf 1,6 G zu erzeugen und 3 Sekunden Daten mit einer simulierten Abtastrate von 50 Hz zu erfassen
Wenn Sie * nix ausführen, verwende ich Sleep () von Windows.h, um die Abtastrate von 20 ms Verzögerung und 50 Hz zu ermitteln
Ich wollte nur sehen, ob der Code für Sie richtig aussieht. Ich habe noch keinen Cicular Buffer erstellt. Ich bin ein bisschen verwirrt darüber, wie er implementiert wird. Der auskommentierte Code stammt aus der Klasse, an der ich arbeite , aber ich verstehe es noch nicht 100%. Ein Ringpuffer würde es erlauben, Datenfenster zusammenhängend zu verschieben, oder?
#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;
}
Probelauf:
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 . . .