- Самодельный автономный летающий аппарат из Android смартфона
- Автономный и интеллектуальный?
- Управление моторами
- Особенности квадрокоптеров
- Собираем все воедино
- Компьютерное зрение
- Развертывание
- DIY автономный дрон с управлением через интернет. Часть 2 про ПО
- ПО для управления дроном на ПК и планшетах
- Установка образа ОС на SD-карту
- Обновление дистрибутива и установка необходимых пакетов
- Настройка и запуск Ardupilot
- MAVProxy
- Установка связи с дроном в локальной сети
- Калибровка датчиков и настройка параметров автопилота
- Видеотрансляция
- Телеметрия через интернет
- Видео через интернет
Самодельный автономный летающий аппарат из Android смартфона
Автономный и интеллектуальный?
Для того, чтобы коптер мог самостоятельно летать, он должен включать в себя все необходимые сенсоры, достаточную вычислительную мощность и средства коммуникации. Вроде бы, не так уж и много, однако практически у всех из доступных коммерческих моделей этого нет. Существуют, скажем, модели, движение которых определяют датчики, расположенные в помещении. Другой вариант – управление через GPS. GPS приемник дешев и прост в использовании, но обладает большими задержками в поступлении данных и недостаточно точен. Все это нам не годится.
Чтобы носить звание «интеллектуального» ваш коптер должен уметь воспринимать и анализировать окружающую действительность. Это требует не только мощного процессора, емкого аккумулятора, качественной камеры и достаточного набора датчиков, но и быстрых коммуникационных устройств. Ну и конечно, вся эта система должна хорошо управляться и просто программироваться. Так мы приходим к мысли: а не реализовать ли мозговой центр коптера на базе смартфона? Удобнее всего использовать устройство на базе Android, поскольку под эту ОС имеются удобные средства разработки и программные компоненты, такие, например, как Intel Integrated Performance Primitives (Intel IPP) или OpenCV. Современный смартфон имеет все нужные нам аппаратные компоненты, поэтому изобретать велосипед совершенно нет необходимости.
Управление моторами
Итак, центр управления выбран, теперь надо подключить к нему моторы. Мы выбрали Pololu Maestro servo controller стоимостью порядка 5 долларов, он подключается по USB и вдобавок имеет Bluetooth интерфейс. С помощью этой карты будут управляться стандартные серво приводы. С помощью Pololu Maestro servo controller и смартфона сравнительно несложно переделать управляемый летательный аппарат в автономный.
С помощью нескольких строк кода и стандартных Android USB средств мы будем контролировать серво моторы и, таким образом, движение коптера. Еще несколько строк кода – и мы получим доступ к GPS, камере и передаче данных по сети.
Вызовем controlTransfer из UsbDeviceConnection:
Контроллер позволяет управлять серво приводами, устанавливая конечную позицию, скорость и ускорение – все, что нужно для плавного перемещения. Аргумент command может принимать одно из трех значений:
Выберите подходящие значения и передайте их на нужный серво мотор, используя аргумент channel. Ссылка на полный исходный код и конфигурацию USB доступа в манифесте приложения приведена в конце поста.
Особенности квадрокоптеров
До сих пор все идет хорошо. Аппаратные компоненты подключаются друг к другу без проблем, программирование несложно, поскольку все реализуется средствами Android. Однако тут есть одна особенность, связанная с конструированием квадрокоптера. В отличие от более простых моделей, таких как автомобиль или самолет, квадрокоптер должен постоянно следить за своей устойчивостью. Вот почему его необходимым компонентом является модуль стабилизации. Конечно, стабилизатор можно сделать программным, написав кучу кода на C++ или Java. Но гораздо проще купить за несколько долларов карту-стабилизатор, подключаемую непосредственно к Pololu и управляющую четырьмя серво приводами устройства. Всё остальное можно сделать с помощью простых команд типа ± altitude, ± speed/, ± inclination и ± direction.
Если вы создаете квадрокоптер, имейте в виду: эта карта здорово упростит вам жизнь. Все, что вам требуется – провести ее начальную калибровку и потом забыть о ней.
Собираем все воедино
Итак, в результате первого этапа конструирования автономного квадрокоптера, мы имеем следующую аппаратную цепочку:
смартфон <> micro USB-USB адаптер <> кабель USB-mini USB <> Pololu Maestro card <> 4 кабеля JR <> карта стабилизации <> кабели JR <> серво приводы <> двигатели
В случае более простого устройства цепочка будет покороче:
смартфон <> micro USB-USB адаптер <> кабель USB-mini USB <> Pololu Maestro card <> кабели JR <> серво приводы <> двигатели
В дополнение вы можете установить и другие приводы на ваше летающее устройство, например, для закрылков или посадочных шасси. Карта Pololu Maestro имеет поддержку управления до 24 приводов – для нашего проекта это, наверное, даже лишнего.
Базовая платформа создана. Теперь пришло время оснастить наше устройство зрением.
Компьютерное зрение
Очевидно, что без системы компьютерного зрения интеллектуальное устройство не может считаться таковым. Наш коптер должен уметь не просто снимать фото, но и анализировать их – для этого воспользуемся возможностями OpenCV.
OpenCV – это open source библиотека для программного анализа изображений, лежащая в основе бесчисленных реализаций систем компьютерного зрения и виртуальной реальности. Изначально разработанная Intel, сейчас она доступна для множества аппаратных платформ и ОС.
Для практики попробуем распознать простой знак в виде круга и расположиться перед этим знаком на определенной дистанции. Чтобы упростить тестовое задание, перемещать смартфон будем рукой.
OpenCV не является библиотекой, напрямую доступной Java под Android. Это нативная библиотека, обычно используемая из программ на С++, так что нам понадобится Android NDK. Съемка изображений и визуализация будет выполнена на Java, для взаимодействия между Java и C++ будем использовать JNI. Нам придется установить Android NDK и Android SDK, создать новый проект Circles, добавить компонент C/ C++ и изменить свойства проекта для использования библиотеки OpenCV, как показано на скриншотах ниже:
В результате, в вашем проекте будут:
Основной Java файл « Src/MainActivity.java »
Файл разметки XML « Res/layout/activity_main.xml » и манифест
Два Makefile « Jni/Android.mk » and « Jni/Application.mk »
Код cpp « Jni/ComputerVision_jni.cpp » и хедер « Jni/ComputerVision_jni.h »
В отличие от Java, C++ должен быть скомпилирован под определенный процессор. Настройка производится путем редактирования переменной APP_ABI в файле Application.mk. Если у вас смартфон на платформе Intel, корректным значением будет x86. Дальше NDK все сделает сам.
Развертывание
OpenCV – библиотека, используемая бесконечным количеством Android приложений, при этом версия библиотеки ими может использоваться разная. Как разработчик, вы можете связать свое приложение с конкретной версией OpenCV, но есть вариант получше. Воспользуйтесь менеджером зависимостей под названием «OpenCV Manager». Это Android приложение, которое определяет, что вам сейчас потребуется OpenCV и загружает именно ту версию, которая необходима.
Мы хотим обнаружить круги в OpenCV, определить их центр и радиус и вывести инструкции оператору смартфона для достижения центрированного круга правильного размера. Следующий Java код получает изображение с камеры с помощью Java API для Android, вызывает функцию на С++ через JNI и прикрепляет указатель на изображение в памяти. Код С++ осуществляет обработку изображения с целью обнаружить круги. Далее опять вызывается Java, чтобы отобразить обнаруженные круги и комментарии.
Код Java:
Для теста я перемещал смартфон перед листом бумаги с напечатанным кругом. Допустим, с расстояния 20 см изображение круга будет иметь размер 300 пикселей – будем считать это правильным положением. Если круг меньше, смартфон надо пододвинуть ближе, если больше – то дальше. Это самый простой вариант. Можно использовать два концентрических круга, больший для навигации на дальнем расстоянии, меньший – на ближнем. Ничто не мешает распознавать и другие специфические фигуры, например, стрелки. В конечном счете мы должны получить систему, использующую как данные GPS, так и цветовую информацию с камеры.
Источник
DIY автономный дрон с управлением через интернет. Часть 2 про ПО
Это продолжение повествования об автономном дроне. В первой части говорилось про hardware, в этой речь пойдет про software. Для начала небольшой ликбез про взаимодействие оператора с коптером. Вот типичная схема у большинства самосборных дронов:
А вот схема у продвинутых дронов:
Так работают игрушечные дроны, которые управляются со смартфона:
Управлять дроном через интернет можно так (при наличии сим-карты со статическим IP-адресом):
Или так, если IP-адрес динамический:
Для надежности и резервирования каналов связи последний вариант можно развить до такого состояния:
Далее я буду описывать процесс настройки полетного контроллера Emlid Navio 2 и микрокомпьютера Raspberry Pi 3.
Но, с небольшими модификациями, эти настройки подойдут для любого полетного контроллера, с которым можно общаться по протоколу MAVLink в связке с любым компьютером на ОС семейства Linux.
Важно! Настройку необходимо делать с отключенным питанием на регуляторах оборотов, чтобы случайно не запустились двигатели.
ПО для управления дроном на ПК и планшетах
Для управления БПЛА используются специальные программы GCS (Ground Control Station). Далее по тексту я буду использовать эту аббревиатуру. Мне по душе пришлась QGroundControl, мультиплатформенная (Windows, Linux, MacOS, iOS, Android) GCS с открытым исходным кодом, которая стала частью проекта DroneCode. Но есть и альтернативы, бесплатные и коммерческие: APM Planner, MissionPlanner, UgCS, LibrePilot, OpenPilot, Tower (DroidPlanner) для Android, MAVPilot (iOS), SidePilot (iOS). А также консольная MAVProxy.
Установка образа ОС на SD-карту
Для нормальной работы автопилота крайне рекомендуется использовать “быстрые” SD-карты (класс 10). Медленные карты памяти не успевают сохранять логи автопилота даже на небольшой частоте, в результате чего они получаются кривыми или вообще не пишутся. Свидетельством этого может быть ошибка “No IO heartbeat”, которую можно наблюдать в консоли MAVLink (как смотреть консоль MAVLink описано ниже). При покупке смотрите на возможность писать 4К видео: скорее всего это будет быстрая SD. К сожалению, я об этом узнал после падения дрона, когда нужно было проанализировать логи и узнать причину. Логи оказались нечитаемы для нескольких GCS. Причина отключения моторов в полете оказалась банальна: я забыл подправить в настройках значение минимального напряжения на аккумуляторе для срабатывания failsafe.
Итак, скачиваем готовый образ Raspbian Stretch с предустановленными Ardupilot и ROS от Emlid со страницы оригинальной инструкции. И пишем его на карту памяти с помощью Etcher или любой подобной программы.
Чтобы сразу после включения Raspberry соединялся с вашей WiFi сетью, необходимо отредактировать файл wpa_supplicant.conf в корне SD-карты. В нем должны быть такие строки:
Можно настроить и без WiFi, подключив одноплатник к роутеру Ethernet-кабелем. Теперь вынимаем SD-карту из ПК, вставляем ее в Raspberry и включаем питание. Через полминуты он должен появиться в админке роутера на странице подключенных устройств (хостнейм navio).
Обновление дистрибутива и установка необходимых пакетов
Открываем SSH-клиент и соединяемся с Raspberry (локальный IP-адрес navio вместо RASPBERRY_IP_ADDRESS):
Стандартный пароль: raspberry. В первую очередь необходимо расширить файловую систему ОС на весь объем SD-карты:
После перезагрузки, соединяемся еще раз и обновляем дистрибутив:
Устанавливаем дополнительные пакеты:
и компилируем обертку gst-rpicamsrc для gstreamer и родной камеры Raspicam:
Проверим работает ли камера (создается видеофайл test.h264):
Если gstreamer запустился, подождите пару секунд, чтобы записалось видео. Прервать процесс можно клавишами Ctrl+C. Если видео есть, значит камера работает.
Настройка и запуск Ardupilot
Релизы новых версий Ardupilot немного запаздывают в сборке от Emlid. Если необходимый функционал доступен в самой последней версии, то установить ее из исходников можно по этой инструкции.
Разработчики Navio добавили в свою сборку простую и удобную утилиту Emlid tool для проверки датчиков и настройки Ardupilot. Сначала проверим, видит ли Raspberry контроллер Navio:
Если в ответ на эту команду выдает что-то вроде:
значит видит. Проверим состояние датчиков (покажет список и состояние):
и драйвера ШИМ-контроллера в ядре Linux:
0 = не работает, 1 = работает.
Прошивка ШИМ-контроллера обновляется так:
Теперь настроим Ardupilot:
В терминале откроется текстовый GUI с пошаговыми менюшками. Выбираем copter последней версии, тип arducopter, автозапуск при включении (On boot: enable), старт после настройки (Ardupilot: start).
Выходим через пункт меню Quit.
Проверим запустился ли Ardupilot:
Обратите внимание, файл запуска в systemd называется arducopter, так как настроен был вариант copter.
Теперь нужно настроить Ardupilot так, чтобы он отправлял нам телеметрию. Для этого отредактируем файл конфигурации:
В нем должны быть такие строки:
Сохраняем файл (Ctrl+X, затем Y) и перезапускаем Ardupilot:
Проверить состояние процесса Ardupilot можно такой командой:
С такими настройками Ardupilot будет транслировать телеметрию (пакеты MAVLink) в локальный UDP-порт 14550. Далее, скрипт MAVProxy (описание ниже) будет забирать оттуда телеметрию и передавать в GCS или скрипт, а также отправлять в обратном направлении пакеты с командами.
Вместо локального адреса и порта можно записать IP-адрес ПК или планшета в локальной сети и пакеты будут транслироваться сразу туда.
Однако, такой подход оправдан, если данные телеметрии больше нигде не используются и у устройства с GCS статический IP адрес. Иначе каждый раз в настройках Ardupilot придется прописывать новый. Чтобы общаться с автопилотом по TCP могли одновременно несколько GCS с динамическими адресами и еще какие-нибудь скрипты на самом бортовом компьютере, удобнее использовать MAVProxy.
Этот скрипт (написан на Python) может получать пакеты MAVLink на локальный UDP-адрес и ретранслировать их на несколько локальных или удаленных IP-адресов как по UDP, так и по TCP. Пакеты передаются в обоих направлениях Ardupilot ⇔ GCS. Кроме того, MAVProxy представляет из себя полноценную GCS, но с текстовым интерфейсом.
MAVProxy
MAVProxy уже установлен в образе Navio. Его также можно установить и на ПК (Windows, Linux, MacOS) для дальнейшего общения с автопилотом в консольном режиме.
Убедившись, что Ardupilot работает, запустим на Raspberry скрипт MAVProxy такой командой:
Параметр —master=udp:127.0.0.1:14550 задает для скрипта источник данных. Это локальный UDP-порт, который был прописан в файле конфигурации Ardupilot. После запуска команды, MAVProxy соединиться с этим портом и выведет на экран сообщения автопилота, примерно как у меня:
Так как автопилот еще не откалиброван и до конца не настроен, то об этом красноречиво говорят и сообщения. В этом режиме можно общаться с автопилотом посредством команд. Если бы дрон был полностью настроен, то вот такая последовательность двух команд привела бы к старту двигателей и взлету дрона на высоту 20 м:
Не откалиброванный автопилот не полетит, а покажет сообщения с причинами, почему он этого сделать не сможет.
Установка связи с дроном в локальной сети
Остановим скрипт (Ctrl+C) и снова запустим его в таком виде:
С дополнительным параметром —out=tcpin:0.0.0.0:5762 MAVProxy будет слушать порт 5762 на входящие TCP соединения от GCS. Как только GCS соединиться, пакеты с данными начнут перемещаться между дроном и GCS. Попробуем подключиться с ПК:
Если подключение удалось, то GCS покажет кучу сообщений с требованием откалибровать датчики и загрузит бортовые параметры с их текущими значениями:
Калибровка датчиков и настройка параметров автопилота
Калибровку автопилота можно сделать почти в любой GCS. В документации Ardupilot она описана во всех подробностях. Прежде всего устанавливаем тип рамы. У меня стандартная 4-х моторная компоновка, поэтому это Quad X.
Первый полет лучше все же сделать в ручном режиме. Подключаем и калибруем радиоуправление (приемник и передатчик).
Осталось откалибровать акселерометр и компас.
Для того, чтобы Ardupilot видел и учитывал данные с внешних датчиков, установим необходимые параметры:
FLOW_ENABLE = 1 (Enabled)
FLOW_ADDR = 0 (0 = вариант для стандартного адреса 0х42)
Для лазерного высотомера VL53L0X (инструкция)
RNGFND_TYPE = 16 (VL53L0X)
RNGFND_ORIENT = 25 (ориентация дальномера вниз)
RNGFND_ADDR = 41 (I2C-адрес в десятичном виде). Адрес датчика по-умолчанию 0x29, что в десятичном виде = 41.
RNGFND_SCALING = 1
RNGFND_MIN_CM = 5
RNGFND_MAX_CM = 120
RNGFND_GNDCLEAR = 15 (расстояние от датчика до поверхности, когда дрон стоит на земле)
PLND_ENABLED = 1
PLND_TYPE = 2
PLND_BUS = 1
Для сонара переднего обзора (инструкция)
RNGFND2_TYPE = 2 (MaxbotixI2C sonar)
RNGFND2_ORIENT = 0 (ориентация дальномера вперед)
RNGFND2_MAX_CM = 700 (макс дальность в сантиметрах)
Теперь перезапускаем Ardupilot из меню GCS, снова соединяемся с бортом и открываем окошко MAVLink Inspector, чтобы увидеть данные с датчиков.
К сожалению, показания IR-Lock тут не видны, для анализа его работы придется взглянуть на бортовые логи. Как это сделать описано здесь.
Осталось настроить параметры безопасности и можно запускать дрон:
Как настроить гироподвес и управление основной камерой в деталях я напишу в одной из следующих статей, основные моменты изложены здесь.
Видеотрансляция
Проверим как работает видеотрансляция в сети WiFi. Такой командой можно запустить видео в TCP-порт на Raspberry с использованием родной утилиты raspivid для камеры Raspicam:
А вот такой командой делается тоже самое, только с использованием ранее скомпилированной обертки rpi-camsrc для gstreamer:
В обоих случаях, трансляция в формате h264 доступна по IP-адресу Raspberry на порту 5001.
Посмотреть ее можно запустив на своем ПК такую команду (должен быть установлен gstreamer), вместо RPI_ADDRESS указываем адрес Raspberry в сети:
В результате должно открыться окошко с видео.
Практически в любую GCS встроен видеоплеер, который может показывать RTSP-видеопоток. Чтобы сделать из Raspberry RTSP-сервер можно использовать консольный плеер VLC. Установка:
Видеотрансляция запускается так:
Видео доступно по адресу (вместо RPI_ADDRESS, адрес Raspberry):
Адрес потока можно использовать для подключения нескольких плееров на разных устройствах, но, так как видеозахват и трансляция для Raspberry весьма трудоемкий процесс, то для нескольких потребителей видео лучше использовать внешний сервер (описание ниже).
Телеметрия через интернет
Чтобы GCS могла подключиться через интернет к дрону с динамическим IP-адресом, необходим промежуточный сервер со статическим IP, на котором будет запущен скрипт MAVProxy. Для этих целей я воспользовался арендой облачного сервера у одного из известных провайдеров. Для MAVProxy подойдет самая минимальная конфигурация, но так как у меня этот же сервер будет заниматься ретрансляцией видео, то я выбрал вариант с чуть большей памятью (одно ядро и 1Гб памяти, Ubuntu 18.04). Для минимальной задержки в прохождении данных между бортом и GCS, сервер должен располагаться в максимальной географической близости к дрону и GCS.
Устанавливаем MAVProxy на сервер. Сначала зависимости:
а потом и сам скрипт через PIP:
и запустим скрипт с такими параметрами:
MAVProxy слушает порт 15001 на входящие пакеты телеметрии от дрона по протоколу UDP, а порт 15002 на входящее TCP-соединение от GCS.
Запустим MAVProxy на Raspberry еще с одним параметром, чтобы телеметрия транслировалась еще и на сервер (вместо SERVER_IP адрес своего сервера):
После старта скрипта на бортовом компьютере, в консоли сервера появятся сообщения от автопилота. Как уже говорилось выше, MAVProxy представляет из себя полноценную GCS с текстовым интерфейсом и в таком состоянии уже можно редактировать параметры и управлять дроном посредством команд в консоли сервера.
Подключим GCS на ПК или планшете к серверу. Настройки соединения такие же как и для локальной сети, только вместо IP-адреса Raspberry указываем адрес сервера и порт 15002.
Теперь можно подключить 4G USB-модем к Raspberry и оценить с какой задержкой реагирует авиагоризонт на экране.
Видео через интернет
Для ретрансляции видео установим на сервер VLC плеер:
После установки, запустим его как ретранслятор c UDP порта 5001 в RTSP канал SERVER_IP:8554/live:
На борту запустим видеотрансляцию с камеры на сервер по UDP (вместо SERVER_IP адрес сервера):
Адрес потока теперь можно использовать как источник видео в настройках GCS или открыть в любом плеере, поддерживающим этот протокол.
Теперь можно спланировать маршрут полета и запустить дрон через интернет, предварительно его включив, например, с помощью помощника по телефону.
Очевидно, что из-за относительно большого времени путешествия видео и телеметрии по сети, такой способ вряд ли подойдет для FPV-полетов в ручном режиме между препятствиями.
Источник