💡 Modern C++: 'constexpr' no es solo para constantes: permite ejecutar lógica en tiempo de compilación, reducir costes en tiempo de ejecución y detectar errores antes de compilar.

jueves, 29 de enero de 2026

Errores reales usando MAVLink en comunicaciones con UAV: qué hacer y cómo evitar perder horas innecesariamente

En las primeras pruebas con MAVLink todo parece bastante sencillo: estableces conexión, empiezas a ver llegar mensajes, ves la telemetría moverse y da la impresión de que ya tienes el sistema más o menos entendido. Los ejemplos funcionan, las herramientas responden y la sensación general es que el funcionamiento del protocolo es más básico de lo que realmente es.

El problema llega cuando pasas de un entorno de pruebas a la realidad. En cuanto aparecen varios componentes —autopiloto, estación de tierra, sensores— MAVLink podría llegar a fallar de formas raritas. Cuando esto pasa, es muy común no ver errores ni mensajes explícitos, simplemente “no funciona”, y muchas veces el código no tiene la culpa.

En este post no voy a explicar qué es MAVLink ni cómo enviar tu primer mensaje. Voy a hablar de errores reales que he visto, y sufrido jajaja, trabajando con sistemas UAV: configuraciones de puertos y baudrate que nadie revisa, XMLs que no coinciden y mensajes que desaparecen sin avisar.

Si ya estás trabajando con MAVLink en un sistema real, es muy probable que alguna de estas situaciones te suene. Y si aún no has llegado ahí, mejor tenerlas en mente antes de perder tiempo con errores que no dan ninguna pista clara.

Número 1. Configurar bien el baudrate y los puertos TELEM: no des por hecho que están bien

Por muy seguro que creas estar, nunca des por hecho que la configuración básica está bien. En general, dar por sentadas cosas en este mundillo no es muy pro tip que digamos. Es sorprendente la cantidad de tiempo que se puede perder depurando cuando, en realidad, no te está llegando ni un solo byte de MAVLink al sistema.

Concretamente, cuando trabajas con autopilotos (CubeOrange, Pixhawk, Durandal, etc.) es muy común asumir que las intefaces TELEM1 o TELEM2 están bien configuradas desde el firmware. No tiene por qué ser así. Dependiendo de la versión del firmware, del modelo o de configuraciones previas, un puerto puede estar deshabilitado, reasignado a otro protocolo o usando un baudrate distinto al que espera la estación de tierra, por ejemplo.

En proyectos reales, basta con que un día prestes el autopiloto para unas pruebas para que alguien cambie una configuración… y nadie se acuerde luego de devolverla a su estado original.

Antes de tocar una sola línea de código, verifica siempre tres cosas:

  1. Qué puerto físico estás usando realmente (TELEM1/TELEM2).
  2. Que la configuración de ese puerto sea la apropiada.
  3. Que el baudrate coincida exactamente en origen y destino.
Cinco minutos aquí pueden ahorrarte horas luego.

Número 2. Cuidado con repetir IDs de mensajes en el dialecto XML

Uno de los errores que más pasan desapercibidos. Cuando defines nuevos mensajes custom en el dialecto XML es importante asegurarse que no repites un ID de mensaje. El generador de cabeceras de MAVLink no muestra ningún tipo de mensaje por terminal en caso de haber empleado un ID en uso. Lo que termina pasando es que ese la cabecera asociada a ese mensaje no se generará.

dialecto common.xml mavlink github
Archivo common.xml de MAVLink | Captura extraída del repositorio oficial de GitHub de MAVLink

Además, este error es especialmente fácil de cometer cuando el XML es considerablemente largo, hay varios mensajes custom o más de una persona tocando el mismo fichero. Pasa mucho, y me ha pasado mucho, copiar y pegar un mensaje para escribir otro y olvidarme de cambiar el ID.

Cada vez que añadas o modifiques mensajes en tu XML de MAVLink, revisa expresamente que los IDs sean únicos. No confíes en que el generador te avise.

Te ahorrarás mucho tiempo.

Número 3. El dialecto XML tiene que coincidir en origen y destino

Si en cada punto de la comunicación estás usando una versión distinta del XML, te puedes encontrar con mensajes que se descartan, que no pasan la validación, o que directamente se interpretan mal. Pueden simplemente empezar a pasar cosas raras y un poquito confusas. Y nos gustan las cosas claras.

Os sentiréis identificados con esta expresión | Derechos de autor: Fizkes | Dreamstime.com

La razón es que si un extremo no conoce el message ID, no podrá decodificar el payload. También pasa que en MAVLink el receptor necesita conocer el mensaje para poder validar correctamente su integridad (CRC/extra CRC), así que un mensaje desconocido o con contenido ligeramente diferente (distinto número de campos) se ignorará.

Además, cuando hay repos distintos en origen y destino, es facilísimo cometer erratas: un campo renombrado en un lado, un enumerado con un valor distinto, o un mensaje que en un lado tiene un campo extra (extensión) y en el otro no.

Número 4. Depurar la comunicación MAVLink usando Wireshark

Pasa muy a menudo que tras implementar una nueva funcionalidad o un nuevo botón que debería enviar tal comando MAVLink no funciona. La cosa es que puede no funcionar por muchísimas razones. Que se te haya olvidado emitir una señal, que una función devuelva siempre false (un descuido lo tiene cualquiera), etc.

Cuando pasa esto y no veo un problema evidente en el código del software que debería hacer el envío hecho un vistazo al software receptor para ver si encuentro el problema. Muchas veces se hace complicado y cuando te quieres dar cuenta llevas una hora perdida con el problema.

Aquí lo que yo suelo hacer es utilizar Wireshark para inspeccionar, normalmente en el equipo destino, la interfaz por la que deberían estar entrando los paquetes de MAVLink. Para hacer esto hay dos opciones: usar un plugin de MAVLink para Wireshark, o bien usar un plugin de MAVLink para Wireshark (jaja).

Con el generador de MAVLink se puede especificar el lenguaje para el que quieres hacer la librería, ¿verdad? En mi caso particular, suelo seleccionar C++, pero si seleccionas WLua podrás obtener un dialecto de parseo de paquetes MAVLink que se puede cargar directamente en Wireshark (common.lua, por ejemplo).

Panel de wireshark mostrando mensajes entrantes de MAVLink gracias al plugin WLua.
Así se ve Wireshark cuando se utiliza un dialecto MAVLink .lua | Imagen extraída de la documentación online de MAVLink

Con esto se puede ver de un vistazo si el equipo que debería estar recibiendo los mensajes y comandos está siquiera haciéndolo, antes de darnos cabezazos con el código.

Puedes echar un vistazo a mi trabajo de fin de grado "Análisis y desarrollo de medidas de seguridad avanzadas para la protección de comunicaciones en vehículos aéreos no tripulados" donde utilizo esta herramienta a modo de parseador para depurar paquetes MAVLink.

No hay comentarios:

Publicar un comentario

Icono de volver arriba del blog Codio