Analiza charakterystyki danych akcelerometru i zaprojektowanie filtra

14

Mam dane z przyspieszeniomierza o wartości około 32 sekund w podstawowym scenariuszu jazdy 25MPH normalnych dróg wraz z uderzeniem około 7 dziur i nierównego odcinka drogi. Akcelerometr jest zamontowany na desce rozdzielczej mojego samochodu za pomocą dwustronnej taśmy.

Problem: Mam wszystkie dane, które są zaszumione z akcelerometru, i muszę w prosty sposób wykryć, że wystąpiło zdarzenie w wyboju. Poniżej znajduje się kilka wykresów danych w dziedzinie czasu i FFT. Akcelerometr mierzy w GForce

Zasadniczo chcę, aby moje arduino wiedziało, że dziura pojawiła się z dość dużą dokładnością i nie używa matematyki i technik na poziomie magisterskim.

Akcelerometr próbkowany przy częstotliwości 100 Hz ma prosty filtr o niskiej częstotliwości 50 Hz RC NA OSI Z

Here is the CSV data for the 32 seconds of accelerometer readings TIME, GFORCE format:

http://hamiltoncomputer.us/50HZLPFDATA.CSV

AKTUALIZACJA: Jest to pełna przepustowość RAW akcelerometru próbkowanego 1000 Hz z najwyższą częstotliwością próbkowania, jaką mogłem uzyskać na Arduino. Bezpośrednie pobieranie pliku CSV: około 112 sekund danych

http://hamiltoncomputer.us/RAWUNFILTEREDFULLBANDWIDTH500HZ.csv

Czarny ślad jest niefiltrowanym RAW Dane akcelerometru: Niebieski ślad jest filtrowany przez filtr pasmowy na podstawie ekstremalnych częstotliwości występujących w FFT, Dominate 2HZ i 12HZ.

http://img213.imageshack.us/img213/194/rollout.png

Wydarzenie wyboju wygląda tak w domenie czasu: wprowadź opis zdjęcia tutaj

nie jestem pewien, jaki składnik 10 do 15 HZ znajduje się w FFT, czy jest to rzeczywisty otwór, czy jest to podskakiwanie kół do drogi, czy też jest to częstotliwość rezonansowa samochodu?

FFT:

FFT

wygląda na to, że są to rzeczywiste zdarzenia wybojowe, tutaj jest HPF @ 13HZ Dominujące cechy dziur wydają się ulepszone

http://img69.imageshack.us/img69/8663/hpf13potholefft.png

Chcę być w stanie wykrywać i liczyć dziury w czasie rzeczywistym

Wydaje się to sprzeczne z intuicją, zawieszenie powinno poruszać się o wiele wolniej niż 10 do 13 Hz, co spowodowałoby chorobę lokomocyjną

AKTUALIZACJA:

Zgodnie z sugestiami AngryEE wykorzystałem pełną szerokość pasma akcelerometru 1000 Hz i maksymalną częstotliwość próbkowania, jaką mogłem uzyskać na arduino.

FFT:

FFT NIEFILTOWANE DANE PEŁNA SZEROKOŚĆ PASMA

oto przykładowy fragment danych o zdarzeniu w wyboju oraz niektóre nierówności i hałas drogowy:

ZDARZENIE Z NIEPOKOJOWYCH DANYCH

Dodano obwód detektora obwiedni diody, wyjście wygląda tak samo ... Akcelerometr zawsze ma moc wyjściową od 0 do 3,3 V, a nie ujemną ... wprowadź opis zdjęcia tutaj

AKTUALIZACJA:

Z wielu testów drogowych nigdy nie przekroczyłem wartości 1.6G do 45 MPH w moim samochodzie na osi Z, użyłem rand () do wygenerowania pseudolosowego przyspieszenia Gforce.

