У попередніх статтях я розповів, як збирав власну автомобільну магнітолу CaRadio на Raspberry Pi, намагався використати електроніку Volkswagen RCD510 і зрештою встановив працюючу систему у свій Golf.
Але досі я майже не розповідав про програмну частину проекту.
Адже Raspberry Pi, дисплей і підсилювач самі по собі ще не роблять магнітолу повноцінною мультимедійною системою. Мені потрібен був CarPlay — бажано бездротовий, із навігацією, музикою та керуванням через сенсорний екран.
Сьогодні все це вже працює в автомобілі. Але шлях до такого результату виявився значно довшим, ніж я спочатку розраховував.
Усе почалося з вибору магнітоли
Кілька років тому я шукав нову магнітолу для автомобіля. Серед доступних варіантів одними з найцікавіших мені здавалися пристрої Teyes.
Вони мали різні комплектації, зокрема з підтримкою Apple CarPlay і без неї.
Під час пошуків я натрапив на інструкції, у яких розповідалося, як додати підтримку CarPlay до деяких моделей Teyes, встановивши додаткову мікросхему.
Саме тоді в мене виникла думка: якщо подібне рішення можна використати в Android-магнітолі, можливо, вдасться пристосувати його і до Raspberry Pi?
У мене вже був досвід створення власної автомобільної магнітоли, тому ідея використати Raspberry Pi замість готового пристрою виглядала цілком природно.
Я почав шукати інформацію про мікросхеми, способи підключення та програмні реалізації CarPlay.
Але досить швидко з'ясувалося, що все дещо складніше, ніж просто підключити один чип.
Знайомство з pycarplay
Під час пошуків мені трапився проект pycarplay на GitHub.
Це була реалізація на Python, яка дозволяла працювати з USB-адаптерами CarPlay.
Спочатку я не зовсім розумів, як саме все влаштовано. З опису було видно, що проект дозволяє запускати CarPlay на Raspberry Pi, але для роботи потрібне додаткове обладнання.
Поступово розібравшись у документації та пошукавши інформацію в інтернеті, я з'ясував, що потрібен спеціальний USB-донгл, подібний до Carlinkit.
Залишалося його знайти.
На Allegro мені трапився недорогий адаптер із виставкового зразка — клон Carlinkit. За мірками того часу він коштував зовсім небагато, тому я вирішив спробувати.
До речі, саме цей адаптер досі працює в моїй магнітолі.
Після покупки я підключив його до Raspberry Pi, встановив необхідне програмне забезпечення і вперше побачив працюючий CarPlay на власному пристрої.
Це був важливий момент.
До цього я лише припускав, що подібну систему можна зібрати самостійно. Тепер стало зрозуміло, що ідея справді здійсненна.
CarPlay у браузері
Наскільки я пам'ятаю, перша реалізація, яку мені вдалося запустити, була пов'язана з ідеєю використання CarPlay в автомобілях Tesla.
Raspberry Pi працював як невеликий вебсервер, а зображення CarPlay можна було відкрити в браузері.
Для експериментів це виявилося досить зручним рішенням.
Система запускалася, телефон підключався, зображення з'являлося, і загалом усе працювало відносно непогано.
Але в мене було інше завдання.
Я не збирався використовувати браузер як основний інтерфейс магнітоли. Мені хотілося отримати окремий застосунок, який можна буде інтегрувати у власну систему й використовувати безпосередньо на сенсорному екрані.
Тому я продовжив шукати інші реалізації.
Від mpv до VLC
Наступною знахідкою став проект carplay-receiver.
Він також був написаний на Python, але використовував інший підхід до відображення відео. Замість браузера зображення CarPlay виводилося через медіаплеєр mpv.
Це вже було ближче до того, що мені потрібно.
Я почав розбиратися в коді й пробувати запустити проект на своєму Raspberry Pi.
Однак із mpv у мене щось не склалося. Зараз уже складно згадати всі подробиці, але швидко досягти бажаного результату не вдалося.
Проте в мене вже був досвід роботи з VLC.
Тому я вирішив переробити виведення зображення під знайомий мені плеєр.
Після кількох експериментів CarPlay усе-таки вдалося запустити.
Щоправда, працювало це далеко не ідеально.
Поки система просто запускалася на столі, з недоліками ще можна було миритися. Але коли я почав думати про її використання в автомобілі, стало очевидно, що продуктивність залишає бажати кращого.
Зображення помітно гальмувало, а швидко розібратися з причинами в мене не вийшло.
Спроба перейти на C++
На той час у мене вже був досвід розробки на C++ із використанням Qt.
Тому виникла ідея відмовитися від Python і перенести необхідну функціональність у власний застосунок.
Мені здавалося, що такий підхід дасть більше контролю над системою і дозволить позбутися хоча б частини проблем із продуктивністю.
Але одна справа — запустити готовий проект, і зовсім інша — розібратися в його внутрішній будові настільки, щоб переписати його іншою мовою.
Потрібно було зрозуміти, як організований обмін із USB-адаптером, яким чином передаються відео та звук, як обробляються дотики й інші команди керування.
Тоді моїх знань і вільного часу для цього виявилося недостатньо.
Спроба не увінчалася успіхом.
У результаті я відклав розробку CarPlay для Raspberry Pi. Як виявилося, майже на два роки.
Повернення до проекту
Майже через два роки я вирішив ще раз вивчити доступні рішення. За цей час багато що змінилося, і я сподівався, що з'явилися нові проекти, які допоможуть просунутися далі.
Під час пошуків мені трапився проект FastCarPlay.
FastCarPlay був написаний на C++, тобто мовою, з якою я хотів працювати від самого початку.
Це не означало, що достатньо було завантажити проект, скомпілювати його й одразу отримати готову магнітолу.
Після першого запуску виявилися проблеми, які довелося поступово вирішувати.
Але тепер у мене була значно краща відправна точка.
На відміну від попередніх експериментів із Python, я міг працювати безпосередньо з C++-кодом і поступово адаптувати його під власні завдання.
Не лише FastCarPlay
Під час вивчення наявних рішень мені також трапився проект LIVI.
Він був цікавий як ще одна реалізація, за якою можна було вивчати взаємодію з Carlinkit і порівнювати технічні підходи.
Водночас використовувати LIVI як основу CaRadio я не став.
Для моїх завдань проект виглядав надто громіздким, а мови, якою він був написаний, я практично не знав.
Проте такі проекти дуже корисні.
Коли намагаєшся розібратися в погано документованому протоколі, можливість подивитися, як одне й те саме завдання вирішили різні розробники, значно полегшує роботу.
До того ж LIVI продовжує активно розвиватися і в деяких напрямках, цілком можливо, уже випереджає поточну версію CaRadio.
Від експерименту до автомобільної магнітоли
Після запуску FastCarPlay робота над CaRadio нарешті зрушила з місця.
Поступово вдалося довести програмну частину до стану, коли CarPlay можна було використовувати не лише для експериментів на столі, а й в автомобілі.
Згодом застосунок отримав власний інтерфейс на C++ із використанням SDL3.
Тепер мені вже не потрібно було відкривати браузер або запускати окремий медіаплеєр для відображення CarPlay.
Усе стало частиною одного застосунку, розрахованого на роботу із сенсорним екраном автомобільної магнітоли.
Звісно, це не означає, що я написав реалізацію CarPlay з нуля.
Основою стали результати роботи інших розробників, які досліджували взаємодію з USB-адаптерами й опублікували свої проекти у відкритому доступі.
Саме завдяки pycarplay, carplay-receiver, FastCarPlay та іншим подібним розробкам у мене з'явилася можливість пройти цей шлях.
Моє завдання полягало в тому, щоб розібратися в наявних рішеннях, адаптувати їх під власну конструкцію й домогтися стабільної роботи в автомобілі.
Що далі
Сьогодні CaRadio вже кілька місяців працює в моєму Volkswagen Golf.
За цей час вона подолала тисячі кілометрів, а бездротовий CarPlay став звичною частиною щоденних поїздок.
Але за зовні простим інтерфейсом приховано чимало цікавих технічних рішень.
Як Raspberry Pi взаємодіє з USB-донглом Carlinkit? Звідки береться відеопотік? Як передаються звук і дотики? І що саме довелося змінити, щоб усе це запрацювало у власному застосунку?
Про все це я хочу розповісти докладніше в наступних статтях.
А поки головне, що варто зазначити: програмна частина CaRadio не з'явилася за один вечір і не була написана з чистого аркуша.
Вона стала результатом кількох років експериментів, невдалих спроб, вивчення чужих проектів і поступового пошуку відповідного рішення.
І, мабуть, саме ця частина історії виявилася для мене найцікавішою.