Уголок радиолюбителя. Как прокачать дрона

Обучаем дрона автономности, управлению голосом и распознаванию лиц.
07 декабря 2016326451Илья Бубнов5106428

В силу своей профессии, я нередко слежу не только за громкими событиями в мире IT, но и за подвигами простых радиолюбителей (а им в свою очередь, приходится быть ещё и программистами). Недавно я наткнулся на статью Лукаса Биволда на портале O’’Reilly, в которой он подробно описал, как из дрона за 200 $ (в России такой стоит около 20 тысяч рублей) с помощью простой компьютерной магии собрать аппарат минимум в 5 раз дороже. Вот перевод статьи.

Выбор готового дрона

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

Большинство производителей дронов обещают предоставлять программный интерфейс (API), но среди них нет лидера, который мог бы предоставить экосистему для любителей. Большинство дронов с удобным интерфейсом стоят более $1000, что является серьезной преградой.

После некоторых поисков, мне удалось найти Parrot AR Drone 2.0, который, по моему мнению, является удачным выбором, если вам нужен недорогой и легко программируемый дрон для развлечений. Вы можете купить новый за $200, но, учитывая количество людей, которые их покупают и никогда не используют, лучше купить подержанный на eBay менее чем за $130.

Parrot AR не так стабильно летает, как гораздо более дорогой (около $550) новый Parrot Bebop 2, но для Parrot AR существует клиентская библиотека на node.js под название node-ar-drone. Она идеально подходит в качестве основы для программирования дрона.

Еще одно преимущество Parrot AR – его очень трудно сломать. При тестировании кода автономного режима мой дрон не раз врезался в стены, мебель, цветочные горшки и гостей, и все еще прекрасно летает.

Одной из проблем дронов по сравнению с наземными роботами является небольшое время работы их аккумулятора. Подзарядка может занимать несколько часов, а хватит её всего где-то на 10 минут полета. Я рекомендую купить 2 дополнительные батареи и менять их в процессе тестирования.

Программирование дрона

Javascript отлично подходит для управления дронами, потому что он по своей сути событийно-ориентирован. Поверьте, при управлении дрона возникает множество асинхронных случаев. Я не разбирался с Node длительное время, но по результатам этого проекта был очень впечатлен его возможностями.

Последний раз, когда я основательно программировал робота, я использовать язык С, но многотопоточность и обработка исключений в нем настолько утомляет, что хочется его избегать. Надеюсь, кто-то построит обёрточный функционал Javascript для других платформ, потому что этот язык значительно упрощает программирование в недетерминированных условиях.

Архитектура

Я решил запустить логический алгоритм на ноутбуке, а систему машинного обучения – в облаке. Такая схема позволила снизить время ожидания по сравнению с запуском нейросети непосредственно на компьютере Raspberry PI , и я считаю, что она является целесообразной для любительских дрон-проектов.

Microsoft, Google, IBM, и Amazon предлагают недорогие облачные интерфейсы машинного обучения. Я выбрал Microsoft’s Cognitive Service для этого проекта, так как это единственный интерфейс, поддерживающий настраиваемое распознавание лиц.

Начало настройки

По умолчанию Parrot AR 2.0 раздает собственную клиентскую беспроводную сеть.  Это невероятно усложняет взлом устройства. Каждый раз, когда вы что-то предпринимаете, вам необходимо отсоединиться от своей сети и подключиться к сети дрона. К счастью, существует очень полезный проект ardrone-wpa2, который поможет настроить дрон на подключение к вашей Wi-Fi сети.

Очень весело использовать протокол Telnet и экспериментировать, Parrot начинает напоминать урезанную версию Linux. Когда вы в последний раз подключались к чему то через Telnet? Вот пример, как можно открыть терминал и войти непосредственно в систему дрона.

% script/connect "The Optics Lab" -p "particleorwave" -a 192.168.0.1 -d 192.168.7.43

% telnet 192.168.7.43

Управление полетом командной строкой

После установки библиотеки node можно сделать цикл типа прочитать-вычислить-записать (REPL) и тем самым начать управлять дроном.

var arDrone = require('ar-drone');

var client = arDrone.createClient({ip: '192.168.7.43'});

client.createRepl();

drone> takeoff()

true

drone> client.animate(‘yawDance, 1.0)

Если вы следуете моим инструкциям, к этому моменту вы уже точно несколько раз уронили ваш дрон. Я тысячу раз переклеивал защитный каркас прежде чем он развалился, и мне пришлось покупать новый. Я сомневаюсь, стоит ли это говорить, но Parrot летает гораздо лучше без каркаса. Но летая без него лопасти могут зацепиться и сломать что-то, испортить мебель.

Управление полетом с веб-страницы

Создать веб-интерфейс для управления полетом – приятно и легко. Платформа express.js сильно упрощает создание небольшого веб-сервера:

var express = require('express');

app.get('/', function (req, res) {

 res.sendFile(path.join(__dirname + '/index.html'));

});

app.get('/land', function(req, res) {

 client.land();

});

app.get('/takeoff', function(req, res) {

 client.takeoff();

});

app.listen(3000, function () {

});

Я устанавливаю функцию для создания запросов методом AJAX с помощью кнопок:

<html>

<script language='javascript'>

function call(name) {

  var xhr = new XMLHttpRequest();

  xhr.open('GET', name, true);

  xhr.send();

}

</script>

<body>

<a onclick="call('land');">Land</a>

</body>

</html>

Съемка потокового видео с дрона

Я нашел, пожалуй, лучший способ смотреть видео с камеры дрона. Он заключается в открытии соединения и непрерывной отправке изображений PNG с моего веб-сервера на мой веб-сайт. Веб-сервер постоянно получает PNG с помощью библиотеки AR с дрона.

var pngStream = client.getPngStream();

pngStream

 .on('error', console.log)

 .on('data', function(pngBuffer) {

       sendPng(pngBuffer);

 }

function sendPng(buffer) {

 res.write('--daboundary\nContent-Type: image/png\nContent-length: ' + buff

er.length + '\n\n');

 res.write(buffer);

});

Запуск технологии распознавания лиц

Программный интерфейс Azure Face API очень мощный и простой в использовании. Вы можете загрузить фото своих друзей, и он сможет распознать их. Он также определит возраст и пол, что, по моему опыту, у него получается удивительно хорошо. Время ожидания – около 200 миллисекунд, стоит $1,5 за 1000 определений, что кажется весьма оправданным. Ниже – мой вариант кода для отправки изображения и запуска алгоритма распознавания лиц.

var oxford = require('project-oxford'),

oxc = new oxford.Client(CLIENT_KEY);

loadFaces = function() {

 chris_url = "https://media.licdn.com/mpr/mpr/shrinknp_400_400/AAEAAQAAAAAAAALyAAAAJGMyNmIzNWM0LTA5MTYtNDU4Mi05YjExLTgyMzVlMTZjYjEwYw.jpg";

 lukas_url = "https://media.licdn.com/mpr/mpr/shrinknp_400_400/p/3/000/058/147/34969d0.jpg";

 oxc.face.faceList.create('myFaces');

 oxc.face.faceList.addFace('myFaces', {url => chris_url, name=> 'Chris'});

 oxc.face.faceList.addFace('myFaces', {url => lukas_url, name=> 'Lukas'});

}

oxc.face.detect({

 path: 'camera.png',

 analyzesAge: true,

 analyzesGender: true

}).then(function (response) {

 if (response.length > 0) {

  drawFaces(response, filename)

 }

});

Я использовал великолепную библиотеку ImageMagick чтобы помечать лица на PNG. На этом этапе можно использовать множество разных расширений, к примеру, интерфейс для определения эмоций emotion API.

Установка системы распознавания речевых команд

Самой сложной частью установки системы распознавания речи является не само по себе распознавание речи, а трансляция звуковой дорожки с веб-страницы на мой локальный сервер в формате, которого требует Microsoft’s Speech API, а это, в свою очередь, выливается в слишком длинный код. Единожды сохранив аудио в одноканальном формате и с верной выборочной частотой, вы сможете начать легко и успешно использовать интерфейс. Стоимость 1000 запросов – $4, так  что для любительских проектов сервис практически бесплатен.

Сервис RecordRTC имеет отличную библиотеку и прекрасно подходит для начальной клиентской звукозаписи. Со стороны клиента мы может добавить код, который бы сохранял аудиофайл:

app.post('/audio', function(req, res) {

 var form = new formidable.IncomingForm();

 // specify that we want to allow the user to upload multiple files in a single request

 form.multiples = true;

 form.uploadDir = path.join(__dirname, '/uploads');

 form.on('file', function(field, file) {

       filename = "audio.wav"

       fs.rename(file.path, path.join(form.uploadDir, filename));

 });

 // log any errors that occur

 form.on('error', function(err) {

       console.log('An error has occured: \n' + err);

 });

 // once all the files have been uploaded, send a response to the client

 form.on('end', function() {

       res.end('success');

 });

 // parse the incoming request containing the form data

 form.parse(req)

 speech.parseWav('uploads/audio.wav', function(text) {

       console.log(text);

       controlDrone(text);

 });

});

Я использовал утилиту FFmpeg для того, чтобы снизить качество аудио и свести его в один канал для загрузки в сервис Microsoft.

exports.parseWav = function(wavPath, callback) {

 var cmd = 'ffmpeg -i ' + wavPath + ' -ar 8000 -ac 1 -y tmp.wav';

 exec(cmd, function(error, stdout, stderr) {

       console.log(stderr); // command output is in stdout

 });

 postToOxford(callback);

});

На этом этапе также можно использовать интерфейс Microsoft для преобразования текста в речь, чтобы дрон мог отвечать вам.

Автономный маршрут доступа

Я использовал библиотеку ardrone-autonomy для планирования автономного маршрута доступа для моего дрона. После многочисленных столкновений с мебелью и домашними цветами в гостиной моя жена деликатно предложила мне перенести тестирование моего проекта в гараж, где меньше того, что можно сломать, но меньше пространства для маневров.

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

var autonomy = require('ardrone-autonomy');

var mission = autonomy.createMission({ip: '10.0.1.3', frameRate: 1, imageSize: '640:320'});

console.log("Here we go!")

mission.takeoff()

         .zero()         // Sets the current state as the reference

         .altitude(1)

         .taskSync(console.log("Checkpoint 1"))

         .go({x: 0, y: 0, z: 1, yaw: 90})

         .taskSync(console.log("Checkpoint 2"))

         .hover(1000)

         .go({x: 0, y: 0, z: 1, yaw: 180})

         .taskSync(console.log("Checkpoint 3"))

         .hover(1000)

         .go({x: 0, y: 0, z: 1, yaw: 270})

         .taskSync(console.log("Checkpoint 4"));

         .hover(1000)

         .go({x: 0, y: 0, z: 1, yaw: 0

         .land()

Посмотрите видео, в котором дрон взлетает и начинает искать моего друга Криса https://www.youtube.com/watch?v=RVW7Jsw4KsQ&feature=youtu.be

Выводы

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

Облачный программный интерфейс Microsoft Cognitive Service очень прост в использовании и невероятно мало стоит. Сначала я был обеспокоен, что непривычно широкоугольная камера дрона может помешать нормальному распознаванию лиц, а также что громкий звук от лопастей будет препятствовать звукам, но на деле все работает гораздо лучше, чем я ожидал. Время ожидания не является проблемой, каковой я предполагал она может быть. Произведение всех вычислений в облаке в режиме передачи изображений в реальном времени сначала кажется немного странным выбором архитектуры, но вероятно станет стандартом для многих приложений в будущем.

 

Новые комментарии