TFG · Ingeniería de Telecomunicaciones · UC3M

Diario de tareas

Registro cronológico del trabajo realizado en el desarrollo del sistema de búsqueda y rescate basado en UAV.

SISTEMA OPERATIVO · ÚLT. ACTUALIZACIÓN: 18 AGO 2026
28Registros
37Días documentados
5Repos en GitHub
9Hitos alcanzados
Situación actual · 18 ago 2026

Dónde está el proyecto ahora

El proyecto tiene ya resuelta toda la base sobre la que se construirá el resto del sistema. Está cerrada la parte normativa —certificado de piloto A1/A3 y número de operador AESA— y el acceso a un espacio de vuelo seguro, gracias a la federación en el club Alas de Galapagar, cuya licencia de socio incluye el seguro obligatorio. He realizado además un primer vuelo de referencia, cuyo registro GPS me sirve para planificar misiones en simulación.

En el plano técnico, la infraestructura extremo a extremo está operativa. La adquisición de datos en el nodo edge se ha organizado por dominios independientes (ambiental, sistema, vuelo y detección), cada uno como un proceso propio con su buffer local en SQLite y publicando bajo una estructura jerárquica de topics sar/{dron_id}/{dominio}, con almacenamiento intermedio local para no perder datos ante cortes de red. El sensor ambiental BME680 sobre la Raspberry Pi 5 alimenta ya el dominio ambiental, cuyas lecturas llegan por MQTT al servidor en la nube (AWS EC2 con Mosquitto e InfluxDB). El enlace entre el nodo edge y la nube ya no depende del entorno de desarrollo: he configurado un módem USB 4G/LTE con una SIM de DIGI —con su propio perfil APN y el PIN desactivado para que arranque de forma autónoma—, de modo que el dron sale a Internet por red celular, reservando la Wi-Fi como enlace local alternativo. Sobre esa conectividad he levantado además una VPN en malla (mesh) con Tailscale que une el servidor, la Raspberry y mi equipo en una red privada Zero Trust, cifrada de extremo a extremo y sin necesidad de abrir puertos al exterior. Los servidores web están en marcha, y tanto las páginas como los servicios dinámicos (API REST e InfluxDB) se sirven ya por HTTPS con certificado propio, accediéndose a estos últimos a través de un reverse proxy en nginx que permite mantener cerrados sus puertos al exterior.

En cuanto al vuelo, he llevado el control autónomo de la simulación a la Raspberry Pi: la Pi comanda el dron simulado (Mission Planner + ArduPilot SITL) por MAVLink a través de la red. Sobre esa base he montado el control por MQTT —un publicador en el EC2 y un receptor en la Pi que traduce las órdenes a MAVLink— y una API REST con una página de botones para teleoperar el dron (armar, despegar, aterrizar, RTL, misión) desde el navegador, ya validada contra el simulador. Este panel se ha ampliado además con un selector que permite elegir a qué dron (dron-01 / dron-02) se dirige cada comando, y con nuevos botones de gestión remota del nodo edge —como apagar la Raspberry Pi o ajustar en caliente parámetros de funcionamiento (cada cuánto envía datos el dominio de sistema o el intervalo anti-spam de las alertas)—. Tanto la API como el receptor se ejecutan como servicios systemd, de modo que arrancan solos y se reinician ante cualquier interrupción.

En el apartado de visión artificial, he desarrollado el pipeline de detección de personas con YOLO y lo he validado sobre vídeo real, ejecutándolo en mi propio equipo (todavía sin el acelerador Hailo y sin desplegar en la Raspberry Pi). Cuando el sistema detecta a una persona, genera una alerta que se publica por MQTT con el mismo esquema store-and-forward que el resto de dominios, incluyendo la caja de la detección, la posición del dron y una foto del fotograma con las coordenadas y la marca temporal superpuestas. En paralelo, he empezado a construir el dataset con Roboflow y ya he capturado las primeras imágenes para el entrenamiento.

El repositorio del servidor se ha reorganizado por carpetas para separar las páginas web, el panel de control y la API, y se trabaja ahora sobre una rama develop que mantiene la rama principal con la versión estable. El fallo de la tarjeta microSD que dejó temporalmente fuera de servicio a la Raspberry Pi está resuelto: se ha sustituido y repetido la instalación de la imagen, además de rehacer el script del receptor, que no estaba subido al repositorio. He puesto en marcha también la presencia web pública del proyecto: una landing de colaboración para captar vídeos aéreos y patrocinios, y una web técnica que documenta el sistema completo (arquitectura de comunicaciones, hardware, software y cloud, IA y marco del proyecto).

