DOCS/Kompendium Wiedzy
|

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:

  1. 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).
  2. 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.py oraz gui/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]
  1. Inicjalizacja Ścieżki: Po kliknięciu Rozpocznij Nagrywanie Toru pobierana jest aktualna pozycja startowa (lat, lon, alt) i zapisywana jako punkt referencyjny linii Start/Meta (_lap_recording_start_pos).
  2. Filtrowanie Szumów: Wątek telemetrii 50 Hz sprawdza przemieszczenie przy pomocy formuły Haversine'a. Punkty o przesunięciu mniejszym niż 2.0 metry są ignorowane, co zapobiega powstawaniu zaszumionych skupisk punktów na postoju.
  3. Automatyczne Wykrycie Zamknięcia Toru: Gdy zarejestrowano co najmniej 15 punktów, a aktualna pozycja pojazdu znajdzie się ponownie w promieniu detekcji DETECTION_RADIUS_METERS (domyślnie 25.0 m) od punktu startowego, rejestrator natychmiast automatycznie zamyka pętlę toru (is_circuit = True).
  4. 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ślnie 0.00005° w RCConfig.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.

⏱️ 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:

  1. 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.
  2. 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()).
  3. 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ę.
  4. 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.

👻 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) oraz RC: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:

  1. 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}}$$
  2. 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}$).
  3. 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ślnie 150.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}$).