Меню

andipanda.dev

CaRadio: как работает Carlinkit с Raspberry Pi

В предыдущей статье я рассказал, как искал способ запустить Apple CarPlay на Raspberry Pi, экспериментировал с pycarplay и carplay-receiver, а спустя почти два года вернулся к проекту благодаря FastCarPlay.

Но там я практически не объяснил, зачем вообще нужен USB-донгл Carlinkit и какую роль он играет в работе моей магнитолы.

На первый взгляд всё выглядит довольно просто: подключаем адаптер к Raspberry Pi, соединяем iPhone и получаем CarPlay на экране.

На практике между телефоном и изображением на дисплее происходит немало интересного.

Попробую объяснить, как устроена эта система, без углубления в исходный код и подробности протокола.

Зачем вообще нужен Carlinkit

Когда я впервые заинтересовался CarPlay на Raspberry Pi, мне казалось, что достаточно найти подходящее программное обеспечение.

Ведь Raspberry Pi имеет USB, Bluetooth, Wi-Fi и вполне способен воспроизводить видео и звук.

Но CarPlay — это не обычная трансляция экрана телефона.

Для установления соединения и дальнейшей работы необходимо реализовать определённый механизм взаимодействия с iPhone. Именно здесь и появляется USB-донгл Carlinkit.

В моей конструкции адаптер выступает посредником между телефоном и Raspberry Pi.

Он обеспечивает часть взаимодействия, необходимого для работы CarPlay, а приложение на Raspberry Pi обменивается с ним данными через USB.

Таким образом, мне не пришлось самостоятельно реализовывать весь механизм подключения iPhone.

Однако сам по себе Carlinkit ещё не превращает Raspberry Pi в автомобильную магнитолу.

Для этого требуется программное обеспечение, которое сможет взаимодействовать с адаптером и обрабатывать полученные данные.

Как устроена система

В CaRadio участвуют несколько основных компонентов.

Первый — iPhone. На нём работают навигация, музыкальные приложения и другие функции CarPlay.

Второй — USB-донгл Carlinkit. Он обеспечивает взаимодействие с телефоном и передаёт данные компьютеру, к которому подключён.

Третий — Raspberry Pi. Именно на нём работает моя магнитола и выполняется приложение CaRadio.

И наконец, дисплей, усилитель и остальные компоненты автомобильной системы, которые позволяют видеть изображение, слышать звук и управлять приложением.

В упрощённом виде схема выглядит так:

iPhone ↔ Carlinkit ↔ USB ↔ Raspberry Pi → дисплей и звук

При этом управление работает и в обратном направлении. Когда я нажимаю на экран магнитолы, соответствующая команда должна попасть обратно на iPhone.

Именно поэтому работа с CarPlay не ограничивается одним лишь воспроизведением видео.

Подключение телефона

В моём случае используется беспроводной CarPlay.

Это удобно в повседневной эксплуатации: сел в автомобиль, включил магнитолу, и через некоторое время телефон подключается без кабеля.

Однако беспроводное подключение не означает, что Raspberry Pi напрямую работает с iPhone.

USB-донгл по-прежнему остаётся частью системы.

Со стороны Raspberry Pi взаимодействие происходит с подключённым USB-устройством, а адаптер уже обеспечивает связь с телефоном.

Для CaRadio это существенное упрощение.

Приложению не нужно самостоятельно управлять всеми этапами беспроводного подключения iPhone. Оно работает с интерфейсом адаптера и обрабатывает данные, необходимые для отображения CarPlay и управления им.

Откуда берётся изображение

Один из первых вопросов, который возникает при знакомстве с подобной системой: каким образом изображение CarPlay появляется на экране Raspberry Pi?

Сам интерфейс CarPlay формируется на стороне iPhone.

Телефон передаёт видеоданные через установленное соединение, а адаптер доставляет их приложению на Raspberry Pi.

Далее программе необходимо обработать видеопоток и вывести изображение на дисплей.

Именно с этой частью у меня возникали проблемы во время первых экспериментов.

В ранних проектах для отображения изображения использовались браузер или отдельные медиаплееры, например mpv.

Позже я пробовал переделать вывод под VLC.