Próximos pasos: ampliar el dataset de detección con muchas más imágenes aéreas para entrenar el modelo definitivo. En paralelo, ensamblar el dron definitivo e incorporar autenticación a la API y cifrado MQTT antes de conectar la cadena de mando a la aeronave real.

Filtrar por área

Julio 2026

Hasta 11 julio Memoria Hardware Sistema
  • Índice de contenidos de la memoria planteado.
  • Lectura e investigación sobre la normativa. Certificado A1/A3 de AESA y número de operador obtenidos.
  • Investigación sobre dónde volar el dron y cómo pedir permisos: consulta a clubes de aeromodelismo (Majadahonda y Alas de Galapagar) por sus condiciones. Inscripción como socia en Alas de Galapagar, ya que no requiere pedir permisos a AESA y ofrece un lugar seguro y cómodo para volar cuando quiera.
  • Compra de la Raspberry Pi 5 y del primer sensor, el BME680 20,85 € — sensor ambiental que mide temperatura, humedad relativa, presión barométrica y resistencia de gas.
    • Conexión sensor – Raspberry configurada.
  • Instancia EC2 configurada en AWS ~4 $/mes (24 h):
    • AMI Ubuntu sobre t3.small.
    • Grupos de seguridad creados: puerto 1883 para la comunicación MQTT con el broker Mosquitto, puerto 22 para SSH y puerto 8086 para el acceso a la base de datos InfluxDB.
    • Instalación del servicio broker Mosquitto en la EC2 para la comunicación con el sensor.
    • Creación de IP elástica (sin ella la IP pública de la EC2 cambiaba al reiniciarse, obligando a modificar los scripts, peticiones HTTP…).
  • Publicación de datos (del sensor a la EC2):
    • La Raspberry Pi actúa como cliente publicador y en el servidor un segundo cliente actúa como suscriptor, recibiendo los mensajes y publicándolos en InfluxDB. Scripts creados: sensor.py en la Pi y mqtt_to_influx.py en la EC2.
    • Implementación de la arquitectura store-and-forward en sensor.py para que ningún dato se pierda ante una caída temporal de la conexión (cada lectura se almacena primero en una base de datos local SQLite, buffer.db).
  • Recepción y almacenamiento en el servidor:
    • mqtt_to_influx.py actúa como cliente suscriptor; se ejecuta en la EC2 dentro de un entorno virtual propio (env) con las librerías paho-mqtt (comunicación con el broker) e influxdb-client (escritura en la base de datos).
    • Cada lectura recibida se almacena en InfluxDB.
  • Almacenamiento en InfluxDB:
    • Abierta una entrada en el grupo de seguridad para el puerto 8086, de forma que se pueda acceder desde el navegador mediante la dirección pública de la EC2.
  • Configuración de servicios systemctl de Linux en la Pi y en el servidor, para que inicien sus procesos automáticamente en cada arranque sin intervención manual.
  • Publicación de los scripts en GitHub. Cada repo incluye README (documentación de uso), .gitignore (evita subir archivos sensibles o innecesarios), requirements.txt (dependencias reproducibles) y .env.example (plantilla de credenciales, que se mantienen fuera del repositorio).
  • Compra del dominio gorostiditfg.com en Cloudflare 10,41 $, para acceder a los servicios mediante subdominios legibles en vez de la IP del servidor.
  • Creación de dos páginas (HTML + CSS sencillo) que usaré más adelante: una para la presentación del proyecto y otra para el control del dron.
11 julio Sistema Vuelo
  • Creación de servidores web:
    • Instalación del servidor web nginx y aprendizaje de la configuración de varios servidores virtuales web en la misma máquina.
    • Alta en el servidor DNS de Cloudflare de los nombres de host necesarios (ya puedo acceder a las páginas creadas con el dominio): www.gorostiditfg.com y control.gorostiditfg.com.
    • Configuración de nginx como reverse proxy para acceder a la interfaz de InfluxDB igual que a las demás webs: como usa el puerto 8086 en la petición HTTP, había que indicarlo y ya no es necesario especificarlo → influxdb.gorostiditfg.com.
  • Gestión de claves públicas / privadas:
    • Limpieza y ordenación de las claves públicas/privadas, que estaban mezcladas. Configuración del fichero .ssh en la EC2 para permitir el acceso con mi clave pública en lugar del .pem (habilitando esta otra forma editando el .ssh).
  • Mission Planner:
    • Configuración del simulador de vuelo Mission Planner. Vuelos de prueba en dos zonas distintas.
    • Desarrollo de un script en Python (con pymavlink) que se conecta al simulador vía MAVLink para enviar comandos de vuelo: armado/desarmado, despegue y modo AUTO para ejecutar misiones por waypoints. La conexión se establece mediante reenvío UDP de Mission Planner al puerto local 14550.
12 julio Vuelo ★ Primer vuelo real
  • Visita al club de Galapagar: recogida del carnet de socia y las llaves de acceso, y presentación con el presidente.
  • Contactos en el club:
    • Presidente: Darco.
    • Primer vuelo acompañada por José Manuel.
    • Contacto por correo: Paco (Francisco). También me presentan a otro socio con un DJI (me enseña su maletín) y a alguien con mucho conocimiento sobre baterías.
  • Me muestran en Mission Planner la zona por la que debo volar, y por qué aparece marcada en amarillo.
  • Primer vuelo real de un dron: uso de la cuenta de mi padre (instalación y configuración de la app DJI en mi móvil).
  • Me recomiendan comprar mejores adaptadores/cables para el dron (uno de carga más rápida).
  • Grabación de vídeos con el DJI en el primer vuelo. Los datos deberían quedar almacenados.
  • Importante: pegar en el dron mi número de operador.
13 julio Memoria Vuelo Sistema
  • Investigación sobre la posibilidad de volar el dron en Comillas (Cantabria), con vistas a realizar un vuelo allí este fin de semana: consulta de la normativa y de las restricciones de la zona.
  • Configuración del dron en su aplicación y colocación física de mi propio número de operador sobre el dron, según exige la normativa.
  • Actualización y mejora de la página web del proyecto para dejarla presentable de cara al tutor.
    • Creación de la página del diario de tareas y de la página de operador.
    • Generación de un código QR que enlaza con la página de operador, para pegarlo en el dron: al escanearlo muestra los datos del operador.
  • Subida de los logs del primer vuelo a Airdata y a PhantomHelp Log Viewer para revisar y analizar los datos del vuelo.
  • Eliminación del puerto 8086 del grupo de seguridad de la EC2, ya innecesario: el acceso a la interfaz de InfluxDB se realiza ahora a través de nginx configurado como reverse proxy (influxdb.gorostiditfg.com), sin exponer el puerto directamente a internet.
  • Comunicación al tutor del avance del proyecto, compartiéndole la web para que pueda hacer el seguimiento del progreso a través del diario de tareas.
14 julio Vuelo Sistema
  • He retomado el control del dron simulado desde Python (Mission Planner + ArduPilot SITL): Había un problema del armado (los pre-arm checks y el GPS del simulador) y he conseguido que vuelva a funcionar. He comprobado que efectivamente funcione el ciclo completo —armado, despegue y misión por waypoints en modo AUTO—, viendo el dron moverse en Mission Planner.
  • Pasar el control de vuelo a la Raspberry Pi, para que las órdenes salgan del nodo edge y no del PC:
    • Configuración de la conexión por red entre la Pi y Mission Planner, usando las IP reales de cada máquina en lugar de 127.0.0.1, el reenvío UDP y el puerto 14550.
    • Entender la lógica de quién envía y quién escucha (udpin/udpout) y por qué en MAVLink la Pi escucha mientras recibe la telemetría del autopiloto.
    • Conseguir que la Pi de órdenes al dron simulado por MAVLink a través de la red, validando así la arquitectura edge-first.
15 julio Sistema ★ Control web completo
  • Implementación del control del dron por MQTT, montando el patrón publicador–receptor:
    • Creación de un publicador (comandos.py, en el EC2) que envía las órdenes por MQTT, y de un receptor (receptor.py, en la Pi) que las traduce a MAVLink y las ejecuta sobre el dron simulado.
    • He empezado por argumentos como armar/desarmar para comprobar que funcione y después he añadido más: despegue, aterrizaje, RTL (volver a casa), mantener posición e iniciar misión.
  • Conversión del publicador en una API REST con Flask (api.py, en el EC2) para poder invocar los comandos por HTTP en lugar de por terminal, y para ello se ha abierto el puerto 5000 en el grupo de seguridad de AWS.
  • Modificación de la página de control web añadiendo botones para cada comando, que llama a esa API: control.gorostiditfg.com
16 julio Sistema
  • Repaso conceptual a fondo de la API REST (api.py) para entender no solo qué hace, sino por qué existe y qué papel tiene dentro de la arquitectura. Se ha revisado la cadena completa de comunicación: navegador (HTTP) → api.py en el EC2, que traduce HTTP a MQTT → broker Mosquitto (puerto 1883) → receptor.py en la Raspberry Pi, que traduce MQTT a MAVLink → autopiloto → dron.
    • El HTTP aparece únicamente porque el emisor es el navegador, que solo habla ese protocolo.
    • api.py y receptor.py no están conectados directamente: se comunican a través del broker, gracias al modelo publicador/suscriptor desacoplado de MQTT.
    • comandos.py y api.py son alternativas paralelas para enviar los mismos comandos, no pasos consecutivos.
    • El formato JSON solo se usa en los tramos HTTP y MQTT; el tramo MAVLink es binario, por ser un enlace de telemetría con ancho de banda limitado.
    • Los puertos son por servicio: Flask en el 5000 y Mosquitto en el 1883. receptor.py no abre ningún puerto porque actúa como cliente, no como servidor.
  • Comprobación de que la página de control con botones funciona correctamente y envía las señales al simulador.
  • Error «puerto 5000 en uso» al relanzar la API: se debía a un proceso zombi que quedó vivo tras un Ctrl+C incompleto. Resuelto con pkill -f api.py.
  • A raíz de esto se ha decidido convertir api.py y receptor.py en servicios systemd, igual que ya lo están mqtt_to_influx.py y sensor.py, para que arranquen solos y no dependan de una terminal abierta. PENDIENTE
  • Creación de clave SSL para proteger con HTTPS todas las páginas creadas, lo que ha implicado abrir también el puerto 443 en el grupo de seguridad del servidor.
  • Al pasar las páginas a HTTPS, la API ha dejado de funcionar. El diagnóstico es un bloqueo de contenido mixto: el navegador impide que una página servida por HTTPS haga peticiones a un recurso HTTP.
    • Solución planteada: crear el subdominio api.gorostiditfg.com en Cloudflare en modo Proxied, configurar nginx como reverse proxy hacia localhost:5000 y actualizar la URL del fetch en el JavaScript del panel. PENDIENTE
  • Nota: la API sigue sin autenticación, decisión deliberada mientras se trabaja en simulación. Habrá que añadirla antes de conectarla al hardware real.
17 julio Hardware Sistema
  • Actualización del repositorio del servidor en GitHub, dividiéndolo en carpetas (www/web/, control/ y api-rest/) e incluyendo las páginas HTML, que hasta ahora solo existían en el servidor.
  • Al ir a actualizar el repositorio de la Pi, se ha detectado que no se puede acceder a ella por SSH. La tarjeta microSD se ha estropeado, probablemente por cortar la corriente bruscamente en lugar de hacer un sudo poweroff. Se ha intentado volver a cargar la imagen de Raspberry Pi OS en la tarjeta y no es capaz de leerla.
  • Lección aprendida: apagar siempre la Pi con sudo poweroff y mantener todo actualizado en GitHub, para no perder los códigos ni el trabajo hecho hasta el momento.
20 julio Hardware
  • Sustitución de la tarjeta microSD de la Raspberry Pi, repitiendo todo el proceso con la nueva SD:
    • Grabación de la imagen del sistema operativo y configuración inicial de la Raspberry (acceso por SSH, red, habilitación del bus I2C).
    • Clonado del repositorio desde GitHub y recuperación del entorno de trabajo.
    • Reescritura de receptor.py, único script que no estaba subido al repositorio y que se perdió con la tarjeta.
  • Actualización del README y publicación de los cambios en GitHub.
21 julio Memoria Sistema
  • Revisión de todo lo realizado hasta el momento y comienzo de la redacción en la memoria del TFG de la arquitectura diseñada: capítulo 5, apartado 5.4 (Arquitectura IoT con AWS EC2 y Mosquitto):
    • Infraestructura de la instancia EC2.
    • Sensor BME680.
    • Flujo de datos con arquitectura store-and-forward.
    • Almacenamiento en InfluxDB.
    • Ejecución autónoma mediante systemd.
  • Revisión del estado de los certificados TLS de los subdominios para identificar cuáles quedaban pendientes de configurar.
  • Resuelto el problema de mixed content: creado el subdominio api.gorostiditfg.com, configurado nginx como reverse proxy hacia localhost:5000, emitido el certificado TLS y actualizada la URL del fetch en el panel de control.
  • Eliminada la regla del puerto 5000 del grupo de seguridad de la instancia, ya innecesaria al accederse a la API a través del reverse proxy de nginx.
22 julio Sistema Memoria
  • Creación de los servicios systemd para receptor.py en la Raspberry Pi y para api.py en la instancia EC2, de forma que ambos arranquen automáticamente y se reinicien ante cualquier interrupción, sin depender de una sesión SSH abierta.
  • Continuación de la redacción del capítulo 5 de la memoria: infraestructura de servicios web y control remoto, y simulación SITL con ArduPilot.
  • Instalación y prueba de Claude Code, para desarrollar una interfaz web más completa y con mayor número de funcionalidades.
27 julio Memoria
  • Reorganización estructural de la memoria: división del antiguo capítulo 5 en capítulo 5 (control de vuelo y telemetría: MAVLink, GCS, pymavlink, SITL, FPV) y capítulo 6 (arquitectura IoT: EC2, BME680, MQTT, servicios web).
  • Reconstrucción del capítulo 2 (estado del arte):
    • 2.1 UAV en SAR · 2.2 Comunicaciones más allá de la línea de visión (BVLOS) · 2.3 Detección de personas con YOLO.
    • Reubicación del contenido mal colocado: comparativa de chasis → 4.2.1; fusión IMU/GPS/Kalman → 4.2.2; justificación de MQTT/EC2 → 6.3; detalles de FPV → 5.5.
28 julio Memoria
  • Redacción del capítulo 3 (normativa), secciones 3.1–3.4 y 3.6: Reglamento (UE) 2019/947, categoría abierta A3, Remote ID obligatorio desde enero de 2026, RD 517/2024, sentencia del TS de junio de 2025, doble registro (operador AESA + aeronave) y Ley 11/2022.
  • Mensaje al tutor (Dani) para preguntar por la posible financiación de la universidad para los materiales del dron. PENDIENTE de respuesta
29 julio Memoria
  • Revisión de la arquitectura del sistema de cara al capítulo 4 (apartado 4.1): repaso del diseño extremo a extremo y preparación del esquema de arquitectura (queda a medias, se continuará).
  • Construcción de la bibliografía en formato IEEE, según la guía de la biblioteca de la UC3M, para los capítulos ya redactados (normativa y estado del arte).
30 julio IA
  • Primer contacto con Roboflow de cara a construir el dataset y entrenar YOLOv8 para el Hailo-8L: investigación, tutoriales y pruebas de anotación para entender cómo funciona, ver la división de los datos y qué es la augmentation.

Agosto 2026

5 agosto Hardware
  • Un socio del club de Galapagar me presta un hexacóptero de fibra de carbono para reutilizar piezas.
  • Análisis de las piezas del dron prestado:
    • Reutilizables: chasis de fibra de carbono, 6 motores T-Motor MN3110-780KV, ESCs, hélices de carbono, tren de aterrizaje, receptor FlySky FS-iA10B y conectores.
    • No reutilizables: controladora DJI NAZA-M Lite (propietaria, incompatible con ArduPilot/MAVLink), GPS DJI, cadena FPV analógica y PDB (sin confirmar).
  • Comparativa de opciones de compra:
    • Plan A (reutilizar piezas): ~545–550 € en componentes nuevos.
    • Plan B (kit nuevo Holybro X500 v2 con Pixhawk 6X): ~943 € y agotado. Se opta por el Plan A.
  • Elaboración de la lista de compra de componentes nuevos: Pixhawk 6C + PM02, GPS Holybro M10, radio de telemetría 433 MHz, batería LiPo 6S, cargador iMAX B6AC, emisora FlySky FS-i6X y consumibles de montaje.
    • La Raspberry Pi 5 + Hailo requiere un UBEC dedicado de ≥5 A (el BEC del PDB no basta).
  • Al estar el kit agotado, llamada a RC-Innovations; me indican mandar un correo para reservar el kit, que tendrán disponible la próxima semana.
6 agosto Hardware IA ★ Primer modelo YOLO
  • Envío del correo a RC-Innovations pidiendo disponibilidad y presupuesto de los componentes.
  • Primera práctica completa con Roboflow para entender de primera mano cómo funciona la herramienta y el flujo de trabajo de un detector YOLO de principio a fin, sobre un caso de prueba sencillo (detección de frutas):
    • Preparación del entorno de trabajo en local (Python, VS Code y Claude Code) y comprobación de que todo ejecuta correctamente.
    • Partiendo de un dataset público de Roboflow Universe, he añadido fotos propias y las he etiquetado a mano (bounding boxes) para personalizar el conjunto.
    • Aplicación del preprocesado y el augmentation, y generación de la versión final del dataset.
    • Descarga del dataset y entrenamiento de un modelo YOLO en local con Ultralytics, obteniendo el modelo entrenado (best.pt).
  • Con esto he cubierto todo el proceso hasta obtener el modelo. El siguiente paso es probar el modelo entrenado sobre vídeo (inferencia), para ver las detecciones en imágenes en movimiento y comprobar si detecta correctamente cada fruta.
7 agosto IA
  • Partiendo del modelo entrenado el día anterior, he profundizado en el ajuste del entrenamiento probando distintos números de épocas:
    • Primera prueba con 15 épocas: insuficiente.
    • Ampliación a 80 épocas con parada temprana (patience=20); la métrica de validación se estabiliza en torno a la época 40, por lo que ese número resulta suficiente para la convergencia.
  • He medido el coste real del entrenamiento en local: ha tardado 2 h 40 min ejecutándose sobre CPU, a pesar de tratarse de un modelo ligero y un dataset pequeño (~300 imágenes con aumentación). Este dato es una referencia clave de cara al proyecto: al ser el dataset real de personas mucho mayor y más complejo, su entrenamiento tendrá que realizarse en la nube.
  • He realizado la inferencia sobre vídeo que quedaba pendiente, guardando el resultado anotado en output.mp4. La he probado tanto con un vídeo grabado con el móvil como con uno grabado desde el dron.
  • Revisión de resultados: analizando las curvas de aprendizaje y la matriz de confusión he visto que el modelo confunde con cierta frecuencia manzana y pera, por tratarse de clases visualmente parecidas y un dataset reducido.
  • Publicación de todo el código en un repositorio de GitHub, con su README documentando el flujo, los parámetros de entrenamiento e inferencia y las limitaciones observadas: github.com/nereagorostidi/yolo-pipeline-test
8 agosto Hardware Memoria ★ Kit reservado
  • Recepción de la respuesta de RC-Innovations por correo con el presupuesto total. Contestación confirmando la reserva del kit para poder recibirlo cuanto antes.
  • Redacción de la memoria, centrada en el cierre de los capítulos 1, 2, 3, y 6.
9 agosto Vuelo IA ★ Primeras grabaciones del dataset
  • He hecho un par de vuelos en el club de aeromodelismo (por la mañana) para empezar a construir mi dataset de detección de personas: grabación de vídeos con el dron sobre mis padres.
  • Procesado del material: extracción de frames de los vídeos y selección de 35 imágenes distintas para el dataset.
10 agosto Sistema
  • Me he centrado en la arquitectura, en cómo estructurar la adquisición de datos del nodo edge. La primera idea que planteo es un proceso único con un scheduler cooperativo por reloj: un solo hilo que en cada vuelta mira qué colector toca según su intervalo, con todos escribiendo en una única base SQLite compartida.
  • Al analizarlo veo que esta opción tiene riesgo de bloqueos y concurrencia sobre la base compartida, y que un fallo en un colector perjudica al resto. He optado por un proceso independiente por dominio (ambiental, sistema, vuelo y detección), cada uno con su propia base SQLite. Con eso elimino los bloqueos, gano resiliencia (si uno cae, los demás siguen) y me queda un sistema mucho más fácil de mantener y ampliar.
    • Topics MQTT jerárquicos (sar/{dron_id}/{dominio}) y client_id como {dron_id}-{dominio} para que Mosquitto no tire conexiones por IDs duplicados.
    • Lectura del dron_id desde un .env compartido.
    • Buffers store-and-forward con QoS 1 para no perder ni un dato si se cae la red.
    • Comunicación directa entre vuelo.py y deteccion.py mediante escrituras atómicas en posicion_actual.json.
11 agosto Sistema IA Memoria ★ Arquitectura de datos implementada
  • Paso el diseño a código y desarrollo los cuatro colectores:
    • ambiental.py para leer los datos del sensor BME680.
    • sistema.py para monitorizar las métricas y el estado de la Raspberry Pi.
    • vuelo.py de forma provisional con telemetría simulada (a la espera de integrar la Pixhawk).
    • deteccion.py integrando YOLO, afinando parámetros como flags explícitos (--mqtt y --preview), un --anti-spam por defecto a 5 s y haciendo que cada proceso infiera automáticamente su base de datos según el dominio, sin configuraciones extra.
  • Actualizo el bridge MQTT en el servidor:
    • Uso un receptor universal suscrito a sar/#: así identifica automáticamente de qué sensor viene el dato leyendo el topic y simplifica la estructura del JSON para que la base de datos lo trague sin procesado extra.
  • Monto el modo fake para agilizar pruebas:
    • Configuro mi propio ordenador como dron-02 para levantar y validar todo el flujo de datos en local con simulación, para no tener que depender de la Pi y su conexión por SSH en cada prueba.
  • Documentación:
    • Documentación de lo configurado para tener toda la arquitectura y las decisiones de diseño en un documento, con diagramas explicativos para repasar.
12 agosto Sistema IA
  • Prueba de la detección de personas sobre vídeo real::
    • Ejecuto deteccion.py con YOLO sobre un vídeo real, corriéndolo en mi propia máquina
    • Al detectar una persona, salta una alerta por MQTT en sar/{dron_id}/deteccion (con buffer store-and-forward), que incluye la caja en píxeles, la posición del dron y la foto.
    • La foto se guarda con overlay de coordenadas (posición del dron) y fecha/hora, y las alertas llevan un throttling anti-spam (5 s) para no saturar el topic con la misma persona.
  • Fallo en el armado desde el panel web:
    • La función de armado deja de responder de repente, así que me pongo a depurar qué está fallando en la comunicación entre la web y la API.
  • Identificación de los dos problemas principales:
    • Bloqueo por Mixed Content: el panel carga bajo HTTPS, pero el API_BASE del index.html seguía apuntando por HTTP directamente a la IP pública de la instancia EC2. Como el navegador bloquea las llamadas HTTP inseguras, cambio la URL para que apunte a https://api.gorostiditfg.com.
    • Pérdida del identificador del dron: al cambiar de dron en la interfaz, la web no incluye el drone_id en el cuerpo de la petición. La API asigna por defecto dron-01, pero como el receptor está escuchando en dron-02, el comando se pierde y nunca llega a ejecutarse.
  • Solución e integración:
    • Añado un desplegable de selección de dron (dron-01 / dron-02) en el panel de control.
    • Modifico la función enviar() para que capture el valor seleccionado y lo adjunte en cada petición a la API.
    • Con esto el flujo queda resuelto: el desplegable define en qué topic publica la API y, siempre que el receptor esté escuchando en ese mismo dron, los comandos entran sin problema.
13 agosto Vuelo Memoria ★ Landing page publicada
  • Depuración del enlace con Mission Planner: aunque la parte web ya está resuelta, el dron sigue sin armar debido a un conflicto de puertos:
    • receptor.py falla al arrancar con WinError 10013 porque Mission Planner tiene ocupado el puerto 14550. Cambio la conexión a MAVLINK_CONN = "udpin:127.0.0.1:14551".
    • Aun así, el script se queda bloqueado esperando en wait_heartbeat() porque el reenvío UDP de Mission Planner sigue apuntando al puerto antiguo. Entro al menú avanzado de Mission Planner (Ctrl + F) y redirijo el forward UDP a 127.0.0.1:14551.
    • En cuanto entran los heartbeats por el nuevo puerto, el receptor se suscribe correctamente y el dron vuelve a armar de extremo a extremo sin problemas.
  • Creación de la landing page para pedir colaboración en el proyecto: ayuda en la compra de materiales o patrocinio, y también de personas que puedan mandarme vídeos que aporten valor a mi dataset de detección de personas: drone-sar.gorostiditfg.com
