scieee AI-readable full text Open interactive document viewer

Diseño e implementación de un planeador VTOL (Vertical Take-Off and Landing) autónomo para distribución de paquetería

González González, Oscar

Abstract

Departamento de Electricidad y Electrónica

Full text

Diseño e implementación de un planeador VTOL (Vertical Take-Off and Landing) autónomo para distribución de paquetería Universidad de Valladolid Escuela Técnica Superior de Ingenieros de Telecomunicación Máster en Ingeniería de Telecomunicación Desarrollado por: Oscar González González Bajo la tutela de: Martín Jaraíz Maldonado 15 de junio de 2024 Universidad de Valladolid 1 RESUMEN. El presente documento recoge de forma práctica el enfoque, los procesos y la línea de desarrollo empleada frente a la propuesta de implementación de un VTOL, enfocado, como fin último, en el reparto de paquetería, presentando una configuración distinta en la estructura y gestión de la movilidad del dispositivo. Para ello, se analizarán las necesidades principales de la aeronave, estableciendo y discutiendo los elementos hardware, exponiendo los algoritmos empleados para la obtención de datos y procesamiento del software y presentando distintas técnicas para la creación del diseño y la realización de pruebas reales. Se expondrán los análisis y las validaciones prácticas necesarias para la implementación final de un prototipo viable y se enfocará su construcción de forma escalable para su utilización en el reparto de paquetería. ABSTRACT. This document presents in a practical way the approach, processes, and development line used for the proposed implementation of a VTOL focused, as an ultimate objective, on the delivery of parcels, employing a different configuration in the structure and management of the mobility of the device. The main needs of the aircraft will be analyzed, establishing and discussing the hardware elements, exposing the algorithms used for data collection and software processing, and presenting different techniques for developing design patterns and the realization of real tests. The practical analysis and validations necessary for the final implementation of a viable prototype will be presented, focusing its construction in a scalable way for its use in parcel delivery. PALABRAS CLAVE. VTOL, dispositivo, paquetes, electrónica, desarrollo. KEY WORDS. VTOL, device, parcels, electronics, develop. Universidad de Valladolid 2 ÍNDICE RESUMEN. ................................................................................................................................................. 1 ABSTRACT. ............................................................................................................................................... 1 PALABRAS CLAVE. ................................................................................................................................ 1 KEY WORDS. ............................................................................................................................................ 1 ÍNDICE ....................................................................................................................................................... 2 1. INTRODUCCIÓN ............................................................................................................................ 6 1.1 Contextualización histórica................................................................................................................ 6 1.2 Objetivos ............................................................................................................................................ 8 1.3 Condiciones de partida .................................................................................................................... 10 2. ESTUDIO GENERAL DEL SISTEMA ........................................................................................ 12 2.1 Usuario ............................................................................................................................................ 13 2.2 Control ............................................................................................................................................. 13 2.3 Microcontrolador ............................................................................................................................. 14 2.4 Actuadores ....................................................................................................................................... 14 2.5 Alimentación ................................................................................................................................... 15 2.6 Sensores ........................................................................................................................................... 15 2.7 Otras consideraciones ...................................................................................................................... 16 3. HARDWARE .................................................................................................................................. 17 3.1 Perspectiva de funcionamiento ........................................................................................................ 17 3.2 Componentes ................................................................................................................................... 18 3.2.1 Motores .................................................................................................................................... 19 3.2.1.1 Estudio teórico: ............................................................................................................ 19 3.2.1.2 Comparación técnica: .................................................................................................. 24 3.2.1.3 Implementación práctica ............................................................................................. 28 3.2.2 ESCs ........................................................................................................................................ 30 3.2.2.1 Estudio teórico ................................................................................................................. 30 3.2.2.2 Implementación práctica .................................................................................................. 35 3.2.3 Servomotores ........................................................................................................................... 36 3.2.3.1 Estudio teórico ................................................................................................................. 37 3.2.3.2 Implementación práctica .................................................................................................. 44 3.2.4 Acelerómetro – Giróscopo ....................................................................................................... 44 3.2.4.1 Estudio teórico ................................................................................................................. 45 3.2.4.2 Implementación práctica .................................................................................................. 49 3.2.5 Sensor ultrasonidos .................................................................................................................. 49 Universidad de Valladolid 3 3.2.5.1 Estudio teórico ................................................................................................................. 50 3.2.5.2 Implementación práctica .................................................................................................. 51 3.2.6 Sensor de presión ..................................................................................................................... 52 3.2.6.1 Estudio teórico ................................................................................................................. 52 3.2.6.2 Implementación práctica .................................................................................................. 54 3.2.7 Fotosensor ................................................................................................................................ 54 3.2.7.1 Estudio teórico ................................................................................................................. 55 3.2.7.2 Implementación práctica .................................................................................................. 59 3.2.8 GPS .......................................................................................................................................... 60 3.2.8.1 Estudio teórico ................................................................................................................. 60 3.2.8.2 Implementación práctica .................................................................................................. 63 3.2.9 Microcontrolador ..................................................................................................................... 64 3.2.9.1 Estudio teórico ................................................................................................................. 64 3.2.9.2 Implementación práctica .................................................................................................. 65 3.2.10 Alimentación .......................................................................................................................... 66 3.2.10.1 Estudio teórico ............................................................................................................... 66 3.2.10.1.1 Proceso de carga ..................................................................................................... 67 3.2.10.2 Implementación práctica ................................................................................................ 68 3.3 Análisis de potencia ......................................................................................................................... 69 3.4 Desarrollo electrónico esquemático ................................................................................................. 71 4. SOFTWARE.................................................................................................................................... 76 4.1 Instalaciones iniciales y compatibilidad .......................................................................................... 76 4. 2 Obtención de datos y configuraciones ............................................................................................ 77 4.2.1 Bibliotecas empleadas .............................................................................................................. 77 4.2.2 Interacción manual con sensores .............................................................................................. 78 4.3 Algoritmos y cálculos teóricos ........................................................................................................ 82 4.3.1 Obtención de ángulos ............................................................................................................... 82 4.3.2 PID ........................................................................................................................................... 84 4.3.2.1 Rasgos específicos del yaw .............................................................................................. 86 4.3.2.2 PID de altitud ................................................................................................................... 87 4.3.3 Otras pruebas ........................................................................................................................... 87 4.3.3.1 Pruebas con GNSS ........................................................................................................... 88 4.3.3.2 Pruebas con fotosensor ..................................................................................................... 88 4.3.3.3 Posicionamiento con MPU6050 ....................................................................................... 88 4.4 Explicación genérica del programa .................................................................................................. 90 4.1 Inicio (setup) ............................................................................................................................... 90 4.2 Ejecución principal (loop) ........................................................................................................... 90 4.5 Recopilación remota de datos .......................................................................................................... 92 5. DISEÑO ........................................................................................................................................... 94 Universidad de Valladolid 4 5.1 Estructura y materiales ................................................................................................................ 94 5.2 Diseño de piezas ......................................................................................................................... 95 6. COSTES .............................................................................................................................................. 101 6.1 Costes de la prueba de concepto y prototipado ......................................................................... 101 6.2 Costes temporales ..................................................................................................................... 102 7. IMPLEMENTACIÓN FINAL .......................................................................................................... 105 7.1 Observaciones ............................................................................. ¡Error! Marcador no definido. ANEXO ................................................................................................................................................... 107 A.1 Código principal del programa ..................................................................................................... 107 A.1.1 Código VTOL ....................................................................................................................... 107 A.1.2 Código WebServer REST API .............................................................................................. 132 A.1.3 Código WebSClient REST API ............................................................................................ 134 A.2 Pruebas de concepto...................................................................................................................... 136 A.2.1 Posicionamiento MPU6050 .................................................................................................. 136 A.2.2 Posicionamiento ADNS3080 ................................................................................................ 138 A.2.3 Posicionamiento GNSS ......................................................................................................... 139 A.2.3.1 NeoGPS ......................................................................................................................... 139 A.2.3.2 TinyGPS ........................................................................................................................ 146 A.3 Enlaces de estimación de costes ................................................................................................... 148 Microcontrolador ............................................................................................................................ 148 Motores BLDC ............................................................................................................................... 148 ESC ................................................................................................................................................. 148 Servomotores .................................................................................................................................. 149 IMU................................................................................................................................................. 149 Sensor de ultrasonidos .................................................................................................................... 149 Sensor de presión ............................................................................................................................ 150 Fotosensor ....................................................................................................................................... 150 GNSS .............................................................................................................................................. 150 Baterías ........................................................................................................................................... 150 Cargador de baterías ....................................................................................................................... 150 Varillas ............................................................................................................................................ 151 PLA de impresión ........................................................................................................................... 151 Protoboard ....................................................................................................................................... 151 Cables de prototipado ..................................................................................................................... 152 Tornillos .......................................................................................................................................... 152 Mando de control ............................................................................................................................ 152 SIGLAS ................................................................................................................................................... 153 Universidad de Valladolid 5 Referencias .............................................................................................................................................. 155 Universidad de Valladolid 6 1. INTRODUCCIÓN 1.1 Contextualización histórica A lo largo de los años, el ser humano ha tratado de crear todo tipo de vehículos y dispositivos orientados al desplazamiento. Uno de los hitos más notables, ha sido la implementación de vehículos que pudieran desplazarse por el medio aéreo. Las primeras ideas que podrían relacionarse de forma directa con la aeronáutica, y más concretamente con los VTOL (Vertical Take-Off and Landing), surgen entorno al siglo quince, de la mano de Leonardo da Vinci, que expuso los primeros bocetos de su “tornillo helicoidal”, donde se mostraba un primer intento de un VTOL que, girando sobre sí mismo actuaría como un tornillo, desplazando el aire hacia abajo, consiguiendo así dicho despegue vertical. Años más tarde, se ha verificado cómo ese tipo de “hélice” era viable [1]. Posteriormente, otro de los avances más transcendentes en materia de VTOL surge en 1783 con la invención del globo por parte de los hermanos Montgolfier y Charles y Robert [2]. Con la utilización de los primeros globos, comenzó a surgir el término UAV (Unmanned Aerial Vehicle), cuyas percepciones iniciales se apreciaron en el entorno bélico, cuando en 1849 la artillería austriaca inventó el globo bomba con la finalidad de atacar Venecia [3], fue utilizado, a pesar de su fracaso. La aparición de los primeros globos incentivó el crecimiento de los dirigibles, destacando el primer viaje de ida y vuelta, aterrizando en el mismo lugar de despegue con La France, un dirigible alimentado con un motor eléctrico a batería, encargado de mover las hélices, el primer vuelo de este dirigible se produjo el 9 de agosto de 1884 [4], la creación de estos dirigibles terminaría culminando con la invención del Zeppelin a finales del siglo diecinueve. En 1898 comenzaron a forjarse los primeros sistemas de radiocontrol destacando la demostración pública de Nikola Tesla en Madison Square Garden, donde controlaba un pequeño barco mediante enlaces de radio [3], lo cual impulsó las pruebas de vehículos no tripulados. En 1903 se produce el primer vuelo tripulado en un avión a motor, por parte de los hermanos Wright, tratándose de un pequeño vuelo de pruebas de unos pocos segundos. Para finales de 1905, su tercera versión de avión motorizado tripulado consiguió un vuelo Universidad de Valladolid 7 de 39 minutos, cubriendo 39,2 kilómetros de distancia [5]. Este último avance dio paso a desarrollos respecto a los aviones de una y dos plazas, que recibieron importantes mejoras como consecuencia de utilizarse en el ámbito militar durante la primera y la segunda guerra mundial. Esta nueva invención, junto con las innovaciones militares, propiciaron que en 1935 se desarrollase el primer dron moderno a manos de las fuerzas aéreas británicas, bautizado como “Queen Bee”, creado con la finalidad de realizar pruebas de control de vuelo baratas para pilotos en formación [3][6], se trataba de un blanco aéreo no tripulado, radio control. Este último modelo de vehículo aéreo comienza a encajar en la definición actual del término dron, definido por la RAE (Real Academia Española) como “Aeronave no tripulada”[7] y como “Avión o barco sin tripulación guiado por control remoto o computadoras a bordo” en otros diccionarios angloparlantes [8]. En marzo de 1935 se hace efectiva la primera patente de lo que hoy día conocemos como helicóptero, definido en la patente como “Avión de elevación directa”, conocido en la actualidad como un tipo de VTOL [9]. En septiembre de 1939 se realizó la primera prueba práctica del artefacto en Stratford, Connecticut [10]. Esta patente dio paso al diseño posterior de diversos tipos de VTOL, tanto en el ámbito empresarial como militar. Como consecuencia de los avances en el desarrollo de transistores, comenzaron a surgir aviones de radiocontrol en 1960, destinados al uso recreativo [6]. En los años posteriores se siguieron sucediendo avances militares, pero fue en 2006 cuando dieron comienzo los primeros permisos legales para la utilización de drones en Estados Unidos en el ámbito civil [11][6]. A partir de esta fecha se dio paso a un auge elevado de drones radiocontrol y UAV orientados al ocio, así como destinados a labores de reconocimiento y rescate por parte de cuerpos estatales sanitarios, de bomberos y forestales. En 2009 comienzan a hacerse notar los primeros proyectos exitosos de vehículos VTOL para el transporte de personas, de la mano de la startup china Terrafugia [12], afianzándose así su término en contraposición a la concepción popular de dron como una estructura formada por cuatro motores, aportando una definición más genérica de dispositivo aéreo. En torno a 2013, algunas de las compañías más importantes de reparto, paquetería y tecnológicas, tales como FedEx, UPS, Amazon, Google o Uber comenzaron a interesarse por las ventajas de emplear drones, invirtiendo en investigación y desarrollo [3][13]. Universidad de Valladolid 8 A lo largo de los siguientes años, estas inversiones en paquetería comenzaron a ponerse en práctica por parte de algunas empresas, obteniendo los permisos pertinentes [14]. También se observaron ejemplos de utilización en distribución durante la pandemia COVID-19, con la finalidad de repartir vacunas [15]. A pesar de que han surgido ocasiones puntuales de utilización, es a partir de 2022 cuando algunas de estas tecnologías de distribución de paquetería comenzarán a ponerse en práctica en grandes áreas, como es el caso de los anuncios de la empresa Amazon, que en junio de 2022 notificó que comenzaría a enviar paquetes mediante drones en Lockeford, California [16]. Teniendo en cuenta el contexto en el que nos encontramos actualmente, y habiendo aportado una pequeña perspectiva histórica, se observa como muchas empresas tratan de desarrollar todo tipo de drones y dispositivos VTOL. Es este auge el que impulsa la iniciativa de implementación. En este documento se tratará de llevar a cabo un proceso de creación de prototipado, documentación y comprensión de los principios técnicos necesarios para la implementación. Para ello se buscarán nuevas configuraciones de dispositivos VTOL, con la finalidad de afrontar el desarrollo desde cero de uno de estos equipos, de forma similar a cómo podría planificarse en alguna de las anteriormente citadas empresas, en el ámbito de investigación y pruebas. 1.2 Objetivos Este documento tiene como objetivo principal el desarrollo, implementación y estudio de la electrónica y el software que conforman los dispositivos de vuelo, en concreto los VTOL, orientados al área de distribución de paquetería. Para ello, se centrarán los esfuerzos en la creación física de un VTOL, cuyo desarrollo escalable permita desempeñar acciones asociadas a la recogida y entrega de paquetes de forma autónoma, al cual se le incorporarán múltiples características adicionales relacionadas con la eficiencia de cumplir su principal propósito. Las principales áreas bajo estudio que permitirán alcanzar el objetivo fijado se enumeran a continuación: Universidad de Valladolid 15 2.5 Alimentación Al tratarse de un dispositivo que ha de precisar con la característica de movilidad, la principal fuente de alimentación tendrá que ser portátil, en el caso que ocupa, se trabajará con una batería. Dicha batería deberá de estar en sintonía con los requisitos necesarios de funcionamiento en los actuadores que precisen de una mayor cantidad de potencia, tal y cómo se comentaba en la sección 2.4. Como consecuencia de la relativamente elevada potencia de algunos de los actuadores, la batería deberá poseer un voltaje de funcionamiento elevado, así como contar con una capacidad que permita realizar vuelos prolongados y finalmente disponer de la característica de aportar la suficiente potencia en un corto periodo de tiempo sin suponer un riesgo para la salud de esta. En lo relativo a las tensiones, se impone de manera contundente la necesidad de incorporar elementos de adaptación de voltajes, permitiendo tanto que los actuadores funcionen con corriente alterna (motores de vuelo) como que el microcontrolador pueda alimentarse de manera correcta para después aportar la energía necesaria a los distintos sensores incorporados. 2.6 Sensores Los sensores serán los encargados de comunicar al microcontrolador los datos relativos al medio, permitiendo equilibrar el prototipo, efectuar un vuelo suave y geolocalizarse. Dichos sensores, por tanto, poseerán conexiones directas con el microcontrolador que permitan llevar a buen puerto su principal cometido. Como se explicó en la sección relacionada con la alimentación, los sensores estarán alimentados por el microcontrolador a través de sus puertos de alimentación en la medida de lo posible. De este modo no será necesario incorporar dispositivos adicionales que adapten los valores de tensión y corriente desde la fuente de alimentación a los distintos tipos de sensores. Esta práctica resulta viable debido a que, en la mayoría de los casos, los valores de alimentación de los sensores suelen estar medianamente “estandarizados” comprendiendo voltajes de funcionamiento normalmente bajos. La incorporación de sensores dependerá de la existencia de bibliotecas compatibles, facilitando un desarrollo ágil a nivel de software, que permita introducir de forma modular Universidad de Valladolid 16 nuevas mejoras, sin descartar la utilización de escritura directa en binario a los registros para obtener una mayor adaptación. Por último, cabe destacar que el microcontrolador deberá contar con múltiples canales de comunicaciones, asegurando que en un futuro se podrán incorporar cierto número de nuevos sensores, sin que esto suponga un problema de cara a la cantidad de puertos disponibles en el centro neurálgico del dispositivo. 2.7 Otras consideraciones Tras haber tratado de forma general el desarrollo lógico electrónico, resumido de forma visual en la Figura 1, cabe destacar que el proyecto deberá contar con otras aportaciones mecánicas que determinarán de forma seria las configuraciones, distribución y localización de los distintos elementos. Será necesario el desarrollo de una mecánica que permita ensamblar todos los componentes inmiscuidos en el sistema, además de tener que contar con una estructura o fuselaje que aporte cierta estabilidad durante las fases de vuelo. Dicho esto, se recalca que este proyecto tiene como objetivo realizar una implementación física de un producto concebido como prototipo, es por esto por lo que, todas las aportaciones mecánicas se realizarán de forma artesanal, a pesar de que puedan llegar a diseñarse piezas específicas mediante herramientas CAD. Universidad de Valladolid 17 3. HARDWARE Esta sección tratará de arrojar luz en los aspectos relativos a las decisiones tomadas de cara a la implementación física y elección de los componentes. Es por esto por lo que, se analizarán las características técnicas de los mismos, esclareciendo sus especificaciones más importantes y aportando aclaraciones matemáticas sobre los componentes, así como desgranando sus cualidades electrónicas principales en base a las necesidades requeridas. También se realizarán explicaciones sobre los procesos inmiscuidos en la creación del prototipo, aportando detalles acerca de los pasos tomados durante la elaboración de la construcción electrónica, pruebas de funcionamiento realizadas, componentes descartados y otras aportaciones relacionadas con los procesos de prototipado electrónico. Una vez esclarecido el funcionamiento general del sistema mediante diagramas de bloques conceptuales, se pasarán a explicar de forma técnica y detallada, el interior de cada uno de los bloques enunciados anteriormente. 3.1 Perspectiva de funcionamiento Tal y como se expuso durante la sección de introducción de este documento, se tratará de estudiar una configuración de VTOL en concreto. Para ello, se han solicitado los siguientes requisitos de implementación: • Utilización de una configuración distinta a los drones comunes de consumo, evitando para ello la utilización de cuatro motores. • Incorporación de servo motores que permitan modificar el ángulo de sustentación de los motores que generarán el giro para la elevación. • Utilización de un fuselaje escalable, orientado a la implementación de acciones de planeo, prolongando así el vuelo útil del dispositivo. • Incorporación de acciones autónomas por parte de la aeronave, siendo capaz de realizar ciertas funcionalidades sin ningún tipo de supervisión. • Capacidad para portar paquetes, mediante cualquier método. Expuestos los requisitos solicitados, se ha tratado de implementar un VTOL que posea únicamente tres motores, de los cuales se podrá modificar el ángulo de sustentación en dos de ellos, permitiendo aportar nuevas funcionalidades y añadiendo estabilidad al sistema. En cuanto al resto de requisitos, serán debatidos a lo largo de la sección de Universidad de Valladolid 18 hardware de este documento, dejando la implementación de la estructura en manos de secciones posteriores. 3.2 Componentes En lo referente a la elección de componentes cabe destacar que, las elecciones hardware se han visto acotadas por los materiales disponibles en el laboratorio de la Universidad de Valladolid, proporcionados por esta en su mayoría. Las valoraciones expuestas a continuación responden únicamente a las elecciones de componentes dentro de este marco. Si bien es cierto que los materiales proporcionados han sido válidos para el desarrollo del prototipo, podrían existir otros productos que permitieran optimizar aún más las características de la implementación física final. Esta decisión ha venido marcada principalmente por un motivo económico desde el punto de vista del desarrollo. Al tratarse de un proyecto de ingeniería, el factor de costes supone un papel principal, motivo por el cual se ha tomado este camino, tratando de aportar una implementación funcional con los recursos disponibles. A pesar de esta premisa, en posteriores secciones se aportarán datos económicos relativos a los materiales para poder expresar una idea del precio total del prototipado. A continuación, pasarán a explicarse en profundidad los componentes empleados y decisiones tomadas sobre los mismos durante el desarrollo del prototipado. Algunos de los sensores y características expuestas, han sido objeto de estudio con vistas a futuras actualizaciones del proyecto, habiendo realizado pruebas reales con los mismos, sin embargo, no se han implementado de forma práctica en el prototipo final. Este hecho parte de la perspectiva de escalabilidad asociada a la filosofía del proyecto, debido al tiempo disponible y a la gestión de recursos humanos. Sin embargo, se ha realizado un desarrollo que permita la implementación de las citadas funcionalidades. Por otro lado, algunos de los componentes aquí expuestos han sido probados de forma práctica incluyéndolos a la estructura, para después retirarlos tras visualizar que no cumplían con las cotas de calidad esperadas o debido a regulaciones externas, como se expondrá posteriormente. Universidad de Valladolid 19 3.2.1 Motores A la hora de llevar a cabo la elección de los motores en base a los materiales disponibles, se ha dispuesto de dos motores diferentes, siendo el motor A2212/13T de 1000KV y el motor DX2205 de 2300KV de la marca Crazepony. La Figura 2 muestra una imagen con los dos motores disponibles para la implementación del VTOL. Figura 2. Motores disponibles para el desarrollo del VTOL. Presentados ambos motores, se dará paso a una valoración teórica de sus respectivas características, aportando una decisión respecto a la elección de uno de estos componentes. 3.2.1.1 Estudio teórico: A la hora de llevar a cabo una comprensión genérica de los motores, debemos desgranar sus características físicas asociadas. Los motores se basan principalmente en la ley de Ampère-Maxwell, que explica cómo una variación de corriente eléctrica que circula por un conductor genera un campo electromagnético, esta explicación se resume en la siguiente ecuación [17]: 𝛁×𝑩=µ0∗𝑱+µ0∗𝜀0∗𝜕𝑬 𝜕𝑡 Donde 𝑩 representa el vector de inducción magnética, 𝑱 el vector de densidad de corriente eléctrica, µ0 la permeabilidad magnética en el vacío, 𝜀0 la permitividad eléctrica en el vacío y 𝑬 el vector de intensidad de campo eléctrico. Mientras que el operador nabla indica la naturaleza rotacional de la ecuación. Universidad de Valladolid 20 Figura 3. Ejemplificación gráfica sobre el principio básico de funcionamiento de un motor. [18] La Figura 3 aporta una ejemplificación gráfica sobre la ley de Ampère-Maxwell, en la que se muestra el principio básico de funcionamiento de un motor. Al introducir una corriente alterna en las bornas de la bobina, se genera un campo magnético como consecuencia de la anteriormente citada ley. Al encontrarse esta bobina en un campo magnético formado por los imanes, ambos campos magnéticos interactuarán alineándose en función de su polaridad. Si se invierne la polaridad de la corriente alterna en el momento en el que el campo magnético generado se alinea con el campo magnético de los imanes (espira colocada en posición vertical) se producirá una rotación continua, obteniendo el efecto deseado [18]. Conocidos los principios básicos en los que se fundamentan los motores, se pasará a desgranar la física de las principales características específicas de ambos. En cuanto a las características comunes, nos encontramos con que ambos motores son motores sin escobillas, característica que les aportará mayor durabilidad, evitando así el desgaste de estas debido a la rotación del motor. Las escobillas son necesarias cuando el estátor del motor está formado por la parte imantada. Esta casuística surge de una configuración práctica, no es viable crear un motor cuyo rotor esté formado por la parte bobinada sin escobillas, dado que los cables se enrollarían, la corriente ha de pasarse a través de dichas escobillas haciendo contacto con la parte que rota, produciendo un rozamiento que, debido a la fricción, terminaría desgastando las escobillas y por tanto generando averías en el motor [19]. Por este motivo los motores sin escobillas son ampliamente utilizados, como consecuencia, el estátor estará formado por el bobinado, mientras que el rotor lo compondrán los imanes. Esta configuración está presente en ambos motores. Universidad de Valladolid 21 En la Figura 4 pueden apreciarse las diferencias entre un motor con escobillas y sin escobillas típicos. Figura 4. Motor con escobillas y rotor interno (izquierda), motor sin escobillas y rotor externo (derecha). [19] Dado que el estátor está formado por el bobinado, una de las configuraciones más habituales, debido a la posibilidad de implementar un diseño más simple, es la de establecer el rotor en la parte externa. Existen motores sin escobillas de rotor interno, cuya característica principal es que realizan giros más rápidos, sin embargo, son más utilizados los motores de rotor externo debido a que, aunque giran más lento, producen un torque mayor. Continuando con las características principales de los motores, será necesario hacer hincapié en la relación entre torque y velocidad. El torque se define como fuerza de rotación, y viene definido por las siguientes ecuaciones [18]: 𝝉=𝒓×𝑭 𝜏=‖𝒓‖∗‖𝑭‖∗𝑠𝑒𝑛𝜃 Donde 𝜏 representa el torque, 𝒓 la posición del vector de fuerza, 𝑭 el vector de fuerza y θ el ángulo formado entre el vector de fuerza y el radio o vector de posición de fuerza. Universidad de Valladolid 22 Expuesto el torque o momento de fuerza, se expondrá en las siguientes ecuaciones su relación con la velocidad [18]: 𝑃=𝑇𝑟𝑎𝑏𝑎𝑗𝑜 𝑇𝑖𝑒𝑚𝑝𝑜=𝐹∗𝐷𝑖𝑠𝑡𝑎𝑛𝑐𝑖𝑎 𝑇𝑖𝑒𝑚𝑝𝑜 =𝐹∗𝑉𝑒𝑙𝑜𝑐𝑖𝑑𝑎𝑑 𝑃= 𝜏 ‖𝒓‖∗𝑠𝑒𝑛𝜃∗ 𝜔→𝑆𝑖 𝜃=90º →𝜏=𝑃∗‖𝒓‖ 𝜔 Donde 𝜔 representa la velocidad angular. Si contamos con que la potencia y el radio de giro son constantes podremos observar como el torque y la velocidad angular tendrán una relación inversamente proporcional [20]. Esta última conclusión puede verse reflejada en la gráfica de la Figura 5. Extrapolando estas conclusiones al desarrollo de nuestro prototipo, se tratará de obtener un torque mayor en vez de optar por una mayor velocidad, dado que el PID tendrá que realizar cambios bruscos para equilibrar el dispositivo en el aire, tarea que requiere un mayor momento de fuerza angular. Figura 5. Características de torque frente a velocidad en BLDC (BrushLess Direct Current).[20] A la hora de determinar el torque y la velocidad, influirán una gran cantidad de variables como la propia geometría del motor, las propiedades químicas del imán, la cantidad de ellos, la superficie de estos, su distribución física en el rotor, etc [21][22]. Continuando con las características, podemos apreciar en la Figura 2, cómo ambos motores cuentan con orificios de ventilación en la parte superior. Estos orificios mejoran el flujo de aire del interior de los motores, evitando así que el calor generado por la corriente que atraviesa el bobinado derrita el recubrimiento de esmalte de los cables de cobre, esta relación entre potencia y calor se puede visualizar en las siguientes ecuaciones[18]. Universidad de Valladolid 23 𝑃(𝑊)=𝐼(𝐴)∗𝑉(𝑉)=𝐼2(𝐴)∗𝑅(Ω) 𝑄(𝐽)=𝑚(𝐾𝑔)∗𝑐(𝐽 𝐾𝑔∗º𝐶)∗∆𝑇(º𝐶) 𝑃(𝑊)=𝐸(𝐽) ∆𝑡(𝑠)→𝐼2∗𝑅=𝑄(𝐽) ∆𝑡(𝑠) →∆𝑇(º𝐶)=𝐼2(𝐴)∗𝑅(Ω)∗∆𝑡(𝑠) 𝑚(𝐾𝑔)∗𝑐(𝐽 𝐾𝑔∗º𝐶) Donde 𝑄 es la cantidad de calor en julios, 𝑚 la masa del material y 𝑐 la capacidad calorífica del material, dado que en un conductor la masa y la capacidad calorífica del material son constantes, se puede obtener una relación casi directa entre la intensidad y la cantidad de calor generada por el bobinado. Si observamos nuevamente la Figura 2, nos encontraremos con que los motores poseen tres cables cada uno, esto se debe a que cuentan con una configuración trifásica. Este tipo de configuración utiliza tres corrientes desfasadas de la misma frecuencia, permitiendo obtener una potencia más elevada y, en consecuencia, un rango de RPM (Revoluciones Por Minuto) de mayor magnitud. Estos motores son comúnmente empleados en la industria debido a su capacidad de operar con mayor potencia, además generan menores vibraciones y ser menos ruidosos [23]. La Figura 6 muestra una gráfica en la que puede apreciarse la configuración de corrientes desfasadas en trifásica, siendo todas de la misma amplitud y frecuencia. Figura 6. Gráfica de corrientes empleadas en motores trifásicos. [23] La utilización de corrientes trifásicas permite distribuir la potencia de un modo más uniforme, aportando una mayor suavidad en la transición del motor. Además, la anterior Universidad de Valladolid 24 característica produce un par o torque más constante, contribuyendo a la obtención de una mayor eficiencia energética y, en consecuencia, a un menor calentamiento. Finalmente, otorga la capacidad de poseer un rango más alto de velocidades, dado que, al contar con tres fases distintas se mejora la granularidad de las transiciones. Estos sistemas trifásicos contribuyen a facilitar la alternancia en el giro intercambiando dos de los cables, consiguiendo así invertir el orden de las fases, produciendo una rotación en sentido opuesto. En última instancia, cabe destacar que, normalmente, la configuración del bobinado implementado suele ser dLKR, configuración que se muestra en la Figura 7. Figura 7. Configuraciones típicas de esquemas de bobinado.[24] Estas configuraciones vienen fomentadas por una mejor organización del cableado, principalmente, y se emplean en función de la configuración de cables deseada o la construcción del motor. En ocasiones las distintas configuraciones son denominadas de diferentes formas por la industria a pesar de que se refieran a disposiciones idénticas en el bobinado. 3.2.1.2 Comparación técnica: Una vez expuestas las principales características de los motores, encajadas en un marco físico-teórico global, se dará paso a la comparación de sus especificaciones técnicas concretas, con la finalidad de poder determinar sobre el papel qué motor sería el más idóneo para el proyecto. Dado que ambos motores son ampliamente utilizados, resulta difícil encontrar el fabricante original, como consecuencia de la creación de réplicas e implementaciones similares por parte de competidores. Este hecho dificulta la obtención de hojas de datos Universidad de Valladolid 31 En la figura anterior podemos apreciar cómo su principal función es convertir una señal PWM (Pulse Width Modulation) en tres señales sinusoidales desfasadas que permitirán el funcionamiento del motor. Ante este funcionamiento surgen cuestiones técnicas relativas al desfase de la señal o la generación de una señal analógica. La Figura 12 muestra el interior del ESC empleado, así como sus componentes principales. Figura 12. ESC SimonK 30A, componentes internos tras la retirada de disipadores. En esta imagen, se observan sus principales componentes, mostrándose en azul el microcontrolador ATMEGA8A [29], en verde el puente que forman los MOSFET (Metal Oxide Semiconductor Field-Effect Transistors), TPCA8057-H [30], en naranja el grupo de transistores BJT E23 05 junto con resistencias, diodos y condensadores y finalmente dos grupos de reguladores de tensión, mostrándose en morado los reguladores KA7805R y en rojo el regulador 78L05. El funcionamiento principal pasa por la recepción de la señal PWM de entrada en el microcontrolador ATMEGA-8A, este adaptará el ancho de los pulsos en función de la velocidad deseada, con la finalidad de generar señales adaptadas para los MOSFET, activándolos y desactivándolos, pudiendo así generar el desfase. Gracias al puente se consigue la rectificación de la señal, obteniendo de los pulsos generados una parte negativa y positiva que conforman la señal sinusoidal. En cuanto al desfase generado es el microcontrolador el que se encargará de seleccionar que par de Universidad de Valladolid 32 MOSFET se activan en cada ciclo. Finalmente, son necesario los tres pares debido al bobinado delta del motor, la Figura 13 muestra una imagen a modo de resumen, donde se expone el funcionamiento principal del ESC. Figura 13. Explicación gráfica del funcionamiento de un ESC [19]. Centrándonos en el esquema electrónico se expone en la Figura 14 la configuración de dicho puente. Este tipo de puente nos permitirá modificar el sentido de giro del motor simplemente intercambiando las conexiones de las fases 3 y 1 de salida del ESC. Esto sucede porque el microcontrolador mantiene el orden en el que activa los MOSFET, con lo que un simple intercambio de cables invertirá dicho orden. Figura 14. Puente de tres fases, esquematización electrónica [31]. Continuando con las distintas funcionalidades del ESC, debemos mencionar la necesidad del microcontrolador de conocer la velocidad de rotación de los motores. Algunos motores utilizan sensores de efecto Hall con la finalidad de llevar a cabo dicha tarea, en nuestro caso el controlador conocerá dicho sentido de giro a partir de la EMF (Electromotive Force) de retorno. Universidad de Valladolid 33 El ESC consigue llevar a cabo esta tarea debido a la dualidad del campo electromagnético. De igual modo que se utiliza la corriente con la finalidad de inducir un campo magnético en el bobinado que permita la iteración con los imanes del rotor, permitiendo así el movimiento, se sucede también el efecto contrario, donde los imanes del rotor generan una corriente de retorno en el bobinado [18]. Como consecuencia del desfase generado por el microcontrolador, existirán momentos en los cuales alguno de los bobinados no esté recibiendo corriente de salida del puente. En estas circunstancias, como consecuencia de la rotación de los imanes del rotor se genera una fuerza electromotriz inducida en la bobina. Esta corriente es medible y se utiliza para determinar la rotación o la velocidad, también conocida como EMF de retorno [19]. La siguiente ecuación aplica la Ley de Faraday para determinar el EMF de retorno [21]: 𝐸=−𝑁∗𝑑𝜑 𝑑𝑡 Donde 𝐸 es la EMF de retorno, 𝑁 el número de espiras del bobinado y la derivada muestra la variación temporal del flujo magnético 𝜑. La cantidad de armónicos, así como la “idealidad” de la señal vendrán determinados por las condiciones geométricas de distribución de imanes y bobinado [21]. Respecto a la denominación de este tipo de ESC, visto que la electrónica, a grandes rasgos puede ser similar o basarse en los mismos principios, debemos hacer hincapié en su nombre. Este tipo de ESC se denominan SIMONK como referencia al firmware implementado por Simon Kirby [32]. El firmware hace referencia al código de programa compilado en el MCU (Micro Controller Unit), en este caso, nuestro ESC implementa un MCU con dicho firmware, por lo que tendrá características comunes en cuanto al código del programa, a pesar de que el hardware sea diferente o implementado con pequeñas variantes. Este firmware mejora los tiempos de respuesta del motor, en términos de empuje de las hélices frente a la señal PWM recibida. En la Figura 15 se muestran algunas de las conclusiones principales en las que se compara el firmware de Simon Kirby. En dicha figura se representa una señal de entrada Step1 que representa una estimación, frente a la señal Step Universidad de Valladolid 34 2 consistente en una señal de amplitud decreciente, pero con los mismos valores estacionarios. Figura 15. Comparación de los tiempos de respuesta empleando el firmware SimonK. Señal Step1 (izquierda), señal Step2 derecha y valores experimentales de un sistema de primer orden con retardo [32]. En la figura anterior, se aprecia la mejora temporal en la respuesta del empuje del motor, donde se representa el tiempo el RMS (Root Mean Square) está determinado por la siguiente ecuación [32]: 𝑅𝑀𝑆=√1 𝑁∑(𝑅𝑖−𝐹𝑖)2 𝑁 𝑖=1 Calculado como la diferencia de la subida 𝑅𝑖 y la bajada 𝐹𝑖 del empuje para un rango de 500ms y 𝑁 el número de muestras. Finalmente debemos hablar de los sonidos generados por el motor. De cara a la utilización práctica de los motores y a modo de realimentación el ESC generará señales analógicas para emitir diferentes sonidos en los motores, aportando realimentación sobre el estado del sistema. A priori puede parecer una implementación poco intuitiva que los motores generen sonido, pero si nos centramos en el funcionamiento básico de un altavoz podemos observar que principalmente se encarga de convertir una corriente en una fluctuación de aire. Para ello un dispositivo emite una señal eléctrica que recorre una bobina, la cual Universidad de Valladolid 35 generará un campo electromagnético que transmitirá la señal a un imán acoplado a una membrana, generando la fluctuación de aire deseada y por tanto sonido. Los motores BLDC poseen todos los componentes necesarios, el bobinado, los imanes y la señal generada por el microcontrolador del ESC. En este caso se emplea la carcasa del rotor como membrana, ya que solo se emitirán pitidos básicos a distintas frecuencias sin buscar una alta fidelidad sonora. 3.2.2.2 Implementación práctica Tras haber explicado las características electrónicas asociadas, así como sus principales funciones nos centraremos en sus especificaciones prácticas. Nuevamente volvemos a encontrarnos frente a la falta de hojas de datos oficiales del fabricante, como consecuencia de la amplia utilización de este tipo de componentes electrónicos. Sin embargo, dado que la mayoría de ESC comerciales para motores BLDC emplean el firmware SimonK, incluso el propio Simon Kirby aporta una versión de código abierto en su repositorio de GitHub para controladores ATmega [33], podremos observar las características de componentes similares que implementen dicho firmware. Inicialmente nos centraremos en su parte práctica o de utilización, para ello se ha tomado como ejemplo las instrucciones de usuario expuestas en [34], pertenecientes a una serie de ESC que emplean el firmware SimonK. Estas instrucciones aportan detalles acerca de los pasos para la configuración del ESC o su inicialización. Principalmente indican los tipos de sonidos para cada una de las casuísticas como armado de los ESC, control de frecuencia, o protección frente a ciertos valores de voltaje. Dado que los detalles específicos de dicha implementación se relacionan mayormente con el funcionamiento, serán tratados en la sección de software de este documento. Centrándonos en los datos específicos que poseemos sobre el ESC nos remontaremos a la Figura 10 donde se muestran sus principales características relacionadas con la corriente máxima que soportan y el tipo de baterías compatibles. Respecto a su corriente máxima se aprecia que es de 30 A, superar dicha corriente podría generar que el ESC se calentara demasiado como consecuencia del efecto Joule. Universidad de Valladolid 36 En la práctica se han probado los ESC con ambos motores, observando que en el caso de la utilización del motor DX2205 llegaban a calentarse demasiado, llegando a quemarse durante usos prolongados a potencias máximas. Esto concuerda con lo expuesto durante la comparación técnica de los motores, donde se observaba que el motor A2212 consumía, para el voltaje dado, una menor cantidad de corriente. Continuando con la implementación práctica se observa en la Figura 10 sus compatibilidades con tipos de baterías, siendo compatible con baterías de NIMH (Niquel- Metalhidruro) de 5 a 12 celdas en serie y con Li-Po (Polímero de Litio) de 2 a 4 celdas en serie. En nuestro caso se están empleando baterías Li-Po 3S, por lo que estamos dentro de los márgenes recomendados y no se ha apreciado ningún tipo de calentamiento excesivo o hinchazón en las mismas. Finalmente, la Figura 16 muestra el esquema de conexiones del ESC. Figura 16. Esquema de conexiones del ESC. 3.2.3 Servomotores Tras haber expuesto dos de los principales elementos que conformarán el sistema pasaremos a hablar de los servomotores. A la hora de seleccionar este dispositivo nos encontramos en el laboratorio con dos principales componentes, siendo estos el servo MG996R y el micro servo SG90, ambos pueden apreciarse en la Figura 17. Los servos nos permitirán implementar el movimiento de los motores, permitiendo así inclinarlos hacia delante o atrás, ya sea de forma simultánea o independiente. Universidad de Valladolid 37 Figura 17. Servo MG996R (izquierda) y servo SG90 (derecha). Expuestos ambos servomotores, se dará paso a la exposición del estudio teórico. 3.2.3.1 Estudio teórico El término servomotor se asocia con el concepto de conjunto electrónico en el que interviene un motor que, en adición con otros componentes electrónicos, permite regular una posición exacta en su rango de operación. Según lo define la RAE (Real Academia Española): “Sistema electromecánico que amplifica la potencia reguladora.” [35]. A grandes rasgos, son conjuntos electrónicos que consiguen posicionar un motor con precisión en función de unas señales de entrada, lo más común es encontrar servomotores de corriente continua con escobillas, aunque existen todo tipo de variaciones [36]. Dado que el componente del motor que conforma el sistema cuenta con una base física similar a la expuesta durante la sección 3.2.1.1, nos centraremos en las peculiaridades que presentan. En el caso que nos ocupa, la principal función del servomotor es poder determinar la posición de este, es decir, el ángulo de giro en el que se encuentra el motor. De este modo podremos posicionarlo exactamente en un ángulo o posición determinada dentro de su rango de actuación. Universidad de Valladolid 38 La Figura 18 muestra de forma genérica el funcionamiento de un servomotor similar a los empleados para el desarrollo del VTOL. En ella se observan los principales componentes, destacando un sensor que permita determinar el posicionamiento del motor, el propio motor y un circuito de control que permitirá conocer la posición ofrecida por el sensor y recibir señales que permitan posicionar al motor en una posición determinada. Figura 18. Representación esquemática del funcionamiento de un servomotor [36]. Con el objetivo de comprender en mayor profundidad dicho funcionamiento se aporta en la Figura 19 una imagen del interior del servomotor MG996R. En ella podemos observar los engranajes que conformarán la rotación, destacando, en la esquina superior derecha de la primera sección, el tope que impide que el servomotor gire de forma infinita, ajustándose al rango permitido por el potenciómetro. Figura 19. Interior del servomotor MG996R. Universidad de Valladolid 39 Respecto a su electrónica interna los servomotores de este tipo suelen contener un controlador de motor que actuará en función de un comparador, encargado de nivelar las señales del potenciómetro y de la señal PWM de entrada traducida a voltaje analógico. La siguiente figura muestra el funcionamiento lógico de un servomotor de forma esquemática. En ella puede apreciarse cómo el comparador generará una salida que provocará la actuación del motor en el caso de que exista una diferencia entre el valor reportado por el potenciómetro, que indica la posición del motor como consecuencia de estar acoplado a su principal engranaje, y la señal de entrada PWM traducida a nivel de tensión. Figura 20. Funcionamiento lógico de un servomotor [37]. El comparador empleado podría estar formado por un amplificador diferencial, al que, si le añadimos la característica de amplificar la señal y una baja impedancia de salida, asegurando una intensidad suficiente que permita generar un campo electromagnético con potencia necesaria para mover el motor, estaremos hablando de un amplificador operacional. Universidad de Valladolid 40 Figura 21. Esquema Amplificador Operacional en lazo abierto [38]. Tal y como se expone en la figura anterior estaremos generando una tensión con signo positivo o negativo, induciendo corrientes en el motor que permitirán girar en sentido horario o antihorario, ajustando rápidamente la posición de este en función de la señal suministrada. La señal PWM modulará su ancho de pulso para indicar, entre la posición máxima y mínima, el giro en el motor. En lo referente al módulo conversor de PWM podría estar formado por un LPF (Low Pass Filter) conectado a un amplificador operacional con un buffer de salida para eliminar los efectos de la carga [39]. Conocemos que una señal PWM está compuesta por una componente de continua (offset) y la onda cuadrada que compone el tren de pulsos PWM, esta representación puede apreciarse en la Figura 22. Figura 22. Descomposición de una señal PWM [40]. Además, una forma de onda PWM puede descomponerse mediante una suma de sinusoides con el offset anteriormente mencionado. Dicho offset puede filtrarse utilizando un LPF que posea una frecuencia central baja [41]. Universidad de Valladolid 47 En lo referente al giróscopo, el principio de funcionamiento es similar, basándonos en la capacidad que se genera cuando una masa se mueve, contenida por “muelles” u otro sistema de elongación. La principal diferencia se basa en que, para este caso, se empleará el efecto Coriolis, que tiene en cuenta la velocidad de un elemento respecto a un objeto que lo contiene y se encuentra en movimiento. Sus ecuaciones se describen según: 𝐹𝑐 󰇍 󰇍 󰇍 =−2𝑚(𝜔 󰇍 󰇍 × 𝑣 ) Donde 𝐹𝑐 󰇍 󰇍 󰇍 es la fuerza Coriolis, 𝑚 la masa, 𝜔 󰇍 󰇍 la velocidad angular del sistema en rotación y 𝑣 la velocidad del cuerpo en el sistema de rotación. En este caso, dado que tendremos un cuerpo en movimiento, podremos observar cómo varían los valores de capacidad cuando el marco que contiene el cuerpo en movimiento rota, alterando así las direcciones de resonancia. La Figura 28 ofrece un ejemplo de dicho sistema. Figura 28. Configuración espacial de un giróscopo integrado.[49] Tras haber visualizado las principales funcionalidades, en lo que a detección de parámetros físicos se refiere deberemos exponer sus características técnicas asociadas a dichas parametrizaciones. Principalmente contaremos con un giróscopo de tres ejes con un rango dinámico programable de ±250, ±500, ±1000, y ±2000°/sec, esto supondrá un compromiso a la hora de elegir los rangos de operación, pudiendo obtener una granularidad mayor o decantarse Universidad de Valladolid 48 por rangos de operación más altos, ya que se utilizarán 16 bits para representar dichos rangos. En el caso del acelerómetro nos encontramos con una situación similar teniendo un rango dinámico programable de ±2g, ±4g, ±8g y ±16g también con un ADC integrado de 16 bits para muestreo simultáneo. En cuanto al integrado en el que viene insertado nuestro conjunto MEMS, podemos visualizar en la anteriormente mostrada Figura 25. Que contamos con una entrada de 5V y poseemos la capacidad de utilizar los protocolos I2C (twowire) o SPI. Como características adicionales se incluye un regulador de tensión que permitirá convertir la señal de entrada de 5V a los 2.375-3.46V en los que opera el MPU6050 [45]. Si revisamos la configuración típica de funcionamiento expuesta en la hoja de datos, podremos apreciar que se corresponde con la configuración visualizada en la Figura 25, en la que únicamente se ha incorporado un regulador de tensión, con sus resistencias asociadas y los condensadores de paso mostrados en la siguiente figura. Figura 29. Circuito de operación típico MPU-6050 [45]. El componente de color anaranjado es un condensador electrolítico de tántalo, que suele ser empleado, a pesar de su gran tamaño por su baja ESR (Equivalent Series Resistance), mejorando la respuesta transitoria del circuito y permitiendo un rápido amortiguamiento Universidad de Valladolid 49 de la señal, además de contar con una alta estabilidad en mayores rangos de temperatura [50]. 3.2.4.2 Implementación práctica Vistas sus principales características si discutirá sobre la implementación práctica. En el caso de uso que nos ocupa, nuestro MPU-6050 estará principalmente destinado a calcular la posición del VTOL, sus ángulos (pitch, yaw y roll) así como su velocidad angular. Con todo esto vemos que este elemento, será imprescindible de cara a la implementación del PID, el núcleo central de cálculo de estabilización de nuestro VTOL. Dado que los algoritmos de implementación de vuelo, así como su matemática asociada pueden englobarse dentro de una capa lógica, serán tratados durante la sección de software de este documento, discutiendo en mayor profundidad las entradas al conjunto MEMS, sus configuraciones o la matemática asociada para su funcionamiento. 3.2.5 Sensor ultrasonidos Con el objetivo de optimizar algunos aspectos asociados al vuelo, mejorando la experiencia final, se ha empleado el sensor de ultrasonidos HC-SR04 disponible en el laboratorio de la UVA. Figura 30. Sensor de ultrasonido HC-SR04 [51]. Este sensor permitirá realizar cálculos de distancia precisos cuando la distancia no sea notablemente elevada, permitiendo ajustar algunas funcionalidades de nuestro VTOL. Universidad de Valladolid 50 3.2.5.1 Estudio teórico Los sensores de ultrasonidos son ampliamente conocidos, sobre todo en el ámbito de la detección de distancias, destacan algunas aplicaciones como el SONAR (Sound Navigation And Rangign) cuando el uso de campos electromagnéticos no es viable, e.g: un medio como el acuático. Su principio de operación es simple, se basan en que la velocidad del sonido en un medio concreto es constante, en el caso del aire esta velocidad es de 340m/s [18]. Cuentan con un emisor y un receptor, de modo que, midiendo el tiempo que ha tardado en volver la señal al origen, como consecuencia de haberse encontrado un medio no absorbente o parcialmente absorbente, puede calcularse la distancia recorrida por la onda. En el caso de este sensor, empleará ultrasonidos, situados a frecuencias superiores del espectro audible del ser humano (~20kHz). Para la generación de estas ondas sonoras se emplean sensores piezoeléctricos, que permiten convertir las señales eléctricas en vibraciones debido a la contracción y expansión del material piezoeléctrico. Dada la reversibilidad de este tipo de sensores, podemos hablar de transductor, ya que será capaz de emitir y captar dichas vibraciones. Además, el sensor estará operando en la zona de máxima sensibilidad entorno a la frecuencia central de operación, mejorando así la selectividad y respuesta [52]. Se expone a continuación la ecuación empleada para llevar a cabo el cálculo de la distancia: 𝑑=𝑐∗𝑡 2 Donde 𝑐 representa la velocidad de propagación del sonido en el medio, 𝑑 la distancia y 𝑡 el tiempo total empleado por la onda desde su emisión hasta su recepción. La Figura 31 muestra un esquema lógico-electrónico de un transductor ultrasónico piezoeléctrico. Universidad de Valladolid 51 Figura 31. Esquematización electrónica de un transductor piezoeléctrico sonoro [52]. En el caso concreto de nuestro sensor HC-SR04, podemos observar su cristal oscilador en la parte central de la Figura 30, vemos además como cuenta con 4 pines de entrada, 2 de ellos destinados a alimentación, un pin destinado al trigger y otro destinado a la recepción de la señal echo. Al activar el pin trigger se activará una ráfaga de pulsos sónicos que se recibirán en el receptor activando la señal de echo y pudiendo así calcular la distancia recorrida por el pulso calculando el tiempo empleado [51]. Centrándonos en sus características específicas observamos en [51] que posee un consumo de corriente en reposo (quiescent) inferior a 2mA, un rango de distancia de operación máximo de 2 a 4 metros, un ángulo efectivo de detección de ±15cm y un ancho de pulso necesario para el trigger de 10𝜇𝑠. Estas características nos permiten entrever que la utilidad del sensor estará delimitada principalmente por su longitud máxima de alcance, destinado principalmente a detección de objetos cuasi perpendiculares, debido a su directivo ángulo de detección. 3.2.5.2 Implementación práctica En la práctica el sensor será empleado para mejorar aspectos relacionados con la etapa de despegue, permitiendo ajustar valores que únicamente comenzarán a funcionar cuando el dispositivo se eleve una distancia pequeña del suelo, tales como el PID del yaw. Universidad de Valladolid 52 En lo relativo a otros usos, podrá servir para implementar un PID de altitud con mayor precisión cuando el dispositivo acabe de despegar o vaya a aterrizar, aumentando la fiabilidad y precisión del sistema. 3.2.6 Sensor de presión En lo referente al sensor de presión, se hará necesaria su implementación de cara a la obtención de los parámetros físicos de altitud, permitiendo conocer la altura del dispositivo cuando este se encuentre a una longitud elevada durante el vuelo. En este caso se ha empleado el sensor de altitud BMP390 disponible en el laboratorio de la UVA. Figura 32. Implementación circuital sensor BMP390. Se trata de un sensor de la marca Bosch[53] , cuya implementación circuital se basa en un diseño de Adafruit [54], principal vendedor que ofrece el producto junto con sus bibliotecas. 3.2.6.1 Estudio teórico En lo referente a los principios físicos nos encontramos con un sensor de temperaturapresión. Estas constantes físicas nos permitirán relacionar los parámetros obtenidos en las mediciones del sensor con la altitud de este. El fabricante expone una imagen gráfica sobre el funcionamiento de sus sensores de presión, dicho funcionamiento se expone en la Figura 33. Universidad de Valladolid 53 Figura 33. Principio de funcionamiento resistivo en sensores de presión Bosh[55]. Esta figura muestra cómo se implementa el circuito de acondicionamiento mediante un puente Weathstone, cuyas resistencias varían en función de la presión atmosférica que se ejerce sobre la placa metálica del sensor: 𝑉𝐴=𝑅𝐿 𝑅𝑇+𝑅𝐿∗𝑉𝑆 𝑉𝐵=𝑅𝑇 𝑅𝐿+𝑅𝑇∗𝑉𝑆 𝑉𝑜𝑢𝑡=𝑉𝐴−𝑉𝐵=(𝑅𝐿 𝑅𝑇+𝑅𝐿−𝑅𝑇 𝑅𝐿+𝑅𝑇)∗𝑉𝑆=𝑅𝐿1−𝑅𝑇 1+𝑅𝑇∗𝑉𝑆 Al tratarse de un puente de Weathstone balanceado, nos encontraremos con que, cuando no hay deformación 𝑅𝐿=𝑅𝑇→𝑉𝑜𝑢𝑡=0, mientras que cuando se produzca una deformación máxima 𝑉𝑜𝑢𝑡≈𝑅𝐿∗𝑉𝑆 . Obteniendo así un valor de tensión proporcional a la presión atmosférica. En su hoja de datos especifica de forma explícita que uno de los dispositivos objetivos para su uso es la implementación de drones. Destacando una precisión mínima relativa en la presión de ±0.25m desde 700 a 1100hPa, para un rango de temperatura entre 25 y 40 grados celsius [53]. Para realizar el cálculo de la altitud, tanto en las bibliotecas de Adafruit para la familia de sensores 3XX [56], como en la documentación de Bosch para modelos de sensores de Universidad de Valladolid 54 presión anteriores (BMP180) [57], se emplea la siguiente ecuación, partiendo de la presión barométrica: 𝑃=𝑃𝑏[1−𝐿𝑀,𝑏 𝑇𝑀,𝑏(ℎ−ℎ𝑏)]𝑔0𝑀0 𝑅∗𝐿𝑀,𝑏 𝐴𝑙𝑡𝑖𝑡𝑢𝑑=44330.3∗(1−𝑝 𝑝0)1 5.255 Donde 𝑃𝑏 es la presión de referencia, 𝑇𝑀,𝑏 la temperatura de referencia, 𝐿𝑀,𝑏 la tasa de cambio de temperatura, ℎ la altura a la que la presión es calculada, ℎ𝑏 la altura de referencia, 𝑔0 la gravedad, 𝑀0 la masa molar del aire en la tierra y 𝑅∗ la constante universal del gas. Sustituyendo los valores 𝑅∗=8.3144598 J/(mol·K), 𝑔0= 9.8 𝑚/𝑠2, 𝑀0=0.02896𝐾𝑔/𝑚𝑜𝑙, 𝑇𝑀,𝑏=25º𝐶+𝑇=273.15º𝐾+𝑇 (𝐶𝑜𝑛 𝑇~15), y 𝐿𝑀,𝑏=−0.0065𝐾/𝑚, ℎ𝑏=0 , llegamos finalmente a que 𝑝 es la presión medida y 𝑝0 la presión a nivel del mar o presión de referencia. Dicha presión puede obtenerse en la página de la AEMET (Agencia Estatal de Meteorología)[58]. Este es el motivo por el cual el sensor incorpora también un medidor de temperatura, permitiendo realizar la anterior ecuación con mayor exactitud y permitiendo que la temperatura, así como la tasa de cambio de la temperatura puedan ser ajustadas con mayor precisión. 3.2.6.2 Implementación práctica En la práctica el sensor BMP390 nos permitirá medir la altitud a la que se encuentra nuestro VTOL, de este modo, utilizando una realimentación de los datos recogidos por el sensor, podremos implementar un PID que permita que nuestro dispositivo mantenga el vuelo a una altura constante, mejorando la estabilidad del dispositivo y permitiéndonos determinar la altitud a la que se quiere mantener el vuelo. 3.2.7 Fotosensor De cara a la realización de pruebas de concepto, se empleará el fotosensor ADNS3080 [59]. Este sensor servirá para tratar de observar la viabilidad de reconocimiento de imágenes con la finalidad de determinar la posición. En la Figura 34 se muestra el Universidad de Valladolid 55 módulo empleado durante las pruebas, que incorpora el sensor ADNS3080 junto con una lente. Figura 34. Módulo de flujo óptico para el sensor ADNS3080 Expuesto el componente se dará paso a la exposición de su estudio teórico. 3.2.7.1 Estudio teórico El sensor ADNS3080 es un sensor de flujo óptico, principalmente orientado a la fabricación de periféricos, concretamente está destinado a su ensamblaje en ratones de ordenador. A priori se muestra que el propósito subyacente a la creación de dicho sensor nada tiene que ver con la navegación, sin embargo, debido a su bajo coste y a su característica de sensor de flujo se ha utilizado como ayuda de sistema de navegación de drones recreativos, una muestra de su utilización en esta área puede consultarse en la documentación del proyecto ArduPilot [60]. El sensor está diseñado para mejorar la utilización de ratones, empleando un fotosensor con una sensibilidad capaz de detectar 40 pulgadas por segundo y una aceleración de hasta 15g. Contiene un IAS (Image Adquisition System), un DSP (Digital Signal Processor) y cuatro puertos serie. Respecto a su empleabilidad, es cierto que no nos permitirá obtener grandes imágenes de alta resolución, pero debido a su funcionalidad, en condiciones de alta luminosidad permitirá obtener imágenes de baja resolución en escala de grises, pudiendo así mejorar el posicionamiento. Universidad de Valladolid 56 El funcionamiento de este tipo de sensores se basa en la detección de diferencias de flujo óptico, de este modo, poseen la capacidad de determinar el movimiento relativo de posición. La Figura 35 muestra el esquema de ensamblado del sensor ADNS3080 en un ratón. En esta figura puede observarse cómo, mediante la implementación de un emisor de luz LED (Light Emitting Diode), se obtiene la luz reflejada en la superficie de forma directa en el sensor. Para ello, en el caso de ratones, se incorpora una lente que, mediante los mecanismos de refracción y reflexión de la luz permiten orientar el haz de luz reflejado directamente en el fotosensor. Figura 35. Sección de ensamblado del sensor ADNS3080 en una PCB [59]. El haz de luz reflejará de forma diferente en función de las irregularidades de la superficie en la que se encuentre, pudiendo así obtener un mapa topográfico en escala de grises mediante la matriz de fotorreceptores que incorpora el sensor. La Figura 36 muestra los principales módulos del sensor ADNS3080. En la imagen se muestran los módulos inmiscuidos en el proceso, destacando la matriz de fotosensores que se conectará directamente con procesador de imágenes incorporado. De esta forma, mediante el oscilador, se establecerá una frecuencia de muestreo para regular el tiempo de exposición de cada una de las imágenes tomadas y será el procesador de imágenes el que se encargue de calcular las diferencias entre las muestras topográficas de la superficie, con la finalidad de obtener un vector de dirección y obtener la posición relativa. Universidad de Valladolid 63 3.2.8.2 Implementación práctica En cuanto a su implementación práctica, se ha conseguido obtener la posición con una precisión relativa de unos 7-8 metros. En la sección software se incluirán más detalles acerca de las bibliotecas empleadas y la obtención de datos. La premisa de utilización de un sensor GNSS es claramente viable en el caso de viajes largos, donde podría aportar una gran precisión a la navegación, e incluso permitir la incorporación de algún tipo de algoritmo realimentado para la navegación autónoma. Sin embargo, probar esta característica en la práctica no es viable desde el punto de vista legal. En la página web de Ministerio de Transportes y Movilidad Sostenible se aportan los requisitos mínimos legales para el manejo de drones [73], entre los que figuran requisitos como la necesidad de obtener un registro como operador, formación como piloto de drones o la necesidad de poseer un seguro de responsabilidad civil, para drones con un peso superior a los 250g, así como UAS (Unmanned Aerial System) [74]. El límite de aplicación de 250 no tiene validez si el dron puede ser capaz de capturar datos personales o no es concebido como juguete. En el caso que nos ocupa, no se han incorporado ningún tipo de cámaras que pudieran afectar a la privacidad. Este hecho imposibilita la implementación práctica del sensor GNSS dado que las pruebas se han realizado en un entorno privado controlado y teniendo en cuenta que el GNSS nos ha permitido diferenciar distancias de unos 7-8 metros en la práctica, no ha sido posible realizar pruebas fiables en las que se incorpore el dispositivo GNSS en el VTOL. Debido a la basta regulación respecto a esta área y los distintos organismos reguladores tanto a nivel comunitario como nacional [75], las pruebas efectuadas con el VTOL diseñado se han realizado en una propiedad privada controlada, estableciendo límites de potencia por seguridad, sin superar las delimitaciones arquitectónicas de la misma, con la finalidad de evitar posibles inconveniencias legales. Universidad de Valladolid 64 3.2.9 Microcontrolador Una vez comentados los sensores barajados para la implementación de las diferentes características de nuestro VTOL, será necesario tratar cual será el dispositivo central que gestionará todos los datos e implementará la lógica principal del programa. En este caso se ha empleado el microcontrolador ESP-WROOM-32 [76], mostrado en la Figura 42. Figura 42. ESP-WROOM-32 DevKit v1. Este microcontrolador actualmente está descatalogado debido al surgimiento de nuevas versiones por parte del fabricante, incluso se detalla en su hoja de datos “Not Recommended For New Designs”, sin embargo, al ser el material disponible y contar con las capacidades necesarias para el desarrollo del VTOL se utilizará esta versión. 3.2.9.1 Estudio teórico En lo referente a la decisión de utilización se han tenido en cuenta principalmente: • Sus características de procesamiento, incorporando dos microprocesadores Xtensa®32-bit LX6 y poseyendo una frecuencia de reloj de CPU desde 80MHz a 240MHz [76], permitiendo ejecutar más instrucciones de código en un menor tiempo, frente a otros competidores como Arduino [77]. Este hecho puede visualizarse en algunas comparativas llevadas a cabo por la comunidad, donde se comparan consumos, CPU y ciclos de procesamiento, llevando a cabo experimentos en el establecimiento de salidas en alta y baja, así como en el procesamiento de instrucciones [78]. Universidad de Valladolid 65 • Su conectividad y cantidad de puertos, que nos servirán para poder conectar múltiples sensores, soportando los protocolos UART (Universal Asynchronous Receiver/Transmitter), SPI o I2C (Two-Wire) [76]. • Sus tarjetas de comunicación inalámbrica, que soportarán Bluetooth v 4.2, permitiendo conectar todo tipo de dispositivos, así como WiFi (Wireless Fidelity) en su versión 802.11 b/g/n [76]. • Su capacidad para generar múltiples pulsos PWM frente a otros microcontroladores que tienen un número menos elevado de puertos, esto nos limitaría de cara a enviar las señales a los motores. En lo referente a las conexiones implementadas, así como sus características para los puertos empleados serán discutidos durante la sección de los desarrollos esquemáticos y software, donde serán analizadas en detalle. 3.2.9.2 Implementación práctica En la práctica se han utilizado todas las características mencionadas anteriormente, empleando pulsos PWM para el envío de señales de control a los ESC que gestionarán los motores, utilizando protocolos I2C(Two-Wire) para la comunicación con los sensores y UART para la comunicación con otros ESP-32. En lo referente a las características de procesamiento, se ha observado su potencia a la hora de implementar los PID, obteniendo tiempos de respuesta cortos que permiten una mejor implementación de los sistemas de control. Finalmente se han aprovechado sus conexiones WiFi para el envío de estadísticas de forma remota durante las pruebas de vuelo, así como su conexión Bluetooth para su conexión con el control manual del VTOL. Universidad de Valladolid 66 3.2.10 Alimentación En lo referente a la alimentación se han empleado las baterías RoaRingTop 35c de alta descarga, esta batería se muestra en la Figura 43. La capacidad de las baterías es de 2200mAh, formada por celdas de polímero de litio, que suman un total de 11.1V. Figura 43. Batería RoaRingTop 35c 2200mAh. 3.2.10.1 Estudio teórico Respecto a este tipo de baterías nos centraremos en sus principales características. Comenzando con la nomenclatura observamos que se indica 3S 11.1V, la S nos indica que la batería está compuesta por tres celdas Li-Po en serie [79], teniendo en cuenta que el voltaje nominal de una batería Li-Po, debido a la configuración química de las celdas de iones de litio, es de 3.7V tenemos 3.7𝑉∗3=11.1 𝑉 . Otro tipo de nomenclaturas podrían designar que se están colocando las baterías en paralelo utilizando una “P”. En lo referente a 35c indica la tasa de descarga máxima de la batería, describiendo cuanta corriente es capaz de entregar en un instante de tiempo sin sufrir daños estructurales o químicos [79]. En nuestro caso poseemos una batería de 2200mAh con una tasa máxima de descarga de 35c, lo que implica que nuestra batería será capaz de entregar 35𝐶∗ 2.2𝐴ℎ=77𝐴ℎ, lo que significa que puede entregar toda su carga en 1ℎ 35𝐶∗60 ≈ 1.7 𝑚𝑖𝑛𝑢𝑡𝑜𝑠 o lo que es lo mismo 77𝐴ℎ 60𝑚𝑖𝑛 ≈1.7 𝑚𝑖𝑛𝑢𝑡𝑜𝑠. Esta característica es Universidad de Valladolid 67 importante ya que será la que nos permitirá entregar la potencia necesaria a los ESC y finalmente a los motores. Respecto al voltaje de 11.1V podemos indicar que se trata de un voltaje nominal, definido como el RMS (Root Mean Square) con lo que, dependiendo de la carga de la batería, la temperatura u otros factores, podremos obtener valores de tensión distintos. Las baterías constan además de un conector JST-XH-4P que servirá para monitorizar la carga de cada una de las celdas de la batería. Este tipo de conector fue creado por la empresa J.S.T. Mfg.Co [80] con la finalidad de definir estándares en el proceso de carga de baterías. A continuación, se expondrá el proceso de carga con la finalidad de comprender el desarrollo completo. 3.2.10.1.1 Proceso de carga De cara a la realización del proceso de carga será necesario emplear un balanceador que facilite el reparto de la carga en cada una de las celdas de nuestra batería de tres celdas Li-Po. El balanceador empleado ha sido el IMAX-B6 mostrado en la Figura 44. Figura 44. Balanceador de carga IMAX-B6. Este balanceador es compatible con diferentes tipos de conectores JST-XH tal y como se muestra en la siguiente figura. Estos conectores servirán para poder monitorizar los voltajes de cada una de las celdas de la batería por separado, pudiendo balancear la carga para evitar que unas celdas se carguen de forma excesiva mientras que otras no están cargadas, lo que podría dañar la batería. Universidad de Valladolid 68 Tal y como se define en su manual de usuario, para la utilización de baterías cuya química está basada en Li-Po será necesario establecer un límite máximo de carga de 4.2V por celda y evitarse una descarga inferior a 3V por celda, para evitar el dañado de la batería. Figura 45. Conectores JST-XH en función de las celdas de la batería. Además de esto, se indica que la tasa de intensidad máxima debe ser inferior a 1C, en nuestro caso inferior a 2.2Ah [81]. Para realizar la carga será necesario seleccionar el tipo de batería Li-Po y establecer el voltaje y la carga máximos, en el caso que nos ocupa, se ha establecido en 1A para la carga y 11.1V. En cuanto a las conexiones deberemos conectar el positivo y negativo de la batería a los pines de salida OUTPUT del IMAX-B6, y el conector JST-XH-4P al conector socket de monitorización de balanceo de celdas. Es importante destacar que el dispositivo de balanceo permite hacer una configuración totalmente libre en cuanto a tensiones, celdas y voltajes, por lo que será crítico conectar y configurar con precaución los valores de nuestras baterías. 3.2.10.2 Implementación práctica En la práctica ha sido necesario modificar los conectores de las baterías y del balanceador con la finalidad de “estandarizar” las conexiones de nuestro VTOL. Aplicando las configuraciones indicadas en el manual para baterías Li-Po 3S de 11.1V no ha habido ningún tipo de problemas. Universidad de Valladolid 69 El balanceador cuenta además con protecciones frente a cortocircuitos, avisando con diferentes zumbadores en caso de establecer las corrientes en sentido inverso o en caso de que se superen los voltajes configurados en los ajustes durante el proceso de carga. Durante vuelos intensivos se ha visualizado que la temperatura de las baterías ha aumentado significativamente al requerir entregar de golpe grandes cantidades de carga, sin embargo, no se han hinchado ni sufrido ningún tipo de daños. 3.3 Análisis de potencia Una vez expuestos los componentes hardware, deberemos mencionar cuál será el consumo de potencia estimado, con la finalidad de determinar el tiempo de vuelo aproximado de nuestro VTOL. Recopilando los datos de la sección hardware nos encontraremos con que el consumo máximo de nuestros motores BLDC será de 133.2W para los motores A2212 seleccionados. En lo referente a los ESC, dado que no conocemos de forma exacta el conjunto de componentes, ya que el vendedor no lo facilita de forma explícita, podremos estimar el consumo de este en un amperio, suponiendo que sus circuitos integrados trabajen a 5V tendríamos una adición de potencia de 5W. Continuando con los servomotores, en su hoja de datos se indica que tienen un consumo de unos 500mA – 900mA para una tensión de 6V [43], en nuestro caso estarán alimentados con la salida de voltaje de los ESC, operando a 5V, además no estarán realizando cambios bruscos durante la mayor parte del tiempo, con lo que podemos estimar su consumo en unos 500𝑚𝐴ℎ ∗ 5𝑉 = 2.5𝑊. En lo referente a los sensores, tenemos que el sensor de presión BMP390 estará operando a una tensión de alimentación de 3,3V, proporcionada por el ESP-32 principal, se especifica que su salida de 3V3 es capaz de aportar una tensión máxima de 3.6V y una carga máxima de 1.1A[76], sin embargo, el sensor BMP390, configurado con un oversampling a resolución estándar para la presión y a alta resolución para la temperatura tendrá un consumo típico de unos 13,8µA [53]. Será necesario incorporar los consumos aproximados del resto de componentes que permiten el funcionamiento del sensor, y se deberá tener en cuenta que operará a unos 50Hz. Con todo esto podemos estimar el consumo conjunto del encapsulado BMP390 en 25µ𝐴∗3,3𝑉≈83µ𝑊. Universidad de Valladolid 70 Continuando con el MPU6050 se indica que su consumo típico para uso único del acelerómetro y giróscopo con el DMP desactivado des de 3,8mA y operará a una tensión máxima de 3,46V [45]indicando que su consumo se encuentra entorno a los 13mW. Finalmente toca hablar del HC-SR04 que operará a 5V y tendrá un consumo de unos 15mA cuando se es té usando, obteniendo 75mW de potencia. Como hemos podido observar, el consumo de los sensores será prácticamente despreciable frente a la energía consumida por los motores, recopilando todos los datos: 133,2𝑊+5𝑊+2,5𝑊+83µ𝑊+13𝑚𝑊+75𝑚𝑊=140,78𝑊 Tomando estos datos y teniendo en cuenta que nuestra batería cuenta con 24,43Wh, la fuente de alimentación podrá suministrar 24,43W durante una hora, dado que tiene que proporcionar 140,78W, tendrá que aportar 140,78 11,1𝑉 =12,68𝐴 de forma constante. Haciendo una regla de tres obtenemos 12,68𝐴∗1ℎ 2,2𝐴 =1ℎ 5,76=10,41𝑚𝑖𝑛. El tiempo de vuelo estará reducido a 10,41 minutos teniendo en cuenta que los motores estén funcionando a su máxima potencia y los sensores y actuadores se empleen de forma constante. En la práctica se ha podido determinar, que el tiempo de vuelo medio de cada batería completamente cargada es de unos 13-15 minutos, tiempo que será suficiente para la entrega de paquetes en cortas distancias. Una de las posibles aplicaciones prácticas podría ser su implementación en entornos rurales, urbanizaciones o pequeños núcleos urbanos, donde la distancia de las viviendas a los centros logísticos de paquetería es notable para desplazamientos a pie, pero no excesivo empleando vehículos motorizados. Universidad de Valladolid 71 3.4 Desarrollo electrónico esquemático Esta sección tiene como objetivo aclarar algunas de las características técnicas asociadas a la interconexión de los distintos elementos que componen el sistema, así como definir la implementación final tras la realización de las pruebas. Se muestra en la siguiente página una figura relativa al diseño electrónico esquemático, la Figura 46 aporta la historia de colores empleados en el esquemático. Figura 46. Historia del diseño electrónico esquemático Como puede apreciarse, la alimentación principal corre a cargo de la batería, con una tensión aproximada de 12V cuando está totalmente cargada. Dicha tensión se convertirá en los ESC a 5V, tensión con la que operarán el resto de los componentes del circuito a excepción del sensor BMP390, que estará conectado al ESP32 a 3.3V. En lo referente a la conexión de los sensores, en todos los casos utilizan dos pines, destacando la comunicación I2C (Two-Wire) para el MPU6050 y para el BMP390, dejando los pines de eco y gatillo en el sensor de ultrasonidos. Los pulsos PWM se utilizan para el control de los ESC y de los servomotores, regulando tanto la velocidad de giro de los motores con hélices, así como la posición exacta de los servomotores. Universidad de Valladolid 72 Figura 47. Diseño electrónico esquemático Universidad de Valladolid 79 dispositivo entrar en modo de bajo consumo, sin desactivar el sensor de temperatura, por escalabilidad en la implementación, y seleccionando el oscilador interno del sensor. Figura 51. Registro de administración de potencia MPU6050. [91] A continuación, se ha configurado el FSR del giroscopio con una sensibilidad de ±500º/s. Figura 52. Registro de configuración del giroscopio MPU6050. [91] I2CIMU.beginTransmission(0x68); //Envío la dirección del esclavo 0x68 I2CIMU.write(0x1B); //Modificaré el registro del giroscopio(0x1B) I2CIMU.write(0x08); //Escribo en el registro 0 0 0 01 0 0 0 (+-500º/s) FSR I2CIMU.endTransmission(true); //Finalizo la comunicación No se prescindirá de ninguno de los ejes. Siguiendo con la configuración de los FSR, nos centraremos en el del acelerómetro, seleccionado en ±8g y nuevamente sin prescindir de ninguno de los ejes. Universidad de Valladolid 80 Figura 53. Registro de configuración del acelerómetro MPU6050. [91] I2CIMU.beginTransmission(0x68); //Envío la dirección del esclavo 0x68 I2CIMU.write(0x1C); //Modifico el registro del acelerómetro (0x1C) I2CIMU.write(0x10); //Escribo en el registro 0 0 0 10 0 0 0 (+- 8g) FSR I2CIMU.endTransmission(true); Finalmente se seleccionarán los filtros de frecuencia para los datos. Seleccionando un LPF en 44Hz para el acelerómetro y en 42Hz para el giroscopio. Figura 54. Registro de configuración de LPF para los datos del MPU6050.[91] Universidad de Valladolid 81 I2CIMU.beginTransmission(0x68); //Envío la dirección del esclavo 0x68 I2CIMU.write(0x1A); //Escribo en el registro de configuración (0x1A) I2CIMU.write(0x06); //Introduzco 00 000 011 (Seleccionando el LPF en 44Hz para acelerómetro y 42Hz para giroscopio) I2CIMU.endTransmission(true); En este punto habremos establecido la configuración de nuestro sensor y nos quedará la parte relacionada con la obtención de las medidas. Para ello emplearemos los métodos de requestFrom y read. Permitiéndonos obtener 6 registros de 8 bit para los datos del acelerómetro y el giróscopo. Cabe mencionar que cada uno de los valores en los ejes X, Y, Z poseen una precisión de 16 bit, por lo que para combinar los datos de los registros se ha aplicado un desplazamiento, guardando el valor completo en una variable en C. //Se solicita al sensor los datos del acelerómetro I2CIMU.beginTransmission(0x68); I2CIMU.write(0x3B); //Se solicita el registro 0x3B que corresponde con el valor de aceleración del eje X I2CIMU.endTransmission(false); I2CIMU.requestFrom(0x68,6,true);//Se solicitan 6 registros de 8 bit, correspondientes con los valores de aceleración de los tres ejes //A continuación se guarda la lectura de datos de aceleración del IMU en m/(s^2) Acc_X=I2CIMU.read()<<8|I2CIMU.read(); //Son datos de 16 bit, así que se desplazan 8 bit y se aplica la operación OR Acc_Y=I2CIMU.read()<<8|I2CIMU.read(); Acc_Z=I2CIMU.read()<<8|I2CIMU.read(); //Se obtienen los datos del giroscopio del IMU en radianes por segundo I2CIMU.beginTransmission(0x68); I2CIMU.write(0x43); //Datos del giroscopio en el eje X I2CIMU.endTransmission(false); I2CIMU.requestFrom(0x68,6,true); //Solo se solicitan los datos de los ejes X,Y y Z Gyr_X=I2CIMU.read()<<8|I2CIMU.read(); //Se vuelven a guardar los valores desplazando y aplicando OR Gyr_Y=I2CIMU.read()<<8|I2CIMU.read(); Gyr_Z=I2CIMU.read()<<8|I2CIMU.read(); Como puede apreciarse en el código anterior estaremos empleando los registros 0x3B y 0x43 que comienzan con los datos en el eje X respectivamente para el acelerómetro y el giróscopo [91], el resto de los datos se encuentran en registros adyacentes, con lo que iterando con requestFrom podemos obtener todos los datos. Universidad de Valladolid 82 4.3 Algoritmos y cálculos teóricos Tras haber expuesto la configuración y obtención de datos en crudo, así como las bibliotecas empleadas durante el desarrollo, nos centraremos en la parte más técnica de procesamiento de datos, en la que se expondrán los algoritmos principales que componen la base de funcionamiento del VTOL. 4.3.1 Obtención de ángulos El primer paso para poder determinar la posición del VTOL será obtener los ángulos a los que se encuentra este dispositivo, pudiendo obtener las inclinaciones de cada uno de sus ejes. Frente a esta casuística nos encontramos con un problema principal, el giroscopio a medida que pasa el tiempo deja de aportar datos precisos como consecuencia del drift. Este drift se debe principalmente a la propia construcción mecánica del giroscopio, donde tenemos un “muelle” oscilante que se mueve en dos dimensiones en función de las excitaciones en un eje y debido al efecto Coriolis. Esto supone que cada uno de los movimientos como consecuencia de los rozamientos, no permitan volver a establecer la posición inicial de referencia de forma exacta. O que movimientos lentos no produzcan variaciones internas en el sensor como consecuencia de dicho rozamiento. Matemáticamente esto puede observarse en que los datos que obtenemos del sensor son relativos a la velocidad angular, para conseguir la posición deberíamos efectuar una integral. 𝑟(𝑡)=𝑟0+∫𝑣 𝑡 0𝑑𝑡 Esto produce que los términos constantes de la velocidad, al integrarlos generen un error que aumenta linealmente con el tiempo, podríamos concebirlo en nuestro sensor como un offset de continua [92]. Si incorporamos el concepto de frecuencia, podríamos obtener una integral similar a la siguiente: ∫cos (2𝜋𝑓𝑡)=𝑠𝑒𝑛(2𝜋𝑓𝑡) 2𝜋𝑓 Universidad de Valladolid 83 Cuando la frecuencia es elevada el error asociado al ruido desaparecerá totalmente con la integración, sin embargo, si la frecuencia es baja (movimientos muy lentos) el ruido se amplificará, aumentando el drift [93]. En la práctica, estos desajustes los obtendríamos si, al recoger los datos del sensor en radianes por segundo, multiplicamos por el tiempo en el que se obtuvieron los datos, dado que no contamos con unos valores de tiempo infinitamente precisos. Como medida paliativa podríamos utilizar los datos del acelerómetro para contrarrestar dicho drift, dado que, pese a que sus mediciones debido a las vibraciones pueden ser muy inexactas, si utilizamos sus valores medios o sus valores altamente filtrados en frecuencia podremos obtener una situación viable [94]. En este caso, dado que la aceleración es un valor vectorial, podremos aplicar rotaciones matriciales con la finalidad de calcular los ángulos de Euler [95], pudiendo así obtener las componentes angulares de la aceleración que paliarán el problema del drift. En nuestro código inicialmente se realizará una calibración de los sensores inicial, para tratar de minimizar el error (𝐴𝑛𝑔𝑢𝑙𝑜𝐴𝑐𝑐𝑋𝑒𝑟𝑟𝑜𝑟), posteriormente se obtendrán los datos del acelerómetro y se calcularán sus ángulos de Euler. 𝐴𝑛𝑔𝑢𝑙𝑜𝐴𝑐𝑐𝑋= [ 𝑎𝑡𝑎𝑛( 𝐴𝑐𝑐𝑌 𝐴𝑐𝑐𝑠𝑐𝑎𝑙𝑒 √(𝐴𝑐𝑐𝑋 𝐴𝑐𝑐𝑠𝑐𝑎𝑙𝑒)2+( 𝐴𝑐𝑐𝑍 𝐴𝑐𝑐𝑠𝑐𝑎𝑙𝑒)2)∗180 𝜋 ] −𝐴𝑛𝑔𝑢𝑙𝑜𝐴𝑐𝑐𝑋𝑒𝑟𝑟𝑜𝑟 𝐴𝑛𝑔𝑢𝑙𝑜𝐴𝑐𝑐𝑌=[𝑎𝑡𝑎𝑛2(−𝐴𝑐𝑐𝑋 𝐴𝑐𝑐𝑠𝑐𝑎𝑙𝑒,𝐴𝑐𝑐𝑍 𝐴𝑐𝑐𝑠𝑐𝑎𝑙𝑒)∗180 𝜋]−𝐴𝑛𝑔𝑢𝑙𝑜𝐴𝑐𝑐𝑌𝑒𝑟𝑟𝑜𝑟 Donde 𝐴𝑐𝑐 representa los datos recogidos por el sensor y 𝐴𝑐𝑐𝑠𝑐𝑎𝑙𝑒 indica la escala aplicada en la configuración del sensor, en nuestro caso ±8g como se indicó en la sección anterior. Finalmente pasaremos de radianes a grados (nótese que el error ya fue transformado a grados durante la calibración). A continuación, se obtendrán los datos del giroscopio, ajustando también su escala y se adaptará el traspaso de los ángulos pitch (eje Y) y roll (eje X) en los casos en los que haya rotación diagonal. 𝐺𝑦𝑟𝑜𝑋= 𝐺𝑦𝑟𝑜𝑋+[𝐺𝑦𝑟𝑜𝑌∗𝑒𝑙𝑎𝑝𝑠𝑒𝑑𝑇𝑖𝑚𝑒∗𝑠𝑒𝑛(𝐺𝑦𝑟𝑜𝑍∗𝑒𝑙𝑎𝑝𝑠𝑒𝑑𝑇𝑖𝑚𝑒∗ 𝜋 180)] Universidad de Valladolid 84 𝐺𝑦𝑟𝑜𝑌= 𝐺𝑦𝑟𝑜𝑌+[𝐺𝑦𝑟𝑜𝑋∗𝑒𝑙𝑎𝑝𝑠𝑒𝑑𝑇𝑖𝑚𝑒∗𝑠𝑒𝑛(𝐺𝑦𝑟𝑜𝑍∗𝑒𝑙𝑎𝑝𝑠𝑒𝑑𝑇𝑖𝑚𝑒∗ 𝜋 180)] Donde 𝐺𝑦𝑟𝑜 representa los datos del sensor normalizados con su escala y 𝑒𝑙𝑎𝑝𝑠𝑒𝑑𝑇𝑖𝑚𝑒 el tiempo transcurrido tras la lectura de los datos del sensor, consiguiendo pasar de radianes por segundo a grados. Finalmente se aplicará un filtro complementario donde se tendrán en cuenta principalmente los datos del giroscopio y se utilizarán los ángulos de Euler del acelerómetro para corregir dicha posición. 𝑟𝑜𝑙𝑙=0.995∗(𝑟𝑜𝑙𝑙+ 𝐺𝑦𝑟𝑜𝑋)+0.005∗𝐴𝑛𝑔𝑢𝑙𝑜𝐴𝑐𝑐𝑋 𝑝𝑖𝑡𝑐ℎ=0.995∗(𝑝𝑖𝑡𝑐ℎ+ 𝐺𝑦𝑟𝑜𝑌)+0.005∗𝐴𝑛𝑔𝑢𝑙𝑜𝐴𝑐𝑐𝑌 𝑦𝑎𝑤=𝑦𝑎𝑤+ (𝐺𝑦𝑟𝑜𝑍) La utilización de este tipo de filtro lo que nos permite es tener muy en cuenta los nuevos valores del giroscopio, pero incorporando leves modificaciones en los ángulos del acelerómetro, pudiendo así evitar las vibraciones del dispositivo. En la práctica se intercambiaron los valores de roll y pitch como consecuencia de la orientación de los ejes del sensor en la implementación real. 4.3.2 PID Una vez hemos calculado los ángulos a los que se encuentra nuestro VTOL deberemos tratar de realimentar esos datos con el objetivo de que los motores actúen ajustando el equilibrio del dispositivo. Será aquí donde entre en juego el PID. Los PID serán los encargados de efectuar de forma práctica dicha estabilización de vuelo. De cara a su implementación, inicialmente se probó a introducir de forma directa los ángulos en el PID, tratando de ajustar sus coeficientes. Aplicando las siguientes ecuaciones genéricas para cada uno de los ángulos: 𝐴𝑛𝑔𝑒𝑟𝑟𝑜𝑟=𝐴𝑛𝑔𝑎𝑐𝑡𝑢𝑎𝑙−𝐴𝑛𝑔𝑑𝑒𝑠𝑒𝑎𝑑𝑜 𝑃=𝐾𝑝∗𝐴𝑛𝑔𝑒𝑟𝑟𝑜𝑟 𝐼=𝐼+(𝐾𝑖∗𝐴𝑛𝑔𝑒𝑟𝑟𝑜𝑟) 𝐷=𝐾𝑑+(𝐴𝑛𝑔𝑒𝑟𝑟𝑜𝑟−𝐴𝑛𝑔𝑒𝑟𝑟𝑜𝑟_𝑝𝑟𝑒𝑣𝑖𝑜 𝑒𝑙𝑎𝑝𝑠𝑒𝑑𝑇𝑖𝑚𝑒 ) Universidad de Valladolid 85 𝑃𝐼𝐷=𝑃+𝐼+𝐷 Teniendo así que la parte proporcional depende directamente del error, la parte integral va acumulando los errores y la parte derivativa da cuenta de las diferencias de errores respecto al error anterior. Las constantes o coeficientes son valores que se han ido ajustando de forma práctica [96]. Esta primera implementación, en la práctica, arrojaba unos resultados válidos, pero nada estables, pudiendo mantener un vuelo, pero a duras penas, con cambios bruscos. Por este motivo se decidió emplear en el PID la velocidad angular en vez del ángulo total. Al utilizar la velocidad angular, dado que se emplean tasas de cambio en vez de valores absolutos de ángulos las respuestas se visualizaron más rápidas, desembocando en una mayor estabilidad. El problema de esta implementación era que, si el dispositivo al inicio del vuelo no estaba perfectamente calibrado, se recordaba esa posición como buena, volando con un plano de referencia un poco inclinado. Como decisión final se decidió implementar un procesamiento en cascada con un P y un PID. El primer proceso de estabilización trabajaría con los ángulos absolutos, mientras que el segundo ajustaría, una vez estabilizado el vuelo los valores relativos. De este modo el primer PID pasará los valores al segundo cómo ángulo deseado con signo negativo para cada ángulo: 𝑇𝑎𝑠𝑎𝐴𝑛𝑔𝑢𝑙𝑎𝑟𝐷𝑒𝑠𝑒𝑎𝑑𝑎=−𝑃𝐼𝐷𝑡𝑜𝑡𝑎𝑙 Finalmente, el segundo PID realizará unos cálculos análogos, pero culminando con la modificación de los valores del throttle para cada uno de los motores: pwmEscIzq = throttle - PID_total_roll - PID_total_pitch; pwmEscDer = throttle + PID_total_roll - PID_total_pitch; pwmEscCent = throttle + PID_total_pitch; Esta implementación permitía calibrar el VTOL en una superficie plana, pero posteriormente facilitaba el despegue desde superficies inclinadas, adecuando el plano al plano de calibración gracias al primer PID absoluto. Como parte añadida, esta implementación nos permitirá inclinar de forma sencilla nuestro VTOL pudiendo conseguir que se desplace a izquierda, derecha, adelante o atrás. Universidad de Valladolid 86 4.3.2.1 Rasgos específicos del yaw Dado que el VTOL en desarrollo únicamente contará con tres motores y además los dos motores de la parte delantera irán acoplados a unos servomotores se hace necesario definir algunas implementaciones clave de su desarrollo. Al poseer un número impar de motores, se producirá de forma intrínseca un giro en el sentido opuesto al sentido de giro de dos de los motores. Para evitar dicho giro los servomotores generarán un pequeño desajuste en la alineación de los BLDC. Dicho desajuste, junto con el funcionamiento esquemático se representa en la Figura 55. La figura nos muestra el movimiento de rotación que se llevará a cabo para regular este giro. Además, estos giros nos permitirán desplazar el VTOL adelante y atrás sin necesidad de llevar a cabo ajustes adicionales en los parámetros de entrada de los PID. Figura 55. Representación esquemática del movimiento de los BLDC acoplados a servomotores. De cara a su implementación, se ha calculado de forma práctica el desajuste necesario en el posicionamiento de los servomotores para evitar la rotación producida por tener un número de motores de propulsión impares. En lo referente al PID se ha aplicado una equivalencia de valores que permita establecer unos límites de rango de operación, aplicando así el ajuste deseado en función de los valores de yaw realimentados por los sensores. //Mapeo el valor del yaw en función de la diferencia máxima de los servos PID_total_yaw=map(PID_total_yaw, 0,pid_max_value_roll_pitch_yaw , 0, 1000);//Es como aplicar map de 0 a 10 pero con decimales, de 0 a 1000 /100 PID_total_yaw/=100; Universidad de Valladolid 87 Finalmente ha sido necesario emplear el sensor de ultrasonidos para detectar si el vuelo ha comenzado. Para ello, cuando el VTOL se separa unos 10cm del suelo, se activa el PID del yaw. Es necesario realizar esta distinción, dado que, si tras el calibrado movemos el dispositivo a otra zona para el despegue, girándolo durante el proceso, se estaría incrementando la parte integral del yaw como consecuencia del rozamiento de la superficie, derivando en una rotación descontrolada del VTOL. 4.3.2.2 PID de altitud Respecto al control de altura, se ha establecido un PID de forma análoga al expuesto al inicio de la sección 4.3.2, pero empleando un único PID sin conexiones en cascada. Como principal diferencia, se han establecido constantes proporcionales no lineales, dado que, en la práctica, el VTOL no precisa de la misma potencia para ascender o descender, con lo que se han establecido restricciones en función de si el error es debido a superar la altitud deseada o si se necesita incrementar la altura. if (error_alt<10 && error_alt>-10){//Margen más estable kp_alt=kp_alt_ref; }else if(error_alt<=0){ kp_alt=kp_alt_ref+((abs(error_alt)-10)/20);//Se genera un kp no lineal, dado que no le cuesta lo mismo subir o bajar si tiene un throttle más alto o bajo //Se endurece la condición; a medida que aumenta el error también aumenta el KP. }else{ kp_alt=kp_alt_ref+((abs(error_alt)-10)/15);//Además hago que se endurezcan aún más las condiciones cuando se está por encima de la altura deseada } En el caso del valor aplicado al throttle, se realiza de forma uniforme para los tres motores. 4.3.3 Otras pruebas Con la finalidad de arrojar luz acerca de otras alternativas probadas, se exponen algunos de los casos puestos en práctica durante el desarrollo del dispositivo. Estas pruebas en su mayoría se asocian directamente con el posicionamiento. Aunque como se ha comentado durante la sección hardware las pruebas fueron descartadas por viabilidad o por tecnología se aportan unas pequeñas nociones del software empleado. Universidad de Valladolid 88 4.3.3.1 Pruebas con GNSS Las pruebas para determinar las distancias se llevaron a cabo realizando pruebas con dos principales bibliotecas: NeoGPS [97] y TinyGPS [98]. La primera de ellas no resultó ser funcional, debido a incompatibilidades con ESP-32 y sus versiones antiguas, por lo que se empleó la segunda, más antigua pero funcional. Se determinó que en la zona de pruebas no se podrían distinguir prácticamente más de 2-3 puntos sin mucha precisión, teniendo que mantener la posición durante un tiempo y en zonas muy extremas del área disponible. También se llevaron a cabo pruebas sin la utilización de bibliotecas empleando un código similar al expuesto en el módulo de GPS del proyecto [96]. 4.3.3.2 Pruebas con fotosensor De cara a la utilización del ADNS3080 se empleó la biblioteca [99] con la que se pudo monitorizar movimientos hasta a 10cm de una superficie en condiciones normales y de hasta unos 50cm en condiciones de alta luminosidad. Esta biblioteca presenta un desarrollo escrito en Python [100] que permite visualizar imágenes en escala de grises tomadas por el fotosensor. En la práctica se probó con varios sensores, incluso incorporando módulos Arduino, pero no se alcanzaba una resolución de imágenes viable para trabajar a largas distancias, a esto se le sumaba el problema de la homogeneidad de la superficie en la que se probó, que dificultaba aún más que esta alternativa fuera viable. 4.3.3.3 Posicionamiento con MPU6050 Se trataron de implementar algoritmos basados en la aceleración y el giróscopo del MPU6050 para poder determinar la posición con precisión. Para ello se implementó un algoritmo que eliminaba la componente de gravedad empleando matrices de rotación, de forma similar a como se expone en [101]. Básicamente se emplearon las matrices de rotación utilizando un vector que representaba la gravedad en cada componente 𝑣[0,0,9.8] [102]. Universidad de Valladolid 95 5.2 Diseño de piezas Tras determinar de forma genérica la estructura del VTOL, se observó la necesidad de incorporar piezas que permitieran sujetar los motores a las varillas, mantener unidas las varillas ente sí, sujetar la batería, mantener la electrónica adherida al dispositivo e implementar un mecanismo móvil que facilitara que los servomotores movieran los BLDC. Al ser piezas tan específicas, se decidió utilizar un desarrollo tridimensional, haciendo uso de una impresora 3D que generaría las piezas empleando un plástico compuesto por PLA, que posee una rigidez suficiente para asegurar los componentes. El diseño se ha llevado a cabo con la herramienta online ThinkerCAD[103] , a pesar de ser una herramienta simple basada en formas poliédricas básicas, permite realizar diseños de gran complejidad. Para la impresión se ha utilizado la herramienta Ultimaker Cura [104], que permitirá convertir los ficheros STL a ficheros GCODE basados en posiciones que pueda interpretar nuestra impresora 3D. Además, nos ofrecerá la posibilidad realizar multitud de configuraciones de impresión, desde las capas de adhesión hasta soportes y configuraciones geométricas de relleno de piezas. La fabricación de las piezas se ha realizado con una impresora BIQU-B1, vendidas por el fabricante BIQU [105]. La pieza principal para comenzar la construcción será la que una las tres varillas de aluminio, situándolas en ejes de 120º. Esta pieza se muestra en la Figura 57. La pieza se ha diseñado de forma simétrica y contiene orificios, que permitirán, mediante perforaciones en las varillas, introducir tornillos con tuerca para sujetar la estructura. Sobre esta pieza se colocará el soporte para la electrónica, concretamente la PCB principal en la que se alojará la mayor parte del hardware, puede visualizarse en la Figura 58. La Figura 59 muestra los soportes donde se acoplarán los servomotores delanteros en las varillas, estos soportes, además permitirán incorporar una pieza móvil que sujete a los BLDC en su parte superior, esta segunda pieza se muestra en la Figura 60. Para el desarrollo de estas dos últimas piezas se empleó un diseño ya creado del motor MG559R en la plataforma Thingiverse [106]. La Figura 61 muestra el funcionamiento de la pieza móvil, que será movida por el servo. Universidad de Valladolid 96 Figura 57. Pieza central de unión de las varillas metálicas. Figura 58. Vista superior(izquierda) e inferior(derecha) se la sujeción de la PCB genérica. Universidad de Valladolid 97 Figura 59. Soporte para incorporar los servomotores en las varillas delanteras. Figura 60. Pieza móvil (izquierda) acoplada a los servomotores, para incorporar los BLDC y muestra de montaje (derecha). Figura 61. Muestra de funcionamiento de la pieza móvil, incorporando el servomotor. Universidad de Valladolid 98 Continuando con las piezas de los motores, queda mostrar la pieza del motor trasero, que irá montado en la varilla central, puede visualizarse en la siguiente figura. Figura 62. Pieza del motor trasero central en múltiples vistas. Sobre esta misma varilla se colocará el soporte de la batería, aportado en la Figura 63. Nótese que cuenta con un pequeño orificio que atraviesa la pieza, su objetivo es poder incorporar un mecanismo de sujeción adicional como una goma elástica para el prototipado, asegurando completamente la batería, pero facilitando su reemplazo para la realización de pruebas. Figura 63. Soporte de batería situado sobre la varilla central. Universidad de Valladolid 99 A lo largo del proyecto se llevaron a cabo múltiples diseños para poder ajustar los coeficientes de los PID, configurando el roll, pitch y yaw por separado, para ello se diseñaron las piezas mostradas en la Figura 64. Estas piezas en ocasiones se acoplaban a estructuras de madera para realizar las sujeciones. Figura 64. Sujeciones para el cálculo práctico de los coeficientes de los PID de estabilización de vuelo ajuste del roll(izquierda), ajuste del pitch (central) y soporte de desequilibrio para roll, pitch y yaw. De izquierda a derecha y de abajo hacia arriba las dos primeras piezas sirvieron para calibrar el roll con la pieza inferior para sujetar los motores en una balanza y con la superior para introducir la varilla central solo con los motores delanteros montados. La parte central muestra 2 piezas que combinadas permiten bloquear el roll y el yaw, permitiendo equilibrar de forma única el pitch. Finalmente se calibró el yaw con la pieza de la derecha, utilizando un tornillo largo como punto central, incorporado en el orificio de la parte central de la pieza de la Figura 57. También se diseñaron algunos complementos como unas patas a incorporar, pero sus diseños iniciales se descartaron debido a que, tras su montaje no se conseguía una base totalmente plana e interfería a la hora de calibrar el sensor MPU6050. Puede visualizarse en la Figura 65. Estas patas provocaban además accidentes, ya que, al tener un punto de apoyo, si el VTOL caía se inclinaba, descargando toda la energía potencial del golpe en las hélices, mucho más quebradizas. Universidad de Valladolid 100 Figura 65. Diseño de patas para el VTOL, no empleado en la implementación final. Se optó por diseñar unas patas de menor altura que permitieran calibrar la parte central del VTOL en una superficie completamente plana, estas se muestran en la Figura 66. Figura 66. Implementación final de las patas, a colocar en los extremos del VTOL. Universidad de Valladolid 101 6. COSTES A pesar de que la mayoría de los componentes electrónicos han sido proporcionados por la UVA (ETSIT), empleados de los disponibles en el laboratorio, se realizará una estimación de costes materiales. También se realizará una estimación de los costes humanos y la gestión de tiempos empleada durante el desarrollo de este proyecto. 6.1 Costes de la prueba de concepto y prototipado A la hora de visualizar los costes, no se han ceñido de forma exacta a los empleados durante el desarrollo, como consecuencia de emplear materiales proporcionados por la UVA. COMPONENTE MODELO CANTIDAD PRECIO POR UNIDAD PRECIO TOTAL VENDEDOR Microcontrolador ESP-WROOM- 32 DevKitv1 3 0,99 2,97 Aliexpress Motores BLDC A2212/13T - 1000KV 3 9,99 29,97 Amazon ESC ESC SIMONK30A 3 14,99 44,97 ElectroStore Servomotores MG996R 2 11,99 23,98 Amazon IMU MPU-6050 1 5,99 5,99 Amazon Sensor de ultrasonidos HC-SR04 1 1,8 1,8 Amazon Sensor de presión BMP390 1 5,39 5,39 Aliexpress Fotosensor ADNS3080 1 13,78 13,78 Aliexpress GNSS NEO-M8N 1 12,35 12,35 Aliexpress Baterías 35c - 2200mAh 3 22,05 66,15 Amazon Cargador de baterías IMAX-B6 1 17,42 17,42 Amazon Varillas 16mm x 16mm x 1m 3 6,69 20,07 Leroy Merlin PLA de impresión 1,75mm - 1 Kg 1 24,99 24,99 Amazon Protoboard (soldadura) (Pack) 1 14,44 14,44 Amazon Cables de prototipado (Pack) 1 8,48 8,48 Amazon Tornillos M5 (Pack) 1 11,99 11,99 Amazon Mando de control PlayStation 3 1 28,54 28,54 Eneba TOTAL 333,28 € Figura 67. Estimación de costes sobre los principales materiales que permiten desarrollar el proyecto. Universidad de Valladolid 102 Los datos mostrados anteriormente corresponden con anuncios actuales que no se reflejarán en las referencias de este documento, pero serán expuestos en el anexo final. En los casos que no cuentan con total exactitud se exponen alternativas viables con un compromiso disponibilidad precio moderado. El coste de los materiales no aporta de forma única el conformado final del VTOL, sino que incluye componentes dedicados a pruebas de concepto con la finalidad de su estudio de viabilidad. 6.2 Costes temporales A la hora de exponer los costes temporales de la realización del proyecto se aportarán los periodos dedicados al estudio, composición y fabricación de la estructura, desarrollo electrónico, software y pruebas. Cabe destacar que el coste temporal ha venido condicionado principalmente por la realización de pruebas de concepto y pruebas de vuelo. Se muestra a continuación un diagrama Gantt realizado con la herramienta GanttProject [107]. Figura 68. Diagrama de Gantt de costes temporales (primera parte) Universidad de Valladolid 103 Figura 69. Diagrama de Gantt de costes temporales (segunda parte) Las figuras anteriores muestran las tareas con mayor repercusión durante el proyecto, diferenciando entre pruebas de vuelo, pruebas de concepto e investigaciones y avance teórico. El grueso del proyecto comprende un tiempo de un año y medio aproximadamente sin tener en cuenta la parte de la documentación. Durante este periodo se ha desarrollado de forma constante en función del tiempo disponible. Las principales partes que más tiempo han consumido están relacionadas con la obtención de datos fiables de los sensores (compromiso de varianza de datos frente a obtención de datos viables), así como la realización de las pruebas asociadas a dicho funcionamiento. Esta técnica se ha desarrollado de forma reiterada en la práctica, aplicando la base teórica matemática, realizando pruebas y volviendo a realizar nuevos ajustes en los algoritmos, con la finalidad de perfeccionar el funcionamiento y la estabilidad. En la Figura 70 se muestra un resumen textual del informe generado a partir del anterior diagrama de Gantt. Universidad de Valladolid 104 Figura 70. Resumen del diagrama de Gantt expuesto de forma textual. Universidad de Valladolid 111 //----------PID_variables control altura---------- double kp_alt_ref=0.1; double kp_alt=kp_alt_ref; double ki_alt=0;// double kd_alt=0;// int PID_total_alt; //Tiene que ser un entero porque se va a sumar al throttle float error_alt, previous_error_alt; float pid_p_alt=0; float pid_i_alt=0; float pid_d_alt=0; float desired_alt = 0;//Altitud deseada en centímetros (se predefine en 0, cuando se active se cambia a la altura que haya) int throttle_actual =0;//Throttle de referencia por seguridad cuando se activa el control de altitud se modifica //Despegue en superficies con rozamiento bool despegue_inic=false; //Se utiliza para no emplear el yaw hasta que se eleve del suelo unos 15 cm, evitando que se acumule en la integral el error por rozamiento int altitud_corte_despegue=25; bool preparacion_despegue=false;//Creado para evitar que tras calibrar se mueva el dron y se pase la altura máxima, habrá que presionar START en el mando para que empiece a calcular la altura bool START_on = false; //Para el botón start en el mando //Remotelogs para envío vía serie a un segundo ESP32 que actuará como servidor web (API REST) //double timeNow_serial2, timePrev_serial2, elapsedTime_serial2; const byte numCharsLogs = 36;// 2 (<>) + 5 altitud, 5 altitud deseada, 5 error, 5 PID,4 throttle + 5X2=10 (::) String logs; //----------------------------------------------DECLARACIÓN FUNCIONES- ----------------------------------------------------- //-------------------------------------------------------------------- ----------------------------------------------------- //Cálculo sensores altitud void calculoAltitudRelativaCalibrado(); void computoAltitudPresion(); void computoAltitudUltraSonido(); //PID's void ajustePidAngle(); void ajustePidRateAngle(); void ajustePidAltura(); //Control manual void ps3Control(); //Calibración void calculoErrorImuMedio(); void calculoAltitudRelativaCalibrado(); Universidad de Valladolid 112 //-----------------------------------------------------------PROGRAMA- ----------------------------------------------------- //-------------------------------------------------------------------- ----------------------------------------------------- //----------SETUP---------- void setup() { delay(5000);//Para depurar //Inicializo el puerto serie para depuración de datos Serial.begin(9600); //Si hay algún tipo de error en la comunicación Serie se para while(!Serial) {} Serial2.begin(500000); //Se inicia la comunicación con el sensor MPU6050 I2CIMU.begin(I2C_SDA_IMU,I2C_SCL_IMU,100000); //Inicio la comunicación I2CIMU.beginTransmission(0x68); //Envío la dirección del esclavo 0x68 I2CIMU.write(0x6B); //Selecciono el registro de administración de potencia (0x6B) I2CIMU.write(0x00); //Establezco todos los valores a cero I2CIMU.endTransmission(true); I2CIMU.beginTransmission(0x68); //Envío la dirección del esclavo 0x68 I2CIMU.write(0x1B); //Modificaré el registro del giroscopio(0x1B) I2CIMU.write(0x08); //Escribo en el registro 0 0 0 01 0 0 0 (+-500º/s) FSR I2CIMU.endTransmission(true); //Finalizo la comunicación I2CIMU.beginTransmission(0x68); //Envío la dirección del esclavo 0x68 I2CIMU.write(0x1C); //Modifico el registro del acelerómetro (0x1C) I2CIMU.write(0x10); //Escribo en el registro 0 0 0 10 0 0 0 (+- 8g) FSR I2CIMU.endTransmission(true); I2CIMU.beginTransmission(0x68); //Envío la dirección del esclavo 0x68 I2CIMU.write(0x1A); //Escribo en el registro de configuración (0x1A) I2CIMU.write(0x06); //Introduzco 00 000 011 (Seleccionando el LPF en 44Hz para acelerometro y 42Hz para giroscopio) I2CIMU.endTransmission(true); if (calibracion_altitud==1){ I2CBMP.begin(I2C_SDA_BMP, I2C_SCL_BMP, 100000);//Inicializo la comunicación I2C con las direcciones del sensor de presión //Se comprueba el I2C para el BMP if (!bmp.begin_I2C(0x77, &I2CBMP)) { // Indico la dirección del sensor, así como el puntero que contiene las direcciones SDA y SCL personalizadas Universidad de Valladolid 113 Serial.println("Could not find a valid BMP3 sensor, check wiring!"); while (1); } //Configuración de los valores del barómetro //DEJO LOS VALORES RECOMENDADOS PARA EL DRONE EN EL DATASHEET bmp.setPressureOversampling(BMP3_OVERSAMPLING_4X);//Sobremuestreo x4 bmp.setTemperatureOversampling(BMP3_OVERSAMPLING_2X);//Me dicen que X1, pero la biblioteca solo tiene X2 o deshabilitado bmp.setIIRFilterCoeff(BMP3_IIR_FILTER_COEFF_3); //Filtro de orden 3 para suavizar los picos un poco bmp.setOutputDataRate(BMP3_ODR_50_HZ);//Aumento la tasa de muestreo a 50Hz } pinMode(TRIGPIN, OUTPUT); // Sets the trigPin as an Output pinMode(ECHOPIN, INPUT); // Sets the echoPin as an Input //Se inicia la conexión con el mando Ps3.begin("14:d4:24:aa:a4:bc"); Ps3.setPlayer(1); if (test==0){ //Se realizan las correspondencias de pines con los servos servo_der.attach(servoPinDer); servo_izq.attach(servoPinIzq); } //Armo los ESC (Señal de activación de los ESC un pulso PWM con un Duty Cycle bajo) esc_der.attach(escPinDer, minPWM, maxPWM); esc_der.writeMicroseconds(1000); esc_izq.attach(escPinIzq, minPWM, maxPWM); esc_izq.writeMicroseconds(1000); esc_cent.attach(escPinCent, minPWM, maxPWM); esc_cent.writeMicroseconds(1000); delay(500); esc_der.writeMicroseconds(0); esc_izq.writeMicroseconds(0); esc_cent.writeMicroseconds(0); logs="<ESCs armed - iniciando calibracion>"; for (int i=0; i<numCharsLogs;i++) { if(i<logs.length()){ Serial2.write(logs[i]); }else{ Serial2.write(' '); } } if (calibracion==1){ calculoErrorImuMedio(); if (calibracion_altitud==1){ calculoAltitudRelativaCalibrado(); } Universidad de Valladolid 114 }else{ //calibrado en superficie plana para varillas //Calib_angle_acc_roll:- 5.91,Calib_gyro_roll:0.90,Calib_angle_acc_pitch:- 0.22,Calib_gyro_pitch:-3.69,Calib_gyro_yaw:-0.14, //Patas inclinado: //Calib_angle_acc_roll:- 5.82,Calib_gyro_roll:0.77,Calib_angle_acc_pitch:- 8.64,Calib_gyro_pitch:-3.82,Calib_gyro_yaw:-0.09, //Suelo inclinado un poco ladrillo //Calib_angle_acc_roll:- 5.94,Calib_gyro_roll:0.91,Calib_angle_acc_pitch:- 3.58,Calib_gyro_pitch:-3.72,Calib_gyro_yaw:-0.21, //roll Acceleration_angle_error[1]=-5.94; Gyr_Y_error=0.91; //Pitch Acceleration_angle_error[0]=-3.58; Gyr_X_error=-3.72; //Yaw Gyr_Z_error=-0.21; } logs="<Calibracion OK - Inicio Programa>"; for (int i=0; i<numCharsLogs;i++) { if(i<logs.length()){ Serial2.write(logs[i]); }else{ Serial2.write(' '); } } delay(2000); Ps3.setPlayer(2);//Cuando se ha calibrado se cambia la luz del mando para avisar //Se guarda el estado temporal del programa para posteriormente pasar de º/s a º timeNow = millis(); } //----------LOOP---------- void loop() { if(test==0){//DEPURACIÓN //En el caso de que se pierda la conexión con el mando, se para el programa por precaución if(!Ps3.isConnected()){ throttle=1000;//Se baja el throttle a mil, para evitar daños físicos en el VTOL, este valor es prácticamente 0 while(true){//Se mantiene el programa en un bucle, esto está hecho para que en caso de que se acabe la batería del mando no haya problemas Universidad de Valladolid 115 } } } //Se llama a la función que ajusta el throttle e inclinación con el mando //Solo modifica de forma directa el throttle, el resto de cambios se efectúan en el segundo PID ps3Control(); // computoAltitud(); De momento para pruebas seguras //Se calcula la altitud, si no se activa la preparación de despegue, no se empieza a calcular la altitud // (evita errores al desplazar el dispositivo tras el calibrado) if (preparacion_despegue==true){ if (despegue_inic==false){ //En cuanto se inicia el despegue se deja de usar el ultrasonido computoAltitudUltraSonido(); } if(calibracion_altitud==1){ computoAltitudPresion(); } Serial.println(); Serial.print("Altitud: "); Serial.print(altitud_ult); if(calibracion_altitud==1){ Serial.print(" Altitud Presion: "); Serial.print(altitud); } Serial.println(); } //Si se presiona el botón X del mando se activa la altura automática if(control_altitud==true){//Determinará si se emplea el PID de altura o no if(desired_alt_fixed==false){ desired_alt=altitud_with_off; throttle_actual=throttle; //Se guarda el valor actual del throttle para limitarlo por seguridad desired_alt_fixed=true; } ajustePidAltura(); }else{//Si se deshabilita reinicio los valores del PID de altura PID_total_alt=0; error_alt=0; previous_error_alt=0; pid_p_alt=0; pid_i_alt=0; pid_d_alt=0; desired_alt_fixed=false; } //Si la altura es superior al umbral y no se ha despegado aún significa que ya se ha conseguido el despegue, se reinician valores del PID del yaw y se marca el despegue a true if(altitud_ult>altitud_corte_despegue && despegue_inic==false){ //Se establecen los valores en cero por precaución Universidad de Valladolid 116 PID_total_angle_yaw=0; error_angle_yaw=0; pid_p_angle_yaw=0; error_yaw=0; previous_error_yaw=0; PID_total_yaw=0; pid_p_yaw=0; pid_i_yaw=0; pid_d_yaw=0; //Se establece como ángulo deseado el que tenga en ese momento, aunque no sea cero, hará que no gire descontroladamente desired_angle_yaw = Total_angle[2]; //PROBLEMA, COMO NO TIENE EL PID EN EL YAW GIRA EN SENTIDO ANTIHORARIO, SE ADELANTA EL MOTOR IZQUIERDO AL INICIO //Se usa la variable despegue_inic para avisar a los Servos de que inicien con el PID despegue_inic=true; //Volver a ponerlo a false en caso en que se quiera aterrizar y volver a despegar sin parar logs="<Despegue +25 cm - (PID_yaw_ON)>"; for (int i=0; i<numCharsLogs;i++) { if(i<logs.length()){ Serial2.write(logs[i]); }else{ Serial2.write(' '); } } } //Llamada a la función de cálculos del IMU calculosImuAngulo(); //Envío de datos vía puerto serie al segundo ESP32 con servidor web logs="<"+String(altitud)+"::"+String(desired_alt)+"::"+String(error_al t)+"::"+String(PID_total_alt)+"::"+String(throttle)+">"; for(int i=0;i<numCharsLogs;i++){//Siempre se envían numCharsLogs characteres, porque es lo que se espera recibir if(i<logs.length()){ Serial2.write(logs[i]); }else{ Serial2.write(' '); } } //Hasta que el throttle no alcanza un valor significativo no se inician los PID, para evitar errores en la integral Universidad de Valladolid 117 if (throttle>1100||test==1){ //PID del ángulo total, que permitirá equilibrar sin importar la posición, trata posiciones absolutas ajustePidAngle(); //PID de la variación, permite una mayor estabilidad, al tratar posiciones relativas que parten de las absolutas del PID anterior ajustePidRateAngle(); }else{ esc_der.writeMicroseconds(throttle); esc_izq.writeMicroseconds(throttle); esc_cent.writeMicroseconds(throttle); if(test==0 && despegue_inic == false){//DEPURACIÓN si se activa el test se evitan errores de consumo de potencia al no conectar la bateria servo_der.write(servoCentPosDer); servo_izq.write(servoCentPosIzqDespegue); }else if (test==0 && despegue_inic == true){ servo_der.write(servoCentPosDer); servo_izq.write(servoCentPosIzq); } //Se reinician los valores cuando se vuelve a cero, para que no haya errores //PID angle PID_total_angle_roll=0; error_angle_roll=0; pid_p_angle_roll=0; PID_total_angle_pitch=0; error_angle_pitch=0; pid_p_angle_pitch=0; PID_total_angle_yaw=0; error_angle_yaw=0; pid_p_angle_yaw=0; //PID rate angle //Roll error_roll=0; previous_error_roll=0; PID_total_roll=0; pid_p_roll=0; pid_i_roll=0; pid_d_roll=0; //Pitch error_pitch=0; previous_error_pitch=0; PID_total_pitch=0; pid_p_pitch=0; pid_i_pitch=0; pid_d_pitch=0; //Yaw error_yaw=0; previous_error_yaw=0; PID_total_yaw=0; pid_p_yaw=0; Universidad de Valladolid 118 pid_i_yaw=0; pid_d_yaw=0; } }//---FIN LOOP--- //----------------------------------------------------------- FUNCIONES------------------------------------------------------ //-------------------------------------------------------------------- ----------------------------------------------------- ////////////////////////////////////////////////////////////////////// / /////////////////// CALCULOS SENSORES ///////////////////// ////////////////////////////////////////////////////////////////////// / //----------calculosImuAngulo---------- void calculosImuAngulo(){ //Se guarda el tiempo de ejecución para poder pasar de º/s a º //Se guardará el estado anterior del ciclo temporal y el actual, para ver cuanto //tiempo ha pasado. timePrev = timeNow; timeNow = millis(); elapsedTime = (timeNow - timePrev)/1000; //Se solicita al sensor los datos del acelerómetro I2CIMU.beginTransmission(0x68); I2CIMU.write(0x3B); //Se solicita el registro 0x3B que corresponde con el valor de aceleración del eje X I2CIMU.endTransmission(false); I2CIMU.requestFrom(0x68,6,true);//Se solicitan 6 registros de 8 bit, correspondientes con los valores de aceleración de los tres ejes //A continuación se guarda la lectura de datos de aceleración del IMU en m/(s^2) Acc_X=I2CIMU.read()<<8|I2CIMU.read(); //Son datos de 16 bit, así que se desplazan 8 bit y se aplica la operación OR Acc_Y=I2CIMU.read()<<8|I2CIMU.read(); Acc_Z=I2CIMU.read()<<8|I2CIMU.read(); //Se calcula en ángulo de aceleración aplicando la ecuación de Euler y se pasa a grados //Aquí también se aplican las escalas en función de la resolución deseada //(giro en X) //No es necesario aplicar atan2, dado que la solución aportará un resultado entre -90 y 90 Acceleration_angle[0] = (atan((Acc_Y/acc_scale)/sqrt(pow((Acc_X/acc_scale),2) + pow((Acc_Z/acc_scale),2)))*rad_to_deg)-Acceleration_angle_error[0]; //(giro en Y) //Se utiliza atan2, porque de esta forma obtenemos el cuadrante en el que se situa, eliminando el problema //de ángulos desde -180 a 180 Acceleration_angle[1] = (atan2((- Acc_X/acc_scale),(Acc_Z/acc_scale))*rad_to_deg)- Acceleration_angle_error[1]; Universidad de Valladolid 119 //(giro en Z) //No se pueden utilizar solo las ecuaciones de EULER para calcularlo, se empleará solo el giroscopio //Se obtienen los datos del giroscopio del IMU en radianes por segundo I2CIMU.beginTransmission(0x68); I2CIMU.write(0x43); //Datos del giroscopio en el eje X I2CIMU.endTransmission(false); I2CIMU.requestFrom(0x68,6,true); //Solo se solicitan los datos de los ejes X,Y y Z Gyr_X=I2CIMU.read()<<8|I2CIMU.read(); //Se vuelven a guardar los valores desplazando y aplicando OR Gyr_Y=I2CIMU.read()<<8|I2CIMU.read(); Gyr_Z=I2CIMU.read()<<8|I2CIMU.read(); //Se aplican las escalas en función de la resolución de giro deseada //Se meten los float Gyro_X = Gyr_X/gyro_scale; Gyro_Y = Gyr_Y/gyro_scale; Gyro_Z = Gyr_Z/gyro_scale; //Se corrige el error medio Gyro_X = Gyro_X-Gyr_X_error; Gyro_Y = Gyro_Y-Gyr_Y_error; Gyro_Z = Gyro_Z-Gyr_Z_error; //Utilizo la velocidad angular para el PID gyro_roll_input = (gyro_roll_input * 0.7) + (Gyro_Y * 0.3); //Gyro pid input is deg/sec. gyro_pitch_input = (gyro_pitch_input * 0.7) + (Gyro_X * 0.3);//Gyro pid input is deg/sec. gyro_yaw_input = (gyro_yaw_input * 0.7) + (Gyro_Z * 0.3);//Gyro pid input is deg/sec. //traspaso el ángulo de pitch a roll si hay rotacion Gyro_X+= (Gyro_Y*elapsedTime) * sin((Gyro_Z*elapsedTime) * (1/rad_to_deg)); Gyro_Y-= (Gyro_X*elapsedTime) * sin((Gyro_Z*elapsedTime) * (1/rad_to_deg)); //Se calcula el ángulo total, tomando los valores del giroscopio y el acelerómetro //Se pasan los datos del giroscopio de grados/seg a seg multiplicando por el tiempo transcurrido desde la lectura //Estas variables implementan un filtro complementario que aportará mayor precisión //Los coeficientes se han ajustado en base a un compromiso entre respuesta rápida y suavidad de los cambios en la respuesta //Ángulo en eje X Total_angle[0] = 0.995*(Total_angle[0]+(Gyro_X*elapsedTime)) + 0.005*Acceleration_angle[0]; //Ángulo en eje Y Total_angle[1] = 0.995*(Total_angle[1]+(Gyro_Y*elapsedTime)) + 0.005*Acceleration_angle[1]; //Paso los datos del Gyr_Z a grados Universidad de Valladolid 120 Total_angle[2]=Total_angle[2]+(Gyro_Z*elapsedTime); } //---------------computoAltitudPresion()-------------- void computoAltitudPresion(){ if (! bmp.performReading()) { Serial.println("Failed to perform reading :("); return; } //Cojo los datos y le resto el error de la calibración altitud_biblioteca=bmp.readAltitude(SEALEVELPRESSURE_HPA)- alt_err_calibr; if (first_read_altitud==true){//Acelero la estabilización del filtro altitud_filtrada=altitud_biblioteca; first_read_altitud=false; } //Filtro solo con la altitud: (filtrado para que sea rápido y con un poco de ruido) altitud_filtrada=altitud_filtrada*0.9+altitud_biblioteca*0.1; altitud=altitud_filtrada; //Se supondrá que la altura nunca puede ser negativa, para eso se ha introducido un offset, no hace falta recortarla //Pero sí hace falta un offset if (altitud>0){ altitud=altitud*100;//La paso a centímetros } if (altitud_biblioteca>0){ altitud_biblioteca=altitud_biblioteca*100; } altitud_with_off=offset_altitud+altitud;//Genero la altitud con offset (Siempre tiene que haber offset, porque no se trunca la altitud) //El dato usable será altitud_with_off, ya que la otra altitud puede ser negativa //Depuración /* Serial.print("Altitud:"); Serial.print(altitud); Serial.print(","); Serial.print("Altitud_biblioteca:"); Serial.print(altitud_biblioteca); Serial.println(""); */ Universidad de Valladolid 127 previous_error_alt = error_alt; } ////////////////////////////////////////////////////////////////////// / /////////////////// CONFIGURACIÓN MANDO ///////////////////// ////////////////////////////////////////////////////////////////////// / void ps3Control(){ //---Joystick_Izquierdo--- if(((Ps3.data.analog.stick.ly*-1)<50) && ((Ps3.data.analog.stick.ly*-1)>-50)){ JoyIzq=0;//Si está en la posición central no modifico el throttle }else if(((Ps3.data.analog.stick.ly*-1)>50)){ JoyIzq=1; //Si subo el Joystick incremento en 1 el throttle en cada iteración }else if(((Ps3.data.analog.stick.ly*-1)<-126)){ JoyIzq=-5; }else{ JoyIzq=-1; //Si bajo el Joystick decremento en 1 el throttle en cada iteración } //Ajusto la elevación en función del Joystick //Establezco límites, si bajo el Joystick hasta abajo para inmediatamente, si lo bajo un poco resta hasta llegar al mínimo, si lo subo aumenta el throttle hasta 1800, si no lo toco sumará cero y se mantiene if(JoyIzq==-5){ throttle=1000; }else if (throttle+JoyIzq>1799){ throttle=1800; }else if (throttle+JoyIzq<1001){ throttle=1000;//Lo que hace es parar los motores }else if (throttle>1000 && throttle<1400){//Para conseguir un despegue rápido throttle+=50*JoyIzq; }else{//Si no se pasa de los límites ni para funciona incrementando o decrementando el throttle throttle+=JoyIzq; } /* //Depuración Serial.print("JoyIzq="); Serial.print(JoyIzq); Serial.println(""); */ //---Joystick_Derecho--- Universidad de Valladolid 128 //Motor derecho if(((Ps3.data.analog.stick.ry*-1)<50) && ((Ps3.data.analog.stick.ry*-1)>-50)){ JoyDer_servDer=servoCentPosDer; //Se ha medido el desfase en grados entre motores (37 grados) y se ha buscado de forma práctica el punto medio }else if(((Ps3.data.analog.stick.ry*-1)>50)){ JoyDer_servDer=map(Ps3.data.analog.stick.ry*-1, 50, 128, servoCentPosDer, servoMaxPosDer); }else{ JoyDer_servDer=map(Ps3.data.analog.stick.ry*-1, -128, -50, servoMinPosDer, servoCentPosDer); } //Depuración /* Serial.print(" JoyDer_servDer="); Serial.print(JoyDer_servDer); */ //Motor izquierdo if(((Ps3.data.analog.stick.ry*-1)<50) && ((Ps3.data.analog.stick.ry*-1)>-50)){ JoyDer_servIzq=servoCentPosIzq; }else if(((Ps3.data.analog.stick.ry*-1)>50)){ JoyDer_servIzq=map(Ps3.data.analog.stick.ry*-1, 50, 128, servoCentPosIzq, servoMaxPosIzq); }else{ JoyDer_servIzq=map(Ps3.data.analog.stick.ry*-1, -128, -50, servoMinPosIzq ,servoCentPosIzq); } //Depuración /* Serial.print(" JoyDer_servIzq="); Serial.println(JoyDer_servIzq); */ //Movimientos //Virar izquierda y derecha if(((Ps3.data.analog.stick.rx*-1)<50) && ((Ps3.data.analog.stick.rx*-1)>-50)){ desired_angle_roll=0; }else if(((Ps3.data.analog.stick.rx*-1)>50)){ desired_angle_roll=-10; }else{ desired_angle_roll=10; } //Rotación //Rotación hacia la derecha if( Ps3.data.analog.button.r1>5 ){ desired_angle_yaw-=1; } //Rotación hacia la izquierda if( Ps3.data.analog.button.l1>5 ){ desired_angle_yaw+=1; } Universidad de Valladolid 129 if( Ps3.data.button.start ){ Serial.println("Pressing the START button"); } //---Activación despegue--- if (Ps3.data.button.start==true && START_on==false){ preparacion_despegue=!preparacion_despegue; if (preparacion_despegue){ logs="<Preparacion Despegue Iniciada>"; for (int i=0; i<numCharsLogs;i++) { if(i<logs.length()){ Serial2.write(logs[i]); }else{ Serial2.write(' '); } } Ps3.setPlayer(7); }else{ Ps3.setPlayer(2); } START_on=true; } if (Ps3.data.button.start ==false){ START_on=false; } //---Activación control altura--- if (Ps3.data.analog.button.cross>5 && X_on==false){ control_altitud=!control_altitud; if (control_altitud){ Ps3.setPlayer(6); }else{ Ps3.setPlayer(2); } X_on=true; } if (Ps3.data.analog.button.cross==0){ X_on=false; } } ////////////////////////////////////////////////////////////////////// / /////////////////// CALCULOS CALIBRACIONES ///////////////////// ////////////////////////////////////////////////////////////////////// / //----------calculoErrorImuMedio---------- void calculoErrorImuMedio(){//Vale para calibrar si está perfectamente recto //Esta función calculará el error medio al inicio, para ello se leerán 500 valores del acelerometro y giroscopio //Y se irán sumando, para después dividir entre el total de medidas Universidad de Valladolid 130 //Como el dispositivo no estará en movimiento existirá un error medio entre medidas que después se utilizará //para calibrar las medidas reales tomadas //Error medio acelerómetro for(int i=0;i<iteraciones_calibracion;i++){ //Se solicita al sensor los datos del acelerómetro I2CIMU.beginTransmission(0x68); I2CIMU.write(0x3B); //Se solicita el registro 0x3B que corresponde con el valor de aceleración del eje X I2CIMU.endTransmission(false); I2CIMU.requestFrom(0x68,6,true);//Se solicitan 6 registros de 8 bit, correspondientes con los valores de aceleración de los tres ejes //A continuación se guarda la lectura de datos de aceleración del IMU en m/(s^2) Acc_X=I2CIMU.read()<<8|I2CIMU.read(); //Son datos de 16 bit, así que se desplazan 8 bit y se aplica la operación OR Acc_Y=I2CIMU.read()<<8|I2CIMU.read(); Acc_Z=I2CIMU.read()<<8|I2CIMU.read(); //Se va acumulando el error //(giro en X) Acceleration_angle_error[0] += atan((Acc_Y/acc_scale)/sqrt(pow((Acc_X/acc_scale),2) + pow((Acc_Z/acc_scale),2)))*rad_to_deg; //(giro en Y) //Se utiliza la solución de matriz de giro de otra rotación debido a que se emplean más datos~~ Acceleration_angle_error[1] += atan2((- Acc_X/acc_scale),(Acc_Z/acc_scale))*rad_to_deg; //Se aplica el error medio if (i==iteraciones_calibracion-1){ Acceleration_angle_error[0] = Acceleration_angle_error[0]/iteraciones_calibracion; Acceleration_angle_error[1] = Acceleration_angle_error[1]/iteraciones_calibracion; } } for(int i=0;i<iteraciones_calibracion;i++){ //Se obtienen los datos del giroscopio del IMU en radianes por segundo I2CIMU.beginTransmission(0x68); I2CIMU.write(0x43); //Datos del giroscopio en el eje X I2CIMU.endTransmission(false); I2CIMU.requestFrom(0x68,6,true); //Solo se solicitan los datos de los ejes X,Y y Z Gyr_X=I2CIMU.read()<<8|I2CIMU.read(); //Se vuelven a guardar los valores desplazando y aplicando OR Gyr_Y=I2CIMU.read()<<8|I2CIMU.read(); Gyr_Z=I2CIMU.read()<<8|I2CIMU.read(); //Se aplican las escalas en función de la resolución de giro deseada Gyro_X = Gyr_X/gyro_scale; Gyro_Y = Gyr_Y/gyro_scale; Universidad de Valladolid 131 Gyro_Z = Gyr_Z/gyro_scale; //Se va acumulando el error Gyr_X_error+=Gyro_X; Gyr_Y_error+=Gyro_Y; Gyr_Z_error+=Gyro_Z; //Se aplica el error medio if (i==iteraciones_calibracion-1){ Gyr_X_error=Gyr_X_error/iteraciones_calibracion; Gyr_Y_error=Gyr_Y_error/iteraciones_calibracion; Gyr_Z_error=Gyr_Z_error/iteraciones_calibracion; } } } //---------------calculoAltitudRelativaCalibrado()-------------- void calculoAltitudRelativaCalibrado(){ for(int i=0;i<iteraciones_calibracion_altitud;i++){ if (! bmp.performReading()) { Serial.println("Failed to perform reading :("); }else{ if(i==10){//Para que no tarde en establecerse el valor altitud_filtrada=bmp.readAltitude(SEALEVELPRESSURE_HPA); } //Implemento un filtro complementario para evitar las fluctuaciones altitud_filtrada=altitud_filtrada*(float)0.9 + bmp.readAltitude(SEALEVELPRESSURE_HPA)*(float)0.1; //Depuración Serial.print("Altitud_filtrada:"); Serial.print(altitud_filtrada); Serial.print(","); Serial.print("Altitud biblioteca:"); Serial.print(bmp.readAltitude(SEALEVELPRESSURE_HPA)); Serial.print(","); Serial.println(""); if(i> iteraciones_estabilizacion_calibracion_altitud-1){//Solo cuenta tras un periodo de adaptación alt_err_calibr+=altitud_filtrada; } //Se aplica el error medio if (i==iteraciones_calibracion_altitud-1){ Universidad de Valladolid 132 alt_err_calibr=alt_err_calibr/(iteraciones_calibracion_altitud- iteraciones_estabilizacion_calibracion_altitud); Serial.println("ERROR"); Serial.println(alt_err_calibr); Serial.println("ERROR"); } } }//for } A.1.2 Código WebServer REST API /* SERVIDOR ESP32 */ // Import required libraries #include "WiFi.h" #include "ESPAsyncWebServer.h" // Set your access point network credentials const char* ssid = "VTOL"; const char* password = "vtollogs"; // Create AsyncWebServer object on port 80 AsyncWebServer server(80); const byte numChars = 36; char receivedChars[numChars]; boolean newData = false; String logs="NO_LOG"; String readLogs() { return String(logs); } void setup(){ // Serial port for debugging purposes Serial.begin(9600); Serial.println(); // Setting the ESP as an access point Serial.print("Setting AP (Access Point)…"); // Remove the password parameter, if you want the AP (Access Point) to be open WiFi.softAP(ssid, password); IPAddress IP = WiFi.softAPIP(); Serial.print("AP IP address: "); Universidad de Valladolid 133 Serial.println(IP); server.on("/logs", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/plain", readLogs().c_str()); }); // Start server server.begin(); //Inicio la comunicación serie2 con el VTOL Serial2.begin(500000); } void loop(){ recvWithStartEndMarkers(); showNewData(); } void recvWithStartEndMarkers() { static boolean recvInProgress = false; static byte ndx = 0; char startMarker = '<'; char endMarker = '>'; char rc; while (Serial2.available() > 0 && newData == false) { rc = Serial2.read(); if (recvInProgress == true) { if (rc != endMarker) { receivedChars[ndx] = rc; ndx++; if (ndx >= numChars) { ndx = numChars - 1; } } else { receivedChars[ndx] = '\0'; // terminate the string recvInProgress = false; ndx = 0; newData = true; } } else if (rc == startMarker) { recvInProgress = true; memset(receivedChars,0, sizeof(receivedChars)); } } } void showNewData() { int i=0; Universidad de Valladolid 134 if (newData == true) { //Serial.print("This just in ... "); //Serial.println(receivedChars); logs=receivedChars; Serial.println(logs); newData = false; } } Obtenido principalmente de [108] con modificaciones. A.1.3 Código WebSClient REST API #include <WiFi.h> #include <HTTPClient.h> const char* ssid = "VTOL"; const char* password = "vtollogs"; //Your IP address or domain name with URL path const char* serverNameLogs = "http://192.168.4.1/logs"; #include <Wire.h> String logs; String logs_anteriores; int counter=0; unsigned long previousMillis = 0; const long interval = 100; void setup() { Serial.begin(9600); WiFi.begin(ssid, password); Serial.println("Connecting"); while(WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.print("Connected to WiFi network with IP Address: "); Serial.println(WiFi.localIP()); } void loop() { Universidad de Valladolid 135 unsigned long currentMillis = millis(); if(currentMillis - previousMillis >= interval) { // Check WiFi connection status if(WiFi.status()== WL_CONNECTED ){ logs = httpGETRequest(serverNameLogs);//Se queda haciendo poolling cada intervalo if (logs!=logs_anteriores){ //Si los logs no han cambiado no hagas nada Serial.println(logs); } // save the last HTTP GET Request previousMillis = currentMillis; logs_anteriores=logs; counter=0; } else { if (counter<3){//Solo se muestra 3 veces para no saturar los logs Serial.println("WiFi Disconnected"); counter++; } } } } String httpGETRequest(const char* serverName) { WiFiClient client; HTTPClient http; // Your Domain name with URL path or IP address with path http.begin(client, serverName); // Send HTTP POST request int httpResponseCode = http.GET(); String payload = "--"; if (httpResponseCode>0) { //Serial.print("HTTP Response code: "); //Serial.println(httpResponseCode); payload = http.getString(); } else { Serial.print("Error code: "); Serial.println(httpResponseCode); } // Free resources http.end(); return payload; Universidad de Valladolid 136 } Obtenido principalmente de [108] con modificaciones. A.2 Pruebas de concepto A.2.1 Posicionamiento MPU6050 ////////////////////////////////////////////////////////////////////// / /////////////////// CALCULOS UAV ///////////////////// ////////////////////////////////////////////////////////////////////// / //----------calculosImuPosicion---------- void calculosImuPosicion(){ //Obtengo las aceleraciones en m/s^2 teniendo en cuenta el error (de cada eje del sensor) aceleracion_x=((Acc_X-Acc_X_error)/acc_scale)*gravity; aceleracion_y=((Acc_Y-Acc_Y_error)/acc_scale)*gravity; aceleracion_z=((Acc_Z-Acc_Z_error)/acc_scale)*gravity; //Si el sensor está girado tendré que aplicar matrices de rotación: //Paso angulos a radianes alfa = Total_angle[2]*(1/rad_to_deg); beta = Total_angle[0]*(1/rad_to_deg); ganma = Total_angle[1]*(1/rad_to_deg); //Dado que el vector de gravedad solo tiene componente en Z, se simplifican las matrices de rotación //Se han cambiado rotación_x y rotación_y de sitio debido a la posición del sensor y los vectores de este rotacion_y = ((cos(alfa)*cos(beta))*vector_gravedad[0]) + (((cos(alfa)*sin(beta)*sin(ganma))- (sin(alfa)*cos(ganma)))*vector_gravedad[1]) + (((cos(alfa)*sin(beta)*cos(ganma))+(sin(alfa)*sin(ganma)))*vector_grav edad[2]); rotacion_x = ((sin(alfa)*cos(beta))*vector_gravedad[0]) + (((sin(alfa)*sin(beta)*sin(ganma))+(cos(alfa)*cos(ganma)))*vector_grav edad[1]) + (((sin(alfa)*sin(beta)*cos(ganma))- (cos(alfa)*sin(ganma)))*vector_gravedad[2]); rotacion_z = ((-sin(beta))*vector_gravedad[0]) + ((cos(beta)*sin(ganma))*vector_gravedad[1]) + ((cos(beta)*cos(ganma))*vector_gravedad[2]); //Ahora paso a restar las componentes en cada dirección para obtener la aceleración con independencia de la gravedad aceleracion_total_x=aceleracion_x-rotacion_x; aceleracion_total_y=aceleracion_y-rotacion_y; //si se desactiva la posición habrá que resetear las variables a cero //------------X------------ velocidad_x += (aceleracion_total_x*elapsedTime); Universidad de Valladolid 143 lock(); bool safe = is_safe(); NeoGPS::clock_t sow = GPSTime::start_of_week(); NeoGPS::time_t utc = fix().dateTime; unlock(); if (safe && (sow != 0)) { DEBUG_PORT << F("Acquired UTC: ") << utc << '\n'; DEBUG_PORT << F("Acquired Start-of-Week: ") << sow << '\n'; start_running(); } #endif } // get_utc //-------------------------- void start_running() { bool enabled_msg_with_time = false; #if defined(UBLOX_PARSE_POSLLH) if (!enable_msg( ublox::UBX_NAV, ublox::UBX_NAV_POSLLH )) DEBUG_PORT.println( F("enable POSLLH failed!") ); enabled_msg_with_time = true; #endif #if defined(UBLOX_PARSE_PVT) if (!enable_msg( ublox::UBX_NAV, ublox::UBX_NAV_PVT )) DEBUG_PORT.println( F("enable PVT failed!") ); enabled_msg_with_time = true; #endif #if defined(UBLOX_PARSE_VELNED) if (!enable_msg( ublox::UBX_NAV, ublox::UBX_NAV_VELNED )) DEBUG_PORT.println( F("enable VELNED failed!") ); enabled_msg_with_time = true; #endif #if defined(UBLOX_PARSE_DOP) if (!enable_msg( ublox::UBX_NAV, ublox::UBX_NAV_DOP )) DEBUG_PORT.println( F("enable DOP failed!") ); else DEBUG_PORT.println( F("enabled DOP.") ); enabled_msg_with_time = true; #endif #if defined(UBLOX_PARSE_SVINFO) if (!enable_msg( ublox::UBX_NAV, ublox::UBX_NAV_SVINFO )) DEBUG_PORT.println( F("enable SVINFO failed!") ); enabled_msg_with_time = true; #endif #if defined(UBLOX_PARSE_TIMEUTC) Universidad de Valladolid 144 #if defined(GPS_FIX_TIME) & defined(GPS_FIX_DATE) if (enabled_msg_with_time && !disable_msg( ublox::UBX_NAV, ublox::UBX_NAV_TIMEUTC )) DEBUG_PORT.println( F("disable TIMEUTC failed!") ); #elif defined(GPS_FIX_TIME) | defined(GPS_FIX_DATE) // If both aren't defined, we can't convert TOW to UTC, // so ask for the separate UTC message. if (!enable_msg( ublox::UBX_NAV, ublox::UBX_NAV_TIMEUTC )) DEBUG_PORT.println( F("enable TIMEUTC failed!") ); #endif #endif state = RUNNING; trace_header( DEBUG_PORT ); } // start_running //-------------------------- bool running() { switch (state) { case GETTING_STATUS : get_status (); break; case GETTING_LEAP_SECONDS: get_leap_seconds(); break; case GETTING_UTC : get_utc (); break; } return (state == RUNNING); } // running } NEOGPS_PACKED; // Construct the GPS object and hook it to the appropriate serial device static MyGPS gps( &gpsPort ); #ifdef NMEAGPS_INTERRUPT_PROCESSING static void GPSisr( uint8_t c ) { gps.handle( c ); } #endif //-------------------------- static void configNMEA( uint8_t rate ) { for (uint8_t i=NMEAGPS::NMEA_FIRST_MSG; i<=NMEAGPS::NMEA_LAST_MSG; i++) { ublox::configNMEA( gps, (NMEAGPS::nmea_msg_t) i, rate ); } } //-------------------------- static void disableUBX() { Universidad de Valladolid 145 gps.disable_msg( ublox::UBX_NAV, ublox::UBX_NAV_TIMEGPS ); gps.disable_msg( ublox::UBX_NAV, ublox::UBX_NAV_TIMEUTC ); gps.disable_msg( ublox::UBX_NAV, ublox::UBX_NAV_VELNED ); gps.disable_msg( ublox::UBX_NAV, ublox::UBX_NAV_POSLLH ); gps.disable_msg( ublox::UBX_NAV, ublox::UBX_NAV_DOP ); } //-------------------------- void setup() { // Start the normal trace output DEBUG_PORT.begin(9600); while (!DEBUG_PORT) ; DEBUG_PORT.print( F("ublox binary protocol example started.\n") ); DEBUG_PORT << F("fix object size = ") << sizeof(gps.fix()) << '\n'; DEBUG_PORT << F("ubloxGPS object size = ") << sizeof(ubloxGPS) << '\n'; DEBUG_PORT << F("MyGPS object size = ") << sizeof(gps) << '\n'; DEBUG_PORT.println( F("Looking for GPS device on " GPS_PORT_NAME) ); DEBUG_PORT.flush(); // Start the UART for the GPS device #ifdef NMEAGPS_INTERRUPT_PROCESSING gpsPort.attachInterrupt( GPSisr ); #endif gpsPort.begin(9600); // Turn off the preconfigured NMEA standard messages configNMEA( 0 ); // Turn off things that may be left on by a previous build disableUBX(); #if 0 // Test a Neo M8 message -- should be rejected by Neo-6 and Neo7 ublox::cfg_nmea_v1_t test; test.always_output_pos = false; // invalid or failed test.output_invalid_pos = false; test.output_invalid_time= false; test.output_invalid_date= false; test.use_GPS_only = false; test.output_heading = false; // even if frozen test.__not_used__ = false; test.nmea_version = ublox::cfg_nmea_v1_t::NMEA_V_4_0; test.num_sats_per_talker_id = ublox::cfg_nmea_v1_t::SV_PER_TALKERID_UNLIMITED; test.compatibility_mode = false; test.considering_mode = true; test.max_line_length_82 = false; test.__not_used_1__ = 0; test.filter_gps = false; test.filter_sbas = false; test.__not_used_2__= 0; test.filter_qzss = false; Universidad de Valladolid 146 test.filter_glonass= false; test.filter_beidou = false; test.__not_used_3__= 0; test.proprietary_sat_numbering = false; test.main_talker_id = ublox::cfg_nmea_v1_t::MAIN_TALKER_ID_GP; test.gsv_uses_main_talker_id = true; test.beidou_talker_id[0] = 'G'; test.beidou_talker_id[1] = 'P'; DEBUG_PORT << F("CFG_NMEA result = ") << gps.send( test ); #endif while (!gps.running()) if (gps.available( gpsPort )) gps.read(); } //-------------------------- void loop() { if (gps.available( gpsPort )) trace_all( DEBUG_PORT, gps, gps.read() ); // If the user types something, reset the message configuration // back to a normal set of NMEA messages. This makes it // convenient to switch to another example program that // expects a typical set of messages. This also saves // putting those config messages in every other example. if (DEBUG_PORT.available()) { do { DEBUG_PORT.read(); } while (DEBUG_PORT.available()); DEBUG_PORT.println( F("Stopping...") ); configNMEA( 1 ); disableUBX(); gpsPort.flush(); gpsPort.end(); DEBUG_PORT.println( F("STOPPED.") ); for (;;); } } Procedente de NeoGPS[97]. A.2.3.2 TinyGPS #include <SoftwareSerial.h> #include <TinyGPS.h> /* This sample code demonstrates the normal use of a TinyGPS object. It requires the use of SoftwareSerial, and assumes that you have a 4800-baud serial GPS device hooked up on pins 4(rx) and 3(tx). */ TinyGPS gps; Universidad de Valladolid 147 SoftwareSerial ss(4, 3); void setup() { Serial.begin(115200); ss.begin(4800); Serial.print("Simple TinyGPS library v. "); Serial.println(TinyGPS::library_version()); Serial.println("by Mikal Hart"); Serial.println(); } void loop() { bool newData = false; unsigned long chars; unsigned short sentences, failed; // For one second we parse GPS data and report some key values for (unsigned long start = millis(); millis() - start < 1000;) { while (ss.available()) { char c = ss.read(); // Serial.write(c); // uncomment this line if you want to see the GPS data flowing if (gps.encode(c)) // Did a new valid sentence come in? newData = true; } } if (newData) { float flat, flon; unsigned long age; gps.f_get_position(&flat, &flon, &age); Serial.print("LAT="); Serial.print(flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6); Serial.print(" LON="); Serial.print(flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6); Serial.print(" SAT="); Serial.print(gps.satellites() == TinyGPS::GPS_INVALID_SATELLITES ? 0 : gps.satellites()); Serial.print(" PREC="); Serial.print(gps.hdop() == TinyGPS::GPS_INVALID_HDOP ? 0 : gps.hdop()); } gps.stats(&chars, &sentences, &failed); Serial.print(" CHARS="); Serial.print(chars); Serial.print(" SENTENCES="); Serial.print(sentences); Serial.print(" CSUM ERR="); Serial.println(failed); if (chars == 0) Serial.println("** No characters received from GPS: check wiring **"); Universidad de Valladolid 148 } Procedente de TinyGPS [98]. A.3 Enlaces de estimación de costes Microcontrolador https://es.aliexpress.com/item/1005005562548949.html?algo_pvid=9fe1feb1-49bb- 41bb-92df-b0397911ddab&algo_exp_id=9fe1feb1-49bb-41bb-92df-b0397911ddab- 0&pdp_npi=4%40dis%21EUR%214.88%210.99%21%21%215.20%211.05%21%4021 0391a017175320643383973e771c%2112000034113114728%21sea%21ES%210%21A B&curPageLogUid=2drgazU3i2Go&utparamurl=scene%3Asearch%7Cquery_from%3A Motores BLDC https://www.amazon.es/CENPEK-escobillas-Outrunner-Multi-Copter- Quadcopter/dp/B098STSYD8/ref=sr_1_2?__mk_es_ES=%C3%85M%C3%85%C5%B D%C3%95%C3%91&crid=327XAN9WY8B5R&dib=eyJ2IjoiMSJ9.tL8- 6sgB_qLtBtYBYJbZlEaDhJyhZzmtQRDmYDjCn7xG2XMJkPHww6sfKCSu8Onl_Fu msVroZIHZAXeE94ytEPZaSSlToGLO3gIOHjBEZChJYfzt8zH3mChewN1moRNsuP Sc3T2Nf9bWJ1c96QssogIG5ixicGKnAvFia4Q2WxKoPibH5gFo9VwXiRthTaTt1QjtD DEvxt2xqAh7sWo4l- b0Jsy6sdl4QyHC3muoB9aOAaaOTNrkm4HbxSCxyVbkcHlfN0uaYYj5bxokI0IlIIDY MtIE51c0OkTvNQD0oFM.9SA7c3v-- ZFopJRkTryzoTE6Bop5MEbISI_T0oPibhg&dib_tag=se&keywords=bldc+a2212+1000 kv&qid=1717532114&sprefix=bldc+a2212+1000kv%2Caps%2C115&sr=8-2 ESC https://grupoelectrostore.com/shop/motores/controladores/esc-brushless/esc-30a- simonk-para-motor-brushless/ Universidad de Valladolid 149 Servomotores https://www.amazon.es/AZDelivery- %E2%AD%90%E2%AD%90%E2%AD%90%E2%AD%90%E2%AD%90- hubchrauber-MG996R-Digital/dp/B07H87592P?source=ps-sl-shoppingads- lpcontext&ref_=fplfs&smid=A1X7QLRQH87QA3&th=1 IMU https://www.amazon.es/ARCELI-aceler%C3%B3metro-Aceler%C3%B3metro- girosc%C3%B3pico- Transductor/dp/B07BVXN2GP/ref=sr_1_5?dib=eyJ2IjoiMSJ9.6WZyh- bXpazpT59jV2bla3vRpPJ4tertHJMPD1GEMegj8FC21Q76qYkbaT7JVpSIyvRJw4sAu 8az- cSaonX4Q6oU0X2B9I_jdJet2jZaiNyvYSfgY4d66HmUQ928gv6PM4EHXmUfrpIO2u DVrGpvQ6sUeEvab2DB1J0Xk8DK6PbzENeOXhV3qnYukUUA5bGFFm2V8BIJXPic GAbiCW6p0jun8d_NlgAjAqyspXLCbMnNzZQi1fb5- 7D4_1nu_oMRKezSuToEbzXlgzGwaaB2MenhYjMNSWZ59Gp25ga9TTA.xTRQJvka jKsCj5kcFf4ltJ42797m9T0pWX7Jbxf0NGQ&dib_tag=se&keywords=mpu6050&qid=1 717532258&sr=8-5 Sensor de ultrasonidos https://www.amazon.es/ARCELI-transductor-medici%C3%B3n-Distancia- ultras%C3%B3nico/dp/B07MPZR59P/ref=sr_1_5?__mk_es_ES=%C3%85M%C3%85 %C5%BD%C3%95%C3%91&crid=2RK8PMEYVVBFT&dib=eyJ2IjoiMSJ9.Gi1Y5lY k0Ir72ac5dQlQDfnHVjjV3BLScVg9mxVLRC2UnVNclE9n79mf0FN8ZRnwI79yzM3 RnGU0LGpkrK2FUQKMwdH8mv8QY06h9Nt7MooKXQAXUENCepbjFPBqbILkuF xVL0HHXAQcpG_Oq7stVK2Zwr1Q2cUtn4yAe24b- kDhsOSJhW08bJ3liJ6WtBa_y_4d4m7AsDLhNNmGWlV9Ki8HAoct52gHFdphsViwlx bggIJPdi5mR7FmVmYGQD8qheM19R5URiE6sFADMrL0IVfiyt7kQtrZRyKr42Cqjlk. TnHEQKZucw83qv2ab85Mzt68wP5Z5xL7FTsj-2lB-tQ&dib_tag=se&keywords=hcsr04&qid=1717532277&sprefix=hc-sr04%2Caps%2C134&sr=8-5 Universidad de Valladolid 150 Sensor de presión https://es.aliexpress.com/item/1005006838209282.html?spm=a2g0o.productlist.main.3. 7f6436c60JpoBX&algo_pvid=6d7f4da2-740a-49c9-87c6- 407171c04e2d&algo_exp_id=6d7f4da2-740a-49c9-87c6-407171c04e2d- 1&pdp_npi=4%40dis%21EUR%2118.58%215.39%21%21%21143.58%2141.64%21% 40211b664d17175323988907239ea291%2112000038467788181%21sea%21ES%210 %21AB&curPageLogUid=DQlclw6eSE4H&utparamurl=scene%3Asearch%7Cquery_from%3A Fotosensor https://es.aliexpress.com/item/1005005928511999.html?spm=a2g0o.productlist.main.3. 377e10631Ot7H8&algo_pvid=17799a7b-15f9-416f-9216- cea8e87eab89&algo_exp_id=17799a7b-15f9-416f-9216-cea8e87eab89- 1&pdp_npi=4%40dis%21EUR%2113.78%2113.78%21%21%21106.48%21106.48%21 %402103919917175324204908449ea0d4%2112000034889137453%21sea%21ES%21 0%21AB&curPageLogUid=r5nIw6EOTo6I&utparamurl=scene%3Asearch%7Cquery_from%3A GNSS https://es.aliexpress.com/item/32748573256.html?src=google Baterías https://www.amazon.es/RoaringTop-2200mAh-Bater%C3%ADa-Helic%C3%B3ptero- Paquetes/dp/B08H82KFS6 Cargador de baterías https://es.aliexpress.com/item/1005005028773427.html?spm=a2g0o.productlist.main.7. 6d1c10e9VRlr7o&algo_pvid=95037b67-de37-43f1-a68f- a63497a32c50&aem_p4p_detail=202406041322308328451669961900000996648&alg Universidad de Valladolid 151 o_exp_id=95037b67-de37-43f1-a68f-a63497a32c50- 3&pdp_npi=4%40dis%21EUR%2186.38%2117.42%21%21%21667.52%21134.57%21 %402103919917175325505264152ea0ec%2112000031387031898%21sea%21ES%210 %21AB&curPageLogUid=nKUv1LjSIoa2&utparamurl=scene%3Asearch%7Cquery_from%3A&search_p4p_id=202406041322308328451 669961900000996648_1 Varillas https://www.leroymerlin.es/productos/ferreteria-y-seguridad/perfiles-pletinas-chapas-y- rejillas/perfiles/perfil-aluminio/perfil-forma-cuadrada-de-aluminio-en-bruto-standers- alt-16-x-an-16mm-x-l-1-m-87825791.html PLA de impresión https://www.amazon.es/dp/B083YX1TZG?psc=1&ref=ppx_yo2ov_dt_b_product_detail s Protoboard https://www.amazon.es/ELEGOO-Breadboard-Prototipo-Electr%C3%B3nicos- Compatibles/dp/B072Z7Y19F/ref=sr_1_13?__mk_es_ES=%C3%85M%C3%85%C5% BD%C3%95%C3%91&crid=2SHL87UTTGEVW&dib=eyJ2IjoiMSJ9.8uriLRwUu- DSdazoeIh3ri3WUKcyagC0PsqrA11KpIqkjqNyxHvcZqRP0SsJeBgzuUIQCI6oLMPg DPrbF6ccUFITXdbWTJvSFuEAmSG_YVXCNKyTz02UUG_EMhhxTemlHirmGZnkt jrGvFpv1ewedPE1Gc10XKzz0FaWOz01wQnOl65hM6KUgo4Dar4IWUT2exYJbfQwi d4c4qUDQY7BUDd1N1AyXz4Qjlx1ptzFDB011sV1INSCe9N2uOTZC6odo- lGfVcFcjkAN9wtKHCSQXhW3z8QVtU8An92cdbEpNs.cGk-E3- RmJawlbi7OqkzncLo5C3xK6bzgZzHKkMeBms&dib_tag=se&keywords=protoboard& qid=1717531770&sprefix=protoboard%2Caps%2C122&sr=8-13 Universidad de Valladolid 152 Cables de prototipado https://www.amazon.es/Macho-Hembra-Macho-Macho-Hembra-Hembra-Prototipo- Protoboard/dp/B01NGTXASZ/ref=sr_1_5?dib=eyJ2IjoiMSJ9.lRvFWkXHlJfQN2AEa5 s0aUIb6uSP0wcinD_8edzK5ZtEjDa5V- dkkfBfpsRdCIsSqcqQGqzj1b30FNY8uHNaOB2INJG5agsiDlthJWmlLrfmHExjDFfKa B8ACkKYkppqRxi6kikBvExRt33TFXyYMD6PEffzPSOD6C5Wvc703U250JZMO2U 8WUXJ8bFOk0jhzfCVIrqeAhjKn2pda1KTOQthlWy8mPOfkqleudH8c9WqHHnZm5Q tyRgZjse40g12qY1D0Xb2- 4F_yU4H49mJ3KaWOtU4xkBsI8lBMcAFEbU.ZPK9UmnvttLUBjb2iu8OaFz8BWgN h7gVvMLaejHo_Ks&dib_tag=se&keywords=cable+prototipado&qid=1717531831&sr =8-5 Tornillos https://www.amazon.es/520-tornillos-tuercas-hexagonales- roscados/dp/B09LRS8WLD/ref=sr_1_5?__mk_es_ES=%C3%85M%C3%85%C5%BD %C3%95%C3%91&crid=W14A7QILN3J2&dib=eyJ2IjoiMSJ9.G_VDHTKwH47Sg2h YsIdGP_0oYKQ5vVmNJbDHhU88bEMlJGAQURlQ4Kdf5oNebW3sFRzYwJjZVndg JI-F9RVg9e5AtKrouFY_Ha9r81BHxWMonaaYK8b5ltCBG- q65_wdPyjYKbgZjKUzU5XlBfkhlqTNYn0MxWp9cvrcpImHEkodhO- 51Hdet1opKIKtf6aB01QEzYn1yqdxSWS9UG-mt9602ni9YEIEtsIvpEfJV- uJRAUoLcOaI2YuXWWKtKlbJluvm9AwDBMGh6rounwJeOd368s0UquJdWLd6LBn cJk.34PnSZ_thdiw8GvGRkM7PA- 5B10HhPmDtQU31FxBdGc&dib_tag=se&keywords=tornillos%2Bm5&qid=17175318 44&sprefix=tornillos%2Bm%2Caps%2C122&sr=8-5&th=1 Mando de control https://www.eneba.com/es/2-mandos-blancos-ps3-e757c04d