Работало это не слишком хорошо: изображение заметно тормозило, и использовать такую систему в автомобиле было неудобно.

Когда я вернулся к разработке и начал работать с FastCarPlay, появилась возможность решать эти задачи непосредственно в C++.

В нынешней CaRadio отображение CarPlay встроено в собственное приложение с интерфейсом на SDL3.

Это позволяет использовать один интерфейс магнитолы вместо набора отдельных программ.

А что со звуком?

С изображением всё относительно понятно: телефон формирует картинку, а Raspberry Pi выводит её на дисплей.

Но для автомобильной магнитолы не менее важен звук.

Музыка, голосовые подсказки навигации и другие звуковые данные тоже должны пройти через систему и попасть на автомобильные динамики.

Поэтому программная часть CaRadio должна работать не только с видео, но и с аудиоданными.

В моей конструкции Raspberry Pi является основным вычислительным устройством магнитолы, а для воспроизведения используется отдельный усилитель.

Таким образом, CarPlay становится частью общей аудиосистемы автомобиля.

При этом обработка изображения и звука — разные задачи. Даже если видеопоток уже удалось вывести на экран, это ещё не означает, что вся мультимедийная система готова к работе.

Управление через сенсорный экран

Ещё одна важная часть — обратная связь с телефоном.

Когда я нажимаю на кнопку в интерфейсе CarPlay, действие должно выполняться на iPhone.

Сам по себе сенсорный экран Raspberry Pi ничего не знает о CarPlay. Он лишь сообщает приложению координаты касания.

Программное обеспечение должно обработать эти координаты и передать соответствующее событие через USB-адаптер.

После этого телефон реагирует на действие, а обновлённое изображение снова поступает на дисплей магнитолы.

Получается двусторонний обмен: телефон передаёт изображение и звук, а магнитола отправляет команды управления.

Без этой части CarPlay был бы просто изображением, на которое невозможно повлиять.

Почему недостаточно просто подключить донгл

Когда я впервые купил адаптер Carlinkit, мне хотелось как можно быстрее увидеть работающий CarPlay на Raspberry Pi.

И благодаря открытым проектам это действительно удалось.

Но между первым успешным запуском и полноценной магнитолой оказалась большая разница.

Недостаточно один раз вывести изображение на экран.

Нужно, чтобы система запускалась предсказуемо, телефон подключался, изображение и звук работали без заметных проблем, а сенсорное управление оставалось удобным.

Кроме того, автомобильная магнитола должна быть частью самого автомобиля.

В моём случае CaRadio необходимо корректно включаться, реагировать на выключение зажигания и завершать работу Raspberry Pi без риска повредить файловую систему.

Эти задачи уже выходят за рамки самого CarPlay и требуют отдельной логики приложения и аппаратной части.

Именно поэтому CaRadio постепенно превратилась из эксперимента с USB-донглом в самостоятельный проект.

Что в итоге делает CaRadio

Если упростить, USB-донгл Carlinkit помогает установить взаимодействие с iPhone, а CaRadio превращает полученные данные в работающую автомобильную мультимедийную систему.

Приложение взаимодействует с адаптером, обеспечивает отображение CarPlay, обработку звука и сенсорного управления, а также объединяет эти функции с остальной логикой магнитолы.

При этом я не разрабатывал протокол CarPlay с нуля.

В основе программной части лежат идеи и наработки открытых проектов, прежде всего FastCarPlay, которые я изучал и адаптировал под свою конструкцию.

Для меня главным результатом стало не просто появление CarPlay на экране Raspberry Pi, а возможность ежедневно пользоваться им в автомобиле.

Что дальше

В этой статье я постарался объяснить общий принцип работы системы, не углубляясь в технические подробности.

За каждым из описанных этапов скрывается гораздо больше деталей: обмен данными по USB, обработка видеопотока, передача звука, управление подключением и интеграция с интерфейсом приложения.

Возможно, со временем я расскажу об отдельных частях подробнее.

А если кто-то захочет повторить подобный проект или разобраться в программной части CaRadio, со мной можно связаться по электронной почте. По возможности поделюсь опытом и отдельными наработками.

Пока же главное для меня — то, что связка Raspberry Pi и Carlinkit оказалась вполне пригодной для повседневного использования в автомобиле.