Развлекаться с автономным летательным аппаратом – это, конечно, весело, но создавать их самому еще интереснее! Эта статья адресована тем, кто хочет разработать свой собственный интеллектуальный коптер и содержит набор простых инструкций, как достичь результата с использованием смартфона на Android, OpenCV, C++ и Java. Ну а если вы сможете пройти первые шаги и пожелаете далее совершенствовать свой аппарат – в конце поста вы найдете полезную ссылку и пищу для размышления.
Автономный и интеллектуальный?
Для того, чтобы коптер мог самостоятельно летать, он должен включать в себя все необходимые сенсоры, достаточную вычислительную мощность и средства коммуникации. Вроде бы, не так уж и много, однако практически у всех из доступных коммерческих моделей этого нет. Существуют, скажем, модели, движение которых определяют датчики, расположенные в помещении. Другой вариант – управление через 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:
import android.hardware.usb.UsbDeviceConnection;
// …
private UsbDeviceConnection connection;
// …
connection.controlTransfer(0x40, command, value, channel, null, 0, 5000);
Контроллер позволяет управлять серво приводами, устанавливая конечную позицию, скорость и ускорение – все, что нужно для плавного перемещения. Аргумент command может принимать одно из трех значений:
public static final int USB_SET_POSITION = 0x85;
public static final int USB_SET_SPEED = 0x87;
public static final int USB_SET_ACCELERATION = 0x89;
Выберите подходящие значения и передайте их на нужный серво мотор, используя аргумент 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:
…
// capture images from the camera
import org.opencv.Android.CameraBridgeViewBase;
// load OpenCV native dependancy
import org.opencv.Android.OpenCVLoader;
…
public void onResume()
{
super.onResume();
// OpenCV loading with a callback
// non typical code specific to OpenCV
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_6, this, mLoaderCallback);
}
…
// once the OpenCV manager link established,
// we can load the dynamic library
System.loadLibrary("jni_part");
…
Код С++
…
// typical for JNI : Java class method name
// pointer to RGB image as argument
JNIEXPORT int JNICALL Java_com_example_circles_MainActivity_process
(JNIEnv *jenv, jobject obj, jlong addrGray, jlong addrRgba)
…
// Get the bitmap from pointer
Mat& mRgb = *(Mat*)addrRgba;
// blur, required before detecting circles
medianBlur(mGr,mGr,5);
// OpenCV detection – Hough transformation
HoughCircles(mGr, //grayscale input image
*circles, //output vector
CV_HOUGH_GRADIENT, //detection method to use
4, //inverse ratio of the accumulator resolution to the image
mGr.rows/8, //min distance between centers of detected circles
220, //higher threshold of the two passed intern canny edge detector
200, //accumulator threshold 100
20, //min radius
mGr.cols/8 //max radius
);
Для теста я перемещал смартфон перед листом бумаги с напечатанным кругом. Допустим, с расстояния 20 см изображение круга будет иметь размер 300 пикселей – будем считать это правильным положением. Если круг меньше, смартфон надо пододвинуть ближе, если больше – то дальше. Это самый простой вариант. Можно использовать два концентрических круга, больший для навигации на дальнем расстоянии, меньший – на ближнем. Ничто не мешает распознавать и другие специфические фигуры, например, стрелки. В конечном счете мы должны получить систему, использующую как данные GPS, так и цветовую информацию с камеры.
Планы на будущее
Установите OpenCV Manager и ваш APK файл из Eclipse. Запустите его и пройдите все шаги настройки. Оно будет определять круги в поле зрения и руководить перемещением смартфона в центр круга заданного диаметра.
На тестовом смартфоне мы получали и обрабатывали снимок каждые 8 сотых секунды – 12.5 кадров в секунду. Это доказывает, что компьютерное зрение для коптера – вещь совершенно реальная даже при ограниченных временных и финансовых ресурсах.
Возможности дальнейшего развития очень широки. OpenCV – это open source библиотека, портированная на многие платформы. Вдобавок, Intel IPP заменяет некоторые низкоуровневые вызовы OpenCV и ускоряет ваш код, вставляя функции, хорошо оптимизированные под процессоры Intel. Вы можете сохранить переносимость кода – в дальнейшем, возможно, вам понадобится более мощный смартфон.
Ну а что делать дальше – вам подскажут материалы с сайта Intel. Там написано очень подробно, как самому построить летающий аппарат и чему его научить.
Теперь некоторые более конкретные ссылки:
Автор: saul
https://www.youtube.com/watch?v=xqHrTtvFFIs