Синхронізувати рот; гуманоїдний робот Quai Lab

У цій статті представлено рішення для синхронізувати рух рота робота гуманоїд своїм голосом. Звук оброблятиметься в режимі реального часу на неусиленому джерелі: ПК, телефон, вихід на планшет тощо.
Завданням є керування сервомотором, що приводить у дію відкривання/закриття на вертикальній осі дула. Цей рух дуже спрощений у порівнянні з рухами губ/щелеп ... Для більшої реалістичності також потрібно було б розпізнати фонеми, щоб імітувати спосіб їх вимови, враховуючи також розмовну мову (англійська, французька тощо). .).

синхронізувати

Це поза нашою темою, ми тут будемо задоволені ефектом, близьким до ефекту, який виробляють ляльководи та вентрілокісти в анімації їх рукою.

Завантажте код Arduino InMoov ротовий синхрон

Багато іграшок імітують рух рота, мені не довелося довго шукати, щоб знайти в дитячих іграшках Барбі з гніздовим штекером, для аудіозв'язку, який я на мить мав надію відновити ланцюг ... але, на жаль, Синхронізація працює належним чином лише для двох або трьох попередньо записаних речень.

Цей тип іграшок, ймовірно, має рухи, які слід робити в пам’яті, тим самим уникаючи обробки сигналів. Шкода…, але принаймні Барбі врятували 🙂

Принцип збережено

Голосовий звуковий сигнал коливається між значеннями негативні та позитивні з більш-менш високою амплітудою. Для управління сервомотором ми обчислимо ефективну потужність (у ватах) сигналу, який також називається середньоквадратичним значенням (англійською мовою Root Mean Square), щоб надати більшу або меншу амплітуду розкриттю щелепи відповідно до сили голосу. Система самокалібрується із закритим положенням рота, а сервомотор відключений, коли не видається звук.

Я даю вам формулу для розрахунку середньоквадратичної віддачі для функції за інтервал між Т1 і Т2.

З f (t) наш дискретизований звуковий сигнал і (T1-T2) тривалість вибірки.


Кілька нагадувань про голос:

Голос має частоту між 800 Гц і 3 кг Гц (людське вухо сприймає частоти до 20 кГц).
Звуковий сигнал на виході ПК досить слабкий, як правило, між -0,5 і + 0,5 в, і має посилюватися при виході на зовнішні динаміки.
Мінімальна частота для оцифровки сигналу повинна бути вдвічі більшою за сигнал, щоб не мати втрат (теорема дискретизації Найквіста - Шеннона), на компакт-диску також звук дискретизується на частоті 44,1 кГц на 16 бітах.

Візуалізація звукового сигналу на вході (червоний) і після зміщення 0,5 В готовий до оцифровки

Наша мета полягає в тому, щоб побудувати цю систему на основі Arduino Uno, ми знаємо, що аналогові входи (A0-A5) arduino вимірюють напругу від 0 до 5 В на 10 бітах, тобто 1024 значення.

Якщо ми відбираємо аудіосигнал таким, яким він є, негативна частина буде асимільована до 0v, тому ми виміряємо лише половину сигналу, а з іншого боку, точність вимірювання на основі еталону при 5 вольтах буде лише з (1024 x 0,5)/5 = 102 можливі значення !

Щоб довести наш сигнал між -0,5 і 0,5 в до сигналу від 0 до 1 вольта, ми повинні додати зміщення + 0,5В. Для цього 2 резистори, встановлені як роздільний міст, зроблять трюк, 0,5 в відповідає 1/10 опорної напруги 5 вольт, доступної на arduino, тому співвідношення наших 2 резисторів повинно бути приблизно у співвідношенні 1 до 10.

R1 = 10ko (коричневий - чорний - оранжевий)
R2 = 100 кб (коричневий - чорний - жовтий)

Для пам'яті Ur1 = U x R1/(R1 + R2) = (5 x 10 000)/(100 000 + 10000) = 0,45 Вольт

Конденсатор досить високого значення (від 1 до 10 мікрофарадів) блокує повернення прямих напруг (поляризований конденсатор незалежно від напрямку).

Для підвищення точності внутрішній компаратор ATmega328 дозволяє нам змінювати еталонну напругу його компаратора (або зовнішній штифт AREF), або можливість встановити внутрішню напругу 1,1 вольта з інструкцією> analogReference (INTERNAL), ідеально підходить для наших потреб.

Монтажна схема

Я використовував один із аудіоканалів для дискретизації, інший канал підключений до підсилювача.
(Припустимо, що голосовий вихід подвоюється на 2 аудіоканалах)

Програма:

Він представляє деякі оптимізації:
зчитування значення на A0 здійснюється шляхом маніпулювання регістрами ATmega (еквівалентно AnalogRead але набагато швидше).
Ми також отримуємо швидкість і ємність зберігання, задовольняючись 8-бітовим значенням замість 10 (тому 2 найменш значущі біти, які, як кажуть, є низьким порядком, ігноруються). Ми використовуємо точність 256 значень від 0 до 1,1 Вольт.

Дякую Дідьє за цей код, який можна знайти на Arduinoos

Для розрахунку середньоквадратичної віддачі ми використовуємо абсолютне значення, щоб заощадити час обчислення, а не виконувати прохід у квадраті, за яким слідує квадратний корінь ...

Ви можете налаштувати частоту дискретизації та кількість відібраних проб для розрахунку середньоквадратичного значення.
Я вважаю, що хороший компроміс між швидкістю обробки та точністю досягається завдяки відбір проб на 8 кілограмів з 64 зразок вікна.
Ці процедури приймають близько 9 мс: час вибірки + обчислення середньоквадратичного значення + переведення в кутове значення.
Час вибірки: 64 x (1/8000) = 0,008 або 8 мс

ШІМ-сигнал, що надходить на серводвигун, має частоту 50 Гц, тобто період 20мс додається до часу відгуку, необхідного для переміщення сервоприводу (кілька мілісекунд)

Це спричиняє затримку в часі приблизно тридцять мілісекунд між звуком, що видається, і рухом рота.

Коли аудіо та візуальне не збігаються точно, наш мозок адаптується і дозволяє до певного відставання. Це злиття двох подразників, незважаючи на їх невідповідність, називається ефектом вентрилокізм сказав "Часова" коли існує невелика затримка між тим, коли ми бачимо зображення, і коли ми чуємо звук, мозок синхронізує звук із зображенням.

Загалом мозок менш чутливий до асинхронності, коли зір передує слуху, не везе ... у нашому випадку все навпаки ...

Потрібно зробити два вдосконалення

1 - Додавання смугового фільтра для усунення фонових шумів, музики та перешкод.
2 - Додавання лінії затримки на посиленій звуковій доріжці для компенсації часу обробки звукового сигналу.