[Перевод] Программируем голосовое управление коптером с использованием Node.js и ARDrone

f1628cd05e0aca700a2b0235c65fd063.jpg

В этом туториале мы разберем создание программы для дрона с голосовым управлением на Node.js и Web speech API. Коптер — Parrot ARDrone 2.0.

Напоминаем: для всех читателей «Хабра» — скидка 10 000 рублей при записи на любой курс Skillbox по промокоду «Хабр».

Skillbox рекомендует: Практический курс «Мобильный разработчик PRO».

Введение


Дроны восхитительны. Мне очень нравится играть со своим коптером, записывая фото и видео или просто развлекаясь. Но беспилотные аппараты (БПЛА) используются не только для развлечения. Они работают в кинематографе, изучают ледники, применяются военными и представителями сельскохозяйственной сферы.

В этом туториале мы разберем создание программы, которая позволит управлять дроном. используя голосовые команды. Да, коптер будет делать то, что вы ему говорите. В конце статьи — готовая программа и видео управления БПЛА.

Железо


Нам нужно следующее:

  • Parrot ARDrone 2.0;
  • Ethernet-кабель;
  • хороший микрофон.


Разработка и управление будет вестись на рабочих станциях с Windows/Mac/Ubuntu. Лично я работал с Mac и Ubuntu 18.04.

Программное обеспечение


Загрузите последнюю версию Node.js с официального сайта.

Также нужна последняя версия Google Chrome.

Разбираемся с коптером


Давайте попробуем понять, как работает Parrot ARDrone. У этого коптера есть четыре мотора.

d51072f0c6ccbc6d5aa08c9ec92b78aa.png

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

78029f39aed7eb8d4c0711e3e3ad7e5a.png

Как мы видим на диаграмме выше, изменение разных параметров приводит к смене направления движения коптера. Например, уменьшение или увеличение скорости вращения левого и правого роторов создают крен. Это позволяет дрону лететь вперед или назад.

Изменяя скорость и направление движения моторов, мы задаем углы наклона, позволяющие коптеру совершать движение в других направлениях. Собственно, для текущего проекта аэродинамику изучать не нужно, просто стоит понять основные принципы.

Как работает Parrot ARDrone


Дрон представляет собой точку доступа Wi-Fi. Для того чтобы получать и отправлять команды коптеру, необходимо к этой точке подключиться. Есть много разнообразных приложений, позволяющих управлять коптерами. Выглядит все это примерно так:

d3aae2f5cce06994229187962e42bf0a.png

Как только дрон подключен, открываем терминал и telnet 192.168.1.1 — это IP коптера. Для Linux можно использовать Linux Busybox.

Архитектура приложения


Наш код будет разделен на следующие модули:

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


API работает при условии наличия интернет-подключения. Чтобы его обеспечить, мы и добавляем подключение по Ethernet.

Пора создавать приложение!

Кодим


Для начала создадим новую папку и переключимся на нее при помощи терминала.

Затем создаем Node-проект, используя указанные ниже команды.

Для начала устанавливаем требуемые зависимости.

npm install 

Будем поддерживать следующие команды:

  • взлет;
  • посадка;
  • вверх — дрон поднимается на полметра и зависает;
  • вниз — опускается на полметра и зависает;
  • влево — идет влево на полметра;
  • вправо — идет вправо на полметра;
  • поворот — поворачивается по часовой стрелке на 90 градусов;
  • вперед — идет вперед на полметра;
  • назад — идет назад на полметра;
  • стоп.


Вот код, который позволяет принимать команды, фильтровать их и контролировать дрон.

const express = require('express');
const bodyparser = require('body-parser');
var arDrone = require('ar-drone');
const router = express.Router();
const app = express();
const commands = ['takeoff', 'land','up','down','goleft','goright','turn','goforward','gobackward','stop'];
 
var drone  = arDrone.createClient();
// disable emergency
drone.disableEmergency();
// express
app.use(bodyparser.json());
app.use(express.static(__dirname + '/public'));
 
router.get('/',(req,res) => {
    res.sendFile('index.html');
});
 
router.post('/command',(req,res) => {
    console.log('command recieved ', req.body);
    console.log('existing commands', commands);
    let command = req.body.command.replace(/ /g,'');
    if(commands.indexOf(command) !== -1) {
        switch(command.toUpperCase()) {
            case "TAKEOFF":
                console.log('taking off the drone');
                drone.takeoff();
            break;
            case "LAND":
                console.log('landing the drone');
                drone.land();
            break;
            case "UP":
                console.log('taking the drone up half meter');
                drone.up(0.2);
                setTimeout(() => {
                    drone.stop();
                    clearTimeout();
                },2000);
            break;
            case "DOWN":
                console.log('taking the drone down half meter');
                drone.down(0.2);
                setTimeout(() => {
                    drone.stop();
                    clearTimeout();
                },2000);
            break;
            case "GOLEFT":
                console.log('taking the drone left 1 meter');
                drone.left(0.1);
                setTimeout(() => {
                    drone.stop();
                    clearTimeout();
                },1000);
            break;
            case "GORIGHT":
                console.log('taking the drone right 1 meter');
                drone.right(0.1);
                setTimeout(() => {
                    drone.stop();
                    clearTimeout();
                },1000);
            break;
            case "TURN":
                console.log('turning the drone');
                drone.clockwise(0.4);
                setTimeout(() => {
                    drone.stop();
                    clearTimeout();
                },2000);
            break;
            case "GOFORWARD":
                console.log('moving the drone forward by 1 meter');
                drone.front(0.1);
                setTimeout(() => {
                    drone.stop();
                    clearTimeout();
                },2000);
            break;
            case "GOBACKWARD":
                console.log('moving the drone backward 1 meter');
                drone.back(0.1);
                setTimeout(() => {
                    drone.stop();
                    clearTimeout();
                },2000);
            break;
            case "STOP":
                drone.stop();
            break;
            default:
            break;    
        }
    }
    res.send('OK');
});
 
app.use('/',router);
 
app.listen(process.env.port || 3000);


А вот HTML- и JavaScript-код, который слушает пользователя и отправляет команду на Node-сервер.


    
        
        
        Voice Controlled Notes App
        
        
        
        
 
    
    
        

Voice Controlled Drone

A tiny app that allows you to control AR drone using voice

Sorry, Your Browser Doesn't Support the Web Speech API. Try Opening This Demo In Google Chrome.

Give the command

Press the Start Recognition button and allow access.


И еще JavaScript-код для того, чтобы работать с голосовыми командами, отправляя их на сервер Node.

try {
 var SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
 var recognition = new SpeechRecognition();
 }
 catch(e) {
 console.error(e);
 $('.no-browser-support').show();
 $('.app').hide();
 }
// other code, please refer GitHub source
recognition.onresult = function(event) {
// event is a SpeechRecognitionEvent object.
// It holds all the lines we have captured so far.
 // We only need the current one.
 var current = event.resultIndex;
// Get a transcript of what was said.
var transcript = event.results[current][0].transcript;
// send it to the backend
$.ajax({
 type: 'POST',
 url: '/command/',
 data: JSON.stringify({command: transcript}),
 success: function(data) { console.log(data) },
 contentType: "application/json",
 dataType: 'json'
 });
};


Запускаем приложение


Программу можно запустить следующим образом (важно убедиться, что коптер подключен к Wi-Fi, а Ethernet-кабель подключен к компьютеру).

Открываем localhost:3000 в браузере и кликаем Start Recognition.

6c9af8547e4c4bcb06829fd75b9aa97d.png

Пробуем управлять дроном и радуемся.

Трансляция видео с дрона


В проекте создаем новый файл и копируем туда этот код:

const http = require("http");
const drone = require("dronestream");
 
const server = http.createServer(function(req, res) {
 
require("fs").createReadStream(__dirname + "/public/video.html").pipe(res);
 });
 
drone.listen(server);
 
server.listen(4000);


А вот HTML-код, его размещаем внутри папки public.


 
 
 
 Stream as module
 
 
 
 

Drone video stream


Запускаем и подключаемся к localhost:8080 для просмотра видео с фронтальной камеры.

e8920cbb4b7bfe2b24ac8c788d8dcdc6.png

Полезные советы


  • Управляйте этим дроном в помещении.
  • Всегда надевайте защитную крышку на дрон перед взлетом.
  • Проверьте, заряжен ли аккумулятор.
  • Если дрон ведет себя странно, удерживайте его снизу и переверните. Это действие переведет коптер в аварийный режим, и роторы немедленно остановятся.


Готовый код и демонстрация


LIVE DEMO

DOWNLOAD

Получилось!


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

Что вы можете предложить для улучшения программы?

Skillbox рекомендует:

© Habrahabr.ru