Mój pomysł polega na tym, że jeśli mogę spojrzeć na okna danych z 1 do 3 sekund, mogę obliczyć przesunięcie osi Z, ale martwiłem się o dryft akcelerometru i błędy w integracji. Nie muszę tu być nawet 90% dokładny,> 70% byłoby miło, ale jeśli patrzę na przesunięcie od jednej do trzech sekund na raz, czy byłoby to możliwe w czasie rzeczywistym? W ten sposób widzę, czy przemieszczenie jest większe niż jak 1 cal, 2 cale, 5 cali. Im większe przesunięcie, tym bardziej nierówny był guz lub dziura:

Czy możesz sprawdzić, czy robię to dobrze, po prostu skonfigurowałem na pulpicie, używając rand () do generowania losowego przyspieszenia od -1,6 do 1,6 G, rejestrując 3 sekundy danych przy symulowanej częstotliwości próbkowania 50 Hz

Jeśli chcesz uruchomić * nix, używam Sleep () z Windows.h, aby opóźnić 20 ms, częstotliwość próbkowania 50 Hz

Chciałem tylko sprawdzić, czy kod wygląda dobrze dla ciebie, nie zrobiłem jeszcze bufora, jestem trochę zdezorientowany, jak go zaimplementować: skomentowany kod pochodzi z klasy, nad którą pracuję , ale jeszcze tego nie rozumiem w 100%. Okrągły bufor pozwoliłby na ciągłe przesuwanie okien danych, prawda?

#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;
}

Przykładowy przebieg:

    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 . . .
zacharoni16
źródło
3
Bardzo szczegółowy opis. Jednak: edytowanie tego w celu sformułowania konkretnego, stosunkowo wąskiego pytania pomogłoby uzyskać ukierunkowane odpowiedzi.
Anindo Ghosh
Napisałem ogólne, szczegółowe pytanie, potrzebuję sposobu na wykrycie, że doszło do dziury na podstawie surowego, hałaśliwego sygnału akcelometru. Wyodrębnianie przydatnych funkcji lub metody wykrywania, które pozwoliłyby mikrokontrolerowi, np. Arduino, na wykrycie zdarzenia
wybojowego,
Ponieważ zdarzenie w wyboju jest wolniejsze niż wibracje, które istnieją niezależnie od wyboju, prawdopodobnie powinieneś je LPF i zwiększyć ładną nierówność, która zbliża się do wyłomu. Filtr średniej ruchomej może to zrobić. Aby ułatwić życie, możesz również rozważyć użycie wartości abs pomiaru przed LPF, ponieważ wydaje się, że twój dziura charakteryzuje się nawet pojedynczym pakietem o zwiększonej amplitudzie obwiedni, modulowanym przez częstotliwość drgań samochodu.
Chintalagiri Shashank
Zaktualizowano informacje, dziękuję i będę pracował nad średnią ruchomą, rezonans zawieszenia wydaje się wynosić około 12,5 Hz? Zakładam, że LPF w sprzęcie miałby tam odcięcie
zacharoni16
Podaj dobry przykładowy plik CSV lub coś takiego. Podane powyżej dane nie wydają się działać jako link.
Olin Lathrop

Odpowiedzi:

13

Wygląda na to, że można to rozwiązać przez dość proste filtrowanie. Oto twoje oryginalne dane:

To za dużo, aby zobaczyć, co dzieje się w indywidualnym wydarzeniu na odpowiednim poziomie szczegółowości. Oto tylko dane z drugiego 26 do 28:

Początkowo myślałem, że to filtr dolnoprzepustowy, ale to nie działa, ponieważ nie ma tam sygnału niskiej częstotliwości. Zamiast tego rośnie amplituda sygnału wysokiej częstotliwości. Oto dolnoprzepustowy nałożony na oryginał:

