Rozdział 11: Systemy Wyścigowe RCSIM – Pomiary Czasu GPS Outdoor oraz Wizyjne QR Indoor
System RCSIM wyposażony jest w kompleksowy silnik wyścigowy obsługujący dwa uzupełniające się tryby rywalizacji:
- Tryb Plenerowy GPS (Outdoor GPS Circuit & Rally Racing): Wykorzystuje precyzyjną nawigację satelitarną (GPS / GPS-RTK), zaawansowaną kompresję trajektorii RDP, automatyczne wykrywanie zamknięcia pętli toru, czasy sektorowe, dynamiczną deltę do rekordu oraz mechanizm Samochodu-Ducha (Ghost Car).
- Tryb Torów Zamkniętych QR (Indoor Vision Racing): Wykorzystuje optyczny pomiar czasu oparty o kamerę pokładową FPV i specjalne tablice z kodami QR, wirtualną symulację zużycia opon i paliwa, procedury Pit-Stop oraz tablicę transmisyjną dla widowni (TV Broadcast Leaderboard).
🛰️ 11.1 Architektura Wyścigów Plenerowych GPS (Outdoor GPS Racing)
Tryb GPS przeznaczony jest do profesjonalnych wyścigów modeli RC w terenie otwartym, na torach asfaltowych, szutrowych, torach off-road, parkingach oraz w rajdach terenowych.
📁 Wykaz Kluczowych Plików i Modułów Źródłowych:
pc_app/core/mission_manager.py– Główny menedżer logiki wyścigu GPS (MissionManager), zarządzający stanem sesji (MissionState), weryfikacją zaliczenia bramek, czasami okrążeń i śladem Ducha.pc_app/core/mission/track_recorder.py– Moduł rejestracji trasy na żywo (TrackRecorder), wykonujący filtrowanie dystansu oraz kompresję śladu algorytmem Ramer-Douglas-Peucker (RDP).pc_app/core/mission/mission_storage.py– Podsystem zapisu i odczytu tras do formatów.json,.kml(Google Earth) oraz.wpt.pc_app/core/models/mission.py– Struktury danych Pydantic (Waypoint,LapInfo,TargetInfo,MissionData,GhostPosition).pc_app/core/utils/geo_utils.py– Biblioteka geodezyjna obliczająca odległości sferyczne (haversine), namiary (bearing), współrzędne lokalne ENU oraz indeksy redukcji punktów (rdp_indices).pc_app/core/race_director.py– Dyrektor wyścigu (RaceDirector), koordynator sesji wieloosobowej, odliczania startowego, tabeli wyników oraz ostrzeżeń antykolizyjnych.pc_app/gui/dialogs/mission_editor_window.py– Pełnoekranowy edytor mapy satelitarnej i waypointów GPS (MissionEditorWindow).pc_app/gui/osd/instruments/lap_timer.pyorazgui/osd/widgets/lap_timer_widget.py– Widgety telemetryczne HUD wyświetlające czas, rekord i deltę w goglach/monitorze FPV.pc_app/gui/dialogs/spectator_leaderboard_window.py– Wieża czasów dla widowni na żywo (SpectatorLeaderboardWindow).
🏎️ 11.2 Rejestrator Toru i Automatyczne Wykrywanie Pętli (TrackRecorder)
W celu stworzenia toru wyścigowego operator nie musi ręcznie stawiać waypointów na mapie – wystarczy przejechać jedno okrążenie zapoznawcze:
[Start Nagrywania] ──> [Filtrowanie Dystansu >2m] ──> [Wykrycie Powrotu <25m] ──> [Kompresja RDP (Epsilon)] ──> [Generacja Waypointów Toru]
- Inicjalizacja Ścieżki: Po kliknięciu
Rozpocznij Nagrywanie Torupobierana jest aktualna pozycja startowa(lat, lon, alt)i zapisywana jako punkt referencyjny linii Start/Meta (_lap_recording_start_pos). - Filtrowanie Szumów: Wątek telemetrii 50 Hz sprawdza przemieszczenie przy pomocy formuły Haversine'a. Punkty o przesunięciu mniejszym niż
2.0 metrysą ignorowane, co zapobiega powstawaniu zaszumionych skupisk punktów na postoju. - Automatyczne Wykrycie Zamknięcia Toru: Gdy zarejestrowano co najmniej
15 punktów, a aktualna pozycja pojazdu znajdzie się ponownie w promieniu detekcjiDETECTION_RADIUS_METERS(domyślnie25.0 m) od punktu startowego, rejestrator natychmiast automatycznie zamyka pętlę toru (is_circuit = True). - Kompresja Trajektorii Algorytmem RDP (Ramer-Douglas-Peucker):
- Tysiące surowych punktów GPS poddawane są analizie pod kątem odchylenia prostopadłego od odcinków prostych z konfigurowalnym parametrem dokładności
rdp_epsilon(domyślnie0.00005°wRCConfig.mission.rdp_epsilon). - Algorytm zachowuje kluczowe punkty wierzchołkowe zakrętów (Apexy), redukując liczbę waypointów o ponad
90%przy zachowaniu idealnego profilu toru wyścigowego.
- Tysiące surowych punktów GPS poddawane są analizie pod kątem odchylenia prostopadłego od odcinków prostych z konfigurowalnym parametrem dokładności
⏱️ 11.3 Detekcja Bramek GPS, Sektory i Delta Czasowa w Czasie Rzeczywistym
Podczas trwania aktywnej sesji wyścigowej (MissionState.ACTIVE) silnik MissionManager.update_vehicle_state() w każdym cyklu telemetrii (50 Hz) wykonuje dwustopniową detekcję zaliczenia punktu kontrolnego:
- Szybki Bounding Box (Pre-Check ~100m): $$\Delta \text{lat} < 0.0015^\circ \quad \land \quad \Delta \text{lon} < 0.0015^\circ$$ Pozwala to na natychmiastowe odrzucenie obliczeń trygonometrycznych, gdy model znajduje się daleko od kolejnej bramki.
- Precyzyjna Odległość Sferyczna (Haversine 2D):
$$d = 2 R \cdot \arcsin\left(\sqrt{\sin^2\left(\frac{\Delta \phi}{2}\right) + \cos(\phi_1)\cos(\phi_2)\sin^2\left(\frac{\Delta \lambda}{2}\right)}\right)$$
Jeśli $d < \text{DETECTION_RADIUS_METERS}$, bramka zostaje natychmiast uznana za zaliczoną (
_on_waypoint_captured()). - Międzyczasy Sektorowe i Delta na Żywo (Live Delta Time):
- W momencie minięcia każdego waypointu rejestrowany jest międzyczas
current_lap_splits[target_wp_index]. - Jeśli istnieje zapis z najlepszego okrążenia (
best_lap_splits), na bieżąco obliczana jest różnica czasowa: $$\text{Live Delta} = \text{time_since_lap_start} - \text{best_lap_splits}[i]$$ - Wartość ujemna (np.
-0.35s, zielony kolor w OSD) oznacza przewagę nad rekordem toru, a wartość dodatnia (np.+0.82s, czerwony kolor) stratę.
- W momencie minięcia każdego waypointu rejestrowany jest międzyczas
- Przekroczenie Linii Mety i Zaliczenie Okrążenia (
_handle_lap_completion()):- Po minięciu ostatniego punktu pętli czas okrążenia jest zatwierdzany, a jeśli jest to nowy rekord życiowy, następuje aktualizacja
best_lap_time, zapisanie profilu międzyczasów oraz zrzut trajektorii Samochodu-Ducha.
- Po minięciu ostatniego punktu pętli czas okrążenia jest zatwierdzany, a jeśli jest to nowy rekord życiowy, następuje aktualizacja
👻 11.4 Samochód-Duch (Ghost Car Replay)
Unikalną funkcją systemu RCSIM w trybie GPS jest możliwość bezpośredniej rywalizacji z własnym rekordem życiowym:
- Rejestracja Trajektorii Rekordu: Podczas przejazdu najszybszego okrążenia system zapisuje 4-elementowe krotki:
(lat, lon, heading, timestamp_od_startu_okrążenia). - Wizualizacja na Mapie i OSD: Na mapie satelitarnej oraz minimapie rysowana jest półprzezroczysta sylwetka "Ducha" (Ghost Car), która porusza się po torze dokładnie w tym samym tempie, w jakim przejechane zostało rekordowe okrążenie.
- Wskaźnik Odległości do Ducha: Kierowca widzi w OSD, czy fizycznie wyprzedza swój rekordowy przejazd, czy zostaje w tyle.
👁️ 11.5 Wyścigi Halowe i Optyczny Pomiar Czasu QR (Indoor QR Vision Racing)
W środowiskach zamkniętych (hale, parkingi, Mini-Z), gdzie sygnał GPS nie dociera, aktywowany jest tryb track_mode = "qr_vision" oparty o silnik QRLapTimingEngine:
- Kody QR Minimalnej Złożoności (Version 1, ECC 7%): Duże, kontrastowe moduły $21 \times 21$ z payloadami
RC:SF(Start/Meta),RC:S1-RC:S3(Sektory) orazRC:PIT(Boks). - Polityki Wyzwalania Bramek:
- 🏁
PASS_EXIT(Fotokomórka) – czas rejestrowany w klatce opuszczenia kadru przez kod. - 👁️
FIRST_SIGHT– czas rejestrowany przy pierwszej detekcji. - 📐
PEAK_SIZE– rejestracja w momencie osiągnięcia maksymalnej powierzchni kodu w kadrze (punkt najbliższy obiektywowi).
- 🏁
- Fuzja Odometrii IMU: W trybie halowym zarys toru generowany jest w locie z wektorów prędkości i kąta żyroskopu Yaw (Dead Reckoning).
🏎️ 11.6 Wirtualna Fizyka Osiągów i Strategia Pit-Stop
Silnik wyścigowy posiada zintegrowany model dynamicznej wirtualnej fizyki pojazdu, który bezpośrednio moduluje moc silnika (PWM) przesyłaną do regulatora ESC:
┌─────────────────────────────────────────────────────────┐
│ Fizyka Osiągów RCSIM │
├─────────────────────────────────────────────────────────┤
Przepustnica UI ──► Mieszanka Opon (SOFT 1.00 / MED 0.95 / HARD 0.90) │
│ Masa Paliwa (-5% pełny bak / +5% rezerwa) ├──► Sygnał PWM (ESC)
│ Krzywa Zużycia (<20% stanu = spadek mocy do 40-50%) │
│ Pit-Limiter (redukcja do 30% mocy w boksie) │
└─────────────────────────────────────────────────────────┘
- Mieszanki Opon:
- 🔴 SOFT: $100%$ mocy bazowej, zużycie $2.0\times$.
- 🟡 MEDIUM: $95%$ mocy bazowej, zużycie $1.0\times$.
- ⚪ HARD: $90%$ mocy bazowej, zużycie $0.4\times$ (długi dystans).
- Procedura Pit-Stop: Zatrzymanie przed tablicą
RC:PIT(lub w strefie GPS Pit) uruchamia odliczanie postoju serwisowego (np. 5.0 s), po czym następuje regeneracja opon i dotankowanie paliwa do $100%$.
📺 11.7 Pełnoekranowa Wieża Czasów dla Widowni (SpectatorLeaderboardWindow)
Dedykowany moduł transmisyjny (klawisz F11) dla telebimów, monitorów torowych i streamingu:
- Wieża Wyników Live (P1..Pn): Pozycje zawodników, czasy bieżące, najlepsze okrążenia (podświetlenie fioletowe dla Purple Lap), straty do lidera.
- Wskaźniki Techniczne: Stan ogumienia, poziom paliwa, status zjazdu do alei serwisowej (
PIT). - Synchronizacja Sieciowa MQTT: Automatyczna wymiana danych ze wszystkimi zawodnikami w sieci lokalnej lub przez broker chmurowy.
- Wykrywanie Kolizji (Anty-Kolizja): Ciągłe monitorowanie odległości między pojazdami ($<2.0\text{ m}$) przy prędkościach wyścigowych z ostrzeżeniem dźwiękowym i wizualnym.
👓 11.8 Wirtualne Bramki AR i Rzutowanie Linii Wyścigowej 3D (Augmented Reality HUD & Virtual Gates)
Wersja v1.3.18 stacji RCSIM GCS integruje zaawansowany silnik Rozszerzonej Rzeczywistości (Augmented Reality - AR) zaimplementowany w module pc_app/gui/osd/widgets/ar_navigation_widget.py (ARNavigationWidget). Pozwala on na rzutowanie wirtualnych bramek wyścigowych 3D, trajektorii trasy oraz wskaźników nawigacyjnych bezpośrednio na żywy obraz wideo z kamery FPV w czasie rzeczywistym.
┌────────────────────────────────────────────────────────┐
│ Silnik Rzutowania Perspektywicznego AR │
├────────────────────────────────────────────────────────┤
Współrzędne GPS/SLAM ────►│ 1. Fuzja pozycji z IMU (Roll, Pitch, Yaw) │
Kamera FPV FOV (62°) ────►│ 2. Macierz transformacji R_cam = R_body @ R_rot │──► Rzutowanie 3D na Ekran 2D
Profil Bramki (W x H) ───►│ 3. Obliczenie ogniskowej: f = W / (2 * tan(FOV/2)) │ (Wstęga 3D, Bramka, Offscreen)
└────────────────────────────────────────────────────────┘
🎯 1. Matematyka Rzutowania Perspektywicznego 3D -> 2D
Silnik AR pobiera w czasie rzeczywistym aktualną pozycję pojazdu $(lat, lon, alt)$, kąty orientacji przestrzennej z czujnika IMU $(roll, pitch, yaw)$ oraz współrzędne kolejnych waypointów misji:
- Macierz Transformacji Orientacji: Łączy obroty wokół osi Yaw, Pitch i Roll z macierzą przejścia do układu współrzędnych kamery: $$\mathbf{R}{\text{cam}} = \mathbf{R}{\text{body}\to\text{cam}} \cdot \mathbf{R}{\text{roll}} \cdot \mathbf{R}{\text{pitch}} \cdot \mathbf{R}_{\text{yaw}}$$
- Wektor Przestrzenny Celu: Pozycja geograficzna waypointa konwertowana jest na metryczny wektor różnicowy względem obiektywu kamery z uwzględnieniem krzywizny Ziemi ($111320\text{ m/deg}$).
- Rzutowanie na Płaszczyznę Ekranu:
Przy zadanym kącie widzenia obiektywu kamery
camera_fov_deg(domyślnie $62.0^\circ$) ogniskowa w pikselach wynosi: $$f = \frac{W_{\text{ekranu}}}{2 \cdot \tan\left(\frac{\text{FOV}}{2}\right)}$$ Współrzędne na ekranie $2D$ obliczane są według równań perspektywy: $$x_{\text{screen}} = \frac{X_{\text{cam}}}{Z_{\text{cam}}} \cdot f + \frac{W_{\text{ekranu}}}{2}, \quad y_{\text{screen}} = \frac{Y_{\text{cam}}}{Z_{\text{cam}}} \cdot f + \frac{H_{\text{ekranu}}}{2}$$
🏁 2. Style Wizualne Wirtualnych Bramek AR
Kierowca może wybrać jeden z dwóch trybów renderowania bramek wyścigowych w konfiguracji widgetu (gate_style):
| Styl Bramki | Wygląd w Goglach FPV | Charakterystyka i Zastosowanie |
|---|---|---|
🚩 Słupki (posts) |
Dwie pionowe linie wyznaczające lewą i prawą krawędź bramki. | Klasyczny styl slalomowy i rajdowy. Minimalistyczny obrys nie zasłania widoczności trasy. Grubość linii skaluje się dynamicznie do odległości ($pen_width \propto \frac{200}{dist}$). |
🌀 Portal 3D (portal) |
Pełna 4-punktowa brama przestrzenna (ramka prostokątna) z półprzezroczystym, neonowym wypełnieniem. | Styl wyścigów dronowych i futurystycznych torów wyścigowych. Daje kierowcy maksymalne poczucie "przelatywania" lub "przejeżdżania" przez wirtualną bramę. |
🛤️ 3. Wirtualna Linia Wyścigowa 3D (AR Racing Line)
- Trójwymiarowa Wstęga Toru: Moduł rysuje na podłożu wirtualną linię toru łączącą wszystkie waypointy misji.
- Interpolacja Odcinków: Każdy segment pomiędzy waypointami jest dzielony na 12 podpunktów z interpolacją liniową, co zapewnia płynne wygładzenie zakrętów w perspektywie kamery.
- Tryby Referencji Wysokości (
ground_reference_mode):camera_relative: Linia utrzymywana jest na stałej wysokości $1.5\text{ m}$ poniżej osi kamery (idealne dla pojazdów naziemnych RC).waypoint_absolute: Linia uwzględnia rzeczywistą wysokość bezwzględną każdego punktu z bazy GPS (dla dronów i modeli latających).
🧭 4. Radar Celu Poza Ekranem (Off-Screen Indicator)
Gdy kolejny punkt kontrolny lub bramka znajduje się poza polem widzenia obiektywu kamery (np. za autem lub pod ostrym kątem z boku):
- Silnik AR natychmiast aktywuje wskaźnik obwodowy
_draw_offscreen_indicator. - Na krawędzi ekranu wideo pojawia się dynamicznie obracająca się strzałka (
arrow_indicator.png) oraz precyzyjna odległość w metrach (np.48 m), natychmiast wskazując kierowcy kierunek, w którym należy skręcić.
⚙️ 5. Konfiguracja Parametrów AR w Stacji GCS
Wszystkie parametry wirtualnych bramek można dostosować w pliku konfiguracyjnym lub w Graficznym Edytorze OSD:
gate_style:"posts"(słupki) lub"portal"(pełna brama 3D),gate_color: Kolor bramek (domyślnie bursztynowy#FFB400),line_color: Kolor wirtualnej linii wyścigowej (np. neonowa zieleń#00FF00),max_render_distance: Zasięg widoczności bramek (domyślnie150.0 m),camera_fov_deg: Kąt widzenia obiektywu kamery (dopasowywany do obiektywu, np. $62^\circ$, $120^\circ$, $150^\circ$),width/height: Wirtualna szerokość bramki (np. $5\text{ m} - 20\text{ m}$) i wysokość ($2\text{ m} - 10\text{ m}$).