COMPARTIR:Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn

Jugar con pequeños drones civiles es divertido. Construirlos, ¡mucho más! Todo aquel interesado en crear su propio dron autónomo “inteligente” encontrará en este artículo instrucciones sencillas para hacerlo con un smartphone Android*, OpenCV*, C++, y Java*. Y esto es solo el comienzo. Cuando haya dominado estas instrucciones, podrá utilizar otros programas que le permitirán refinar el dron aún más. En el Programa Académico de Software Intel® [1] encontrará más información acerca de Intel® OpenCourseWare para estudiar por su cuenta.

Materiales y métodos

¿Autónomo e inteligente?

Para que un dron vuele de manera autónoma, todos los sensores necesarios, el poder de procesamiento y los chips de comunicación deben estar integrados. Si bien este requisito no parece gran cosa, deja a un lado a muchos de los drones comerciales actuales de uso civil que se venden al público en general.

¿Ha visto el anuncio comercial creado por Lexus y KMEL Robotics [2] en el que aparecen “enjambres” de pequeños drones ultraprecisos? Para coreografiar los movimientos, se los posicionó en el espacio dentro de la habitación donde se los operaba, con el uso de potentes sensores ubicados en todo el recinto. Quizá sepa también que los drones, que han recibido mucha atención últimamente, se pueden navegar mediante GPS. El GPS es práctico y de muy fácil acceso porque es digital, razón por la cual se lo usa en los aviones durante la etapa de vuelo en piloto automático a gran altitud. Pero la precisión de ± 2.5 m y la considerable latencia no permiten que un dron entregue una pizza a la puerta de una casa, porque si se acercara 2.5 m demás, chocaría con la puerta, y si se ubicara 2.5 m demasiado a la izquierda o a la derecha, también chocaría. Sí, estos drones tienen navegación independiente, pero no son muy “inteligentes”.

Para que a un dron se lo pueda llamar inteligente, debe tener integradas suficientes prestaciones de procesamiento como para, por ejemplo, capturar un video y analizar en tiempo real objetivos tales como códigos QR (fácil), formas o movimientos (difícil). Incluso se pueden medir volúmenes y reconstruir un espacio en tiempo real, como se hizo con el vehículo aéreo no tripulado del MIT [3]. Sin embargo, todas estas “mejoras” exigen un procesador potente, además de sensores tales como acelerómetros y GPS, y posiblemente la capacidad de comunicarse de vez en cuando por una red 3G/4G También sería conveniente que pesara poco, fuera fácil de programar y tuviera una buena batería. A fin de cuentas, lo que nos queda es un potente teléfono móvil que puede, a su vez, activar las funcionalidades de vuelo de un dron.

Recientemente desarrollamos un control remoto para drones que utiliza un smartphone con Android, en nuestro caso el ZTE V975 Geek, con un procesador Intel® Atom™ Z2580. Al utilizar Android, es sencillo desarrollar el software y compartir el código entre una PC y el teléfono. Incluso se pueden usar en ambos bibliotecas nativas como Intel® Integrated Performance Primitives (Intel® IPP) [4] y OpenCV [5]. Por eso, no hace falta empezar desde cero; el smartphone tiene todos los componentes necesarios: cámara, GPS, acelerómetro y 3G.

Control del motor

Cuando hayamos decidido qué computadora integrada emplear, estaremos listos para conectar los motores. Nosotros seleccionamos el servocontrolador Pololu Maestro*, que cuesta unos € 5 (menos de 6 dólares), se conecta por USB e incluso tiene Bluetooth* con una interfaz serie Bluetooth opcional. Esta tarjeta se usa para controlar servomotores estándares. Más allá del tipo de dron que uno vaya a dirigir, sea un cuadricóptero o algún otro tipo, solo hay que reemplazar la pieza de control por radio con un smartphone Android y la tarjeta Pololu para convertirlo en un dron inteligente autónomo. Esta receta se puede reutilizar indefinidamente. Es simple, no?

Con unas pocas líneas de código y un paquete estándar USB para Android, podemos controlar los servomotores y, en consecuencia, los movimientos de la aeronave. Con unas líneas de código más, podemos acceder al GPS, tomar fotos y enviarlas por la red 3G. A nivel de software, trabajar con Android posibilita que el diseño avance rápidamente.