Zauważ, że wynika to z „średniej” sygnału całkiem dobrze, a nie podczas zdarzenia wyboju. Jeśli odejmiemy tę średnią od oryginalnego sygnału, pozostanie nam znacznie więcej odchyleń od tej średniej podczas wydarzenia niż w innym przypadku. Innymi słowy, tak naprawdę chcemy filtra górnoprzepustowego. Zrobimy to, odejmując dolnoprzepustowy od oryginału, ponieważ tak się tu dostaliśmy, ale w systemie produkcyjnym zrobiłbyś to przez jawne filtrowanie górnoprzepustowe. Tak czy inaczej, oto oryginał z filtrem górnoprzepustowym:

Wskazuje to teraz na oczywiste podejście do wykrywania zdarzenia. Podczas imprezy występuje znacznie większa amplituda sygnału niż w innym przypadku. Możemy to wykryć, obliczając RMS i stosując filtrowanie dolnoprzepustowe:

Powiększając wszystkie dane, widzimy:

To wyraźnie identyfikuje pięć zdarzeń w danych, chociaż nie wiem, czy to właśnie te dane mają pokazać. Przyglądając się bliżej wydarzeniom, zauważasz, że każde z nich ma niskie spadki około 1 sekundy przed i po szczytach. Oznacza to, że można zrobić więcej, jeśli próg sygnału RMS, jaki jest teraz, nie jest wystarczający. Na przykład prosty algorytm, który szukał wysokości punktu względem najniższej w ciągu 1 sekundy w obie strony, powinien dodatkowo zmniejszyć szum tła. Innym sposobem na powiedzenie o tym samym jest rozróżnienie tego sygnału w poszukiwaniu wzrostu w ciągu 1 sekundy. Zdarzenie w wyboju zostanie wówczas wykryte przez dublet, co oznacza wysoki pik, po którym następuje niski pik.

Innym sposobem spojrzenia na to jest pasmowe przekazywanie sygnału RMS. Jest już filtrowane dolnoprzepustowo, ale ponieważ szukasz nagłych zdarzeń z silnymi zboczami, odsuwanie niektórych niskich częstotliwości powinno działać również w celu zmniejszenia szumu tła.

Stąd jest wiele sposobów na udoskonalenie sygnału, ale mam nadzieję, że pokazałem, jak uzyskać użyteczny wynik co najmniej pierwszego przejścia.

Dodany:

Byłem ciekawy, jak dobrze będzie wyglądało zanurzenie po obu stronach szczytu, więc spróbowałem. Użyłem filtru nieliniowego, zaczynając od RMS z poprzedniego wykresu. Wartość każdego punktu jest minimalną wartością powyżej najniższego punktu w poprzedniej sekundzie i najniższego punktu w następnej sekundzie. Wynik wygląda całkiem dobrze:

Najniższy z 5 pików jest ponad 3 razy wyższy niż najwyższy szum tła. To oczywiście zakładając, że te 5 nierówności reprezentuje zdarzenia, które chcesz wykryć, a reszta nie.

Dodano w odpowiedzi na komentarze:

Zrobiłem filtry w dziedzinie czasu, więc nie znam bezpośrednio odpowiedzi częstotliwościowej. Dla filtra dolnoprzepustowego splotłem sygnał wejściowy z jądrem filtra COS ^ 2. Jeśli dobrze pamiętam, promień (odległość od środka do krawędzi) jądra wynosi kilka 100 ms. Eksperymentowałem z tą wartością, dopóki fabuła nie wyglądała dobrze. Do filtrowania dolnoprzepustowego RMS użyłem tego samego jądra filtra, ale tym razem o promieniu około sekundy. Nie pamiętam dokładnie. Eksperymentuj, aż uzyskasz dobre wyniki.

Filtr nieliniowy nie wykrył dubletów. Jak powiedziałem, znalazłem różnicę między bieżącym punktem a najniższym ze wszystkich punktów w ciągu 1 sekundy wcześniej, a także różnicę między bieżącym punktem a najniższym ze wszystkich punktów w ciągu 1 sekundy po. Potem wziąłem min z tych dwóch.

