Додай голосове управління до електроніки з Raspberry Pi і Arduino
Рейтинг статті: / 11
НайгіршеНайкраще 
PocketSphinxКомп'ютери не дуже розумні, бо вони роблять лише те, що ми заставляємо їх робити. Тепер ви можете сказати своєму RPi зробити щось розумне, наприклад, керувати підключеними пристроями у своєму будинку, використовуючи тільки голос.
Це не важко - ви можете легко це зробити за допомогою деякого відкритого вихідного коду і RPi. Потім додайте Arduino з інфрачервонним (IR) світлодіодом і також зможете сказати своєму роботу Roomba, що йому робити. Раніше ми вже розглядали розпізнавання голосу за допомогою Raspberry Pi, а зараз спробуємо розширити наші знання та навички.
Давайте скажемо Game?
Цей проект став можливим завдяки рокам досліджень десятків учених, інженерів і лінгвістів у всьому світі, які працюють для розпізнавання мови в режимі реального часу, яке змогло б працювати на скромному обладнанні - це ті досягнення, які принесли нам Siri на пристроях Apple і можливості розпізнавання мови, вбудовані в Android від Google.
Зокрема, ми побачимо, як використати відкритий код інструментарія розпізнавання мови від спеціалістів з університету Карнегі-Меллона з назвою PocketSphinx, призначеного для використання у вбудованих системах. Ця дивовижна бібліотека дозволяє делегувати складне перетворення звуку в текст, так що ми зможемо зосередитися на реалізації логіки більш високого рівня, щоб перетворити текст в значимі дії типу управління системою освітлення у вашому будинку і навіть вашим роботом-пилососом Roomba. Це також дозволяє нам, як дослідникам, залізти під капот і експериментувати з аспектами розпізнавання мови, які, як правило, зарезервовані для тих, хто реалізує інструментарії або вивчає з науковими цілями.
Підготовка Raspberry Pi
Перш ніж зможете використовувати RPi для розпізнавання мови, ви повинні переконатися, що зможете записувати звук з USB-мікрофону. Дистрибутив Raspbian налаштований на використання для звуку Advanced Linux Sound Architecture (ALSA). Незважаючи на свою назву, ця система цілком зріла і буде працювати з багатьма пакетами програмного забезпечення і звуковими картами без змін або труднощів конфігурації. Для конкретного випадку RPi є кілька налаштувань, які ми повинні зробити, щоб переконатися, що USB-карті віддана перевага перед вбудованим аудіо.
Спочатку підключіть USB-гарнітуру і подайте живлення на RPi. Після того, як RPi закінчить завантаження, можете перевірити, чи виявлене і готове до використання USB-аудіо, виконавши команду aplay -L. Повинна відобразитись назва вашої карти, наприклад, в нашому прикладі: Logitech H570e Stereo, USB Audio. Якщо ваша звукова USB-карта з'явилася в цьому списку, то можете перейти далі, щоб зробить її використання для системи за замовчуванням. Щоб зробити це, використайте свій улюблений текстовий редактор для редагування файлу alsa-base.conf, наприклад,так:
sudo nano /etc/modprobe.d/alsa-base.conf
Ви повинні змінити рядок options snd-usb-audio index=-2  на options snd-usb-audio index=0 і додати рядок нижче options snd_bcm2835 index=1. Після того, як закінчите, збережіть файл і перезавантажте RPi з sudo reboot, щоб використовувати нову конфігурацію.
Щоб перевірити зміни, скористайтеся командою arecord -vv --duration=7 -fdat ~/test.wav, щоб записати короткий 7-ми секундний відрізок аудіо з мікрофону. Спробуйте його відтворити з aplay ~/test.wav, і повинні почути через USB-навушники те, що записали раніше. Якщо ні, спробуйте відтворити такий попередньо записаний звук, як aplay /usr/share/sounds/alsa/Front_Center.wav, щоб виявити, проблема у мікрофоні чи колонках. (Інтернет буде хорошою допомогою при усуненні цих проблем.)
Якщо ви почули свій запис, то чудово! Ви готові перейти до налаштування програмного забезпечення.
Компіляція програмного забезпечення необхідних компонентів
Так, як ми стоїмо на плечах програмних гігантів, то є кілька пакетів для установки і кілька частин програмного забезпечення для компіляції, перш ніж ваш RPi буде готовий прийняти програму голосового управління.
По-перше, перейдіть до отримання пакетів, необхідних для виконання SphinxBase, виконавши:
sudo apt-get install libasound2-dev autoconf libtool bison \
swig python-dev python-pyaudio
Ви також повинні встановити деякі бібліотеки Python для використання з нашим демо-додатком. Щоб зробити це, треба буде встановити і використати команду pip за допомогою:
curl -O https://bootstrap.pypa.io/get-pip.py
sudo python get-pip.py
sudo pip install gevent grequests
Порада: Якщо підключення до RPi збоїть і схильне до відключень, то можете трохи заощадити душевного болю, виконавши наступні команди в screen session (сесії екрана). Щоб зробити це, виконайте наступне, перш ніж продовжити:
sudo apt-get install screen
screen -DR sphinx
Якщо на будь-якому етапі отримаєте відключення від RPi (і він не перезапустився), то можете запустити screen -DR sphinx, щоб знову з'єднатися і продовжити звідти, де ви зупинилися.
Отримання інструментів Sphinx
Тепер можете перейти до отримання пакету SphinxBase, який використовується PocketSphinx, а також іншим програмним забезпеченням сімейства CMU Sphinx.
Щоб отримати SphinxBase, виконайте наступні команди:
git clone git://github.com/cmusphinx/sphinxbase.git
cd sphinxbase
git checkout 3b34d87
./autogen.sh
make
(На цьому етапі можете сходити випити каву ...)
sudo make install
cd ..
Ви готові перейти до PocketSphinx. Щоб отримати PocketSphinx, виконайте такі команди:
git clone git://github.com/cmusphinx/pocketsphinx.git
cd pocketsphinx
git checkout 4e4e607
./autogen.sh
make
(Час для другої чашки кави ...)
sudo make install
cd ..
Щоб оновити систему з новими бібліотеками, запустіть sudo ldconfig.
Тестування розпізнавання мови
Тепер у вас на місці будівельні блоки для розпізнавання мови, але бажано перевірити, що це насправді працює, перш ніж продовжити.
Можете запустити тест PocketSphinx, використавши pocketsphinx_continuous -inmic yes.
Ви повинні побачити щось подібне, яке показує, що система готова почати говорити:
Listening...
Input overrun, read calls are too rare (non-fatal)
Можете проігнорувати попередження. Ідіть вперед і говоріть!
Коли закінчите, то повинні побачити технічну інформацію разом з кращою пропозицією від PocketSphinx про те, що сказали, а потім ще рядок READY, який дає вам знати, що система готова до подальшого введення:
INFO: ngram_search.c(874): bestpath 0.10 CPU 0.071 xRT
INFO: ngram_search.c(877): bestpath 0.11 wall 0.078 xRT
What
READY....
В даний момент розпізнавання мови запущене і працює. Ви готові перейти до реального задоволення від створення користувальницького додатка голосового управління!
Керування всіма речами
Для демо-додатку, автор запрограмував систему, яка має можливість контролювати три окремі системи: Philips Hue, освітлювальну систему Insteon та iRobot Roomba – робота-пилососа. З першими двома ви будете спілкуватися за допомогою моста або концентратора, підключеного до мережі. Для третього, будете спілкуватися з Arduino через послідовний порт USB, а потім Arduino буде переводити ваші команди в інфрачервоні (IR) сигнали, які імітують пульт дистанційного керування Roomba.
Якщо ви просто хочете зануритися в демо-додатки і спробувати їх, то можете використати наступні команди, щоб отримати вихідний код Python і запустити його на RPi:
git clone https://github.com/bynds/makevoicedemo
cd makevoicedemo
python main.py
На цьому етапі ви повинні отримати на екрані повідомлення, що RPi готовий до введення. Спробуйте сказати одну з команд – “Turn on the kitchen light” (Включити світло на кухні) або “Turn off the bedroom light” (Вимкнути світло у спальні) - і перегляньте слова, які з'являються на екрані. Оскільки ми ще не створили файл configuration.json, то світло на кухні повинне бути ще вимкнене.
Використання PocketSphinx
Є кілька режимів, які можна налаштувати для PocketSphinx. Наприклад, можна запропонувати прослуховувати для певного keyword - ключового слова (він буде намагатися ігнорувати все, що чує, крім ключового слова), або йому можна запропоновати використовувати grammar - граматику, яку вкажете (він намагатиметься відповідати на все, що чує, обмежуючись граматикою). В нашому прикладі, ми використовуємо режим граматики, яка була розроблена, щоб дозволити нам захопити всі команди, які будемо використовувати. Файл граматики вказаний в форматі JSGF або JSpeech Grammar Format, який має потужний, але простий синтаксис для вказівки мови, яку він очікує почути, в термінах простих правил.
На додаток до файлу граматики, вам потрібно зібрати ще три файли для того, щоб використовувати PocketSphinx в нашому додатку: файл словника (dictionary), який визначатиме слова в термінах того, як вони звучать, файл моделі мови (language model), який містить статистичні дані про слова і їх порядок, і акустичну модель (acoustic model), яка використовується для визначення того, як аудіо корелюється зі звуками в словах. Файл граматики, словник, і модель мови - всі будуть генеруватися спеціально для нашого проекту, в той час як акустична модель буде універсальною моделлю для американської англійської (U.S. English).
Створення словника
Для того, щоб згенерувати наш словник, використаємо lmtool, інструмент на веб-основі, створений CMU спеціально для швидкої генерації подібних файлів. Входом для lmtool є файл corpus, який містить всі або більшість з пропозицій, які ви хотіли б мати в змозі розпізнати. У нашому простому випадку використання ми маємо наступні пропозиції в corpus:
turn on the kitchen light
turn off the kitchen light
turn on the bedroom light
turn off the bedroom light
turn on the roomba
turn off the roomba
roomba clean
roomba go home
Ви можете ввести їх в текстовому редакторі і зберегти файл як corpus.txt або можете завантажити готову версію з репозиторію GitHub.
Тепер, коли у вас є свій corpus-файл, перейдіть до використання lmtool. Щоб завантажити corpus-файл, натисніть кнопку Browse (Огляд), щоб з’илося діалогове вікно, в якому можна вибрати corpus-файл, який щойно створили.
Потім натисніть кнопку Compile Knowledge Base (Компіляція бази знань). Ви потрапите на сторінку з посиланнями на скачування результату. Можете завантажити стиснений файл .tgz, який містить всі створені файли, або просто завантажити файл .dic, позначений як Pronunciation Dictionary. Скопіюйте цей файл в ту ж директорію makevoicedemo, яка була створений на RPi раніше. Ви можете перейменувати файл, використовуючи команду mv *.dic dictionary.dic, щоб було зручніше з ним працювати.
Після того, як зробите це, завантажте попередньо створену акустичну модель з Sphinx Sourceforge. Після того, як перемістите її в каталог makevoicedemo, витягніть її з архіву:
tar -xvf cmusphinx-en-us-ptm-5.2.tar.gz
Створення Grammar File
Як згадувалося раніше, все, що чує PocketSphinx, він намагатиметься записувати в словах граматики. Подивіться, як описаний формат JSGF в примітці W3C. Він починається з декларації формату з подальшою декларацією назви граматики. Ми просто назвемо його "commands".
Будемо використовувати три основних правила: action (дія), object (об'єкт) і command (команда). Для кожного правила визначте “tokens” (маркери), які ви очікуєте, будуть сказані користувачем. Наприклад, двома маркерами для нашого правила action є TURN ON (вмикання) і TURN OFF (вимкнення). Тому ми представляємо правило як:
<action> = TURN ON |
TURN OFF ;
Точно так само правило _object_ ми визначаємо як:
<object> =  KITCHEN LIGHT|
BEDROOM LIGHT|
ROOMBA        ;
Нарешті, щоб продемонструвати, що ми можемо розмістити правила або створити їх з явними маркерами, визначаємо команду як:
public <command> = <action> THE <object>  |
ROOMBA CLEAN            |
ROOMBA GO HOME         ;
Зверніть увагу на ключове слово public перед <command>. Це дозволяє нам використовувати правило <command>, а в майбутньому імпортуючи його в інші файли граматики.
Ініціалізація декодера
Ми використовуємо Python як нашу мова програмування, тому що її код легко читати, він потужний і, завдяки передбачливості розробників PocketSphinx, його також дуже легко використовувати з PocketSphinx.
Основною робочою конячкою при розпізнаванні мови з PocketSphinx є decoder (декодер). Для того, щоб використати декодер, потрібно спочатку встановити config (конфігурацію), яку використовуватиме декодер.
from pocketsphinx import *
hmm = 'cmusphinx-5prealpha-en-us-ptm-2.0/'
dic = 'dictionary.dic'
grammar = 'grammar.jsgf'
config = Decoder.default_config()
config.set_string('-hmm', hmm)
config.set_string('-dict', dic)
config.set_string('-jsgf', grammar)
Як тільки це буде зроблено, ініціалізація декодера також буде простою за допомогою decoder = Decoder(config).
Для прикладу програми, ми використовуємо бібліотеку pyAudio, щоб отримати мову користувача з мікрофону для перетворення з PocketSphinx. Специфіка цієї бібліотеки менш важлива для наших цілей (дослідження розпізнавання мови) і тому ми просто приймемо як належне, що pyAudio працює так, як рекламується.
Специфіка отримання декодером тексту вислову трохи складна, проте основний процес може бути зведений до наступних кроків.
\# Запуск 'вислову'
decoder.start_utt()
\# Оброблення soundbite
decoder.process_raw(soundBite, False, False)
\# Закінчити вислів, коли користувач перестав говорити
decoder.end_utt()
\# Отримати гіпотезу (для того, що було сказане)
hypothesis = decoder.hyp()
\# Отримати текст гіпотези
bestGuess = hypothesis.hypstr
\# Вивести те, що було сказане
print 'I just heard you say:"{}"'.format(bestGuess)
Ті, хто зацікавлений в отриманні додаткової інформації про окремі деталі цього процесу, повинні звернути свою увагу на код pocketSphinxListener.py у прикладі проекту.
Є багато різних параметрів конфігурації, з якими ви можете експериментувати, і, як згадувалося раніше, інші режими розпізнавання, щоб спробувати. Наприклад, дослідити варіант конфігурації allphone_ci PocketSphinx і його вплив на точність декодування. Або спробуйте ключове слово spotting для активації світла. Або спробуйте статистичну модель мови, подібну тій, яка була згенерована, яку ми раніше використовували з lmtool, замість файлу граматики. Як практик, ви можете експериментувати майже нескінченно досліджуючи полосу, що можливо. Одна річ, яку ви швидко помітите, що PocketSphinx є дослідною системою, яка ктивно розвивається, а це іноді означає, що ви повинні переписувати додатки відповідно з новими API і іменами функцій.
Тепер, коли ми розглянули те, що потрібно для перетворення мови в текст, давайте зробимо щось цікаве з ним! У наступному розділі розглянемо деякі рудиментарні зв'язки з мережевими вогнями Insteon і Philips Hue.
Нехай буде GET /Lights HTTP/1.1
Протягом багатьох років були спроектовані, побудовані і розгорнуті незліченні системи, щоб включити і виключити скромну лампочку. Обидві системи Insteon і Philips Hue мають такі можливості, але обидві мають набагато більше. Вони спілкуються з системою через бездротові протоколи, а Insteon має додаткову перевагу, бо також може зв'язуватись через лінії електроживлення будинку. Спілкування напряму з лампами в обох цих системах було б для деяких епічним хакі, проте на даний момент ми встановлюємо наші сигнали трохи нижче і отримаємо місце для спілкування через посередників.
Обидві системи оснащені мережевим концентратором (“hub”) або мостом (“bridge”), які виконують необхідну роботу, щоб такі пристрої в мережі, як смартфони зі встановленими відповідними додатками, могли передавати команди до світильників.
Виявляється, обидві ці системи мають API, які базуються на HTTP і які можемо використати в нашому прикладі голосового управлінням системами. Обидві компанії мають програми для розробників, до яких можна приєднатися, щоб повною мірою скористатися API:
Для тих, хто хотів поповнити свої знання трохи більше "партизанського стилю", є багато ресурсів в Інтернеті, які пояснюють основи спілкування з концентраторами обох цих виробників. Багато майстрів опубліковали веб статтті на цю тему, розкриваючи їх секрети через вікові навички ретельного обстеження, аналізу мережі та зворотного інжинірингу. Ці навички мають неоціненне значення бо і майстри, і ці системи пропонують великий досвід для тих, хто готовий працювати з ними.
Приклад проекту має мінімальний набір команд Python, які можуть бути використані для спілкування як з старим Insteon 2242-222 Hub, так і поточним мостом Philips Hue, щоб ви могли стартувати.
Я наказую тобі, робот
Roomba, підготуйся, щоб виконати мої бажання!
Щоб розширити наш звіринець барвистих пристроїв, ми також захопили Arduino Leonardo, до якого підключили інфрачервоним світлодіод і запрограмували для відправки команд до нашому iRobot Roomba – роботу-пилососу.
Arduino підключається до RPi за допомогою USB-кабелю, який також подає живлення і дозволяє послідовний зв'язок. Ми використовуємо бібліотеку IRremote, щоб зробити важку роботу миготіння IR LED з відповідним точним часом.
PocketSphinx_1
Саморобна плата підключення інфрачервоного світлодіода до Arduino. Звичайно, вона може бути меншою.
PocketSphinx_IR
Принципова схема для простого кола IR LED.
Для того, щоб в бібліотеці щось мати для спілкування, ми повинні підключити деяку схему передачі ІЧ до відповідних контактів нашого Arduino. Апаратно все можна звести до транзистора, ІЧ-підсвічуванням і резистора або двох, які можуть бути розміщені на платі і підключені до Arduino. В даному прикладі тестували набір SparkFun Max Power IR LED Kit і установку мінімалістського ІЧ-передавача з резистором 330 Ом, транзистором 2N3904 NPN та інфрачервоним світлодіодом, підключених до Arduino через три штирі виводів.
Використаємо бібліотеку IRremote, щоб дозволити створювати і відправляти ІЧ сигнали до Roomba, які виконують емуляцію пульта дистанційного керування Roomba. Ці сигнали є серією кодованих імпульсів, тривалість яких відповідає двійковим сигналам. Коли вони закодовані для передачі за допомогою бібліотеки, то вони виглядають подібно до наступного скетча нашого прикладу:
// Очистити
const unsigned int clean[15] = {3000,1000,1000,3000,1000,3000,1000,3000,3000,1000,1000,3000,1000,3000,1000};
// кнопка живлення
const unsigned int power[15] = {3000,1000,1000,3000,1000,3000,1000,3000,3000,1000,1000,3000,3000,1000,1000};
// Док
const unsigned int dock[15] = {3000,1000,1000,3000,1000,3000,1000,3000,3000,1000,3000,1000,3000,1000,3000};
Для того, щоб Roomba отримав і зрозумів ці сигнали, автор знайшов, що краще відправити їх чотири рази, що зробимо в наступній функції sendRoombaCommand:
void sendRoombaCommand(unsigned int* command){
for (int i = 0; i < 4; i++){
irsend.sendRaw(command, 15, 38);
delay(50);
}
}
PocketSphinx_Arduino
Додавши бібліотеку IRremote до коду Arduino, ви зможете відправляти інфрачервоні (ІЧ) сигнали керування для Roomba.
Після того, як ІЧ-устаткування було підключене до відповідних контактів і компільований та завантажений скетч через Arduino IDE, ви зможете відправляти команди через послідовний порт, який буде переведавати те, що Roomba може зрозуміти. Бінарність дійсно стає універсальною мовою!
Тепер все разом
Так що у вас є повна система керування вогнями Insteon, світлом Philips Hue та iRobot Roomba лише звуками свого голосу!
PocketSphinx_All
Raspberry Pi (у чорному корпусі) + Arduino + інфрачервоний світлодіод = повний пристрій для голосового керування вашим освітленням і роботами.
Все це було б неможливе без щедрого внеску багатьох проектів з відкритим вихідним кодом, які ми використали. Даний приклад проекту також є відкритим джерелом, тому ви можете звернутися до нього при здійсненні власних проектів голосового управління на RPi і повторити його частини у своїх наступних проектах.
(Джерело EN: makezine.com)
 
>
КнигаНовиниПрактика пошукуПартнериПро нас
Підтримка та дизайн: Могильний С.С. Шаблон: Joomla Templates by BuyHTTP Joomla Hosting