Llame a controlTransfer desde UsbDeviceConnection:

import android.hardware.usb.UsbDeviceConnection;
// …
private UsbDeviceConnection connection;
// …
connection.controlTransfer(0x40, command, value, channel, null, 0, 5000);

La tarjeta permite mover un servomotor mediante la determinación de la posición final, la velocidad y la aceleración, que es todo lo necesario para lograr un movimiento fluido. El argumento “command” puede ser uno de los siguientes valores:

public static final int USB_SET_POSITION = 0x85;
public static final int USB_SET_SPEED = 0x87;
public static final int USB_SET_ACCELERATION = 0x89;

Hay que elegir el valor correspondiente y apuntar al servomotor correcto con “channel”. El código fuente completo y la configuración del acceso por USB en el manifiesto de la aplicación se incluyen en el archivo zip [1].

El caso especial de los cuadricópteros

Hasta ahora, venimos bien. El hardware es plug-n-play, el código es sencillo y todo se hace en Android. Pero el desarrollo de sistemas integrados retiene ciertas cualidades específicas, como veremos a continuación con los cuadricópteros. Hay una diferencia importante entre los drones multirrotor y los modelos más simples, como los autos o aviones a control remoto. Si tenemos un auto eléctrico a control remoto, solo necesitamos un servo variador (ESC) para la aceleración y otro servo para la dirección. Pero los multirrotores necesitan un motor que los equilibre constantemente para que mantengan la posición deseada. Por suerte, los cuadricópteros vienen con su propia tarjeta de estabilización. En lugar de hacer la conexión directamente a la tarjeta Pololu y los cuatro motores ESC del cuadricóptero y tener que escribir un complejo software de estabilización en C/C++ o Java sobre Android, es mucho más fácil conectar la tarjeta de estabilización a la tarjeta Pololu y dejar que la tarjeta de estabilización maneje los cuatro motores. Todo lo demás que necesite manejarse se puede hacer con comandos simples de Java, como +/- altitude, +/- speed/, +/- inclination y +/- direction. Optamos por hacer todo en un smartphone Android porque tiene un procesador potente, pero la responsabilidad de equilibrar los motores se la dejamos a una pequeña tarjeta dedicada de muy bajo costo. Como desarrollador, es bueno que conozca esta tarjeta y por qué decidimos usarla, pero también apreciará que solo requiere de una calibración inicial; una vez hecha, ya puede olvidarse.

Conclusión de la primera etapa

Al final de la primera etapa de creación de un cuadricóptero autónomo, la cadena de hardware es:

teléfono móvil <> adaptador host micro USB-USB <> cable USB-mini USB <> tarjeta Pololu Maestro <>
4 cables JR <> tarjeta de estabilización <> cables JR <> variador <> motores del vehículo aéreo no tripulado

En comparación, la cadena de hardware de drones más simples es:

teléfono móvil <> adaptador host micro USB-USB <> cable USB-mini USB <> tarjeta Pololu Maestro <> cables JR <> variador <> motores del vehículo aéreo no tripulado

Además, también se pueden controlar otros servomotores, p. ej. una cámara direct 3D de dos canales fijada al cuadricóptero. O, si uno quiere, puede controlar los alerones, los equipos de aterrizaje, etc. Las tarjetas Pololu Maestro pueden controlar entre 6 y 24 motores; es mucho más de lo que se necesita para este proyecto, pero ello da una gran flexibilidad.

Hasta ahora, hemos hablado del software y el hardware preferidos que constituyen los componentes de nuestro proyecto integrado. En la próxima sección, veremos cómo desarrollar software de análisis de imágenes para que este dron sea inteligente.

Visión por computadora

Aunque ya hemos dejado en claro que nuestro dron necesita mucha capacidad de procesamiento para ser inteligente y autónomo, lo que todavía nos falta es el código para aprovechar este potencial. ¡Es momento de darle “ojos” a nuestro dron!

¿Por qué?