Oprogramowanie, którego użyłem, było programem, który zhackowałem w tym celu. Miałem już różne procedury do odczytu i zapisu plików CSV, więc wszystko, co musiałem napisać, to kod filtrujący, co jest bardzo proste. Reszta została wykonana przy użyciu istniejących programów do manipulowania i drukowania plików CSV.

Olin Lathrop
źródło
WOW, to bardzo ekscytujące wyniki, masz świetny sposób na wyjaśnienie rzeczy w praktyczny sposób i cieszę się, że wróciłem do domu i zacząłem nad tym pracować! Jestem ciekawy, jakiej częstotliwości odcięcia użyłeś w HPF, a odcięcia LPF dla sygnału RMS, który wygląda idealnie. Ponadto, nieliniowy filtr, którego użyłeś do wykrycia dubletów, zrobiłeś to w Matlabie lub w aplikacji do projektowania? Chcę spróbować zaprojektować to również sprzętowo, 5 szczytów, które otrzymujesz, pokrywa się z 5 dziurami, które trafiłem, Świetny wynik! Mam Matlaba i również używam SciDavis
zacharoni16
@zach: Spróbuję zaktualizować moją odpowiedź, aby odpowiedzieć na niektóre pytania. Niestety moja odpowiedź została przekonwertowana na wiki społeczności, więc czekam na modyfikację, aby to naprawić. To CW naprawdę jest do kitu, gdy spędzasz na czymś czas, a potem nagle nie jesteś już właścicielem.
Olin Lathrop
@OlinLathrop Będziesz musiał przekonwertować go z powrotem podczas edycji. Powinieneś mnie oflagować, aby wycofać go po zakończeniu edycji. Zrobię to teraz, ale nie zdziw się, jeśli będziesz musiał ponownie oflagować. Jeśli chodzi o skargę na CW, musimy cofnąć CW raz na 4-6 miesięcy, myślę, że mówisz o bardzo wąskim przypadku sytuacji, w której jest tak wiele zmian, a użytkownik nie chce być CW, i w porównaniu do radzenia sobie z Tony'm lub w innej sytuacji, chodzi o idealną flagę do radzenia sobie, łatwe i czyste cięcie. :)
Kortuk
1
@Andrew: Jak powiedziałem w ostatnim akapicie mojej odpowiedzi, mam różne programy w puszkach, które manipulują plikami CSV i procedurami bibliotecznymi, które ułatwiają ich czytanie i pisanie. Dodawanie powyższego kodu filtrującego jest szybkie i łatwe. Większość filtrów to tylko kilka wierszy kodu wykonywanych wiele razy. W przypadku jednorazowych testów, takich jak to, co zrobiłem powyżej, nie ma potrzeby efektywnego korzystania z procesora, ponieważ wszystko kończy się natychmiast. Na przykład wywoływałem funkcję COS, gdy było to potrzebne, zamiast budowania tabeli.
Olin Lathrop,
1
@OlinLathrop Widziałem to, o czym wspomniałeś w odpowiedzi, ale nie wiedziałem, czy masz skonfigurowane niestandardowe skrypty, może Matlab lub coś do uruchomienia tego lub co zrobiłeś. Czy możesz podzielić się tym, jak to robisz? Brzmi fascynująco. Czy używasz bibliotek graficznych w puszkach do wyświetlania danych wyjściowych, po prostu zrzucając i drukując w Excelu lub używając gnuplot / oktawy lub ...?
akohlsmith,
2

Dziury wykrywające krawędzie mogą powodować problemy. Odpowiedzią jest obwiednia drgań samochodów, ponieważ rzeczywiste drgania widoczne przez czujnik mają znacznie wyższe częstotliwości. Poszedłbym z RMS do prądu stałego, który reaguje na około 15 Hz lub więcej, a niskie przekazywanie rzeczy.

