Filtr Kalmana od teorii do praktyki – #3 – Testy na STM32

Filtr Kalmana od teorii do praktyki – #3 – Testy na STM32

W poprzedniej części wyprowadziłem model stanowy dla systemu określającego położenie kątowe robota na podstawie danych z akcelerometru i żyroskopu. Zaprojektowałem filtr Kalmana dla tego modelu i sprawdziłem jego działanie z rzeczywistymi danymi pomiarowymi.

Teraz zajmę się przeniesieniem algorytmu na środowisko docelowe, czyli na STM32.

« Poprzedni artykuł z serii

Do implementacji filtru wykorzystałem płytkę STM32F4 Discovery i moduł MiniIMU-9v2 zawierający trzyosiowy żyroskop, akcelerometr i magnetometr. W programie będę korzystał z dwóch pierwszych czujników.

Struktura programu

Szkielet programu jest podobny do tego wykorzystanego w implementacji filtru alfa-beta. Na STMie działa system FreeRTOS, na którym uruchomiono następujące wątki:

  • wątek diagnostyczny - nadrzędny wątek z którego uruchamiane są wszystkie pozostałe.
  • wątek czujnika - co 100ms sczytuje po I2C pomiary z akcelerometru i żyroskopu.
  • wątek filtru - co 100ms wykonuje iterację Filtru Kalmana z uwzględnieniem aktualnych odczytów z czujników.
  • logger - wysyła dane pomiarowe z czujników i aktualną estymatę obliczoną z KF przez USART.

Obliczenia macierzowe na STM32

W Matlabie implementacja Filtru Kalmana jest bardzo prosta ze względu na jego przystosowanie do obliczeń macierzowych. Mamy tam gotowe funkcje macierzowe do transpozycji, mnożenia, odwracania itp. Podczas implementacji na mikrokontrolerze nie mamy tego luksusu. Mamy tutaj dwa rozwiązania. Możemy wykorzystać gotową bibliotekę do obliczeń macierzowych albo napisać swoją. Ja zdecydowałem się na drugie rozwiązanie.

Moja biblioteka obliczeń macierzowych jest bardzo prosta. Implementacja znajduje się w folderze /code/matrix (pliki w załączniku). Każda macierz jest reprezentowana jako tablica typu float. Nie wykorzystuję żadnych dodatkowych parametrów określających ilość wierszy i kolumn. W programie wykonuję dodawanie i mnożenie na macierzach 2x2, 2x1, 1x2 i 1x1. Dla każdej kombinacji działania i rozmiarów macierzy jest oddzielna funkcja np. do pomnożenia macierzy 2x2 i 2x1 wykorzystuję funkcję matrix\_2x2\_mul\_2x1.

Pierwsze dwa argumenty to macierze, które przez siebie mnożę, trzeci argument to zmienna w której przechowujemy wynik działania.

Implementacja filtru Kalmana

Obliczenia macierzowe zostały wykorzystane w pliku /code/filter/filter.c do implementacji Filtru Kalmana. Jak widać na każde równanie z głównego wzoru przypada kilka działań macierzowych. Należy stworzyć dodatkowe zmienne przechowujące wyniki pośrednie.

Wyniki

Wynik działania algorytmu przedstawia wykres. Wariancje zostały dobrane tak samo jak we wcześniejszym skrypcie matlabowym. Jak widać przefiltrowany sygnał wykazuje się niewielkim opóźnieniem i nie reaguje na gwałtowne chwilowe zmiany wartości.

Wynik działania algorytmu.

Wynik działania algorytmu.

Należy zauważyć, że wykorzystywane przeze mnie czujniki są bardzo wysokiej jakości. Żyroskop praktycznie nie ma dryftu, a szumy akcelerometru są bardzo niewielkie. W takim wypadku implementacja filtru niewiele daje. Praktycznie jedyną jego zaletą jest ochrona przed błędami grubymi, które mogą się trafić w jakiś pojedynczych odczytach.

« Poprzedni artykuł z serii

akcelerometr, filtr, implementacja, kalman, stm32, żyroskop

Załączniki

data3.txt (plain, 9 KB)

Dane odczytane z STM32.

Kalman_C.zip (zip, 286 KB)

Kompletny projekt pozwalający na uruchomienie filtru Kalmana na STM32.

Komentarze

Trwa przerwa techniczna - komentarze do tego wpisu są dostępne na forum: