Stan początkowy: jeden tor komunikacji dla różnych zadań
Telemetria, komendy sterujące i większe dane przestrzenne współdzieliły założenia dotyczące częstotliwości oraz niezawodności. Ramka telemetrii miała około 75 bajtów, ramka sterowania około 20 bajtów, a pętla decyzyjna SBC pracowała z częstotliwością 30 Hz — jeden cykl co 33,3 ms.
stała ramka binarna, sekwencja i znacznik czasu
mała niezawodna komenda z potwierdzeniem
z 33,3 ms do 16,7 ms na cykl
Diagnoza: niezawodność i częstotliwość to nie to samo wymaganie
Świeża telemetria szybko traci wartość, dlatego spóźniony pakiet bywa gorszy niż pakiet pominięty. Komenda napędu jest inna: liczą się kolejność i potwierdzenie. Dane przestrzenne są cięższe i zmieniają się wolniej. Traktowanie wszystkich trzech strumieni jednakowo tworzyło zbędny narzut oraz łączyło niezależne tryby awarii.
Koniec z backlogiem: telemetria ma dostarczać najnowszy stan, nie historię kolejki
W ścieżce czasu rzeczywistego FIFO może zachować próbki poprawne technicznie, ale już nieaktualne. Jeżeli odbiorca chwilowo zwolni, nadrabianie t−3, t−2 i t−1 tylko opóźnia dojście do stanu t. Starsza próbka może więc zostać pominięta, aby odbiorca pracował na najświeższej poprawnej ramce.
pomiar → serializacja → kolejka → transport → kolejka → parser → decyzja
pomiar → aktualna ramka → transport → walidacja → aktualny stan
Decyzja: rozdzielenie kanałów
Stałe ramki i bit-pakowanie: parser czyta offsety zamiast interpretować opis wiadomości
Redukcja 75 → 28 B oraz 20 → 9 B nie wynika wyłącznie z kompresji. Reprezentacja została zmieniona na stałą ramkę binarną, pola o znanej szerokości oraz flagi pakowane bitowo. Odbiorca czyta przewidywalne offsety i waliduje wersję, sekwencję, timestamp oraz sumę kontrolną.
Dlaczego watchdog pozostaje po stronie ESP32
Komputer z Linuksem może się zrestartować, zawiesić albo utracić łącze. Reakcja awaryjna nie może więc zależeć od tej samej ścieżki, która mogła ulec awarii. ESP32 mierzy wiek ostatniej zaakceptowanej komendy i lokalnie zatrzymuje wyjścia po skonfigurowanym czasie.
if (now_ms - last_valid_control_ms > CONTROL_TIMEOUT_MS) {
drive_left = 0;
drive_right = 0;
state = SAFE_STOP;
}Rezultat i interpretacja
Mniejsze ramki ograniczyły pracę serializacji i parsowania, a niezależne kanały zapobiegły blokowaniu świeżej telemetrii przez większe lub niezawodne transfery. W zmierzonym systemie pętla decyzyjna wzrosła z 30 Hz do 60 Hz. Kluczowa poprawa była architektoniczna: każda klasa danych otrzymała transport oraz politykę awarii odpowiadającą jej rzeczywistym potrzebom.
Firmware referencyjny, kod SBC i dokumentacja protokołu.
Dołączona paczka zawiera przykład Arduino, pakiet Python dla SBC, testy, dokumentację protokołu i licencję. Przed użyciem na sprzęcie sprawdź stałe, piny oraz progi bezpieczeństwa.