...

суббота, 23 января 2021 г.

Я сделаю свою «умную» колонку… «with blackjack and hookers!»

Привет всем. В данной статье я расскажу историю как мы с двоюродным братом сделали свою «умную» колонку.

На самом деле никакая она неумная, грубая и не особо полезная, но зато весёлая и с характером.

За мной сама идея, программирование, железо (подбор и настройка).

От брата 3D-модель, 3D-печать, железо (подбор и электромонтаж).

Статья по-большей части описывает то, что делал я, лишь немного касаясь 3D-модели.

"Ты на самом деле хочешь дружить с роботом?"

Будучи большим фанатом известного мультсериала «Футурама», однажды (где-то в 2018 году) мне захотелось заиметь самодельную голову робота Бендера Родригеса. В голове, в том числе крутились дурацкие варианты сделать её из какой-нибудь кастрюли. В силу своей глупости идея была забыта и заброшена ровно до того момента пока у одного хорошего человека, моего брата, товарища xbost’а не появился 3D-принтер (весна 2019 года). И тут эта идея снова ожила…

Обсудив эту идею за пивом, принялись за работу. Брат начал делать 3D-модель, а я искать, что из электронного хлама в ящике стола можно задействовать в проекте.

К тому моменту, у меня уже несколько лет валялась без дела плата Intel Galileo Gen2. И было желание задействовать её в этом проекте. Изначально никаких «умных» функций не планировалась, просто запихнуть её в корпус вместе с динамиком и светодиодами, вытащить кнопочку, при нажатии на которую воспроизводились бы цитаты из серий и светились диоды.

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

Это привело к мысли, что на основе Бендера с его вредным, эгоистичным и вообще отрицательным характером можно сделать для себя отличную «умную» колонку. Этакий арт-проект, протест против умных колонок. И обязательно работающую оффлайн, даже ценой производительности.

Первые попытки

Почитав о системах распознавания речи с возможностью оффлайн-распознавания, а также узнав, что ещё один хороший человек, коллега с прошлой работы, в то время писавший диплом, использует CMU Sphinx, выбор был остановлен на нём.

В силу своей природной… хм… невнимательности, я упустил существование более подходящей для моей задачи версии – pocketsphinx, и начал с «большого» CMU Sphinx на Java.

Создал простенькие JSGF-грамматику и программу на Яве. Взял несколько наиболее известных цитат для проигрывания(“with blackjack and hookers”, “bite my shiny metal ass”, “kill all humans” и т.п.). Пробовал изначально на достаточно мощном компьютере(MacBook Pro 13-го года), был доволен результатом производительности, но понимал, что на Галилео меня ждёт нечто другое. Но дело оказалось совсем плохо.

Вообще Галилео уже давно заброшен Интелом. Стандартный Линукс, шедший с ним мне в принципе особенно не нравился. Поэтому попробовал с последней доступной для него сборкой Дебиан.

Туда с проблемами(подробности уже честно не вспомню) был поставлен JRE. В качестве устройства ввода/вывода аудио была использована USB-гарнитура. И… Результат был крайне печален в плане производительности. Сейчас опять же не вспомню, возможно неправильную акустическую модель использовал на ней, но на реакции уходило 30-60 секунд. Плюс брат начал разрабатывать 3D-модель, и сказал, что габариты Галилео большеваты. Плюс отсутствие встроенного Wi-Fi. В общем Галилео опять отправилась в стол.

Решено было попробовать на гораздо более популярной Малинке, и выбор пал на слабую, но самую компактную версию Raspberry Pi Zero W. А также, прокачав внимательность, узнал о pocketsphinx (отличная статья для старта), перешёл на него, и переписал программу на Питоне.

При переходе на Малину, с подачи xbost’а, родилось название для проекта – Pinder (Raspberry Pi + Bender). Да, я прекрасно помню историю с Pidora в русскоязычном сегменте, но в данном случае намеренно выбрал такое лулзовое для русского уха название.

И так предыстория завершена, можно переходить непосредственно к описанию Пиндера.

Внутренняя железная часть

Перечень использованных компонентов:

  • Raspberry Pi Zero W – собственно основа всего.

  • UPS-Lite for Raspberry Pi Zero

    Маленький ИБП для Малинки. Его штатный выключатель был выпаян, и к его контактам был припаян микропереключатель (см. далее по списку).

  • RGB адресная светодиодная лента на WS2812B, 60 светодиодов на 1 метр

    Для подсветки и анимации «зубов»(18 штук) и глаз(2 штуки).

  • USB-аудиокарта

    В принципе подойдёт любая, работающая в Линуксе. Подключается через OTG-кабель в единственный доступный для этого порт на Малине Зеро.

  • Усилитель и один динамик от таких колонок

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

  • Микрофон HBC10A

    Но во время разработки поначалу использовался микрофон от телефонной гарнитуры Philips.

  • Микропереключатель с лапкой KLS7-KW10

    Замыкается/размыкается при вставлении/вынимании "антенны" Бендера. Включает/выключает питание от UPS к Малине.

  • 3,5мм разъём и гнездо jack. Для подключения микрофона к аудиокарте (микрофон находится наверху Бендера, в антенне).

В общем внутри всё достаточно колхозно.

Схема подключений очень простая:

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

3D-модель, корпус

Здесь я не смогу рассказать многого, так как эта часть работы полностью брата.

3D-модель и небольшая инструкция доступны здесь.

Зубы и глаза напечатаны фотополимерной смолой на Anycubic Photon. Все остальные части PLA на Creality Ender 3.

Если будут какие-то вопросы по 3D-модели и печати можно задать мне, я их передам, либо попробовать напрямую спросить у xbost’а на thingiverse (но не уверен будет ли он на них отвечать).

Краткая схема сборки:

Фото

Фото в процессе сборки и полностью собранном виде:

Программная часть 1

В качестве ОС используется штатный Raspbian (теперь Raspberry Pi OS).

За распознавание, как уже писалось выше, отвечает pocketsphinx. В качестве аудиоподсистемы используется Alsa (Pulseaudio выпилен).

Подсветка управляется с помощью библиотеки Adafruit_Blinka.

Данные о заряде/напряжении читаются из UPS-Lite посредством SMBus.

При разработке никакими лучшими практиками не руководствовался, поэтому код «попахивает».

Код лежит здесь.

Поддерживается два языка: английский и русский. Для каждого языка своя JSGF-грамматика, набор аудио-сэмплов(сэмплов в репозитории нет, по соображениям авторских прав) и синтез речи. Русский дорабатывалась(и дорабатывается) с некоторым опозданием.

Основной целью была просто возможность отвечать фановыми фразами из серий. Задаешь ему вопросы типа “Как дела?”, “Где ты родился?”, “Что думаешь о Сири?”. Ищется и воспроизводится ответ из сэмплов (в случае отсутствия сэмпла используется синтез речи, но об этом чуть позже).

Изначально скорость ответов на Малине была не очень шустрой (4-6 секунд до ответа):

Покопавшись у себя в коде, были найдены и уничтожены необязательные паузы. То же самое касалось и сэмплов (были пустые места вплоть до 1 секунды в начале файлов).  А также прочитана информация о параметрах оптимизации pocketsphinx. Получилось уже получше:

Далее начал добавлять кое-какие полезные функции. Первой стала проигрывание музыки с локальной ФС или интернет-радио с помощью MPD. При этом докричаться до Бендера при проигрывании музыки на приличной громкости сложновато:

После достаточно долгого перерыва, живя на даче, была добавлена первая функция “умного дома”-  управление освещением в своём углу через ModBusTCP. Вот только Бендера недостаточно иногда просто попросить включить свет, нужно обязательно сказать "пожалуйста". Работает достаточно шустро:

Программная часть 2

Потом однажды захотелось добавить читалку RSS-новостей. Это уже было невозможно без синтеза речи, но при этом хотелось, чтобы синтезатор звучал как, или хотя бы похоже на голос Бендера. Такой синтез речи на Малине Зеро представляется малореальным и поэтому в этом моменте пришлось сдаться и задействовать онлайн-сервис.

Почитав информацию и попробовав разные варианты остановился на Microsoft Azure Custom Speech.

При создании пользовательского голоса на выбор есть три варианта:

  • Statistical Parametric – стандартное качество, нужно небольшое количество(для английского языка) сэмплов для обучения.

  • Concatenative – высокое качество, нужно 6000 сэмплов для обучения.

  • Neural премиум-качество. По факту недоступно(доступно из США, при написании челобитной в Майкрософт зачем тебе это нужно и выкладывании 100 000$).

Более подробно по технологиям синтеза речи можно почитать например на Википедии.

У меня не было большого количества сэмплов, поэтому сначала поигрался со Statistical Parametric. Результат был неплох, голос конечно не был похож(такой тип синтеза для сильной похожести и не предназначен), но интонации передавал сносно. В итоге на основе набора данных созданного с помощью этой модели я создал оффлайновую модель для CMU Flite, используемую в случае отсутствия связи с MS Azure.

Но всё же хотелось большей похожести и я решился попробовать собрать 6000 сэмплов для Concatenative модели, использующей отрывки из сэмплов настоящего голоса. Очень помог некий хороший человек, выложивший на YouTube 7 видео The Best of Bender. Надёргав оттуда сэмплов, приплюсовав к ним те что уже были и натравив на них майкрософтовский же Text-to-Speech (здесь у меня набор тулзов вспомогательных), получил что-то около 2000 транскрибированных сэмплов. Было принято решение просто скопировать это всё три раза под разными именами, чтобы получить 6000.

В итоге всё это было залито на обучение модели, и результат получился следующим:

Да конечно не идеально, но меня результат трудов устроил.

В итоге синтез речи используется не только для чтения новостей, но и в случае отсутствия оригинального сэмпла. Сначала ищется сэмпл. Если его нет, проверяется связь с порталом MS Azure, если есть – синтезируется с помощью него. Если же связи с Azure нет – используется локальная модель Flite(а для русского языка роботизированный голос eSpeak).

В сумме периодическими волнами и рывками разработка шла с весны 2019-го по весну 2020-го, в свободное время(хорошо видно по коммитам на гитхабе). Далее уже даже не волнами, просто отдельными всплесками.

Будущее

Как таковых планов развития проекта нет. Если появляется желание и вдохновение, то добавляю что-нибудь. Так конечно напрашивается сделать режим просто болталки на нейронке, обученной на фразах Бендера. Ещё возможно добавить режим bluetooth-колонки(и чтобы зубы загорались синим в этом режиме) и приложение для смартфона, для активации схемы патриотизма.

Но для начала надо изобрести удлинитель пальца.

Заключение

Исходный код ПО и 3D-модель выложены под открытыми лицензиями, так что если у кого-то есть желание сделать своего Бендера, добавить свои функции и улучшить – буду рад.

На этом статья подошла к концу. Спасибо, что прочитали!

Всем хороших новостей!

Let's block ads! (Why?)

Комментариев нет:

Отправить комментарий