14 agosto Sistema
  • Doy por terminada la landing de micromecenazgo (drone-sar.gorostiditfg.com): repaso de los textos finales, la sección de colaboración con los dos tipos de ayuda (vídeos aéreos y patrocinio), y añadido del journal. Publicada y operativa.
  • Empiezo a montar la estructura de la web técnica del proyecto (Guardian Eye), la página donde desarrollaré todo el proyecto a fondo: una documentación navegable, dividida en secciones, que recogerá el sistema completo de extremo a extremo.
    • Parte de proyecto: introducción, objetivos, metodología, filosofía y normativa.
    • Parte de arquitectura: comunicaciones, hardware y software/cloud.
    • Parte de exploración: inteligencia artificial, multimedia, impacto y colaboradores.
  • Publicación en YouTube del vídeo del primer test de detección de personas.
  • Repaso a fondo del perfil de GitHub: descripciones cortas para los seis repos con el patrón TFG ·, definición de topics y creación del README del perfil con badges.
15 agosto Sistema ★ Web técnica publicada
  • Continúo con la web técnica y la dejo bastante cerrada, aunque todavía me queda algún detalle por pulir. Desarrollo el contenido de las secciones principales:
    • Arquitectura: comunicaciones (con la redundancia multicanal), hardware y software/cloud.
    • Inteligencia artificial: sistema de detección.
    • Páginas de proyecto.
  • Dejo la web técnica enlazada con la landing, los repos de GitHub y el journal.
  • Repaso a fondo del perfil de GitHub: descripciones cortas para los seis repos con el patrón TFG ·, definición de topics y creación del README del perfil con badges.
16 agosto Memoria Sistema
  • Repaso de la página web del proyecto, con modificación de alguna sección.
  • Reorganización de la estructura de la memoria para reflejar la arquitectura IoT multidominio. Decisión principal: partir el antiguo capítulo 6 en dos:
    • Cap. 6 → adquisición de datos IoT (edge a nube, los cuatro dominios, store-and-forward, InfluxDB).
    • Cap. 7 → servicios web y control remoto (DNS, nginx, TLS, API REST, cadena de mando).
  • El capítulo 5 se queda con el control de vuelo local (MAVLink, GCS, pymavlink, SITL); la detección (YOLO/Hailo) pasa al capítulo 8 y la validación al capítulo 9.
  • Añado figuras nuevas para que quede más claro: 6.2 (arquitectura multidominio), 6.3 (store-and-forward genérico), 5.3 (secuencia de misión autónoma), 7.5 (cadena de mando completa) y 4.1 (arquitectura general del sistema).
  • Compra de tarjeta SIM prepago 10 €.
17 agosto Sistema ★ VPN en malla y enlace 4G
  • Repaso de la memoria.
  • Levanto una VPN en malla (mesh) con Tailscale para conectar de forma segura los tres equipos (servidor AWS, Raspberry y mi PC). Funciona como red Zero Trust: cada equipo recibe su propia IP dentro de la red y todos se comunican de forma cifrada de extremo a extremo, sin abrir puertos al exterior.
    • Dejo Tailscale en el autoarranque de la máquina de AWS y de la Raspberry, para que se unan solas a la malla al encenderse.
    • Configuro el módem USB 4G/LTE: la Raspberry lo reconoce como interfaz de red, pero no sale a Internet hasta crear un perfil APN de DIGI (SIM de prepago DIGI).
    • Desactivo el PIN de la SIM para que el módem arranque solo, sin meterlo a mano.
    • Reviso las tablas de rutas de la Raspberry: por defecto todo el tráfico sale por 4G/LTE, y la Wi-Fi solo entra si se retira el pincho USB (a mano o por script) o para conectarme a un equipo de la misma red local.
  • Mejora futura: un script en Python que vigile la cobertura 4G y desactive esa ruta si se cae. PENDIENTE