Blog

Budowa platformy dynamometrycznej - wyzwania software'owe

W świecie inżynierii sportowej terminy takie jak "platforma dynamometryczna" i "platforma tensometryczna" oznaczają to samo. Urządzenie mierzące siłę reakcji podłoża.

Start: Prototyp z tektury i marzeń

Pierwszy prototyp powstał we wrześniu 2025 roku i był daleki od perfekcji. Sercem układu była chińska podróbka Arduino Uno, a zamiast profesjonalnych belek tensometrycznych użyłem czujników nacisku FSR402 (Force Sensitive Resistor).

FSR to w zasadzie rezystor, który zmienia opór pod wpływem nacisku. W praktyce działało to bardziej jak przycisk: albo jest nacisk, albo go nie ma. Podłączyłem to bezpośrednio do Arduino, do tego mały ekranik OLED wyświetlający wysokość skoku.

Konstrukcja opierała się na płycie OSB 1m x 1m, która pod moim ciężarem uginała się tak bardzo, że środkiem dotykała podłogi (i czujników FSR). To generowało masę fałszywych odczytów. Jednak największym wyzwaniem software'owym okazało się błędne wykrywanie fazy lotu.

Podczas szybkiego zejścia w dół przed skokiem (tzw. unweighting phase), siła nacisku spada. Dla mojego prostego programu spadek siły oznaczał lot. Platforma mierzyła skok zanim w ogóle oderwałem się od ziemi. Jako szybki fix wprowadziłem minimalny czas trwania "lotu", co trochę pomogło, ale platforma była niestabilna, kod nie nadawał się do rozbudowy, a debugowanie na małym ekranie OLED to koszmar. Brakowało pomiaru mocy, prędkości, w sumie to wszystkiego. Mimo to, ten prototyp dał mi motywację żeby zrobić to porządnie.

ESP32 i "Prawdziwa Fizyka"

Wyrzuciłem FSR i Arduino. W nowej wersji użyłem ESP32, 8 belek tensometrycznych (takich jak w wagach łazienkowych) i precyzyjnego przetwornika ADC CS1238.

Ślepa uliczka czyli Odbiornik bezprzewodowy

Na początku wymyśliłem sobie, że platforma będzie w pełni samodzielna. Jedno ESP32 w platformie mierzy i mieli dane, a drugie ESP32 (jako odbiornik z ekranem LCD) wyświetla wyniki. Cała matematyka działała po stronie platformy.

Szybko zderzyłem się ze ścianą. Ograniczenia pamięci, trudności w debugowaniu, brak bazy danych i wykresów. Zrozumiałem, że takie narzędzie potrzebuje mocy obliczeniowej PC i wygodnego interfejsu. Pomysł z dedykowanym odbiornikiem wylądował w koszu.

Ostateczna Architektura: Dumb Hardware, Smart Software

Przeszedłem na model, w którym ESP32 robi tylko to, co konieczne: taruje czujniki na starcie, pilnuje częstotliwości próbkowania i wypluwa surowe dane przez port szeregowy.

Resztę – czyli całą logikę, fizykę i UI – przejęła aplikacja desktopowa w Pythonie, korzystająca z biblioteki DearPyGui. Po pierwszych kilku godzinach kodowania miałem działający wykres i podstawowy pomiar. Pomyślałem, że to już 90% roboty.

Od tamtego momentu minęły trzy tygodnie pracy nad tym programem. Dopiero teraz mogę powiedzieć, że algorytm działa poprawnie (przynajmniej tak mi się wydaje). Oto niektóre z napotkanych problemów:

Problemy i Rozwiązania

Problem 1: Nieznana masa i szum

Aby policzyć moc, muszę znać prędkość. Aby znać prędkość, muszę znać przyspieszenie. A żeby znać przyspieszenie, muszę znać masę. Ale jak ją zmierzyć, gdy sygnał z tensometrów jest niestabilny?