Chintalagiri Shashank
źródło
Właśnie wykonałem kolejny test z pełną przepustowością czujnika 1000 Hz i próbkowałem tak szybko, jak mogłem, przez szeregowy z Arduino. Uzyskiwanie podobnych wyników. Każda częstotliwość powyżej 17 Hz szybko zanika w porównaniu z dominującą częstotliwością 2 Hz i 13 Hz. Wciąż nie rozumiem, skąd pochodzą sygnały 9 do 13,5 Hz. Akcelerometr jest zamontowany na desce rozdzielczej. Zawieszenie oczywiście nie porusza się przy 9 do 13 Hz, inaczej skakałbym jak szalony. Nie jestem pewien, co masz na myśli przez RMS do DC?
zacharoni16
Twój akcelerometr jest w jakiś sposób przymocowany do samochodu. Nawet jeśli w jakiś sposób przykręciłeś coś do podwozia, śruby mogą tłumić i wzmacniać częstotliwości. Samochód jest wystarczająco złożoną bestią, aby rzeczy wibrowały na wielu różnych częstotliwościach. Istnieją obwody (i prawdopodobnie algorytmy matematyczne), które przekształcają sygnał prądu przemiennego na jego wartość skuteczną prądu stałego. Wyszukiwanie powinno je znaleźć. Może to pomóc w wygenerowaniu obwiedni sygnału poprzez zamianę wibracji o wysokiej częstotliwości na ich amplitudę.
Chintalagiri Shashank
Co z prostownikiem półfalowym (diodą)? ale to przekształciłoby wszystko w pozytywne szczyty, zdarzenie w dziurce ciągnie -G, czy to nie będzie problem?
zacharoni16
Nie spodziewam się, że to będzie problem. Twoje amplitudy wibracji wydają się być wystarczająco wysokie, aby być dominującym efektem. Jednak patrząc na twoje sygnały, sugerowałbym zamiast tego pełną rektyfikację fali, aby uniknąć pominięcia mniejszych dziur.
Chintalagiri Shashank
Shashack Dodano obwód Evelope zamieszczony powyżej, moc wyjściowa niewiele się zmieniła. Wybrałem stałą czasową RC na około 2mS, próbuję przy 2mS 500 Próbek / sekundę Napięcie akcelerometru jest zawsze między 0 a 3,3V, chociaż ... nigdy nie jest ujemne, więc dioda nie zadziała?
zacharoni16
2

Zamiast szukać filtru domeny częstotliwości lub progu, zalecam próbę znalezienia jądra dla „typowej” dziury i wykonanie z nim bieżącej korelacji. Byłoby to uważane za technikę dopasowywania szablonów i wydawałoby się, że nadaje się na platformę mikrokontrolera.

Szybki przegląd można znaleźć na stronie http://scribblethink.org/Work/nvisionInterface/vi95_lewis.pdf , a być może DOBBS, STEVEN E., NEIL M. SCHMITT i HALUK S. OZEMEK. „Wykrywanie QRS przez dopasowanie szablonu przy użyciu korelacji w czasie rzeczywistym na mikrokomputerze.” Journal of engineering of 9.3 (1984): 197-212.

Jeśli byłeś na grubszej platformie, poleciłbym obrócić falki.

Scott Seidman
źródło
Dzięki :) To wydaje się bardzo trudne do zrobienia, czy coś mi brakuje?
zacharoni16
Trudniejsze niż prosty filtr, ale większe prawdopodobieństwo, że zrobi to, co chcesz, gdy skończysz! Oczywiście, nie próbuj implementować go na mikrokontrolerze, dopóki nie sprawdzi się w Matlabie lub R
Scott Seidman
Aby uruchomić „filtr” w czasie rzeczywistym, prawdopodobnie potraktowałbyś go jako splot, a nie mnożenie w dziedzinie częstotliwości na każdym kroku. Korelacja krzyżowa (główne podejście do dopasowywania szablonów) byłaby tą samą dokładną operacją, z tym wyjątkiem, że skala czasowa odpowiedzi impulsowej nie zostałaby odwrócona, tak jak w przypadku splotu, i nazwalibyśmy tę odpowiedź impulsową „szablonem” . Teraz musisz tylko dowiedzieć się, jaki powinien być ten szablon.
Scott Seidman
Dzięki za odpowiedź, będę musiał przeprowadzić o wiele więcej badań i studiów, aby ją wdrożyć, ponieważ wydaje się, że jest ona powyżej mojego obecnego poziomu umiejętności. Doceniam jednak wysiłek
zacharoni16
2

Innym podejściem byłoby obliczenie ruchomej wariancji sygnału, aby sprawdzić, czy dziury naprawdę wystają. Oto funkcja matlaba dla filtra ruchomej wariancji, szerokość N punktów - sprytnie (jeśli sam muszę to powiedzieć) przy użyciu splotu do obliczeń

function y=movingvar(X,N)
% y=movingvar(X,N)
% Calculates N-point moving variance of  Vector X
% Highly recommend that N be odd (no error checking)
% Note: first and last N/2 points will be unreliable.
% Output will be a column vector.


X=X(:);
XSQR=X.*X;
convsig=ones(1,N);
y=(conv(convsig,XSQR)-(conv(convsig,X).^2)/N)/(N-1);

y=y(ceil(N/2):length(X)+floor(N/2));
Scott Seidman
źródło
Czy byłoby to podobne do obliczenia odchylenia standardowego?
zacharoni16
tak, po prostu do kwadratu
Scott Seidman
1

Początkowo sądzę, że filtr dolnoprzepustowy może być niewłaściwym typem filtra. Dziura jest zasadniczo zdarzeniem o wysokiej częstotliwości - takim jak funkcja kroku lub fala prostokątna. Samo spojrzenie na filtrowane dane 50 Hz sprawia, że ​​myślę, że tracisz informacje o wyboju - wszystko wygląda jak te same skręty bez wyraźnego rozróżnienia dla zdarzenia wyboju. Najpierw użyłbym filtra górnoprzepustowego, a następnie filtra dolnoprzepustowego o znacznie wyższej częstotliwości. Możesz całkowicie uniknąć filtrowania dolnoprzepustowego, jeśli twój akcelerometr jest już filtrowany w dolnoprzepustowym.

Po uzyskaniu filtrowanych danych górnoprzepustowych uważam, że prosty komparator z ustawionym progiem odpowiednio wykryje szczyty w danych przyspieszenia spowodowanych przez dziury i pozwoli je policzyć.

AngryEE
źródło
Zdejmę filtr RC 50 Hz, a następnie akcelerometr użyje domyślnego LPF 500 Hz lub 1000 Hz, który powinien być wystarczająco wysoki, aby uzyskać wibracje mechaniczne. Zwiększę częstotliwość próbkowania ze 100 Hz do 1000 Hz i opublikuję więcej danych. Dzięki za wgląd
zacharoni16,
Użyłem pełnej przepustowości akcelerometru i szybszego próbkowania, wydaje się, że otrzymuję podobne dane :( jest to mylące, jak filtrować i izolować zdarzenia
wybojów
Powiedziałem, aby użyć filtra HIGH pass, a nie niskiego. Byłbym zainteresowany, aby zobaczyć FFT niefiltrowanych danych.
AngryEE
Cóż, akcelerometr ma wbudowany LPF 1000 Hz i nie mogę tego zmienić. Wkrótce opublikuję FFT niefiltrowanych danych
zacharoni16
Nie musisz tego zmieniać - chcesz wysokich częstotliwości, które pochodzą z gwałtownego przyspieszenia po uderzeniu w dziurę, ale nie delikatnego kołysania podczas normalnej jazdy. Twój sygnał wydaje się charakteryzować wibracjami niskiej częstotliwości z kilkoma głównymi przejściowymi skokami. Chcesz, aby wysokie częstotliwości wychwytywały szybkie impulsy przejściowe, ale chcesz odrzucić stałe niskie częstotliwości. Dlatego prawdopodobnie należy odfiltrować co 50 Hz lub 100 Hz.
AngryEE