Menu

andipanda.dev

CaRadio: jak działa Carlinkit z Raspberry Pi

W poprzednim artykule opisałem, jak szukałem sposobu na uruchomienie Apple CarPlay na Raspberry Pi, eksperymentowałem z pycarplay i carplay-receiver, a po prawie dwóch latach wróciłem do projektu dzięki FastCarPlay.

Nie wyjaśniłem jednak dokładniej, po co właściwie potrzebny jest adapter USB Carlinkit i jaką rolę odgrywa w działaniu mojego radia.

Na pierwszy rzut oka wszystko wygląda dość prosto: podłączamy adapter do Raspberry Pi, łączymy iPhone'a i otrzymujemy CarPlay na ekranie.

W praktyce między telefonem a pojawieniem się obrazu na wyświetlaczu dzieje się całkiem sporo interesujących rzeczy.

Postaram się wyjaśnić, jak działa ten system, bez zagłębiania się w kod źródłowy i szczegóły protokołu.

Po co właściwie potrzebny jest Carlinkit

Kiedy po raz pierwszy zainteresowałem się CarPlay na Raspberry Pi, wydawało mi się, że wystarczy znaleźć odpowiednie oprogramowanie.

Raspberry Pi ma przecież USB, Bluetooth, Wi-Fi i bez problemu potrafi odtwarzać obraz oraz dźwięk.

CarPlay nie jest jednak zwykłym przesyłaniem obrazu z ekranu telefonu.

Aby nawiązać połączenie i zapewnić dalsze działanie, potrzebny jest określony mechanizm komunikacji z iPhonem. I właśnie tutaj pojawia się adapter USB Carlinkit.

W mojej konstrukcji adapter pełni funkcję pośrednika między telefonem a Raspberry Pi.

Zapewnia część komunikacji niezbędnej do działania CarPlay, natomiast aplikacja uruchomiona na Raspberry Pi wymienia z nim dane przez USB.

Dzięki temu nie musiałem samodzielnie implementować całego mechanizmu łączenia z iPhonem.

Sam Carlinkit nie zmienia jednak Raspberry Pi w radio samochodowe.

Do tego potrzebne jest oprogramowanie, które potrafi komunikować się z adapterem i przetwarzać otrzymywane dane.

Jak zbudowany jest system

CaRadio składa się z kilku głównych elementów.

Pierwszy to iPhone. To na nim działają nawigacja, aplikacje muzyczne i pozostałe funkcje CarPlay.

Drugi to adapter USB Carlinkit. Zapewnia komunikację z telefonem i przekazuje dane do komputera, do którego jest podłączony.

Trzeci to Raspberry Pi. To właśnie na nim działa moje radio i uruchomiona jest aplikacja CaRadio.

Do tego dochodzą wyświetlacz, wzmacniacz i pozostałe elementy systemu samochodowego, które pozwalają wyświetlać obraz, odtwarzać dźwięk i sterować aplikacją.

W uproszczeniu schemat wygląda tak:

iPhone ↔ Carlinkit ↔ USB ↔ Raspberry Pi → wyświetlacz i dźwięk

Sterowanie działa również w przeciwnym kierunku. Kiedy dotykam ekranu radia, odpowiednie polecenie musi wrócić do iPhone'a.

Dlatego obsługa CarPlay nie ogranicza się wyłącznie do odtwarzania obrazu.

Łączenie telefonu

W moim przypadku korzystam z bezprzewodowego CarPlay.

To wygodne podczas codziennego użytkowania: wsiadam do samochodu, włączam radio i po chwili telefon łączy się bez kabla.

Bezprzewodowe połączenie nie oznacza jednak, że Raspberry Pi komunikuje się bezpośrednio z iPhonem.

Adapter USB nadal pozostaje częścią systemu.

Od strony Raspberry Pi komunikacja odbywa się z podłączonym urządzeniem USB, a adapter zapewnia łączność z telefonem.

Dla CaRadio jest to duże uproszczenie.

Aplikacja nie musi samodzielnie zarządzać wszystkimi etapami bezprzewodowego łączenia iPhone'a. Korzysta z interfejsu adaptera i przetwarza dane potrzebne do wyświetlania CarPlay oraz sterowania nim.

Skąd bierze się obraz

Jedno z pierwszych pytań, jakie pojawia się przy poznawaniu takiego systemu, brzmi: w jaki sposób obraz CarPlay trafia na ekran Raspberry Pi?

Sam interfejs CarPlay jest generowany po stronie iPhone'a.

Telefon przesyła dane wideo przez nawiązane połączenie, a adapter dostarcza je do aplikacji na Raspberry Pi.

Następnie program musi przetworzyć strumień wideo i wyświetlić obraz na ekranie.

Właśnie z tą częścią miałem problemy podczas pierwszych eksperymentów.

We wcześniejszych projektach do wyświetlania obrazu wykorzystywano przeglądarkę lub osobne odtwarzacze multimedialne, na przykład mpv.

Później próbowałem przerobić wyświetlanie obrazu tak, aby korzystało z VLC.

Nie działało to zbyt dobrze: obraz wyraźnie się zacinał, a korzystanie z takiego systemu w samochodzie było niewygodne.