Algunos drones pueden usar navegación por GPS, pero la exactitud y la latencia del GPS no permiten lograr trayectorias precisas entre edificios, gente o árboles, por ejemplo. A menudo, los drones vuelan con precisión y destreza en el laboratorio, pero obtienen sus indicaciones de posicionamiento de cámaras y sensores sofisticados instalados en la habitación. Esta técnica no se puede usar al aire libre, por una cuestión de dimensiones.

En el mundo real, es esencial que el dron sea capaz de “ver”; por ejemplo, que reconozca y siga marcadores o identifique visualmente a seres humanos. Falta entonces poder capturar imágenes de Android y analizarlas con OpenCV.

¿Cómo?

OpenCV es una biblioteca de funciones de programación de código fuente abierto para analizar imágenes. Es la base de numerosos proyectos de realidad virtual y visión por computadora. La desarrolló originalmente Intel y ahora se puede utilizar con una amplia variedad de plataformas de sistemas operativos y hardware. Se puede desarrollar el código en una PC e implementarlo en servidores, smartphones o plataformas de Internet de las Cosas.

Como práctica, primero intentaremos reconocer una marca simple, como un círculo, y navegar con el smartphone de modo que quedemos frente al círculo a una distancia fija. Imagine que el dron fuera capaz de navegar por GPS a la posición global de una pista (aproximadamente 3 m). Debe poder reconocer marcas en el suelo o el pavimento a fin de poder situarse con exactitud sobre la posición de aterrizaje, a una altura fija. Luego el dron aterrizará en el lugar marcado, con un margen de unos pocos centímetros. Para simplificar la prueba, mostraremos los controles de vuelo en la pantalla y usted moverá el teléfono con la mano para simular el movimiento del dron.

Navegación de un círculo con un smartphone

Proyecto Java nativo+

OpenCV no forma parte de las bibliotecas disponibles directamente de Java en Android. Es una biblioteca nativa que se usa por lo general desde C++, así que es necesario usar el NDK para Android. La parte de captura y exhibición de imágenes será en Java, y para la comunicación entre Java y C++ se usará JNI. Necesitamos instalar el NDK para Android y el SDK de Android, crear el mencionado proyecto de “Círculos”, agregar un componente C/ C++ y cambiar la configuración del proyecto para usar la biblioteca OpenCV; esto se ilustra con las siguientes capturas de pantalla de Eclipse:

Configuración del proyecto Java

Configuración del proyecto Java

Configuración del proyecto C/C++

Configuración del proyecto C/C++

Configuración del analizador de proyecto C/C++

Configuración del analizador de proyecto C/C++

Incluye la configuración para STL, OpenCV* y NDK

Incluye la configuración para STL, OpenCV* y NDK

Al final, nuestro proyecto tendrá:

Archivo principal de Java « Src/MainActivity.java »
Archivo de diseño XML « Res/layout/activity_main.xml » y el manifiesto
Dos archivos make « Jni/Android.mk » y « Jni/Application.mk »
Código cpp « Jni/ComputerVision_jni.cpp » y el encabezado « Jni/ComputerVision_jni.h »

Arquitectura de hardware

A diferencia de Java, C++ se debe compilar para un procesador específico. Para hacer el ajuste, solo hay que modificar la variable APP_ABI en el archivo Application.mk. En el caso de nuestro smartphone con procesador Intel Atom, el valor correcto es “x86”; el NDK hará el resto.

Implementación

OpenCV es una biblioteca que utilizan innumerables aplicaciones de Android, y cada aplicación puede usar una versión diferente de la biblioteca. Usted, como desarrollador de aplicaciones, podría empaquetar la versión requerida de OpenCV con su aplicación, pero hay un método mejor: use un administrador de dependencia llamado “OpenCV Manager”. Es una aplicación de Android que detecta cuándo se necesita OpenCV, qué versión, ayuda con la instalación y luego carga OpenCV. Su aplicación deberá establecer una conexión con OpenCV Manager y el resto se hará “automágicamente”.

Interacción C++/Java y algoritmo

Nuestro objetivo es detectar círculos en OpenCV, determinar el centro y el radio, y después mostrar órdenes para que el operador del teléfono logre un círculo perfecto de buen tamaño. El siguiente código de Java recupera la imagen de la cámara con la API de Java para Android. Hace una llamada a C++ por JNI y adjunta un puntero a la imagen que se encuentra en la memoria. Luego, el código de C++ procesa imágenes para detectar círculos. Se vuelve a llamar a Java para mostrar los círculos detectados y los comentarios en la imagen.

Manejo remoto

Durante las pruebas, moví el teléfono frente a una hoja de papel impresa. Con la finalidad de simular la posición final del dron, escogí una distancia para ver qué tan ancha parecía de acuerdo con los elementos ópticos de la cámara del teléfono. Ejemplo: dibujé un círculo de 10 cm en la hoja de papel, coloqué el teléfono a 20 cm de la hoja y el círculo apareció como de 300 px de ancho. Esa es la anchura que debe tener para que la distancia sea correcta. Si el círculo es demasiado grande, me moveré hacia atrás; si es demasiado pequeño, me moveré hacia delante. Al final, el dron estará a una distancia exacta en el círculo.

Nuestro primer caso de prueba es muy simple: 1 círculo = 1 distancia. Pero también se puede ir más allá y usar varios círculos concéntricos: el círculo más grande se puede detectar con facilidad desde mucha distancia, los del medio se pueden usar cuando el dron esté demasiado cerca como para ver el círculo más grande y, por último, el dron aterrizará sobre el círculo interior más pequeño. Si los círculos no tienen la precisión suficiente, se pueden usar formas más complejas, como flechas.

Centre el círculo en la imagen del smartphone para simular el posicionamiento del dron en el centro, justo sobre la marca de aterrizaje. Este tipo de control es en realidad muy simple y, cuando se lo combina con otra información (p. ej., color, posición GPS y tal vez profundidad), es muy fácil de poner en práctica.

Código Java

…
// capturar imágenes desde la cámara
import org.opencv.Android.CameraBridgeViewBase;
// cargar dependencia nativa OpenCV 
import org.opencv.Android.OpenCVLoader;
…
public void onResume()
{
super.onResume();
// carga de OpenCV con llamada de respuesta
// código no típico específico de OpenCV
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_6, this, mLoaderCallback);
}
…
// una vez establecido el enlace con el administrador de OpenCV,
// podemos cargar la biblioteca dinámica  
System.loadLibrary("jni_part");
…

Código C++

…
// típico para JNI : nombre de método de clase Java
// puntero a la imagen RGB como argumento
JNIEXPORT int JNICALL Java_com_example_circles_MainActivity_process
(JNIEnv *jenv, jobject obj, jlong addrGray, jlong addrRgba)
…
// Obtener el mapa de bits del puntero
Mat& mRgb = *(Mat*)addrRgba;
// desenfoque, necesario antes de detectar los círculos  
medianBlur(mGr,mGr,5);
// detección de OpenCV – transformada de Hough
HoughCircles(mGr, //imagen de entrada en escala de grises
*circles, //vector de salida
CV_HOUGH_GRADIENT, //método de detección que se empleará
4, //relación inversa de la resolución del acumulador respecto de la imagen
mGr.rows/8, //distancia mín. entre centros de los círculos detectados
220, //umbral superior de los dos pasado el detector de bordes Canny interno
200, //umbral del acumulador	100
20, //radio mínimo
mGr.cols/8 //radio máximo
);

Rendimiento y pasos siguientes

Instale OpenCV Manager desde Google Play* [6] y el archivo APK de su aplicación desde Eclipse* [7]. Inicie la aplicación y siga los pasos de instalación; detectará los círculos en el campo visual y lo guiará al centro del círculo con un diámetro predefinido.

