Documentos de Académico
Documentos de Profesional
Documentos de Cultura
Tarragona 2020
Diseño e implementación de un Drone
y un dispositivo Android
Índice de figuras
y un dispositivo Android
2
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 83. Respuesta del sistema balancín para una ganancia de (Kp = 1.4 Ki = 0.009 Kd=
0) ..................................................................................................................................... 76
Gráfico 84. Respuesta del sistema balancín para una ganancia de (Kp = 1.3 Ki = 0.005 Kd=
0) ..................................................................................................................................... 76
Gráfico 85. Respuesta del sistema balancín para una ganancia de (Kp = 1.1 Ki = 0 Kd= 0)
........................................................................................................................................ 77
Gráfico 86. Respuesta del sistema balancín para una ganancia de (Kp = 1.1 Ki = 0.009 Kd=
0.1) .................................................................................................................................. 78
Gráfico 87. Respuesta del sistema balancín para una ganancia de (Kp = 1.1 Ki = 0.007 Kd=
0.15) ................................................................................................................................ 78
Gráfico 88. Diagrama de flujo del control PID del sistema balancín ................................ 79
Gráfico 89. Estructura de control del balancín utilizando la app ......................................79
Gráfico 90. Evolución de la respuesta del mpu-6050 en función del valor del mando ......80
Gráfico 91. Registro para despertar el módulo MPU-6050............................................... 81
Gráfico 92. Registro para la configuración de la sensibilidad del giroscopio. ................... 81
Gráfico 93. Registro para la configuración de la sensibilidad del acelerómetro. ............... 81
Gráfico 94. Comportamiento del drone aplicando un controlador proporcional................ 85
Gráfico 95. Relación entre la variación de la ganancia y el valor que toma el error ..........86
Gráfico 96. Comportamiento del drone aplicando un controlador PI ................................ 86
Gráfico 97. Ejemplo de cómo funciona la parte integral .................................................. 87
Gráfico 98. Ejemplo de cómo funciona la parte derivativa ............................................... 87
Gráfico 99. Comportamiento del drone aplicando un controlador PID ............................. 88
Gráfico 100. Posible lazo de realimentación de nuestro sistema drone ............................. 89
Gráfico 101. Dirección de giro correcta de las hélices del drone ......................................90
Gráfico 102. Estrategia de control del modo Acrobático .................................................. 91
Gráfico 103. Estrategia de control del modo Acrobático con la posibilidad de posicionar el
drone a 0º ......................................................................................................................... 92
Gráfico 104. Creación de la señal PWM sincronizada con el lazo de control ................... 93
Gráfico 105. Hélice sin calibrar ....................................................................................... 95
Gráfico 106. Velocidad del motor izquierdo trasero sin haber calibrado su hélice ............ 95
Gráfico 107. Origen de las vibraciones en nuestro sistema .............................................. 96
Gráfico 108. Hélice ya calibrado ..................................................................................... 96
Gráfico 109. Velocidad del motor izquierdo trasero con su hélice calibrada .................... 97
Gráfico 110. Aislamiento del sensor MPU-6050 del frame utilizando goma espuma ....... 98
Gráfico 111. Aislamiento del microcontrolador del frame utilizando goma espuma ......... 98
Gráfico 112. Ejemplo de una señal atenuada por un filtro digital paso bajo...................... 99
Gráfico 113. Configuración del filtro digital paso-bajo, de acuerdo al datasheet del MPU-
6050................................................................................................................................. 99
Gráfico 114. Filtro digitales paso-bajo del acelerómetro y giroscopio respectivamente .. 100
Gráfico 115. Comparación en la lectura de las velocidades angulares sin emplear filtro (izq)
y empleando filtro (der) ................................................................................................. 101
Gráfico 116. Comparación entre la velocidad angular Roll sin filtrar y la filtrada (Filtro
EMA) ............................................................................................................................ 102
Gráfico 117. Filtro EMA: Velocidad del motor sin emplear filtro (izq) y empleando filtro
(der) ............................................................................................................................... 103
Gráfico 118. Efecto “windup” ....................................................................................... 104
Gráfico 119. Técnica antiwindup por limitación del término integral ............................. 105
Gráfico 120. Técnica antiwindup por integración condicional ....................................... 105
Gráfico 121. Banco de pruebas para la sintonización PID del drone .............................. 106
3
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 122. Velocidad angular del eje pitch (sintonización de Kp) – Prueba I .............. 107
Gráfico 123. Velocidad angular del eje pitch (sintonización de Kp) – Prueba II ............. 108
Gráfico 124. Velocidad angular del eje pitch (sintonización de Kp) – Prueba III ........... 108
Gráfico 125. Velocidad angular del eje pitch (sintonización de Kd) – Prueba I .............. 109
Gráfico 126. Velocidad angular del eje pitch (sintonización de Kd) – Prueba II ............. 110
Gráfico 127. Velocidad angular del eje pitch (sintonización de Kd) – Prueba III ........... 110
Gráfico 128. Velocidad angular del eje pitch (sintonización de Ki) – Prueba I ............... 111
Gráfico 129. Velocidad angular del eje pitch (sintonización de Ki) – Prueba II.............. 111
Gráfico 130. Función inicializar motores del sistema drone ........................................... 113
Gráfico 131. Cálculo de la velocidad angular y aplicación del filtro EMA ..................... 114
Gráfico 132. Filtro EMA expresado mediante código .................................................... 115
Gráfico 133. Algoritmo de control de los motores del sistema drone ............................. 115
Gráfico 134. Función para crear la señal PWM a enviar a los actuadores ....................... 116
Gráfico 135. Interfaz inicial para el desarrollo de una nueva aplicación en Mit App Inventor
...................................................................................................................................... 117
Gráfico 136. Incorporación de la funcionalidad bluetooth a la aplicación (Mit App Inventor)
...................................................................................................................................... 118
Gráfico 137. Ejemplo sobre cómo insertar capas para establecer orden en la aplicación (Mit
App Inventor) ................................................................................................................ 118
Gráfico 138. Diseño final de nuestra app de control del sistema balancín ...................... 119
Gráfico 139. Programación en bloques de nuestra app controladora para el sistema balancín
...................................................................................................................................... 121
Gráfico 140. Descarga de la aplicación en (Mit App Inventor) ...................................... 122
Gráfico 141. Versión final de la app controladora del sistema balancín.......................... 122
Gráfico 142. Diseño final de nuestra app de control del sistema drone ........................... 123
Gráfico 143. Programación en bloques de nuestra app controladora para el sistema drone
(Parte I).......................................................................................................................... 123
Gráfico 144. Programación en bloques de nuestra app controladora para el sistema drone
(Parte II) ........................................................................................................................ 124
Gráfico 145. Versión final de la app controladora del sistema drone .............................. 124
Gráfico 146. Ángulo de inclinación del eje pitch tras recibir comandos de la app .......... 126
Gráfico 147. Velocidad angular del eje pitch tras recibir comandos de la app ................ 127
Gráfico 148. Ángulo de inclinación del eje roll tras recibir comandos de la app............. 127
Gráfico 149. Velocidad angular del eje roll tras recibir comandos de la app .................. 128
4
Diseño e implementación de un Drone
y un dispositivo Android
Índice de tablas
5
Diseño e implementación de un Drone
y un dispositivo Android
Índice
1 Introducción................................................................................................................9
2 Estructura y componentes del Cuadricóptero ............................................................. 10
2.1 Dinámica ...........................................................................................................10
2.2 Mecanismo funcional ......................................................................................... 13
2.2.1 Control Automático .................................................................................... 14
2.3 Descripción de los componentes ........................................................................ 16
2.3.1 El sensor MPU-6050................................................................................... 16
2.3.2 El Microcontrolador Arduino UNO............................................................. 19
2.3.3 Motores sin escobillas (Brushless) .............................................................. 21
2.3.4 Variador Electrónico de Velocidad (ESC) ................................................... 24
2.3.5 Módulo Bluetooth HC-06 ...........................................................................27
2.3.6 Batería LiPo de 3 celdas.............................................................................. 28
2.3.7 El Chasis..................................................................................................... 29
3 Diseño ...................................................................................................................... 33
3.1 Mecánica ...........................................................................................................33
3.1.1 Chasis elegido ............................................................................................. 33
3.1.2 Ensamblaje ................................................................................................. 36
3.2 Electrónica ......................................................................................................... 38
3.2.1 Esquema de las conexiones electrónicas del drone ......................................38
3.2.2 Placa de distribución de potencia (PDB) ..................................................... 39
3.3 Software ............................................................................................................ 41
3.3.1 Inicialización del sensor MPU-6050............................................................ 41
3.3.2 Inicialización del variador electrónico de velocidad (ESC) .......................... 53
3.3.3 Inicialización del módulo Bluetooth HC-06 ................................................ 56
3.3.4 Primeras pruebas con el ESC y el módulo bluetooth HC-06 ........................ 59
3.4 Control PID ....................................................................................................... 62
3.4.1 Teoría ......................................................................................................... 63
3.4.2 Construcción del balancín ...........................................................................65
3.4.3 Sintonización del controlador PID del sistema balancín .............................. 68
3.4.4 Explicación del código PID del Balancín .................................................... 79
3.4.5 Sistema Drone ............................................................................................ 85
3.4.5.1 Efectos de un controlador PID en un drone ..........................................85
3.4.5.2 Descripción del problema .................................................................... 89
3.4.5.3 Descripción de la solución ................................................................... 91
6
Diseño e implementación de un Drone
y un dispositivo Android
7
Diseño e implementación de un Drone
y un dispositivo Android
8
Diseño e implementación de un Drone
y un dispositivo Android
1 Introducción
2da parte (Diseño): Trataremos el montaje del chasis estructural donde todos
los dispositivos estarán ensamblados y alojados. Además, describiremos las
distintas conexiones entre los componentes que conforman el cuadricóptero,
así como también describiremos la placa PDB donde están conectados los
cuatro variadores electrónicos de velocidad (ESC). Finalmente,
desarrollaremos no sólo la programación del algoritmo de control de nuestro
drone y de un sistema balancín, sino que también describiremos el proceso de
diseñar la interfaz de nuestra app Android.
9
Diseño e implementación de un Drone
y un dispositivo Android
2.1 Dinámica
10
Diseño e implementación de un Drone
y un dispositivo Android
Ahora bien, para el correcto manejo del drone, es importante primero comprender
cuáles son los principales movimientos que el mismo puede realizar. Estos movimientos son
los siguientes: Guiñada (Yaw), Alabeo (Roll), Cabeceo (Pitch) y Altitud (Throttle). A
continuación, procederemos a explicar cada uno de ellos.
11
Diseño e implementación de un Drone
y un dispositivo Android
12
Diseño e implementación de un Drone
y un dispositivo Android
Por otra parte, como se ha podido observar en las imágenes anteriores, un rotor gira
en el mismo sentido que su homólogo ubicado en el extremo opuesto, y lo mismo ocurre
para el otro par. Esta disposición de los motores se encuentra en cualquier tipo de
configuración de cuadricóptero. Si los motores no estuviesen dispuestos de esta manera, el
drone empezaría a girar sobre sí mismo y dificultaría su control.
En resumen, para conseguir que el drone se desplace hacia una dirección (izquierda,
derecha, arriba o abajo), debemos hacer girar 2 rotores del mismo bando más rápido que los
otros 2 con respecto al eje longitudinal o transversal (según hacia donde se desee desplazar).
Esto es debido a que cuando comenzamos a girar varios motores con distintas velocidad de
giro, se consigue desestabilizar la posición de equilibrio horizontal que previamente tenía el
drone cuando sus motores giraban a la misma velocidad, creándose una fuerza con dirección
hacia arriba en el bando donde los motores giran más rápido.
13
Diseño e implementación de un Drone
y un dispositivo Android
Es aquí donde entran en juego los ESC: Electronic Speed Controller, Control Electrónico
de Velocidad, o también conocido como Variador Electrónico de Velocidad.
De manera muy resumida, los ESC se encargan de controlar la velocidad, y con ello,
la dirección del drone. No obstante, debe haber un componente o aparato cuya función sea
la de transmitir la información adecuada a estos variadores de velocidad, y así poder
conseguir la estabilidad deseada del vuelo; entrando en juego la Placa procesadora.
Para que la placa procesadora le envíe la información adecuada a los variadores
electrónicos de velocidad, es necesario que la placa reciba datos de entrada, es decir,
información del exterior. Los dispositivos que se encargan de recibir esta información son
llamados sensores. En otras palabras, los sensores son los responsables de captar los datos
del mundo externo que los rodea. En el cuadricóptero, nuestro único sensor será el MPU-
6050, el cual a su vez incluye 2 sensores integrados; acelerómetro y giroscopio (se describirá
más adelante).
Ahora bien, es importante remarcar que estos datos de entrada que recopilará el
sensor MPU-6050 no será la única información que recibirá la placa procesadora, sino que
también recibirá información del control manual. Como su nombre lo indica, este
componente será el responsable de poder controlar el vuelo del drone a través de una app
diseñada por nosotros en un dispositivo Android. Y, como este control debe ser de manera
remota (inalámbrica), hace falta la presencia de otro dispositivo que se encargue de
comunicar esta app con la placa procesadora. Es aquí donde entra en juego el módulo de
comunicaciones inalámbrico, el cual utilizará un módulo Bluetooth HC-06 (se describirá
más adelante). Todos estos dispositivos electrónicos serán alimentados por una batería.
Sin embargo, para que todos estos componentes en conjunto consigan la elevación,
el control, la estabilidad y la maniobrabilidad del drone, se debe recurrir a un algoritmo o
sistema automático de control que garantice que el mismo no se llegue a estrellar, y es aquí
donde entra el concepto de control automático.
14
Diseño e implementación de un Drone
y un dispositivo Android
15
Diseño e implementación de un Drone
y un dispositivo Android
16
Diseño e implementación de un Drone
y un dispositivo Android
𝑦
𝜃𝑋 = tan−1 ( ) (1)
√𝑥 2 + 𝑧 2
𝑥
𝜃𝑌 = tan−1 ( )
√𝑦 2 + 𝑧 2 (2)
𝜃𝑋 = 𝜃𝑋 𝐴𝑛𝑡𝑒𝑟𝑖𝑜𝑟 + 𝜔𝑋 ∙ ∆𝑡 (3)
𝜃𝑌 = 𝜃𝑌 𝐴𝑛𝑡𝑒𝑟𝑖𝑜𝑟 + 𝜔𝑌 ∙ ∆𝑡 (4)
Donde:
𝜃𝑋 es el ángulo que gira el eje X sobre su propio eje.
𝜃𝑋 𝐴𝑛𝑡𝑒𝑟𝑖𝑜𝑟 es el ángulo calculado en la última llamada a esta fórmula.
𝜔𝑋 es la lectura actual del giroscopio del ángulo X.
∆𝑡 es el tiempo que transcurre cada vez que es llamada la fórmula.
Ahora bien, el módulo MPU-6050 cuenta con 8 pines que pasarán a describirse a
continuación:
17
Diseño e implementación de un Drone
y un dispositivo Android
SCL (Serial Clock) y SDA (Serial Data). Estos dos pines son utilizados para
la interfaz de comunicación I2C. Este protocolo de comunicación permite al
módulo trabajar como maestro (master) y comunicarse con otros dispositivos
que trabajen como esclavos (slaves). A través de un bus de 2 líneas (los pines
SCL y SDA), se efectúa dicha comunicación entre el módulo maestro y el
dispositivo esclavo donde la información es enviada por medio del serial
data.
Para cada dispositivo externo a comunicarse, debe existir una
dirección específica (representado a través del pin ADO, explicado más
adelante) por la cual el módulo maestro se comunicará con el esclavo.
XDA (Auxiliary Data) y XCL (Auxiliary Clock): Estos dos pines también se
utilizan para el protocolo de comunicación I2C pero con sensores externos,
como los magnetómetros o los barómetros.
18
Diseño e implementación de un Drone
y un dispositivo Android
Ahora bien, la manera en que se consigue adjudicar un determinado pin ya sea como
entrada o como salida es mediante el comando de programación pinMode(). Para la lectura
de datos, se utiliza la función digitalRead() y para la escritura se utiliza la función
digitalWrite(). (Jadiaz, 2016).
Cada pin posee un tensión de salida de 5 V y tienen una resistencia pull-up de 20
hasta 50 kilo ohms que están desactivadas por defecto. Pero que, sin embargo, pueden
activarse con la función de digitalWrite() con un valor de HIGH o LOW respectivamente
siempre y cuando dicho pin está configurado como entrada. La corriente máxima de salida
es de 40 mA.
Además, algunos pines tienen funciones específicas que pasarán a ser descritos a
continuación.
19
Diseño e implementación de un Drone
y un dispositivo Android
y un dispositivo Android
21
Diseño e implementación de un Drone
y un dispositivo Android
22
Diseño e implementación de un Drone
y un dispositivo Android
tal manera de que se cree otro campo magnético que sea opuesto al campo creado por los
imanes, empujando al eje para que éste continúe girando, y así sucesivamente.
En otras palabras, el motor brushless trifásico debe ser alimentado siguiendo una
cierta secuencia de los sentidos que tomará la corriente al circular a través de las bobinas del
motor. El dispositivo (ESC) es la que se encargará de alimentar al motor en la secuencia
correcta.
Una de las principales razones por las que se optó por este tipo de motor es que
carecen de escobillas, por lo que no tiene las desventajas del rozamiento y del consecuente
desgaste que estas producen. Otras de las ventajas que tienen estos motores brushless frente
a los que tienen escobillas son su elevada velocidad de giro y su potencia. Esto no ocurre en
los motores con escobillas, ya que al aumentar la velocidad estas provocan fricción, y por
tanto, disminuye el par motor. (Compañía Levantina de Reductores, S.f).
Ahora bien, uno de los criterios más importantes que se debe de tener presente a la
hora de adquirir estos motores es su empuje.
El empuje es la fuerza con que cada motor ejerce sobre el drone para elevarlo.
(Roberto, S.f). En el caso de un cuadricóptero, la fuerza necesaria para hacerlo elevar vendrá
representada por la suma del empuje de los cuatro motores en conjunto.
Para el tipo de motor que se ha adquirido, éste contiene un empuje de 885 gramos
cada uno, el cual el empuje total resulta ser de 3540 gramos. Esto quiere decir que los
motores serán capaces de levantar un peso total de 3540 gramos. En la etapa de Diseño,
apartado de Mecánica, se trata esta temática con más profundidad (pág 33).
A continuación, se procederá a visualizar dos tablas; una primera tabla en la que se
realizará la comparativa entre los motores con escobillas y sin escobillas, y una segunda
tabla en donde se mostrarán las características más relevantes del tipo de motor Brushless
adquirido.
Características Motor con escobillas Motor sin escobillas
Ciclo de vida Menor Mayor
Precio Económico Caro
Rendimiento Menor Mayor
Rango de velocidad Bajo Alto
Necesidad de control
electrónico NO SI
Necesidad de
Mantenimiento continuo SI NO
Tabla 3. Comparativa entre motores con escobillas y sin escobillas
Modelo A2212/13 T
KV (RPM/Volt) 1000 KV
Batería ideal para funcionar 2 ~ 3 celdas
Máxima eficiencia de corriente 4 ~ 10 A (>75%)
Corriente máxima 12 A / 60 segundos
Número de Polos 14
Máxima Eficacia 80 %
23
Diseño e implementación de un Drone
y un dispositivo Android
Empuje 885 g
Resistencia interna 0.090 ohms
Peso 53 g
Diámetro del eje 3.17 mm
Largo 40 mm
Anchura 27.7 mm
Tabla 4. Especificaciones del motor sin escobillas a utilizar
Tres cables negros (lado derecho): Son los 3 cables de trifásica y van
conectados al motor para proveerle de los pulsos necesarios, (generados por
la placa controladora), para hacerlo girar.
24
Diseño e implementación de un Drone
y un dispositivo Android
25
Diseño e implementación de un Drone
y un dispositivo Android
26
Diseño e implementación de un Drone
y un dispositivo Android
Como puede observarse en la imagen, el ESC cuenta con 6 transistores del tipo
MOSFET. Estos transistores actúan como interruptores que se abren cuando se aplica la
tensión necesaria en sus puertas. A través de estos transistores, se conseguirá controlar el
movimiento y la velocidad de giro del motor Brushless activando los 2 MOSFETs
apropiados para crear el campo magnético rotatorio y que, de esta manera, el motor logre
girar. Sin embargo, procederemos a explicar el proceso de activación de los variadores ESC
y motores en la sección de Inicialización del variador electrónico de velocidad ESC.
Para saber qué tipo de variador debemos elegir para nuestros motores Brushless, se
debe tener en cuenta un factor muy importante y es el: nivel de amperaje o intensidad
eléctrica soportada por los variadores. Estos variadores indican en una etiqueta la cantidad
de amperios que son capaces de soportar. Es importante que los ESC a utilizar admitan más
amperaje del que los motores puedan llegar a utilizar en su máxima potencia. A continuación,
se adjunta la tabla de características de los ESC a utilizar.
Tensión de entrada Batería LiPo 2~6 S
Máxima corriente de salida 20 A
Presencia de UBEC NO
Peso (incluyendo cables) ~6g
Dimensiones 24.5 x 12.5 x 3mm
Tabla 5. Especificaciones de los ESC a utilizar
Solo puede ser configurado como esclavo, y es de hecho el rol que va a tomar, ya que
se encargará de hacer cumplir las órdenes que reciba desde el dispositivo Android, el cual
actuará como maestro. Dispone de 4 pines de conexión, los cuales se describirán brevemente
a continuación:
VCC: Es la conexión a la alimentación, tiene un rango de operación entre los
3.3V ~ 5 V.
27
Diseño e implementación de un Drone
y un dispositivo Android
En este tipo de baterías, cada celda tiene una tensión nominal de 3.7 V. Una celda
puede conformar una batería por sí sola. Sin embargo, estas celdas se suelen agrupar en serie
con la finalidad de conseguir mayores voltajes. Debido a que la batería adquirida
corresponde a una de 3 celdas, tenemos una tensión de salida de 11.1 V.
Es importante tener en cuenta la corriente y la tensión que se necesita para alimentar
a todos los componentes electrónicos del sistema de manera simultánea antes de proceder a
adquirir la batería, teniendo también en consideración el hecho de que la misma debe ser
capaz de mover los 4 motores brushless. Es por esta razón que se ha elegido la batería de
polímero de litio (LiPo), debido a la gran potencia que la misma ofrece para el correcto
funcionamiento de los motores.
En una etiqueta adherida a la propia batería, suele contener información relevante
que se debe entender y así saber si dicha batería es idónea para nuestro sistema. Uno de estos
valores corresponde con unidades de V, y es la tensión de salida que entrega la batería; es
imprescindible verificar que esta tensión de salida sea compatible con la alimentación que
requiere el tipo de motor a utilizar. Mientras más voltaje tenga la batería, más capacidad
tendrá de alimentar y mover motores más grandes.
28
Diseño e implementación de un Drone
y un dispositivo Android
2.3.7 El Chasis
El chasis es el cuerpo del drone; es el que se encarga de dar soporte a todas las demás
piezas. Dependiendo de la estructura y forma que tenga el chasis, el drone puede clasificarse
de acuerdo al número de rotores o motores que lo conforman. Es decir, el drone puede
tratarse de un cuadricóptero (4), hexacóptero (6) u octocóptero (8).
Los chasis de los drones están fabricados generalmente con tres distintos tipos de
materiales, los cuales pasarán a ser descritos brevemente a continuación.
Fibras de carbono: Se caracterizan por ser de un material muy resistente,
pesado y, entre los distintos materiales que pueden conformar un drone,
resulta ser el más costoso.
Fibra de vidrio: Se caracterizan por no ser tan resistentes que los de fibra de
carbono. Sin embargo, resultan ser más ligeros y, por ende, más económicos
que los de fibra de carbono.
29
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 25. Impresión fallida de la parte superior de unos de los brazos del cuadricóptero.
Gráfico 26. Vista de planta del extremo del brazo impreso del drone
30
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 27. Vista de perfil del extremo del brazo impreso del drone
31
Diseño e implementación de un Drone
y un dispositivo Android
32
Diseño e implementación de un Drone
y un dispositivo Android
3 Diseño
Para la elección del chasis actual, se ha tenido en cuenta varios factores, entre ellos
están: la calidad del material que lo conformará, su ligereza, su robusteza y su duración.
Poner especial atención en todos estos factores es importante, ya que el chasis no sólo debe
aguantar el peso de todos los componentes ensamblados en él, sino que también estará sujeto
a las fuerzas o sobrecargas que ocurren cuando el drone se encuentra en el aire.
A continuación, se procederá a representar el peso de cada uno de los componentes
(sin tener en cuenta el peso del propio chasis), así como de su peso total, y se comparará con
el empuje total de los cuatro motores brushless.
Peso de los componentes
Placa Arduino UNO 25 g
4 motores Brushless 212 g
Batería LiPo 184 g
4 variadores ESC 24 g
Placa PDB 11 g
TOTAL 456 g
Tabla 7. Balance de pesos de los componentes SIN el chasis
Se puede observar que el peso total de todos los componentes principales del drone
(sin tener en cuenta el peso del propio chasis) es de aproximadamente 456 gramos. Por otra
parte, el empuje que posee cada motor es de 885 gramos, siendo el empuje total de 3540
gramos. Esto quiere decir que el peso del “esqueleto” del drone debe ser inferior al siguiente
número:
456 𝑔 + 𝑃𝑒𝑠𝑜 𝑑𝑒𝑙 𝑐ℎ𝑎𝑠𝑖𝑠 < 3540 𝑔
𝑃𝑒𝑠𝑜 𝑑𝑒𝑙 𝑐ℎ𝑎𝑠𝑖𝑠 < 3540 𝑔 − 456 𝑔
𝑃𝑒𝑠𝑜 𝑑𝑒𝑙 𝑐ℎ𝑎𝑠𝑖𝑠 < 3084 𝑔
33
Diseño e implementación de un Drone
y un dispositivo Android
El peso del chasis debe ser inferior a 3084 gramos para que el conjunto de los 4
motores sea capaz de hacer volar al drone. Una vez sabido el empuje total y el peso total de
los elementos, se procede a escoger un modelo de chasis que se ajuste a las necesidades y
que cumplan con el requisito importante del peso y de los factores característicos
mencionados anteriormente.
Para la búsqueda de distintos modelos de chasis, se ha consultado una página web de
diseños 3D llamado Thingiverse en donde sus usuarios comparten sus propias creaciones,
proyectos e ideas a la comunidad. Dentro de los muchos diseños que se encuentran, se ha
encontrado uno que cumple con las características deseadas. A continuación, se procederá a
mostrar las imágenes de planta y de perfil de cada uno de los elementos estructurales del
chasis mediante el software de diseño y modificación de piezas para impresión 3D online
gratuito llamado TinkerCAD.
22.23 cm
6.85 cm
Gráfico 31. Vista de perfil del extremo del brazo del drone
Gráfico 32. Vista de planta del extremo del brazo del drone
34
Diseño e implementación de un Drone
y un dispositivo Android
35
Diseño e implementación de un Drone
y un dispositivo Android
3.1.2 Ensamblaje
Una vez impresas las distintas partes del cuerpo del drone, nos centramos ahora en
el ensamblaje de sus piezas. Este punto resulta ser el más delicado, ya que debemos
garantizar la sujeción de todos los componentes y asegurarnos de que estos no se desprendan
en pleno vuelo.
Para el ensamblaje de las dos plataformas y de los brazos del cuadricóptero, hacemos
uso tornillos de cabeza hexagonal y tuercas de sujeción.
36
Diseño e implementación de un Drone
y un dispositivo Android
37
Diseño e implementación de un Drone
y un dispositivo Android
3.2 Electrónica
En esta etapa, centraremos nuestra atención en explicar las distintas conexiones entre
los distintos componentes a nivel de hardware del sistema en su totalidad, así como de la
asignación de los pines de los componentes conectados al microcontrolador arduino; el
esquema general del que nos regimos.
3.2.1 Esquema de las conexiones electrónicas del drone
38
Diseño e implementación de un Drone
y un dispositivo Android
Una PDB (por sus siglas en inglés, Power Distribution Board), se trata de una placa
que se encarga de distribuir la corriente entregada por la batería. No sólo son muy utilizadas
en el mundo de los drones, sino que en la electrónica en general. Además, suelen ser de
pequeño tamaño y evitan que tengamos malas conexiones entre los distintos elementos
electrónicos.
La Placa de Distribución de Potencia que hemos utilizado es del modelo PDB-XT60.
Este se encuentra conectado con nuestra batería LiPo de 3 celdas por medio del conector
XT60.
39
Diseño e implementación de un Drone
y un dispositivo Android
40
Diseño e implementación de un Drone
y un dispositivo Android
3.3 Software
Gráfico 41. Sensor MPU-6050 inclinado con las direcciones de sus aceleraciones
41
Diseño e implementación de un Drone
y un dispositivo Android
42
Diseño e implementación de un Drone
y un dispositivo Android
43
Diseño e implementación de un Drone
y un dispositivo Android
Existen varias formulaciones para un filtro complementario, entre las más usadas,
está la siguiente:
𝜃 = 𝐴 ∗ (𝜃𝑝𝑟𝑒𝑣 + 𝜃𝑔𝑖𝑟 ∙ ∆𝑡) + 𝐵 ∗ 𝜃𝑎𝑐𝑒𝑙 (7)
Donde:
- 𝜃𝑝𝑟𝑒𝑣 es el ángulo de rotación total calculado previamente.
- 𝜃𝑔𝑖𝑟 es el ángulo del giroscopio medido previamente.
- ∆𝑡 es el tiempo transcurrido desde la última vez que se hecho uso del filtro.
- 𝜃𝑎𝑐𝑒𝑙 es el ángulo del acelerómetro previamente calculado mediante el uso del
arco tangente.
- A y B son dos constantes que pueden tomar valores arbitrarios siempre y cuando
se cumpla la siguiente condición:
Ahora bien, ya hemos visto la teoría que hay detrás de este dispositivo. Es momento
de pasar a familiarizarnos con el sensor acelerómetro de manera práctica. Para ello, debemos
realizar la conexión de la placa Arduino con el módulo MPU-6050 y proceder luego con la
programación.
44
Diseño e implementación de un Drone
y un dispositivo Android
Cabe mencionar que hacemos uso de la librería propia de Arduino llamada Wire, con
la finalidad de establecer una comunicación con el módulo MPU-6050 mediante el protocolo
I2C. La primera línea de nuestro primer código de prueba para el acelerómetro incluye esta
librería. Luego, definimos y declaramos las variables necesarias para almacenar la lectura
de las aceleraciones en sus 3 ejes (X, Y, Z). Debido a que el módulo sensor entrega valores
del tipo enteros de un tamaño de 16 bits (2 bytes), debemos definir estas variables del tipo
enteros “int16_t”.
En la función setup del Arduino, establecemos una comunicación serial con tal de
poder visualizar los datos recogidos por el sensor a través del monitor serial. Luego,
comenzamos nuestra primera comunicación I2C con el módulo, donde debemos despertarle
del sleep mode1. Para ello, debemos buscar por internet el datasheet2 de este módulo para
saber cuál es el registro interno que alberga esta característica. El registro en cuestión es el
PWR_MGMT_1, donde escribimos un “0x00” a través de la función Wire.write (0x00) y así
despertarlo del modo de bajo consumo.
En la función loop (bucle), inicializamos de nuevo la comunicación I2C con el
módulo (había finalizado en la etapa setup previamente). Luego, debemos indicarle al
módulo MPU-6050 donde vamos a comenzar a leer los datos que este almacena en sus
registros internos. Estos datos (en este caso) no son más que las lecturas de las aceleraciones
en sus tres ejes.
El primer registro del cual comenzaremos a leer sus datos es el ACCEL_XOUT_H.
Mediante la sintaxis Wire.write (0x3B), le indicamos al módulo que comenzaremos dicha
lectura a partir de este registro. Ahora bien, sabemos que necesitamos 3 registros para
almacenar los 3 valores de las aceleraciones de cada eje. Sin embargo, debemos exigir la
lectura de 6 registros (y no 3) a través de la siguiente sintaxis Wire.requestFrom
(MPU_address, 2*3, true).
La razón del porque debemos exigir la lectura de seis registros y no tres, es debido al
hecho de que cada valor que mide el sensor tiene un tamaño de 2 bytes. Como cada registro
1
Sleep mode: Es el modo de bajo consumo para dispositivos electrónicos (Modo de suspensión).
2
Datasheet: Es la hoja de datos donde alberga las características y funcionalidades de un componente.
45
Diseño e implementación de un Drone
y un dispositivo Android
sólo tiene la capacidad de almacenar 1 byte, debemos reservar 2 registros por cada valor a
almacenar, obteniéndose un total de 6 registros.
El primer registro contiene lo que se denomina la parte alta del byte (High byte) y el
segundo registro contiene la parte baja del byte (Low byte). A continuación, adjuntamos una
imagen para mayor compresión.
Gráfico 47. Registros donde se almacenan las aceleraciones en los ejes X, Y, Z leidas por el sensor
46
Diseño e implementación de un Drone
y un dispositivo Android
47
Diseño e implementación de un Drone
y un dispositivo Android
48
Diseño e implementación de un Drone
y un dispositivo Android
Compilamos el código, y obtenemos a través del monitor serial los siguientes valores:
49
Diseño e implementación de un Drone
y un dispositivo Android
variables donde almacenaremos las lecturas que capta el sensor en sus 3 ejes (X, Y, Z).
Debido a que el módulo sensor entrega valores del tipo enteros de un tamaño de 16 bits (2
bytes), debemos definir estas variables nuevamente del tipo entero “int16_t”.
En la función setup del Arduino, establecemos la misma configuración para la
comunicación I2C con el módulo MPU-6050 que hemos hecho previamente para utilizar el
acelerómetro, con la salvedad de que debemos de buscar la nueva dirección de memoria del
registro que nos permita realizar esta configuración en el datasheet. Según este documento,
la dirección de memoria de este registro corresponde al 0x1B. Ahora que sabemos esta
información, procedemos a configurar el rango de escala a 250 º/s a través de la siguiente
sintaxis: Wire.write (0x1C), Wire.write (0x00).
En la función loop (bucle), inicializamos de nuevo la comunicación I2C con el
módulo. De manera similar a como hemos procedido con el acelerómetro, debemos indicarle
al módulo MPU-6050 donde vamos a comenzar a leer los datos que este almacena en los
registros internos pertenecientes a los del giroscopio.
De acuerdo con el datasheet¸ el primer registro del cual comenzaremos a leer sus
datos es el GYRO_XOUT_H, y mediante la sintaxis Wire.write (0x43), le indicamos al
módulo que comenzaremos la lectura de sus datos a partir de este registro. Igualmente que
en el acelerómetro, requerimos un total de 6 registros para almacenar los valores de las
velocidades angulares en sus 3 ejes (X, Y, Z). A partir de aquí, aplicamos los mismos pasos
especificados en la figura 49 para almacenar los valores recogidos por el sensor.
Ahora bien, dependiendo de la configuración previa del giroscopio, buscamos en el
datasheet del módulo el valor de la sensibilidad del bit menos significativo. Para el rango de
escala completa seleccionado, la sensibilidad es de 131 LSB º/s. Una vez encontrado,
debemos dividir los valores sin procesar del giroscopio por esta constante e imprimirlos a
través del monitor serial.
Para poder testear el código y comprobar que funciona, procedemos a cargarlo a la
placa microcontroladora y rotamos el módulo lentamente en torno al eje X (Roll). A
continuación, adjuntamos los valores obtenidos a través del monitor serial, en donde las 3
primeras columnas corresponden a las velocidades angulares de los ejes X, Y, Z, y las 2
últimas columnas corresponden a los ángulos de rotación en los ejes X e Y.
Sin embargo, como podemos observar en la imagen, estos valores no concuerdan con
la realidad, ya que presentan un alto grado de desviación. Esto se debe a que las limitaciones
50
Diseño e implementación de un Drone
y un dispositivo Android
que entrega el giroscopio no pueden ser compensadas por el acelerómetro si éste último no
se llega a usar.
Una de estas limitaciones que presenta el giroscopio es la del error acumulativo por
causa de la integración de la velocidad angular, tendiendo a acumular errores (y ruido) en
las mediciones, y por ende, provocando el efecto de deriva, como bien hemos explicado
anteriormente. Esta es la razón por la que hacemos uso del filtro complementario.
Primeras mediciones con el módulo MPU-6050 haciendo uso del filtro complementario
Gráfico 54. Obtención de los ángulos de rotación X e Y usando el filtro complementario (I)
51
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 55. Obtención de los ángulos de rotación X e Y usando el filtro complementario (II)
Gráfico 56. Obtención de los ángulos de rotación X e Y usando el filtro complementario (III)
Estos valores reflejan una mayor precisión que los obtenidos sin el uso del filtro
complementario. Es importante eliminar el efecto de deriva y el ruido de estas mediciones,
puesto que a partir de estas lecturas, el controlador PID tomará las acciones pertinentes para
mantener en vuelo (y de manera estable), al drone.
Sin embargo, para la absoluta estabilidad del drone, no sólo es importante el correcto
filtrado del ruido presente en las mediciones que realiza el módulo MPU-6050, sino que
también debemos cerciorarnos de la correcta calibración de los variadores de velocidad (y
por ende, también de los motores). En el siguiente apartado explicaremos cómo realizar esta
calibración.
52
Diseño e implementación de un Drone
y un dispositivo Android
Los variadores electrónicos de velocidad (ESC), junto con los motores, son los
actuadores de nuestro sistema. Están encargados de regular la velocidad de giro de nuestros
motores eléctricos sin escobillas. Además, convierten la tensión continua de la batería en
tensión variable, apta para estos motores.
El propósito de esta sección es la de familiarizarnos sobre el funcionamiento de los
motores y de los ESC, así como de entender la manera en que ambos componentes se
complementan. Para las primeras mediciones de prueba, las realizaremos sin el uso del
drone.
En general, los variadores electrónicos de velocidad son controlados mediante la
modulación de ancho de pulsos PWM. Mediante el uso de la librería “Servo”, la placa
controladora será la responsable de generar esta señal PWM a una frecuencia de 50 Hz y a
un determinado ancho de pulso con la finalidad de poder controlar la velocidad de giro del
motor.
Como bien se ha explicado en el apartado de Variador Electrónico de Velocidad, este
ancho de pulsos debe de variar dentro del rango de los 1 a 2 milisegundos. Sin embargo,
cada ESC posee sus propias variaciones de este rango de operación, pudiendo variar desde
los 1.2 ms (punto bajo) hasta los 1.9 ms (punto alto). A continuación, se adjunta una imagen
para mayor compresión.
53
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 58. Esquema de conexión del ESC, motor, batería con el Arduino
Gráfico 59. Conexión final resultante para la calibración del ESC y motor brushless
54
Diseño e implementación de un Drone
y un dispositivo Android
55
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 61. Esquema de conexión general para encender dos leds (Ejemplo)
56
Diseño e implementación de un Drone
y un dispositivo Android
57
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 62. Esquema de conexión final para encender 2 leds mediante app
Los resultados de este primer pequeño ejemplo han sido los esperados. El módulo
bluetooth recibe las órdenes desde la aplicación Android, y éste las transmite al
microcontrolador para que efectúe las acciones pertinentes a realizar.
De la misma manera, podemos realizar esta analogía pero basado en nuestro sistema
Drone. Sin embargo, en lugar de querer encender leds, la interfaz de la app será distinta y
nos permitirá controlar el direccionamiento del drone (Pitch, Yaw, Roll, Throttle).
58
Diseño e implementación de un Drone
y un dispositivo Android
Es importante de que el variador ESC responda de manera efectiva ante los comandos
que recibe de la controladora de vuelo al momento de dirigir nuestro drone. Con tal de
asegurarnos de la buena comunicación entre los dispositivos módulo bluetooth, el arduino,
el variador ESC y el motor, hemos decidido crear un pequeño programa que consiste en
controlar la velocidad de giro del motor a través del móvil.
Gráfico 63. Esquema de conexión para las pruebas del módulo HC-06 y ESC
Para realizar las primeras pruebas utilizando el módulo bluetooth HC-06 y el variador
ESC, hemos decidido incluir 4 leds de distinto color.
- Rojo: el motor está apagado.
- Azul: la velocidad de giro del rotor aumenta.
- Blanco: la velocidad de giro del rotor disminuye.
- Verde: el motor está encendido.
Cada uno de estos leds se encuentra conectado a resistencias de 330 ohm a tierra. A
continuación, adjuntamos la distribución de pines para este esquema de conexión.
Componente Pin del componente Pin de conexión a la placa
Arduino
VCC 3V3
Módulo bluetooth HC-06 GND GND
TX RX (D0)
RX TX(D1)
Variador ESC PWM (blanco) D9
GND GND
Led rojo (ánodo) D4
Leds Led azul (ánodo) D6
59
Diseño e implementación de un Drone
y un dispositivo Android
60
Diseño e implementación de un Drone
y un dispositivo Android
Ahora bien, procedemos a compilar el código. Una vez que ha terminado el proceso
de compilación y nos hayamos cerciorado de que no hay errores, procedemos a conectar los
cables TX y RX del módulo HC-06 al arduino.
Gráfico 64. Esquema de conexión final utilizando ambos componentes ESC - HC06
Los resultados han sido los esperados. El módulo bluetooth recibe las órdenes desde
la aplicación Android, y éste las transmite al microcontrolador para que efectúe las acciones
pertinentes a realizar. Al presionar el ícono de la flecha girando hacia la izquierda,
disminuimos la velocidad de giro del rotor, y la aumentamos al presionar la flecha contigua.
61
Diseño e implementación de un Drone
y un dispositivo Android
62
Diseño e implementación de un Drone
y un dispositivo Android
3.4.1 Teoría
Control Proporcional
La acción integral se encarga de eliminar el error residual que queda del controlador
proporcional, reduciéndolo a cero, o en otras palabras, calcula la integral de la señal de error
𝑒(𝑡). La fórmula para este tipo de control viene dada por la siguiente expresión:
𝑡
𝐼𝑠𝑎𝑙𝑖𝑑𝑎 = 𝐾𝑖 ∙ ∫ 𝑒(𝜏) ∙ 𝑑𝜏 (10)
0
63
Diseño e implementación de un Drone
y un dispositivo Android
El tiempo que le tome al sistema en eliminar dicho error dependerá de qué tan grande
sea la constante Ki. El hecho de querer eliminar este error lo más rápido posible al
incrementar la constante Ki trae consigo los siguientes efectos:
- El error en régimen permanente disminuirá.
- La inestabilidad del sistema aumentará.
- La velocidad del sistema aumenta.
La constante Ki de integración indica la velocidad con la que se repite la acción
proporcional. (Canalés, 2014).
Control Derivativo
Donde:,
- y(t): Es la señal de control.
- e(t): Es la señal de error.
- Kp, Ki, Kd: Representan los parámetros del controlador PID.
64
Diseño e implementación de un Drone
y un dispositivo Android
Como bien sabemos, el drone no volará de manera estable si los motores no han sido
previamente calibrados de manera correcta. Es por esta razón, que es importante que
hayamos realizado el proceso de calibración antes de proceder a continuar con la
construcción del PID.
Sin embargo, el hecho de saber cómo controlar los motores de nuestro drone no
garantiza que el mismo vuele de manera estable. Para poder controlar correctamente los
motores, primero debemos asegurarnos que por cada inclinación que realicemos con el
drone, la diferencia entre el ángulo que midamos y el ángulo deseado no sea tan grande, y si
lo es, deberemos de corregir este error.
En síntesis, para poder garantizar un vuelo estable, debemos primero asegurarnos de
que este error sea lo más pequeño posible. Por lo tanto, tendremos que realizar primero varias
pruebas y medidas relacionadas con el cálculo del ángulo antes de hacer volar nuestro drone.
Para ello, la mejor alternativa es comenzar con la construcción de un balancín adaptado solo
para 2 motores, los cuales van a representar solamente a un eje, en este caso el eje X.
La implementación de este balancín nos permitirá hallar las constantes (Kp, Ki, Kd).
Estos valores afectarán el comportamiento del controlador PID del balancín. La finalidad de
construir este sistema es la de adquirir una mejor noción sobre el funcionamiento de un
controlador PID digital
Ahora bien, a continuación, procederemos con la construcción del balancín y, una
vez finalizado, pasaremos a realizar el circuito esquemático.
65
Diseño e implementación de un Drone
y un dispositivo Android
66
Diseño e implementación de un Drone
y un dispositivo Android
Una vez colocados los soportes, procedemos a taladrar un agujero sobre la parte de
arriba de cada soporte. Ahora colocamos el balancín entre la mitad. El resultado final es el
siguiente:
Gráfico 69. Sistema balancín SIN componentes electrónicos (con sus medidas)
67
Diseño e implementación de un Drone
y un dispositivo Android
La rapidez que tenga nuestro sistema en conseguir la estabilidad dependerá del ajuste
de los parámetros Kp, Ki y Kd. El proceso de escoger los valores de tales parámetros de
manera que satisfagan las especificaciones de diseño del controlador se le conoce como
sintonización.
Existen muchas formas de ajustar un PID. Entre los más famosos, está el método de
Ziegler-Nichols.
68
Diseño e implementación de un Drone
y un dispositivo Android
Criterio de Ziegler-Nichols
Una vez conocidos estos 2 parámetros, podemos calcular los parámetros de nuestro
controlador (P, PI, PD, o PID).
Control Kp Ki Kd
P 0.50*Kc
PI 0.45*Kc 0.54*Kc/Pc
PD 0.80*Kc 0.075*Kc*Pc
PID 0.59*Kc 1.18*Kc/Pc 0.075*Kc*Pc
Tabla 13. Tabla de valores para el cálculo de los parámetros P, PI, PD o PID según Ziegler-Nichols
Este método ofrece la posibilidad de sintonizar los parámetros sin llegar a conocer
el modelo matemático que rige la planta. Debido a que no conocemos el modelo matemático
de nuestro sistema balancín, hemos optado por utilizar el método de Ziegler-Nichols en lazo
cerrado.
Sin embargo, para que podamos utilizar el criterio propuesto por Ziegler y Nichols,
y para que el sistema oscile, éste deberá tener un orden igual o superior a 3. La explicación
del por qué es bien sencilla; los sistemas de 1er orden y 2do orden no oscilan de manera
mantenida. Esto también lo podemos ver al estudiar el lugar geométrico de las raíces de las
plantas a controlar.
69
Diseño e implementación de un Drone
y un dispositivo Android
70
Diseño e implementación de un Drone
y un dispositivo Android
Ángulo vs tiempo
0
-5 0 0.5 1 1.5 2 2.5 3
Ángulo de inclinación (º)
-10
-15
-20
-25
-30
-35
-40
-45
-50
Tiempo (s)
Gráfico 76. Respuesta del sistema balancín para una ganancia de (Kp = 1.3 Ki = 0 Kd= 0)
71
Diseño e implementación de un Drone
y un dispositivo Android
Ángulo vs tiempo
20
10
Ángulo de inclinación (º)
0
0 2 4 6 8
-10
-20
-30
-40
-50
Tiempo (s)
Gráfico 77. Respuesta del sistema balancín para una ganancia de (Kp = 2.5 Ki = 0 Kd= 0)
La respuesta del sistema para una ganancia de 2.5 presenta oscilaciones que
disminuyen con el paso del tiempo. A medida que hemos seguido incrementando la
ganancia, estas oscilaciones crecen en el tiempo y no llegan a mantenerse estables. Esto nos
da un indicio de que el modelo matemático de nuestro sistema balancín es de un orden
inferior a 3, y que ésta es la razón por la que no conseguimos hacerlo oscilar de manera
mantenida. En conclusión, no podemos aplicar el criterio de Ziegler-Nichols.
No obstante, existen otras opciones para la sintonización de parámetros de un
controlador PID, entre los más populares, está el ajuste manual de un PID.
Sintonización manual de un controlador PID
Para ajustar el PID de manera manual, debemos de variar los parámetros del
controlador a medida que observamos el comportamiento del sistema. Para ello, seguiremos
el siguiente orden:
1. Ajustamos primero la ganancia proporcional para disminuir el error del sistema y
aumentar la velocidad, hasta que comience a oscilar.
2. Aumentamos la constante integral luego con tal de eliminar el error en estado
estacionario.
3. Por último, incrementamos la ganancia derivativa con tal de conseguir más
estabilidad en el sistema.
Al observar la gráfica 76, el sistema presenta una oscilación leve y un tiempo de
establecimiento medianamente rápido (Ts = 1 s). No obstante, la salida del sistema dista
mucho del valor de la consigna, obteniéndose un error elevado. Procedemos a incrementar
la constante integral (Ki) para eliminar el error residual del sistema.
72
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 78. Respuesta del sistema balancín para una ganancia de (Kp = 1.3 Ki = 0.009 Kd= 0)
Gráfico 79. Estudio de la respuesta del sistema balancín para una ganancia de (Kp = 1.3 Ki = 0.009 Kd = 0)
Donde:
- Tp (Tiempo de pico): Es el tiempo que transcurre hasta que se alcanza el
primer pico. En este caso, tenemos un Tp de 0,906 segundos.
- Tr (Tiempo de crecimiento): Es el tiempo que tarda la salida en alcanzar
por primera vez el valor final (la consigna). En este caso, tenemos un Tr
de 0,6 segundos.
73
Diseño e implementación de un Drone
y un dispositivo Android
Ángulo vs tiempo
20
10
Ángulo de inclinación (º)
0
0 2 4 6 8 10
-10
-20
-30
-40
-50
Tiempo (s)
Gráfico 80. Respuesta del sistema balancín para una ganancia de (Kp = 1.3 Ki = 0.009 Kd= 0.8)
74
Diseño e implementación de un Drone
y un dispositivo Android
Ángulo vs tiempo
4
Gráfico 81. Respuesta del sistema balancín para una ganancia de (Kp = 1.3 Ki = 0.009 Kd= 0.2)
Ángulo vs tiempo
40
30
Ángulo de inclinación (º)
20
10
0
0 2 4 6 8 10 12 14 16
-10
-20
-30
-40
-50
Tiempo (s)
Gráfico 82. Respuesta del sistema balancín para una ganancia de (Kp = 1.2 Ki = 0.009 Kd= 0)
75
Diseño e implementación de un Drone
y un dispositivo Android
Ángulo vs tiempo
40
Gráfico 83. Respuesta del sistema balancín para una ganancia de (Kp = 1.4 Ki = 0.009 Kd= 0)
Ángulo vs tiempo
30
20
Ángulo de inclinación (º)
10
0
0 5 10 15 20 25 30
-10
-20
-30
-40
-50
-60
Tiempo (s)
Gráfico 84. Respuesta del sistema balancín para una ganancia de (Kp = 1.3 Ki = 0.005 Kd= 0)
76
Diseño e implementación de un Drone
y un dispositivo Android
Ángulo vs tiempo
10
0
Ángulo de inclinación (º)
0 1 2 3 4 5 6
-10
-20
-30
-40
-50
Tiempo (s)
Gráfico 85. Respuesta del sistema balancín para una ganancia de (Kp = 1.1 Ki = 0 Kd= 0)
77
Diseño e implementación de un Drone
y un dispositivo Android
Ángulo vs tiempo
30
10
0
0 2 4 6 8 10 12
-10
-20
-30
-40
-50
Tiempo (s)
Gráfico 86. Respuesta del sistema balancín para una ganancia de (Kp = 1.1 Ki = 0.009 Kd= 0.1)
Ángulo vs tiempo
10
0
Ángulode inclinación (º)
0 1 2 3 4 5 6 7 8 9
-10
-20
-30
-40
-50
Tiempo (s)
Gráfico 87. Respuesta del sistema balancín para una ganancia de (Kp = 1.1 Ki = 0.007 Kd= 0.15)
78
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 88. Diagrama de flujo del control PID del sistema balancín
79
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 90. Ejemplo de la evolución de la respuesta del mpu-6050 en función del valor del mando
80
Diseño e implementación de un Drone
y un dispositivo Android
81
Diseño e implementación de un Drone
y un dispositivo Android
82
Diseño e implementación de un Drone
y un dispositivo Android
83
Diseño e implementación de un Drone
y un dispositivo Android
encargará de reducir el valor final de la acción integral en cada iteración hasta que
alcancemos el valor de 0. En pocas palabras, la finalidad de este controlador es la eliminar
el error residual que queda del controlador proporcional.
En cuanto al control derivativo, sabemos que la derivada de la señal representa la
velocidad de variación de esta señal de error. Por lo tanto, este control procederá a actuar
cuando exista una desviación entre el error actual y el error anterior. Es por esta razón que
creamos una variable llamada “error_ant”. Para la aplicación de este control, hacemos la
diferencia entre el error actual y el error anterior, y este resultado lo dividimos entre el tiempo
que ha transcurrido entre cada llamada a este control derivativo. Todo esto multiplicado por
nuestra constante Kd, En pocas palabras, la finalidad de este controlador es la de eliminar
las oscilaciones generando una corrección en la señal de control proporcional a la derivada
de la señal de error e(t).
Finalmente, procedemos a sumar el resultado de cada control (proporcional, integral
y derivativo) para así obtener el control PID. Por último, debemos de aplicar las acciones
con las correcciones pertinentes en nuestro sistema actuador, los cuales lo conforman los
ESC y los motores. Para ello, llamamos a la función actuador.
Esta función realiza diversas acciones. La primera de ellas, es garantizar que el valor
de salida del controlador PID esté entre un rango aceptable. En otras palabras, Los valores
PID oscilará entre -1000 y 1000, ya que cuando el mínimo valor del PWM se encuentre en
1000 µs, el máximo valor que se le puede añadir es +1000 µs, y debemos cerciorarnos de no
sobrepasarnos de este valor. Por otra parte, cuando estemos en el máximo valor del PWM,
el cual es 2000 µs, el máximo valor que podemos substraer es de -1000 µs, y así alcanzar el
punto mínimo de 1000 µs. Debemos asegurarnos de no sobrepasarnos de estos rangos.
La segunda acción que realiza nuestra función, es la de crear el ancho de pulso de la
señal con que alimentaremos a nuestros ESC, (que a su vez controlarán a nuestros motores).
Para ello, simplemente sumamos la aceleración inicial que tienen estos motores más la salida
del controlador PID.
Nuevamente, tenemos que asegurarnos de que los valores no sobrepasen los límites
de trabajo: (1000 µs < valor final < 2000 µs). Por ende, debemos volver a mapear los valores
finales PWM para nuestros 2 motores y asegurarnos de que el valor final que enviaremos a
nuestros ESC esté dentro del rango correcto.
Una vez que hayamos mapeado los valores, procedemos a enviar los valores PWM
finales a nuestros 2 motores, mediante la función WriteMicroseconds perteneciente a la clase
Servo. Por último, guardamos en la variable “error_ant” el error actual.
84
Diseño e implementación de un Drone
y un dispositivo Android
85
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 95. Relación entre la variación de la ganancia y el valor que toma el error
Una vez iniciado el proceso, el drone comenzará a elevarse (Situación A). Cuando
llegue al punto donde ocurre el steady state error (por debajo de la posición deseada), la parte
integral realizará la siguiente acción:
86
Diseño e implementación de un Drone
y un dispositivo Android
87
Diseño e implementación de un Drone
y un dispositivo Android
88
Diseño e implementación de un Drone
y un dispositivo Android
Es por ello que nos centramos en desarrollar el modo acrobático primero, con la posibilidad
de incluir también el modo estable en un futuro.
3.4.5.2 Descripción del problema
La manera de proceder con la programación del drone es distinta a la forma con que
se ha programado el sistema balancín. Esto se debe a que en el sistema balancín se utiliza
solamente uno de los 3 ejes (el eje Roll). Mientras que el drone utiliza los 3 ejes del espacio
(Yaw, Pitch, Roll).
En base a los posibles movimientos del drone, debemos de enviar a los 4 motores las
velocidades que permitan que el sistema se mantenga estable en el aire. Además, también
queremos que acate las órdenes que recibe del mando de control. Esta información que recibe
del exterior será captada por la IMU 6050.
De momento, tenemos un lazo de realimentación como la mostrada a continuación:
Sin embargo, es fácil darse cuenta que algunos de estos movimientos están
relacionados entre ellos. Por ejemplo, para desplazarnos hacia la izquierda, primero debemos
aplicar un roll donde las velocidades de los motores laterales derechos sean mayores que las
velocidades de los otros motores.
89
Diseño e implementación de un Drone
y un dispositivo Android
Y si por ejemplo, deseamos movernos hacia adelante, basta con aplicar un pitch,
donde las velocidades de los motores delanteros sean superiores que las velocidades de los
motores traseros.
Por tanto, podemos resumir nuestros movimientos en 4: Pitch, Yaw, Roll, y el
Throttle (altitud). Ahora debemos de ser capaces de producir estos 4 movimientos en nuestro
drone con los 4 motores.
Con tal de poder controlar el pitch, yaw, roll y la altitud de manera independiente, la
dirección de las hélices de los motores deben estar dispuestos de la siguiente manera:
En un primer inicio, podemos variar por ejemplo el pitch sin afectar el roll, la altitud
ni el yaw. Sin embargo, en espacios abiertos donde hay turbulencias y vientos fuertes, los
movimientos del uno del otro se acoplan y se combinan, por lo que resultaría difícil variar
el movimiento de uno de los ejes sin afectar a los otros. No obstante, resaltamos que el
propósito de nuestro drone es hacerlo volar en espacios cerrados y pequeños.
Mediante esta configuración, tenemos un control directo sobre los 4 movimientos.
Además, es lógico pensar que la variación de alguno de estos 4 movimientos va a cambiar
la estabilidad inicial del drone. Por ende, las señales a enviar a nuestros 4 actuadores serán
una combinación del Pitch, Yaw, Roll y la altitud.
Recordemos cómo producir estos movimientos en nuestro drone.
- Yaw: Si deseamos que el drone se mueva en el sentido de giro de las
manecillas del reloj, debemos de aumentar la velocidad de las hélices del
motor frontal izquierdo y del motor trasero derecho. Si deseamos el efecto
contrario, debemos aumentar la velocidad de los otros 2 motores.
90
Diseño e implementación de un Drone
y un dispositivo Android
91
Diseño e implementación de un Drone
y un dispositivo Android
poder incorporar esta funcionalidad extra, es necesario utilizar 2 PID adicionales (para los
ejes Pitch y Roll).
- Un primer PID (lazo de inclinación), que compara la consigna de
inclinación que enviamos desde el mando con el ángulo de inclinación
actual del drone. Este controlador generará una salida que será la consigna
de velocidad para el siguiente PID.
Gráfico 103. Estrategia de control del modo Acrobático con la posibilidad de posicionar el drone a 0º
y un dispositivo Android
y un dispositivo Android
- Ejecución del lazo de velocidad (los 3 PID, uno para cada eje),
actualizando la velocidad con que los motores deberán girar para el
siguiente ciclo.
Una vez realizada las tareas en el momento C, procedemos a crear la señal PWM
para el siguiente ciclo. Para crear los flancos de subida y de bajada de la señal PWM,
utilizamos la función integrada en el arduino llamada digitalWrite. Esta función recibe dos
parámetros:
- Número de pin: le especificamos el pin el cual el motor está asociado.
94
Diseño e implementación de un Drone
y un dispositivo Android
Dentro del mundo del aeromodelismo, es bien sabido que no todas las hélices que
vienen de fábrica están calibradas. Para saber si las hélices adquiridas están calibradas,
podemos utilizar un artefacto llamado calibrador de hélices. En nuestro caso, el equilibrador
de hélices se compone de 2 vasos de igual tamaño. Entre estos 2 vasos, reposa un tornillo
envuelto con cinta aislante por donde entra el eje de la hélice.
Este proceso de calibración consiste en conseguir el punto de equilibrio de las hélices.
Gráfico 106. Velocidad del motor izquierdo trasero sin haber calibrado su hélice
95
Diseño e implementación de un Drone
y un dispositivo Android
Como podemos observar en el gráfico, hay una gran cantidad de ruido presente en la
velocidad a enviar al motor izquierdo trasero. Un mal balanceo de la hélice, provocará que,
cuando el motor gire a grandes revoluciones, una pala tienda a elevarse un poco por encima
de la otra pala, y por ende, la hélice temblará; creándose las vibraciones.
96
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 109. Velocidad del motor izquierdo trasero con su hélice calibrada
Al realizar la comparación de los gráficos 106 y 109, podemos observar una gran
disminución de las vibraciones. Procedemos a realizar esta calibración para todas las hélices
de nuestro cuadricóptero, en caso de que haga falta.
Una técnica simple pero muy poderosa a la hora de reducir (e incluso eliminar) el
ruido de nuestras mediciones, es “aislar” aquellos componentes que puedan verse afectados
por las vibraciones remanentes de las hélices. Este componente es el sensor MPU-6050.
Para aislar nuestro único sensor, simplemente debemos de utilizar un material en
concreto que separe físicamente el sensor del frame de nuestro drone. El material escogido
ha sido de goma espuma, el cual reduce en buena parte las vibraciones.
97
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 110. Aislamiento del sensor MPU-6050 del frame utilizando goma espuma
Al aislar nuestro sensor y realizar las pruebas, nos hemos percatado de que seguía
existiendo ruido que afectaba nuestras mediciones. El drone no respondía a los comandos
enviados desde la app.
La explicación del por qué el sensor continuaba recibiendo ruido de las hélices, es
porque no habíamos aislado el microcontrolador arduino del chasis, y por tanto, las
vibraciones viajaban a través de los cables que conectan al sensor con el arduino.
Gráfico 111. Aislamiento del microcontrolador del frame utilizando goma espuma
98
Diseño e implementación de un Drone
y un dispositivo Android
Un filtro paso bajo es un filtro que se caracteriza por permitir el paso de las
frecuencias que estén por debajo de una frecuencia en específico, llamado frecuencia de
corte. Pueden ser recreados a través de circuitos analógicos, o mediante circuitos digitales
y/o programas informáticos (filtro digital).
Gráfico 112. Ejemplo de una señal atenuada por un filtro digital paso bajo
En nuestro sistema, el filtro digital paso bajo se encargará de separar aquellas señales
de interés que han sido contaminadas con las interferencias remanentes de las hélices (ruido).
Filtro digital paso-bajo que incorpora el sensor MPU-6050
Este dispositivo incorpora un filtro LPF (Low Pass Filter) con distintas frecuencias
de corte. Sin embargo, cuanto más bajo sea la frecuencia de corte, más retardo habrá en
nuestras medidas (incluso superando el periodo de ejecución que hemos establecido
previamente: 8 ms). La siguiente tabla muestra las distintas frecuencias de corte con su
correspondiente retardo.
Gráfico 113. Configuración del filtro digital paso-bajo, de acuerdo al datasheet del MPU-6050
Para seleccionar qué frecuencia de corte deseamos utilizar, basta con escribir en el
registro DLPF_CFG el valor al cual está asociado dicha frecuencia de corte. En nuestro
sistema, hemos optado por una frecuencia de corte 44 Hz (para el acelerómetro) y de 42 Hz
(para el giroscopio), por tanto escribimos en el registro DLPF_CFG el valor de 0x03.
Como podemos observar en el gráfico 112, para la frecuencia de corte escogida,
tenemos un retardo aproximadamente de 4.9 milisegundos. Este retardo es inferior a nuestro
periodo de ejecución que hemos escogido, por tanto es aceptable.
99
Diseño e implementación de un Drone
y un dispositivo Android
Para saber si la frecuencia de corte escogida nos ayudará a reducir el ruido de nuestras
mediciones, basta con calcular la frecuencia de las vibraciones de las hélices. Para ello,
debemos conocer la cantidad de revoluciones por minuto a la que nuestras hélices giran.
Los motores adquiridos son del modelo A2212 con una constante 1000 KV. Esta
constante representa el número de revoluciones por minuto que será capaz de ofrecer al
aplicar 1 voltio de tensión. Al alimentarlo con una batería 3 S de 11.1 voltios, nuestro motor
podrá llegar a girar a una velocidad de 11100 rpm sin carga (con una señal PWM en estado
alto de 2000 microsegundos; 100 % Throttle).
Sin embargo, el drone no girará a esta velocidad durante todo el vuelo. El valor de la
velocidad a enviar a los motores irán variando de acuerdo a los controladores PID y del
usuario.
Debido a que el mecanismo de control se activa cuando el acelerador (variable que
modifica el usuario) está por encima de 1200, podemos asumir que las velocidades de
nuestro drone variarán entre 20 % del valor de la aceleración (1200 microsegundos) y 100
%, correspondiente a 2000 microsegundos. Es decir:
- 11100 𝑟𝑝𝑚 ∙ 20 % = 2220 𝑟𝑝𝑚
100
Diseño e implementación de un Drone
y un dispositivo Android
Nuestro sistema se enfrentará a vibraciones que podrán oscilar entre 37 Hz y 185 Hz.
Para la frecuencia de corte que hemos escogido, 44 Hz (para el acelerómetro) y de 42 Hz
(para el giroscopio), resulta ser entonces un buen filtro.
Cabe resaltar que estos cálculos son aproximaciones rápidas para tener una idea de
la cantidad de ruido teórica que puede afectar nuestras mediciones. No obstante, la
calibración de hélices, en combinación con el proceso de aislar nuestros dispositivos del
cuerpo del drone, reducirá la frecuencia de las vibraciones producidas.
A modo de ejemplo, encendemos los cuatro motores e incrementamos la velocidad
hasta 1357 rpm (11.6 % de aceleración). Luego, procedemos a medir las velocidades
angulares en los 3 ejes (pitch, roll, yaw) en 2 condiciones.
1) Sin utilizar el filtro digital paso-bajo del sensor MPU-6050.
2) Utilizando el filtro.
Los resultados:
Gráfico 115. Comparación en la lectura de las velocidades angulares sin emplear filtro (izq) y empleando filtro (der)
101
Diseño e implementación de un Drone
y un dispositivo Android
Tras varias mediciones y pruebas con nuestro drone, un valor alfa igual a 0.55 nos
ayuda a reducir parte del ruido.
Gráfico 116. Comparación entre la velocidad angular Roll sin filtrar y la filtrada (Filtro EMA)
Para la obtención del gráfico anterior, movemos el drone con la mano a lo largo del
eje Roll, y observamos el comportamiento; de la señal muestreada (color azul), y de la señal
filtrada (color rojo). Para esta prueba, dejamos los motores apagados.
102
Diseño e implementación de un Drone
y un dispositivo Android
Como podemos contemplar, el filtro EMA elimina el ruido de alta frecuencia que se
encontraba superpuesto en nuestra señal de interés (la velocidad angular en el eje Roll).
Ahora veamos el efecto positivo de utilizar el filtro para eliminar las fluctuaciones en la
consigna de velocidad enviada a los motores.
Gráfico 117. Filtro EMA: Velocidad del motor sin emplear filtro (izq) y empleando filtro (der)
Tras analizar los gráficos 116 y 117, podemos concluir que el uso del filtro EMA
resulta indispensable dentro de nuestro sistema. Haremos uso de este filtro únicamente para
filtrar las velocidades angulares de los ejes Pitch, Roll y Yaw.
En cuanto al filtrado de los valores que mide el acelerómetro, utilizaremos el filtro
complementario (en combinación con los valores del giroscopio sin filtrar). La descripción
y explicación de este filtro fue tratado en el apartado de Inicialización del sensor MPU-
6050 (pág. 41).
Emplear cada una de estas técnicas para eliminar las vibraciones nos ayudarán a
mejorar la comunicación entre nuestro controlador de vuelo y el drone, evitando que
aparezcan ciertas situaciones no deseadas como los tambaleos y las oscilaciones.
103
Diseño e implementación de un Drone
y un dispositivo Android
El drone se encuentra amarrado con unas cuerdas a nivel del suelo (posición actual)
y la consigna o la posición deseada es a la altura de 3 metros. Al momento de encender los
motores, el comportamiento de la señal de error y de velocidad a enviar a los motores son
las siguientes:
104
Diseño e implementación de un Drone
y un dispositivo Android
Para este punto, el drone se habrá elevado muchos metros por encima de
su referencia; la señal de error habrá crecido mucho más negativamente.
Existen muchas alternativas para evitar que aparezca el efecto windup, describiremos
la que hemos decidido utilizar, llamada limitación del término integral.
Esta técnica consiste en integrar la señal de error siempre y cuando el valor absoluto
del error se encuentre dentro de un determinado rango. Desde un inicio, hemos optado por
utilizar este método antiwindup para nuestro drone. No obstante, tras repetidas pruebas,
hemos observado mejores resultados con la técnica de limitación del término integral.
105
Diseño e implementación de un Drone
y un dispositivo Android
Como bien sabemos, la variación de los parámetros PID que conforman nuestros
lazos de velocidad y aceleración influye en la estabilización de nuestro cuadricóptero. Para
conseguir estos parámetros, realizaremos el ajuste a prueba y error en un “banco de
pruebas”.
La razón principal por la que no realizamos el ajuste mediante simulación, es que
sería necesario conocer el modelo matemático completo que rige el drone, resultando ser
complejo su implementación.
Por tanto, hemos optado por montar un “banco de pruebas”, donde realizaremos los
testeos y analizaremos el comportamiento que toma el sistema.
106
Diseño e implementación de un Drone
y un dispositivo Android
kp =2 ki = 0 kd = 0
60
40
Velocidad angular (º/s)
20
-20
-40
-60
-80
0 1 2 3 4 5 6 7 8 9 10 11 12
Tiempo (s)
Gráfico 122. Velocidad angular del eje pitch (sintonización de Kp) – Prueba I
107
Diseño e implementación de un Drone
y un dispositivo Android
kp = 1.7 ki = 0 kd = 0
60
20
-20
-40
-60
-80
0 1 2 3 4 5 6 7 8 9 10 11 12 13
Tiempo (s)
Gráfico 123. Velocidad angular del eje pitch (sintonización de Kp) – Prueba II
kp = 1.275 ki = 0 kd = 0
100
80
60
Velocidad angular (º/s)
40
20
0
-20
-40
-60
-80
-100
0 1 2 3 4 5 6 7 8 9 10 11 12 13
Tiempo (s)
Gráfico 124. Velocidad angular del eje pitch (sintonización de Kp) – Prueba III
108
Diseño e implementación de un Drone
y un dispositivo Android
kp = 1.275 ki = 0 kd = 1
40
20
Velocidad angular (º/s)
-20
-40
-60
-80
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Tiempo (s)
Gráfico 125. Velocidad angular del eje pitch (sintonización de Kd) – Prueba I
109
Diseño e implementación de un Drone
y un dispositivo Android
kp = 1.3 ki = 0 kd = 8
40
30
Velocidad angular (º/s) 20
10
0
-10
-20
-30
-40
-50
0 1 2 3 4 5 6 7 8 9 10 11
Tiempo (s)
Gráfico 126. Velocidad angular del eje pitch (sintonización de Kd) – Prueba II
Kp = 1.3 Ki = 0 Kd = 22
60
Velocidad angular (º/s)
40
20
-20
-40
-60
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
Tiempo (s)
Gráfico 127. Velocidad angular del eje pitch (sintonización de Kd) – Prueba III
110
Diseño e implementación de un Drone
y un dispositivo Android
Kp = 1.3 Ki = 0.01 Kd = 22
60
40
Velocidad angular (º/s)
20
-20
-40
-60
-80
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
Tiempo (s)
Gráfico 128. Velocidad angular del eje pitch (sintonización de Ki) – Prueba I
Kp = 1.3 Ki = 0.02 Kd = 22
80
Velocidad angular (º/s)
60
40
20
0
-20
-40
-60
-80
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
Tiempo (s)
Gráfico 129. Velocidad angular del eje pitch (sintonización de Ki) – Prueba II
111
Diseño e implementación de un Drone
y un dispositivo Android
Lazo de aceleración
Pitch Roll
Kp Ki Kd Kp Ki Kd
2 0.04 4 1.7 0.04 4
Tabla 15. Parámetros PID del lazo de aceleración.
La estructura del algoritmo que rige nuestro sistema drone guarda muchas similitudes
con la de nuestro sistema balancín. Por tanto, en esta sección sólo explicaremos aquellas
nuevas secciones de código que hemos incluido.
En nuestro archivo principal, comenzamos con la definición de la única librería que
utilizaremos, Wire.h, para la comunicación con nuestro módulo sensor MPU-6050. Luego,
procedemos con la declaración y definición de las variables en general.
A diferencia del código de nuestro sistema balancín, ahora el usuario podrá:
112
Diseño e implementación de un Drone
y un dispositivo Android
- Escoger qué motores activar. Esta opción la hemos decidido añadir con la
finalidad de analizar el ruido que produce cada motor por separado,
facilitando el proceso de la calibración de las hélices.
Función setup
En la función setup del arduino, comenzamos con la inicialización del sensor MPU-
6050; configuramos la sensibilidad de nuestro acelerómetro y giroscopio. Además,
incluimos la configuración del filtro digital paso bajo que incorpora el sensor, eligiendo una
frecuencia de corte de 44 Hz.
Una vez hayamos finalizado la calibración y corrección del offset de nuestro
dispositivo sensor, procedemos con la inicialización de los motores. En nuestro sistema
drone no hacemos uso de la librería servo.h, por tanto, la manera de inicializar los motores
se lleva a cabo de manera diferente.
113
Diseño e implementación de un Drone
y un dispositivo Android
Los motores brushless necesitan recibir pulsos de 1000 microsegundos por una cierta
cantidad de tiempo para prepararlos antes de que comiencen a girar. Cuando los motores ya
están armados y listos para arrancar, emitirán unos pitidos. A través del bucle principal,
mientras la variable esc_calibrado sea falso, estaremos enviando pulsos de 1000
microsegundos a los motores. Luego, procedemos a leer los posibles comandos de la
aplicación recibidos por el módulo HC-06. Si los motores aún no han emitido dichos pitidos,
no leeremos nada.
Todo este proceso se realizará en ciclos de 8 milisegundos. Cuando los motores
emitan los pitidos, presionamos el botón “soltar stick” en nuestra app, y por tanto, la variable
esc_calibrado se cambiará a verdadero, y saldremos del bucle.
Salimos de la función, y antes de entrar en el bucle principal, comenzamos con la
definición de 2 variables para almacenar el tiempo transcurrido.
- “Time”. Debido a que tenemos que medir el tiempo transcurrido entre
cada iteración, utilizamos la función propia del arduino (millis), el cual
calcula el tiempo en milisegundos desde que se ha encendido el
microcontrolador. Utilizaremos esta variable para el cálculo de los
ángulos y del control derivativo.
Función loop
En la función loop, realizamos el mismo proceso de lectura y cálculo de las
velocidades angulares y las aceleraciones que llevamos a cabo en el sistema balancín, con la
diferencia que hemos incluido el filtro EMA durante la obtención de las velocidades
angulares.
114
Diseño e implementación de un Drone
y un dispositivo Android
Una vez que hayamos refinado las lecturas de las velocidades angulares, realizamos
el llamado a la función low_passFilter (filtro EMA), donde filtraremos la velocidad obtenida
en cada eje (pitch, roll, yaw). Luego, guardamos estos valores filtrados para la siguiente
iteración.
Cuando hayamos filtrados los valores, procedemos a llamar a la función leer_app.
Donde podremos:
- Encender el drone.
- Cambiar la velocidad de giro de los motores al incrementar el throttle.
- Indicarle al drone los desplazamientos o movimientos que queremos que
haga.
- Auto-estabilizar el drone.
- Apagar los motores.
Ahora procedemos a llamar a la función más importante de nuestro sistema; el
sistema actuador. En esta función:
- Ejecutamos los lazos de velocidad y/o de aceleración, donde llamamos a
las funciones PID de cada eje.
- Limitamos las salidas PID de cada eje entre -400 y 400.
- Aplicamos el algoritmo de control de las señales a enviar para cada motor.
- Limitamos las salidas a enviar de cada motor entre 1100 y 2000
microsegundos.
- Actualizamos los errores anteriores de las velocidades angulares.
- Iniciamos un nuevo conteo para comenzar un nuevo ciclo de ejecución, e
inmediatamente llamamos a la función crear_pwm.
115
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 134. Función para crear la señal PWM a enviar a los actuadores
Dentro de la función crear_pwm, enviamos un pulso alto (HIGH) a los cuatro pines
asociados con los motores. Luego, sumamos el tiempo de las señales de los cuatro motores
(calculado por el controlador automático) con el tiempo total transcurrido desde el inicio del
nuevo ciclo. Esto tiene la finalidad de llevar el control de las señales en estado alto de los
actuadores.
Finalmente, con el siguiente bucle while, nos encargamos de pasar de flanco alto a
flanco bajo para cada motor, siempre y cuando se cumpla la condición.
Si la variable perteneciente al motor es menor o igual al tiempo total transcurrido,
apagamos el motor correspondiente. Una vez apagados todos los motores, arduino saldrá del
bucle while.
Después de enviar la señal LOW a todos los pines, procedemos con la visualización
de las señales que haya escogido el usuario previamente, llamando a la función display_data.
Esta función enviará un valor a través del serial monitor o serial plotter por cada iteración
del programa principal. Una vez se termine de ejecutar la función, comenzamos nuevamente
el proceso de lectura de datos.
116
Diseño e implementación de un Drone
y un dispositivo Android
2- Se abrirá una nueva ventana donde debemos iniciar sesión con una cuenta de
google. Una vez hecho esto, se refrescará la página y hacemos clic al botón “Start
new Project”. Le damos un nombre a nuestro proyecto y clicamos en aceptar.
Gráfico 135. Interfaz inicial para el desarrollo de una nueva aplicación en Mit App Inventor
117
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 137. Ejemplo sobre cómo insertar capas para establecer orden en la aplicación (Mit App Inventor)
118
Diseño e implementación de un Drone
y un dispositivo Android
7- Para poder añadir un botón que nos permita activar el bluetooth de nuestro
android y que busque otros dispositivos, clicamos en “User Interface”
“ListPicker”, y arrastramos el elemento sobre la pantalla. El resultado final de la
programación del diseño de nuestra app de control del sistema balancín es el
siguiente:
Gráfico 138. Diseño final de nuestra app de control del sistema balancín
119
Diseño e implementación de un Drone
y un dispositivo Android
Donde:
- La flecha que gira hacia la izquierda: Disminuimos en intervalos de
“0.80” el ángulo de referencia que hayamos establecido previamente. Esto
hará que el balancín se incline hacia la izquierda. La plataforma lo
representa mediante la etiqueta “Button 1”.
120
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 139. Programación en bloques de nuestra app controladora para el sistema balancín
Donde:
- El bloque A: Antes de que hagamos clic en el icono bluetooth, la
instrucción de color verde llamado “Set Listpicker1” nos enlista todos
aquellos dispositivos bluetooth que alguna vez el teléfono móvil ha estado
conectado. Por lo tanto, es importante que ya hayamos apareado el móvil
con el módulo bluetooth previamente.
- Button1: Este botón es la flecha de girar hacia la izquierda. Cada vez que
hagamos clic en él, enviaremos un carácter, en este caso, el número 3. El
envío de caracteres de parte de la app hacia el microcontrolador nos
servirá para que arduino pueda reconocer qué botón ha sido presionado,
puesto que a través del comando Serial.read, arduino recibirá este
carácter.
- Button2: Este botón es la flecha de girar hacia la derecha. Cada vez que
hagamos clic en él, enviaremos un carácter, en este caso, el número 2.
121
Diseño e implementación de un Drone
y un dispositivo Android
- Button3: Este botón es la apagar los motores de manera rápida. Cada vez
que hagamos clic en él, enviaremos un carácter, en este caso, el número
4.
- Button4: Este botón es la de inicio, donde le hacemos saber al arduino que
queremos comenzar el programa principal. Es importante destacar que al
presionar este botón, los motores NO se encenderán de inmediato, sino
que tendremos un margen de 10 segundos para poder conectar la batería.
Cada vez que hagamos clic en él, enviaremos un carácter, en este caso, el
número 1.
122
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 142. Diseño final de nuestra app de control del sistema drone
Gráfico 143. Programación en bloques de nuestra app controladora para el sistema drone (Parte I)
123
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 144. Programación en bloques de nuestra app controladora para el sistema drone (Parte II)
Cada uno de estos caracteres que enviamos nos servirá para que el arduino pueda
reconocer qué botón ha sido presionado. A través del comando Serial.read, arduino recibirá
estos caracteres.
124
Diseño e implementación de un Drone
y un dispositivo Android
- Soltar stick: Este botón tiene dos funciones. La primera de ellas, es que
durante el periodo de armado de los motores, cuando estos emitan los
pitidos, debemos presionar este botón para poder entrar en el programa
principal. La segunda, para actualizar la consigna de velocidad angular a
0 en los 3 ejes, (este botón simula la acción de soltar el joystick de un
mando RC).
125
Diseño e implementación de un Drone
y un dispositivo Android
4 Resultados
Eje Pitch
10
5
Grados (º)
-5
-10
-15
0 2.5 5 7.5 10 12.5 15 17.5 20 22.5
Tiempo (segundos)
Gráfico 146. Ángulo de inclinación del eje pitch tras recibir comandos de la app
126
Diseño e implementación de un Drone
y un dispositivo Android
30
20
10
0
-10
-20
-30
-40
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
Tiempo (segundos)
Gráfico 147. Velocidad angular del eje pitch tras recibir comandos de la app
Eje Roll
0
-5
-10
-15
-20
-25
0 2.5 5 7.5 10 12.5 15 17.5 20 22.5
Tiempo (segundos)
Gráfico 148. Ángulo de inclinación del eje roll tras recibir comandos de la app
127
Diseño e implementación de un Drone
y un dispositivo Android
De igual forma como observamos en el gráfico de inclinación del eje pitch, el sistema
responde de manera progresiva ante los cambios de orientación enviadas desde la aplicación.
Al presionar el botón de auto-estabilización, el drone entra en el modo “estable” y trata de
mantenerse nivelado (0º). Luego, le indicamos que gire hacia la izquierda sobre su propio
eje por unos segundos, le ordenamos que se detenga en esa posición inclinada, y después
volvemos a presionar la opción de auto-estabilización.
30
20
10
0
-10
-20
-30
-40
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
Tiempo (s)
Gráfico 149. Velocidad angular del eje roll tras recibir comandos de la app
128
Diseño e implementación de un Drone
y un dispositivo Android
5 Conclusiones
129
Diseño e implementación de un Drone
y un dispositivo Android
conocimientos en los campos de software y hardware, sino que también podamos hacer uso
de la imaginación y del ingenio para desarrollar proyectos de carácter innovador.
En cuanto a la parte negativa durante la ejecución del trabajo, destacamos la gran
cantidad de tiempo invertido para conseguir mantener estable nuestro drone durante la fase
de sintonización PID. Esto se debe a que nuestro sensor MPU-6050 es muy sensible al ruido,
y no habíamos realizado desde un inicio el proceso de calibración de hélices
correspondientes. Por tanto, señalamos que unas hélices mal ajustadas, o un mal aislamiento
entre los dispositivos sensibles al ruido y el cuerpo que recibe las vibraciones, provocarán
mediciones imprecisas y nuestro sistema nunca sería estable, independientemente del tipo
de ajuste PID empleado.
Como último punto negativo, nos centramos en el dispositivo que funciona como
radiocontrol dentro de nuestro sistema; el móvil con la app Android. De acuerdo a lo que
hemos podido aprender del mundo del aeromodelismo durante la consecución del presente
trabajo, destacamos lo imprescindible de utilizar un mando radio control (RC) con su
respectivo receptor. Estos dispositivos funcionan por interrupciones hardware, consiguiendo
una respuesta rápida del sistema ante el envío de nuevas órdenes por parte del mando RC sin
afectar el ciclo de ejecución del microcontrolador. Sin embargo, en nuestro caso, las órdenes
que enviemos desde la app no serán tratadas de manera inmediata como ocurren con las
interrupciones, sino que quedarán almacenadas en el buffer del HC-06 hasta que el punto
actual de ejecución del programa llame a nuestra función leerApp, donde leemos los datos
del buffer. Esto provoca un ligero retraso que puede afectar la maniobrabilidad de nuestro
drone en pleno vuelo.
Como mejora de nuestro sistema, consideramos la inclusión del mando radio control
RC como hemos mencionado anteriormente. Así como el uso de una placa de montaje, (en
sustitución de la protoboard), para soldar los pines del microcontrolador y los pines de los
distintos componentes que conforman nuestro sistema drone. De esta manera, aseguramos
que ninguna de estas conexiones vaya a soltarse en pleno vuelo. Además, podemos añadir
nuevos sensores; sensor de ultrasonidos, GPS, entre otros, con tal de conseguir un control de
vuelo más preciso y autónomo.
En general, concluimos que el proceso de desarrollo del proyecto ha sido gratificante.
Ha servido no sólo para poner en práctica algunos de los conocimientos adquiridos en la
carrera, sino que también nos ha permitido una mejor compresión de aquellos conceptos que
solo se ven en clase. En lo personal, considero que el presente trabajo es una buena manera
de enlazar conocimientos prácticos-teóricos, y así darnos una idea del futuro trabajo como
ingenieros que podemos llegar a tener.
130
Diseño e implementación de un Drone
y un dispositivo Android
6 Bibliografia
131
Diseño e implementación de un Drone
y un dispositivo Android
132
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 1. Lumenier. (2019). Qav-x charpu fpv Racing quadcopter. [figura]. Recuperado
de: https://www.lumenier.com/consumer/qav-x
Gráfico 5. Translators café. (2017). Drone Lipo Battery calculator. [figura]. Recuperado
de: https://www.translatorscafe.com/unit-converter/ro-RO/calculator/multicopter-
lipo-battery/
Gráfico 6. Translators café. (2017). Drone Lipo Battery calculator. [figura]. Recuperado
de: https://www.translatorscafe.com/unit-converter/ro-RO/calculator/multicopter-
lipo-battery/
Gráfico 7. Translators café. (2017). Drone Lipo Battery calculator. [figura]. Recuperado
de: https://www.translatorscafe.com/unit-converter/ro-RO/calculator/multicopter-
lipo-battery/
Gráfico 8. Translators café. (2017). Drone Lipo Battery calculator. [figura]. Recuperado
de: https://www.translatorscafe.com/unit-converter/ro-RO/calculator/multicopter-
lipo-battery/
133
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 18. Dejan. (2019). How Brushless Motor and ESC Work. [figura]. Recuperado
de: https://howtomechatronics.com/how-it-works/how-brushless-motor-and-esc-
work/.
Gráfico 19. Prometec. (s.f). Lo que hay que saber para elegir los ESC para un
cuadracóptero. [figura]. Recuperado de: https://www.prometec.net/esc-para-drones/
Gráfico 20. Oliveira, Mario & Fernandes, Marcos & Souto, Rafael. (2017).
Implementation of a Low-cost Prototype of Twin Rotor for Academic Studies in
Identification, Optimal Control and Stochastic Filtering.
10.1109/ICoSC.2017.7958718. [figura]. Recuperado de
https://www.researchgate.net/figure/PWM-Signal-for-brushless-motor-speed-
control_fig4_317084889
Gráfico 22. Tecneu. (2019). Módulo Bluetooth HC-06 para Arduino PIC Raspberry.
[figura]. Recuperado de: https://www.tecneu.com/products/modulo-bluetooth-hc-06
Gráfico 23. HP Modelismo. (2019). Gens Ace Batería Lipo 25C 2200 mAh 3S1P 11.1 V.
[figura]. Recuperado de: https://www.hpmodelismo.com/pt/lipo/12150-bateria-lipo-
gens-ace-25c-2200mah-3s1p-111vphantom.html
134
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 31. Wood, Steve. (2013). Spyda 500 Quadcopter. [figura]. Recuperado de:
https://www.thingiverse.com/thing:160607/files
Gráfico 32. Wood, Steve. (2013). Spyda 500 Quadcopter. [figura]. Recuperado de:
https://www.thingiverse.com/thing:160607/files
Gráfico 33. Wood, Steve. (2013). Spyda 500 Quadcopter. [figura]. Recuperado de:
https://www.thingiverse.com/thing:160607/files
Gráfico 34. Wood, Steve. (2013). Spyda 500 Quadcopter. [figura]. Recuperado de:
https://www.thingiverse.com/thing:160607/files
Gráfico 47. IvenSense. (2013). MPU-6000 and MPU-6050 Register Map and
Descriptions Revision 4.2. [figura]. Recuperado de: https://www.invensense.com/wp-
content/uploads/2015/02/MPU-6000-Register-Map1.pdf
135
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 50. IvenSense. (2013). MPU-6000 and MPU-6050 Register Map and
Descriptions Revision 4.2. [figura]. Recuperado de: https://www.invensense.com/wp-
content/uploads/2015/02/MPU-6000-Register-Map1.pdf
Gráfico 60. Durán Rocha, Andrés. (2015). Bluetooth HC-06 y HC-05 Android Arduino.
[figura]. Recuperado de: https://hetpro-store.com/TUTORIALES/bluetooth-hc-06-
app-arduino/
Gráfico 65. Pardos, Carlos. (2013). Controlador PID. [figura]. Recuperado de:
https://www.picuino.com/es/arduprog/control-pid.html
136
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 91. IvenSense. (2013). MPU-6000 and MPU-6050 Register Map and
Descriptions Revision 4.2. [figura]. Recuperado de:
https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-
Map1.pdf
Gráfico 92. IvenSense. (2013). MPU-6000 and MPU-6050 Register Map and
Descriptions Revision 4.2. [figura]. Recuperado de:
137
Diseño e implementación de un Drone
y un dispositivo Android
https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-
Map1.pdf
Gráfico 93. IvenSense. (2013). MPU-6000 and MPU-6050 Register Map and
Descriptions Revision 4.2. [figura]. Recuperado de:
https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-
Map1.pdf
Gráfico 112. Llamas, Luis. (2017). Filtro paso bajo y paso alto exponencial (EMA) en
Arduino. [figura]. Recuperado de: https://www.luisllamas.es/arduino-paso-bajo-
exponencial/
138
Diseño e implementación de un Drone
y un dispositivo Android
Gráfico 113. IvenSense. (2013). MPU-6000 and MPU-6050 Register Map and
Descriptions Revision 4.2. [figura]. Recuperado de:
https://www.invensense.com/wp-content/uploads/2015/02/MPU-6000-Register-
Map1.pdf
139
Diseño e implementación de un Drone
y un dispositivo Android
Tabla 2. Descubre Arduino (equipo). (2019). Arduino UNO, partes, componentes, para
qué sirve y donde comprar. [tabla]. Recuperado de:
https://descubrearduino.com/arduino-uno/
Tabla 4. Heptro-store (tienda online). (s/f). Motor Brushless A2212/13T 1000 KV.
[tabla]. Recuperado de: https://hetpro-store.com/motor-brushless-a2212-13t-1000-
kv/
Tabla 5. Amazon (tienda online). (2018). Ulable Little Bee Mini 20 A 2 – 4S LiPo batería
OPTO PRO ESC sin escobillas para QAV250. [tabla]. Recuperado de:
https://www.amazon.es/Ulable-Little-Bee-Mini-escobillas/dp/B07CKST3PP
140
Diseño e implementación de un Drone
y un dispositivo Android
Tabla 6. HP Modelismo. (2019). Gens Ace Batería Lipo 25C 2200 mAh 3S1P 11.1 V.
[tabla]. Recuperado de: https://www.hpmodelismo.com/pt/lipo/12150-bateria-lipo-
gens-ace-25c-2200mah-3s1p-111vphantom.html
Tabla 13. Pardos, Carlos. (2020). Método de Ziegler-Nichols. [tabla]. Recuperado de:
https://www.picuino.com/es/arduprog/control-ziegler-nichols.html
Tabla 14. Fuente propia.
7 Anexos
141
Diseño e implementación de un Drone
y un dispositivo Android
142
Diseño e implementación de un Drone
y un dispositivo Android
void setup()
{
Wire.begin(); // La comunicación I2C comienza..
inicializaciones(MPU_address, 0x6B, 0x00); // Despertamos al módulo
MPU (sleepmode)
inicializaciones(MPU_address, 0x1B, 0x10); // Configuración escala
giroscopio a +/- 1000 º/s
inicializaciones(MPU_address, 0x1C, 0x10); // Configuración escala
acelerómetro a +/- 8g
Serial.begin(9600);
calibracionMPU_gyr(); // Calibramos el MPU para corregir los offsets
del giroscopio
calibracionMPU_acc(); // Calibramos el MPU para corregir los offsets
del acelerómetro
while(motores_off == true)
{
leer_app();
}
inicializar_motores();
143
Diseño e implementación de un Drone
y un dispositivo Android
void loop()
{
///// * LECTURA DE DATOS MPU-6050 Y APLICACIÓN DEL FILTRO * /////
// Comenzamos a contar el tiempo para aplicarlo en el filtro
complementario
previous_time = time; // El tiempo anterior la almacenamos antes del
tiempo actual
time = millis();
dt = (time - previous_time) / 1000; // Conversión de milisegundos a
segundos
144
Diseño e implementación de un Drone
y un dispositivo Android
Función donde asociamos los pines a los 2 motores. Además, también enviamos
pulsos de 1000 microsegundos con tal de entrar al modo de inicialización. De esta manera,
comenzarán a girar en la función loop.
void inicializar_motores()
{
145
Diseño e implementación de un Drone
y un dispositivo Android
Función donde tomamos 3000 lecturas de las velocidades angulares en cada uno de
sus ejes, para luego realizar el promedio. El promedio es el offset. Haciendo la resta entre
los valores medidos y el offset, obtendremos mediciones más precisas.
void calibracionMPU_gyr()
{
int i;
for(i=0; i<3000; i++)
{
leerMPU(MPU_address, gx, gy, gz); // Leemos los
valores del giroscopio
GyroPitch_cal = GyroPitch_cal + gx; // Almacenamos la
lectura SIN REFINAR del giroscopio en el eje X (PITCH)
GyroRoll_cal = GyroRoll_cal + gy; // Almacenamos la
lectura SIN REFINAR del giroscopio en el eje Y (ROLL)
GyroYaw_cal = GyroYaw_cal + gz; //
Almacenamos la lectura SIN REFINAR del giroscopio en el eje Z (YAW)
delayMicroseconds(1000);
}
GyroPitch_cal = GyroPitch_cal/3000;
GyroRoll_cal = GyroRoll_cal/3000;
GyroYaw_cal = GyroYaw_cal/3000;
}
Función donde tomamos 3000 lecturas de las aceleraciones en cada uno de sus ejes,
para luego realizar el promedio. El promedio es el offset. Haciendo la resta entre los valores
medidos y el offset, obtendremos mediciones más precisas.
void calibracionMPU_acc()
{
int i;
for(i=0; i<3000; i++)
{
leerMPU(MPU_address, ax, ay, az); // Leemos los
valores del acelerómetro
146
Diseño e implementación de un Drone
y un dispositivo Android
Función donde leeremos los valores sin refinar, tanto del acelerómetro como del
giroscopio.
void leerMPU(const int address_firstRegister, int16_t &vx, int16_t &vy,
int16_t &vz)
{
Wire.beginTransmission(MPU_address);
Wire.write(address_firstRegister); // Pedimos la lectura del primer
registro ya sea del acelerómetro o del giroscopio (según sea el caso)
Wire.endTransmission(false); // Esto mantendrá la conexión
activa
Wire.requestFrom(MPU_address, 6, true); // Pedimos la lectura de 6
registros a partir de la dirección "address_firstRegister"
vx = Wire.read()<<8 | Wire.read(); // Se leen los registros del byte
alto y bajo y se almacena el valor sin refinar
vy = Wire.read()<<8 | Wire.read();
vz = Wire.read()<<8 | Wire.read();
}
void calculate_angle()
{
ax -= AccPitch_cal;
ay -= AccRoll_cal;
az -= AccYaw_cal;
147
Diseño e implementación de un Drone
y un dispositivo Android
Ac[0]= atan((ay/A_C)/sqrt(pow((ax/A_C),2) +
pow((az/A_C),2)))*RAD_G; // Ángulo de inclinación del ángulo X
Ac[1]= atan(-1*(ax/A_C)/sqrt(pow((ay/A_C),2) +
pow((az/A_C),2)))*RAD_G; // Ángulo de inclinación del ángulo Y
}
// Aplicamos el filtro
Final_angle[0] = 0.98 *(Final_angle[0] + Gc[0]*dt) + 0.02*Ac[0]; //
Cálculo del ángulo de rotación del ángulo X
Final_angle[1] = 0.98 *(Final_angle[1] + Gc[1]*dt) + 0.02*Ac[1]; //
Cálculo del ángulo de rotación del ángulo Y
angleX = Final_angle[0];
angleY = Final_angle[1];
}
Mediante esta función, nos aseguramos que la variable a tratar (value) no supere los
límites mínimos o máximos.
void mapear_valores(float &value, int valor_min, int valor_max)
{
if(value < valor_min)
{
value = valor_min;
}
if(value > valor_max)
148
Diseño e implementación de un Drone
y un dispositivo Android
{
value = valor_max;
}
}
149
Diseño e implementación de un Drone
y un dispositivo Android
150
Diseño e implementación de un Drone
y un dispositivo Android
void actuador()
{
/* Los valores PID oscilará entre -1000 y 1000, ya que cuando el
mínimo valor del PWM
se encuentre en 1000us, el máximo valor que se le puede añadir es
+1000us, y debemos
cerciorarnos de no sobrepasarnos de este valor. Por otra parte,
cuando estemos en el
máximo valor del PWM, el cual es 2000us, el máximo valor que
podemos substraer es de
-1000us, y así alcanzar el punto mínimo de 1000us. Debemos
asegurarnos de no sobre-
pasarnos de estos rangos */
151
Diseño e implementación de un Drone
y un dispositivo Android
// motor izquierdo
mapear_valores(pwm_left, 1000, 1800);
// motor derecho
mapear_valores(pwm_right, 1000, 1800);
left_motor.writeMicroseconds(pwm_left);
right_motor.writeMicroseconds(pwm_right);
152
Diseño e implementación de un Drone
y un dispositivo Android
153
Diseño e implementación de un Drone
y un dispositivo Android
154
Diseño e implementación de un Drone
y un dispositivo Android
/* Lazo aceleración */
float Roll_Kpacc=1.7; // Estos valores debemos irlos cambiando
hasta conseguir el comportamiento deseado
float Roll_Kiacc=0.04; // Estos valores debemos irlos cambiando
hasta conseguir el comportamiento deseado
float Roll_Kdacc=4; // Estos valores debemos irlos cambiando
hasta conseguir el comportamiento deseado
155
Diseño e implementación de un Drone
y un dispositivo Android
digitalWrite(12, HIGH);
delay(2000);
digitalWrite(12, LOW); // Apagamos el led
156
Diseño e implementación de un Drone
y un dispositivo Android
{
leer_app();
}
157
Diseño e implementación de un Drone
y un dispositivo Android
// Aplicamos el filtro
filtro_complementario();
Función que envía a través del serial plotter la leyenda de las variables dependiendo
de la opción escogida por el usuario.
void escribir_leyenda(int opcion, bool opc_plotter)
{
if(opcion >= 4 && opcion <= 8) turn_offKi();
if(opc_plotter == true)
158
Diseño e implementación de un Drone
y un dispositivo Android
{
switch(opcion)
{
case 1:
Serial.println("anglePitch angleRoll");
break;
case 2:
Serial.println("Pitch_pid Roll_pid Yaw_pid");
break;
case 3:
Serial.println("Pitch_readSpeedw Roll_readSpeedw
Yaw_readSpeedw");
break;
case 4:
Serial.println("l_f r_f l_b r_b");
break;
case 5:
Serial.println("lf");
break;
case 6:
Serial.println("rf");
break;
case 7:
Serial.println("lb");
break;
case 8:
Serial.println("rb");
break;
case 9:
Serial.println("pitch_w filtered_value");
break;
case 10:
Serial.println("roll_w filtered_value");
break;
case 11:
Serial.println("yaw_w filtered_value");
159
Diseño e implementación de un Drone
y un dispositivo Android
break;
case 12:
Serial.println("anglePitch");
break;
case 13:
Serial.println("angleRoll");
break;
case 14:
Serial.println("Pitch_readSpeedw");
break;
case 15:
Serial.println("Roll_readSpeedw");
break;
case 16:
Serial.println("Yaw_readSpeedw");
break;
case 17:
Serial.println("Pitch_desiredSpeedw Pitch_readSpeedw");
break;
case 18:
Serial.println("Roll_desiredSpeedw Roll_readSpeedw");
break;
}
}
}
Función que nos permitirá inicializar los motores con la velocidad mínima, y nos
permite asociar los pines correspondientes.
void inicializar_motores()
{
pinMode(3, OUTPUT); // motor_leftfrontside
pinMode(5, OUTPUT); // motor_rightfrontside
pinMode(6, OUTPUT); // motor_leftbackside
pinMode(9, OUTPUT); // motor_rightbackside
160
Diseño e implementación de un Drone
y un dispositivo Android
turn_offallmotors();
delay(4000);
Función para contar el tiempo transcurrido entre cada iteración. Este tiempo será
utilizado para el cálculo del filtro complementario y durante el control derivativo.
void contar_tiempo()
{
previous_time = time; // El tiempo anterior la almacenamos antes del
tiempo actual
time = millis();
dt = (time - previous_time) / 1000; // Conversión de milisegundos a
segundos
}
Función para calcular el ángulo de inclinación con los datos recopilados del
acelerómetro. Hacemos uso de la fórmula en el caso de que el módulo esté en un plano 3D.
161
Diseño e implementación de un Drone
y un dispositivo Android
void calculate_angle()
{
ax -= AccPitch_cal;
ay -= AccRoll_cal;
az -= AccYaw_cal;
az = az + A_C;
valuepitch = Pitch_readSpeedw;
valueroll = Roll_readSpeedw;
valueyaw = Yaw_readSpeedw;
last_pitchw = Pitch_readSpeedw;
last_rollw = Roll_readSpeedw;
last_yaw = Yaw_readSpeedw;
}
162
Diseño e implementación de un Drone
y un dispositivo Android
163
Diseño e implementación de un Drone
y un dispositivo Android
}
if(dato_enviado == '4') // Girando el drone en el sentido opuesto al
de las agujas del reloj Yaw (+)
{
Yaw_desiredSpeedw = 30; // Fijamos a una
velocidad de 2 º/s
actualizar_consignas(0.0, 0.0, 30); // Actualizamos las
consignas de los 3 ejes (el drone sólo girará en el eje Yaw)
activar_pidangle = false;
}
if(dato_enviado == '5') // Girando hacia la izquierda: Roll (-)
{
Roll_desiredSpeedw = -30; // Fijamos a una
velocidad de -2 º/s
actualizar_consignas(0.0, -30, 0.0); // Actualizamos las
consignas de los 3 ejes (el drone sólo girará en el eje Roll)
activar_pidangle = false;
}
if(dato_enviado == '6') // Posicionamos el drone a 0º (ángulo
pitch y roll a 0º)
{
actualizar_consignas(0.0, 0.0, 0.0); // Actualizamos las
consignas de los 3 ejes (el drone no girará)
activar_pidangle = true;
}
if(dato_enviado == '7') // Girando hacia la derecha: Roll (+)
{
Roll_desiredSpeedw = 30; // Fijamos a una velocidad de
2 º/s
actualizar_consignas(0.0, 30, 0.0); // Actualizamos las consignas
de los 3 ejes (el drone sólo girará en el eje Roll)
activar_pidangle = false;
}
if(dato_enviado == '8') // Desplazandonos hacia adelante: Pitch (-)
{
Pitch_desiredSpeedw = -45; // Fijamos a una velocidad
de -2 º/
actualizar_consignas(-45, 0.0, 0.0); // Actualizamos las consignas
de los 3 ejes (el drone sólo girará en el eje Pitch)
activar_pidangle = false;
164
Diseño e implementación de un Drone
y un dispositivo Android
}
if(dato_enviado == '9') // Disminuimos el throttle (altura del
drone)
{
throttle = throttle - 50.0;
mapear_valores(throttle, 1030, 1700); // Nos aseguramos que la
altura del drone no exceda los valores máximos ni mínimos
actualizar_consignas(0.0, 0.0, 0.0); // Actualizamos las
consignas de los 3 ejes (el drone no girará)
activar_pidangle = false;
}
if(dato_enviado == 'a') // Desplazandonos hacia atrás: Pitch (+)
{
Pitch_desiredSpeedw = 45; // Fijamos a una velocidad de
2 º/s
actualizar_consignas(45, 0.0, 0.0); // Actualizamos las consignas
de los 3 ejes (el drone sólo girará en el eje Pitch)
activar_pidangle = false;
}
if(dato_enviado == 'v') // Soltamos el stick y la consigna de
velocidad vuelve a ser 0
{
if(esc_calibrado == true) actualizar_consignas(0.0, 0.0, 0.0); //
Reseteamos los valores de las consignas
esc_calibrado = true;
}
if(dato_enviado == 't') // Empezamos el programa
{
bateria_conectada = true;
activar_pidangle = false;
}
if(dato_enviado == 'u') // Apagamos los motores
{
left_f = false;
right_f = false;
left_b = false;
right_b = false;
165
Diseño e implementación de un Drone
y un dispositivo Android
Función que actualiza los valores anteriores de las consignas del Pitch, Yaw y Roll
(GYRO velocidad).
void actualizar_consignas(float last_pich, float last_roll, float
last_yaw)
{
lastPitch_desiredSpeedw = last_pich;
lastRoll_desiredSpeedw = last_roll;
lastYaw_desiredSpeedw = last_yaw;
}
166
Diseño e implementación de un Drone
y un dispositivo Android
// PITCH GYR //
// Función controlador PID en el eje Pitch
float PID_PitchGyr()
{
float salidaPID;
Pitch_errorw = Pitch_desiredSpeedw - Pitch_readSpeedw; // Calculamos el
error del sistema
167
Diseño e implementación de un Drone
y un dispositivo Android
168
Diseño e implementación de un Drone
y un dispositivo Android
169
Diseño e implementación de un Drone
y un dispositivo Android
void PID_ROLLangle()
{
Roll_erroracc = Roll_desiredAngle - Roll_readAngleacc; //
Calculamos el error del sistema
void actuador()
{
dt = dt*1000; // Conversión de segundos a milisegundos
170
Diseño e implementación de un Drone
y un dispositivo Android
if(activar_pidangle == true)
{
/* Llamamos a las funciones para calcular el grado de
inclinación de los ejes ROLL y PITCH */
PID_PITCHangle();
PID_ROLLangle();
171
Diseño e implementación de un Drone
y un dispositivo Android
172
Diseño e implementación de un Drone
y un dispositivo Android
Roll_error_antw = Roll_errorw;
Pitch_error_antw = Pitch_errorw;
Yaw_error_antw = Yaw_errorw;
Función que procede a crear la señal PWM para los 4 motores en función de los
valores PID calculados.
void crear_pwm(float l_f, float r_f, float l_b, float r_b)
{
/* Comenzamos con un pulso HIGH */
turn_onallmotors();
izq_f = true;
der_f = true;
izq_b = true;
der_b = true;
antes = millis();
/* Actualización de las consignas a enviar a los motores */
173
Diseño e implementación de un Drone
y un dispositivo Android
174
Diseño e implementación de un Drone
y un dispositivo Android
Función para visualizar las variables que deseemos. Para ello, el usuario deberá
inicializar el valor de la variable “visualizar” en alguno de estos valores, según la variable
que desee observar.
0- Nada.
1- Visualizar los ángulos de inclinación pitch y roll.
2- Visualizar las salidas PID del lazo de velocidad de los 3 ejes.
3- Visualizar las velocidades angulares gyro del roll, pitch y yaw.
4- Visualizar las velocidades PWM a enviar a los 4 motores.
5- Visualizar únicamente la velocidad del motor izquierdo frontal.
6- Visualizar únicamente la velocidad del motor derecho frontal.
7- Visualizar únicamente la velocidad del motor izquierdo trasero.
8- Visualizar únicamente la velocidad del motor derecho trasero.
9- Comparar gráficamente la velocidad angular filtrada del eje pitch con la medición
sin filtrar.
10- Comparar gráficamente la velocidad angular filtrada del eje roll con la medición sin
filtrar.
11- Comparar gráficamente la velocidad angular filtrada del eje yaw con la medición sin
filtrar.
12- Visualizar únicamente el ángulo pitch.
13- Visualizar únicamente el ángulo roll.
175
Diseño e implementación de un Drone
y un dispositivo Android
switch(visualizar)
{
case 1:
visualizar_angles(num_conteo, 3);
break;
//-------------------------------------------------------------------
-------- //
case 2:
envio_datos(num_conteo, 5, Pitch_PIDw, Roll_PIDw, Yaw_PIDw);
break;
//-------------------------------------------------------------------
-------- //
case 3:
envio_datos(num_conteo, 5, Pitch_readSpeedw, Roll_readSpeedw,
Yaw_readSpeedw);
break;
//-------------------------------------------------------------------
-------- //
case 4:
visualizar_pwm(num_conteo, 7);
break;
//-------------------------------------------------------------------
-------- //
case 5:
Serial.println(pwm_leftfrontside);
break;
//-------------------------------------------------------------------
-------- //
case 6:
176
Diseño e implementación de un Drone
y un dispositivo Android
Serial.println(pwm_rightfrontside);
break;
//-------------------------------------------------------------------
-------- //
case 7:
Serial.println(pwm_leftbackside);
break;
//-------------------------------------------------------------------
-------- //
case 8:
Serial.println(pwm_rightbackside);
break;
//-------------------------------------------------------------------
-------- //
case 9:
visualizar_valoresfiltrados(num_conteo, 3, valuepitch,
Pitch_readSpeedw);
break;
//-------------------------------------------------------------------
-------- //
case 10:
visualizar_valoresfiltrados(num_conteo, 3, valueroll,
Roll_readSpeedw);
break;
//-------------------------------------------------------------------
-------- //
case 11:
visualizar_valoresfiltrados(num_conteo, 3, valueyaw,
Yaw_readSpeedw);
break;
//-------------------------------------------------------------------
-------- //
case 12:
Serial.println(Pitch_readAngleacc);
break;
//-------------------------------------------------------------------
-------- //
case 13:
Serial.println(Roll_readAngleacc);
177
Diseño e implementación de un Drone
y un dispositivo Android
break;
//-------------------------------------------------------------------
-------- //
case 14:
Serial.println(Pitch_readSpeedw);
break;
//-------------------------------------------------------------------
-------- //
case 15:
Serial.println(Roll_readSpeedw);
break;
//-------------------------------------------------------------------
-------- //
case 16:
Serial.println(Yaw_readSpeedw);
break;
//-------------------------------------------------------------------
-------- //
case 17:
comparar_valores(num_conteo, 3, Pitch_desiredSpeedw,
Pitch_readSpeedw);
break;
//-------------------------------------------------------------------
-------- //
case 18:
comparar_valores(num_conteo, 3, Roll_desiredSpeedw,
Roll_readSpeedw);
break;
}
}
178
Diseño e implementación de un Drone
y un dispositivo Android
i++;
if(i == maximo) i=0;
}
// Función que envía al puerto serie las velocidades de los 4 motores
void visualizar_pwm(int &j, int maximo)
{
if(j == 0) Serial.print(pwm_leftfrontside);
if(j == 1) Serial.print("\t");
if(j == 2) Serial.print(pwm_rightfrontside);
if(j == 3) Serial.print("\t");
if(j == 4) Serial.print(pwm_leftbackside);
if(j == 5) Serial.print("\t");
if(j == 6) Serial.println(pwm_rightbackside);
j++;
if(j == maximo) j=0;
}
179
Diseño e implementación de un Drone
y un dispositivo Android
if(w == 2) Serial.println(filteredvalue);
w++;
if(w == maximo) w=0;
}
// Función que envía al puerto serie las velocidades angulares filtradas
y las compara con las no filtradas
void comparar_valores(int &x, int maximo, float referencia, float
posicion)
{
if(x == 0) Serial.print(referencia);
if(x == 1) Serial.print("\t");
if(x == 2) Serial.println(posicion);
x++;
if(x == maximo) x=0;
}
Función que reinicializa las constantes integrales a 0, para una mejor visualización
de las señales PWM.
void turn_offKi()
{
Roll_Kiw=0;
Pitch_Kiw=0;
Yaw_Kiw=0;
Roll_Kiacc=0;
Pitch_Kiacc=0;
}
180