Kiedy wróciłem do projektu i zacząłem pracować z FastCarPlay, mogłem zająć się tymi zadaniami bezpośrednio w C++.

W obecnej wersji CaRadio wyświetlanie CarPlay jest zintegrowane z własną aplikacją, której interfejs wykorzystuje SDL3.

Dzięki temu mogę korzystać z jednego interfejsu radia zamiast zestawu osobnych programów.

A co z dźwiękiem?

Z obrazem sprawa jest stosunkowo prosta: telefon generuje obraz, a Raspberry Pi wyświetla go na ekranie.

Jednak w radiu samochodowym równie ważny jest dźwięk.

Muzyka, komunikaty głosowe nawigacji i pozostałe dane audio również muszą przejść przez system i trafić do głośników samochodowych.

Dlatego oprogramowanie CaRadio musi obsługiwać nie tylko wideo, ale także dane audio.

W mojej konstrukcji Raspberry Pi jest głównym urządzeniem obliczeniowym radia, a do odtwarzania dźwięku wykorzystuję osobny wzmacniacz.

W ten sposób CarPlay staje się częścią całego systemu audio samochodu.

Przetwarzanie obrazu i dźwięku to jednak dwa różne zadania. Nawet jeśli udało się już wyświetlić strumień wideo, nie oznacza to jeszcze, że cały system multimedialny jest gotowy do działania.

Sterowanie przez ekran dotykowy

Kolejnym ważnym elementem jest komunikacja zwrotna z telefonem.

Kiedy naciskam przycisk w interfejsie CarPlay, odpowiednia czynność musi zostać wykonana na iPhonie.

Sam ekran dotykowy podłączony do Raspberry Pi nic nie wie o CarPlay. Przekazuje jedynie aplikacji współrzędne dotknięcia.

Oprogramowanie musi przetworzyć te współrzędne i przesłać odpowiednie zdarzenie przez adapter USB.

Następnie telefon reaguje na polecenie, a zaktualizowany obraz ponownie trafia na ekran radia.

Powstaje więc dwukierunkowa wymiana danych: telefon przesyła obraz i dźwięk, a radio wysyła polecenia sterujące.

Bez tej części CarPlay byłby jedynie obrazem, z którym nie można wchodzić w interakcję.

Dlaczego samo podłączenie adaptera nie wystarczy

Kiedy po raz pierwszy kupiłem adapter Carlinkit, chciałem jak najszybciej zobaczyć działający CarPlay na Raspberry Pi.

Dzięki otwartym projektom rzeczywiście udało mi się to osiągnąć.

Okazało się jednak, że między pierwszym udanym uruchomieniem a pełnoprawnym radiem samochodowym jest ogromna różnica.

Nie wystarczy raz wyświetlić obraz na ekranie.

System musi uruchamiać się w przewidywalny sposób, telefon powinien się łączyć, obraz i dźwięk muszą działać bez zauważalnych problemów, a obsługa dotykowa powinna pozostać wygodna.

Co więcej, radio samochodowe musi być zintegrowane z samym samochodem.

W moim przypadku CaRadio powinno poprawnie się włączać, reagować na wyłączenie zapłonu i bezpiecznie zamykać system Raspberry Pi, aby nie uszkodzić systemu plików.

Te zadania wykraczają już poza samo CarPlay i wymagają osobnej logiki aplikacji oraz odpowiednich rozwiązań sprzętowych.

Dlatego CaRadio stopniowo przekształciło się z eksperymentu z adapterem USB w samodzielny projekt.

Co właściwie robi CaRadio

W dużym uproszczeniu adapter USB Carlinkit pomaga nawiązać komunikację z iPhonem, a CaRadio przekształca otrzymywane dane w działający samochodowy system multimedialny.

Aplikacja komunikuje się z adapterem, odpowiada za wyświetlanie CarPlay, obsługę dźwięku i sterowania dotykowego, a także łączy te funkcje z pozostałą logiką radia.

Nie oznacza to jednak, że opracowałem protokół CarPlay od zera.

Podstawą oprogramowania są pomysły i rozwiązania z otwartych projektów, przede wszystkim FastCarPlay, które analizowałem i dostosowywałem do własnej konstrukcji.

Najważniejszym rezultatem nie było dla mnie samo pojawienie się CarPlay na ekranie Raspberry Pi, ale możliwość codziennego korzystania z niego w samochodzie.

Co dalej

W tym artykule starałem się wyjaśnić ogólną zasadę działania systemu, bez zagłębiania się w szczegóły techniczne.

Za każdym z opisanych etapów kryje się znacznie więcej zagadnień: wymiana danych przez USB, przetwarzanie strumienia wideo, przesyłanie dźwięku, zarządzanie połączeniem i integracja z interfejsem aplikacji.

Być może z czasem opiszę niektóre z tych elementów dokładniej.

Jeśli ktoś chciałby zbudować podobny projekt lub dowiedzieć się więcej o programowej części CaRadio, może skontaktować się ze mną mailowo. W miarę możliwości podzielę się doświadczeniem i wybranymi rozwiązaniami.

Na razie najważniejsze jest dla mnie to, że połączenie Raspberry Pi i Carlinkit okazało się w pełni przydatne do codziennego użytkowania w samochodzie.