La detección de círculos es algo muy básico. Una buena idea es comenzar con un fondo plano de alto contraste, fácil de visualizar. Las funciones de visión por computadora simples funcionan con formas simples, de la misma manera que los niños pequeños juegan con formas simples: círculos, cuadrados, estrellas, todas primitivas geométricas definidas como vectores. Pero las funciones de visión por computadora avanzadas pueden manejar cualquier dato fotográfico de entrada, no solo primitivas geométricas simples. Esas bibliotecas se usan en aplicaciones de realidad aumentada; pueden detectar la presencia de cualquier foto en otra foto, aunque esté distorsionada. Un ejemplo: dada la foto del envase de un producto alimenticio, una aplicación detectará la posición y la orientación tridimensional del envase en una foto más grande. La manera en que funcionan la mayoría de las aplicaciones de visión por computadora es mediante el movimiento de un objeto frente a un teléfono móvil fijo. Se detecta el objeto y se lo puede aumentar con objetos 3D, como se muestra en este video:http://www.dailymotion.com/video/xco8xm_la-realite-augmentee-par-total-imme_tech [8].

Por supuesto que no necesitamos que nuestro dron se divierta con envoltorios de comida. Pero la misma biblioteca se puede usar de manera diferente: todavía hay que detectar un patrón fotográfico, pero con un teléfono móvil en movimiento como dron. Un ejemplo: cuando le proporcione al dron la foto del lugar de aterrizaje, será capaz de detectarlo, comprender con gran precisión dónde se encuentra en el espacio en comparación con el patrón, y preparar un método visual. Se trata de la misma biblioteca, pero con un uso diferente.

Para controlar el dron, solo hay que reemplazar las instrucciones que se muestran, y para reemplazarlas hay que enviar las órdenes “power”, “roll”, “pitch” y “yaw” al dron que lleva la cámara. Por suerte, las órdenes para pilotear el dron y las órdenes impresas coinciden exactamente, así que la migración de las pruebas manuales bajo techo a los vuelos al aire libre será sencilla.

En nuestro smartphone de prueba, capturamos y procesamos una imagen cada 8 centésimos de segundo, 12.5 fotogramas por segundo. Esto demuestra que es posible agregar simplemente “visión” por computadora a un dron con un presupuesto de energía, un procesador o un tiempo de desarrollo limitados, lo cual es razonable y realista en el caso de un dron pequeño. Y todo se computa de manera independiente, sin dejar fuera un solo cálculo.

Es posible ir mucho más allá. OpenCV es una biblioteca de código fuente abierto muy portable. Además,Intel IPP [5] reemplaza algunas llamadas de bajo nivel de OpenCV e inyecta rutinas optimizadas para procesadores Intel, de modo que acelera el código. Es posible mantener el código portable y la dependencia en una biblioteca de código fuente abierto a la vez que se disfruta de las ventajas opcionales de rendimiento de Intel IPP.

Por último, utilizar un smartphone Android con procesador Intel para controlar un dron es una solución que combina buen rendimiento, resistencia y facilidad de desarrollo. Este primer proyecto da la opción de migrar a otro sistema operativo o una plataforma de hardware más potente si el smartphone deja de ser suficiente o se desea pasar a drones más grandes. Recomendamos echar un vistazo a los otros programas [1], que muestran otras instrucciones de desarrollo de software que se pueden emplear en el ámbito de los drones y la robótica.

Acerca de los autores

Autores: Paul Guermonprez, Nicolas Vailliet, Cedric Andreolli
Vínculos: http://intel-software-academic-program.com/pages/courses#drones
Dirección de contacto: paul.guermonprez@intel.com
Equipo: Intel Software Academic Program para EMEA-Rusia, París, Francia

Referencias y recursos

[1] Intel Software Academic Program: http://intel-software-academic-program.com/pages/courses#drones

[2] The Mill: Lexus “Swarm” Behind The Scenes: http://vimeo.com/78549177

[3] Autonomous Robotic Plane Flies Indoors at MIT: http://www.youtube.com/watch?v=kYs215TgI7c

[4] Intel® Integrated Performance Primitives (Intel® IPP): http://software.intel.com/en-us/intel-ipp

[5] OpenCV: http://opencv.org

[6] Google Play: https://play.google.com/store

[7] Eclipse: https://www.eclipse.org

[8] www.dailymotion.com: La réalité augmentée, par Total Immersion.http://www.dailymotion.com/video/xco8xm_la-realite-augmentee-par-total-imme_tech

COMPARTIR:Share on FacebookShare on Google+Tweet about this on TwitterShare on LinkedIn

NO COMMENTS

DEJAR UN COMENTARIO