Rozwiązanie: Algorytm stabilności oparty na blokach. Uśredniam sygnał w bloki po 25 sampli. Jeśli 10 takich bloków pod rząd mieści się w wąskim zakresie błędu to ustawiana jest masa ciała. To działa dużo lepiej niż zwykłe min/max na zaszumionym sygnale.

Podobnie z wykresem na żywo, nie ma sensu rysować 1280 punktów na sekundę, Na ekran trafiają uśrednione bloki.

Problem 2: Uciekająca waga i Drift

Temperatura, wilgotność, zmęczenie materiału – wszystko to sprawia, że zero w tensometrach przestaje być zerem.

Rozwiązanie: Jeśli platforma jest w stanie IDLE (czyli nikt na niej nie stoi, siła poniżej progu powietrza), ale odczyt nie jest bliski zeru, następuje automatyczne tarowanie. Dzieje się to płynnie w tle.

Problem 3: Błąd całkowania (Dryf prędkości)

Całkowanie zaszumionego sygnału jest problematyczne. Każdy najmniejszy błąd pomiaru siły sumuje się w czasie, powodując że wyliczona prędkość "odpływa" w kosmos, nawet gdy stoisz nieruchomo.

Rozwiązanie: Agresywne resetowanie. Program ciągle szuka krótkich momentów stabilności (nawet ułamków sekund) po zważeniu, aby wyzerować akumulację prędkości i ewentualnie skorygować masę ciała. Dzięki temu, w momencie gdy zaczynasz skok, całkowanie startuje od zera i błąd nie zdąży narosnąć.

Problem 4: Początek ruchu

Jeśli zacznę całkować dopiero, gdy siła zmieni się o np. 10%, to jestem spóźniony. Straciłem początek impulsu, więc moja wyliczona prędkość końcowa będzie zaniżona.

Rozwiązanie: Retrospekcja. System posiada bufor (historię pomiarów). Gdy wykryję przekroczenie progu (stan PROPULSION), algorytm "cofa się" o 75ms w tym buforze i zaczyna całkować od momentu, gdzie sygnał faktycznie zaczął się zmieniać.

Problem 5: Lot czy Odciążenie?

Przed wyskokiem robisz szybki przysiad (countermovement). Wtedy siła nacisku spada drastycznie, czasem prawie do zera. Głupi algorytm myśli: "mała siła = lot".

Rozwiązanie: Jeśli siła jest mała, ale prędkość jest ujemna (lecisz w dół), to znaczy że to dopiero zamach (odciążenie). Jeśli siła jest mała, a prędkość dodatnia dopiero wtedy jesteś w powietrzu.

Dodatkowo: Jeśli "lot" przy ujemnej prędkości trwa dłużej niż 0.5s, zakładam że ktoś po prostu zeszedł z platformy (wtedy timeout wynosi 0.5s zamiast standardowych 1.5s).

Problem 6: Drgania płyty (Bounce)

Płyta OSB jest sprężysta. Przy wybiciu i lądowaniu potrafi wpaść w rezonans. Może to spowodować, że w trakcie lotu pojawi się "pik" siły (rzekome lądowanie) albo po lądowaniu siła spadnie do zera (rzekomy kolejny skok).

Rozwiązanie: Kod celowo ignoruje odczyty przez krótki czas (kilkadziesiąt ms) bezpośrednio po wykryciu startu i lądowania.

Rozdzielenie faz skoku

  • Unweighting (Odciążenie): Zaczyna się, gdy siła wywarta na platformę spada poniżej masy ciała. Gdy człowiek osiąga zauważalną wartość ujemną (np. -0.1 m/s) cofamy się w buforze i oznaczamy ostatni moment zerowej masy jako początek fazy odciążenia.
  • Braking (Hamowanie): Gdy prędkość przestaje maleć i zaczyna rosnąć (ale wciąż jest ujemna).
  • Propulsion (Wybicie): Gdy prędkość przekracza zero i staje się dodatnia.

Więcej technicznych szczegółów znajdziecie w sekcji skrót dokumentacji projektu.