Programujemy sterowanie głosowe dronem z użyciem Node.js i ARDrone

Programujemy sterowanie głosowe dronem z użyciem Node.js i ARDrone

W tym samouczku omówimy tworzenie programu dla drona z obsługą głosową w Node.js oraz Web Speech API. Kopter to Parrot ARDrone 2.0.

Przypominamy: dla wszystkich czytelników „Habra” — zniżka 10 000 rubli przy zapisie na dowolny kurs Skillbox z kodem promocyjnym „Habra”.

Skillbox poleca: Praktyczny kurs „Mobilny programista PRO”.

Wprowadzenie

Drony są fantastyczne. Bardzo lubię bawić się moim kopterem, robiąc zdjęcia i nagrywając filmy lub po prostu się bawiąc. Ale bezzałogowe statki powietrzne (BSP) nie służą tylko do zabawy. Wykorzystywane są w kinematografii, do badania lodowców, oraz przez wojsko i przedstawicieli sektora rolnictwa.

W tym samouczku omówimy tworzenie programu, który pozwoli na sterowanie dronem za pomocą komend głosowych. Tak, kopter będzie robił to, co mu powiesz. Na końcu artykułu – gotowy program i wideo przedstawiające sterowanie BSP.

Sprzęt

Potrzebujemy następujących rzeczy:

  • Parrot ARDrone 2.0;
  • kabel Ethernet;
  • dobry mikrofon.

Rozwój i zarządzanie będą prowadzone na stacjach roboczych z systemem Windows/Mac/Ubuntu. Osobiście pracowałem z Mac i Ubuntu 18.04.

Oprogramowanie

Pobierz najnowszą wersję Node.js z oficjalnej strony.

Potrzebna jest również najnowsza wersja Google Chrome.

Zrozumienie koptera

Spróbujmy zrozumieć, jak działa Parrot ARDrone. Ten kopter ma cztery silniki.

Programujemy sterowanie głosowe dronem z użyciem Node.js i ARDrone

Przeciwstawne silniki działają w jednym kierunku. Jedna para obraca się zgodnie z ruchem wskazówek zegara, druga – przeciwnie. Dron porusza się dzięki zmianie kąta nachylenia względem powierzchni ziemi, regulacji prędkości obrotów silników oraz kilku innych manewrów.

Programujemy sterowanie głosowe dronem z użyciem Node.js i ARDrone

Jak widać na powyższym diagramie, zmiana różnych parametrów prowadzi do zmiany kierunku ruchu koptera. Na przykład, zmniejszenie lub zwiększenie prędkości obrotów lewego i prawego wirnika tworzy przechył. To umożliwia dronowi lot do przodu lub do tyłu.

Zmieniając prędkość i kierunek ruchu silników, ustalamy kąty nachyleń, które pozwalają kopterowi poruszać się w innych kierunkach. Właściwie, w przypadku bieżącego projektu, nie trzeba badać aerodynamiki, po prostu warto zrozumieć podstawowe zasady.

Jak działa Parrot ARDrone

Dron stanowi punkt dostępu Wi-Fi. Aby otrzymywać i wysyłać komendy do koptera, musisz się z nim połączyć. Istnieje wiele aplikacji umożliwiających sterowanie kopterami. Wygląda to mniej więcej tak:

Programujemy sterowanie głosowe dronem z użyciem Node.js i ARDrone

Gdy dron jest już podłączony, otwieramy terminal i wpisujemy telnet 192.168.1.1 – to IP koptera. Dla systemu Linux można użyć Linux Busybox.

Architektura aplikacji

Nasz kod zostanie podzielony na następujące moduły:

  • interfejs użytkownika z API rozpoznawania głosu;
  • filtrowanie poleceń i dopasowanie ich do wzorca;
  • wysyłanie poleceń do drona;
  • transmisja wideo na żywo.

API działa pod warunkiem posiadania połączenia z internetem. Aby to zapewnić, dodajemy połączenie przez Ethernet.

Czas na stworzenie aplikacji!

Kodujemy

Na początek utworzymy nowy folder i przełączymy się na niego za pomocą terminala.

Następnie tworzymy projekt Node, używając poniższych poleceń.

Zaczynamy od zainstalowania wymaganych zależności.

npm install 

Będziemy wspierać następujące polecenia:

  • start;
  • lądowanie;
  • w górę — dron unosi się na pół metra i wisi;
  • w dół — opuszcza się na pół metra i wisi;
  • w lewo — przesuwa się w lewo na pół metra;
  • w prawo — przesuwa się w prawo na pół metra;
  • obrót — obraca się zgodnie z ruchem wskazówek zegara o 90 stopni;
  • do przodu — przesuwa się do przodu na pół metra;
  • do tyłu — przesuwa się do tyłu na pół metra;
  • stop.

Oto kod, który umożliwia odbieranie poleceń, filtrowanie ich i kontrolowanie drona.

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();
// wyłącz awaryjny
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('otrzymano polecenie ', req.body);
    console.log('istniejące polecenia', commands);
    let command = req.body.command.replace(/ /g,'');
    if(commands.indexOf(command) !== -1) {
        switch(command.toUpperCase()) {
            case "TAKEOFF":
                console.log('wznoszenie drona');
                drone.takeoff();
            break;
            case "LAND":
                console.log('lądowanie drona');
                drone.land();
            break;
            case "UP":
                console.log('unoszenie drona o pół metra');
                drone.up(0.2);
                setTimeout(() => {
                    drone.stop();
                    clearTimeout();
                },2000);
            break;
            case "DOWN":
                console.log('opuszczanie drona o pół metra');
                drone.down(0.2);
                setTimeout(() => {
                    drone.stop();
                    clearTimeout();
                },2000);
            break;
            case "GOLEFT":
                console.log('przesuwanie drona w lewo o 1 metr');
                drone.left(0.1);
                setTimeout(() => {
                    drone.stop();
                    clearTimeout();
                },1000);
            break;
            case "GORIGHT":
                console.log('przesuwanie drona w prawo o 1 metr');
                drone.right(0.1);
                setTimeout(() => {
                    drone.stop();
                    clearTimeout();
                },1000);
            break;
            case "TURN":
                console.log('obracanie drona');
                drone.clockwise(0.4);
                setTimeout(() => {
                    drone.stop();
                    clearTimeout();
                },2000);
            break;
            case "GOFORWARD":
                console.log('przesuwanie drona do przodu o 1 metr');
                drone.front(0.1);
                setTimeout(() => {
                    drone.stop();
                    clearTimeout();
                },2000);
            break;
            case "GOBACKWARD":
                console.log('przesuwanie drona do tyłu o 1 metr');
                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);

Oto kod HTML i JavaScript, który nasłuchuje na polecenia użytkownika i wysyła je do serwera Node.

<!DOCTYPE html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Aplikacja Notatki Sterowana Głosem</title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/shoelace-css/1.0.0-beta16/shoelace.css">
        <link rel="stylesheet" href="styles.css">
 
    </head>
    <body>
        <div class="container">
 
            <h1>Dron sterowany głosowo</h1>
            <p class="page-description">Mała aplikacja, która pozwala kontrolować drona AR za pomocą głosu</p>
 
            <h3 class="no-browser-support">Przepraszamy, Twoja przeglądarka nie obsługuje Web Speech API. Spróbuj otworzyć tę demonstrację w Google Chrome.</h3>
 
            <div class="app">
                <h3>Podaj komendę</h3>
                <div class="input-single">
                    <textarea id="note-textarea" placeholder="Utwórz nową notatkę, wpisując lub korzystając z rozpoznawania głosu." rows="6"></textarea>
                </div>    
                <button id="start-record-btn" title="Rozpocznij nagrywanie">Rozpocznij rozpoznawanie</button>
                <button id="pause-record-btn" title="Wstrzymaj nagrywanie">Wstrzymaj rozpoznawanie</button>
                <p id="recording-instructions">Naciśnij przycisk <strong>Rozpocznij rozpoznawanie</strong> i zezwól na dostęp.</p>
 
            </div>
 
        </div>
 
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        <script src="script.js"></script>
 
    </body>
</html>

I jeszcze kod JavaScript do obsługi poleceń głosowych, wysyłając je do serwera 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'
 });
};

Uruchamiamy aplikację

Program można uruchomić w następujący sposób (ważne, aby upewnić się, że dron jest połączony z Wi-Fi, a kabel Ethernet jest podłączony do komputera).

Otwieramy localhost:3000 w przeglądarce i klikamy Rozpocznij rozpoznawanie.

Programujemy sterowanie głosowe dronem z użyciem Node.js i ARDrone

Próbujemy sterować dronem i cieszymy się.

Transmisja wideo z drona

W projekcie tworzymy nowy plik i kopiujemy do niego ten kod:

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);

A oto kod HTML, umieszczamy go w folderze public.

<!doctype html>
 <html>
 <head>
 <meta http-equiv="content-type" content="text/html; charset=utf-8">
 <title>Strumień jako moduł</title>
 <script src="/dronestream/nodecopter-client.js" type="text/javascript" charset="utf-8"></script>
 </head>
 <body>
 <h1 id="heading">Strumień wideo z drona</h1>
 <div id="droneStream" style="width: 640px; height: 360px"> </div>
 
<script type="text/javascript" charset="utf-8">
 
new NodecopterStream(document.getElementById("droneStream"));
 
</script>
 
</body>
</html>

Uruchamiamy i łączymy się z localhost:8080, aby oglądać wideo z kamery frontowej.

Programujemy sterowanie głosowe dronem z użyciem Node.js i ARDrone

Przydatne wskazówki

  • Steruj tym dronem w pomieszczeniu.
  • Zawsze zakładaj osłonę na drona przed startem.
  • Sprawdź, czy akumulator jest naładowany.
  • Jeśli dron zachowuje się dziwnie, trzymaj go od dołu i przewróć. To działanie przełączy dron w tryb awaryjny, a wirniki natychmiast się zatrzymają.

Gotowy kod i demonstracja

DEMO NA ŻYWO

POBIERZ

Udało się!

Napisanie kodu, a następnie obserwacja, jak maszyna zaczyna słuchać, przyniesie Ci przyjemność! Teraz dowiedzieliśmy się, jak nauczyć drona słuchać komend głosowych. W rzeczywistości możliwości są znacznie większe: rozpoznawanie twarzy użytkownika, autonomiczne loty, rozpoznawanie gestów i wiele więcej.

Co możesz zaproponować, aby poprawić program?

Skillbox poleca:

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster