- MAVLink define mensajes ligeros entre GCS y vehículos no tripulados, con System ID, Component ID y Message ID.
- Las tramas v1.0 y v2 difieren en cabecera: flags, Message ID de 24 bits y firma opcional en v2.
- La integridad se asegura con CRC (X.25/SAE AS-4) y una semilla específica por conjunto de mensajes.
- Mensajes definidos en XML; ejemplo práctico: lectura de GPS (ID 24) con Pixhawk y Arduino.
A grandes rasgos, MAVLink es el idioma común que permite que estaciones de control en tierra y vehículos no tripulados se entiendan entre sí. Aunque nació pensando en micro vehículos aéreos, su uso se ha extendido también a otros UV (vehículos no tripulados) más allá de los drones. En la práctica, sirve para transportar datos como orientación, posición GPS o velocidad, además de órdenes de control, de forma ligera y fiable entre sistemas. En una red con varios dispositivos, MAVLink actúa como la capa que define cómo viajan esos datos y cómo se interpretan de punta a punta, desde el GCS (Ground Control Station) hasta el piloto automático o entre los propios subsistemas del vehículo.
La información disponible sobre este protocolo suele estar muy dispersa, con piezas técnicas sueltas y ejemplos por aquí y por allá. Aquí reunimos y reescribimos todo ese contenido para contarte qué es, cómo estructura sus paquetes (tanto en la versión 1.0 como en la 2), cómo garantiza la integridad mediante CRC y cómo se definen los mensajes en ficheros XML. También bajamos a tierra con un ejemplo sencillo de lectura de telemetría usando un autopiloto tipo Pixhawk y una placa Arduino, y repasamos brevemente las librerías más empleadas. La idea es que, al terminar, tengas claras las bases y puedas identificar los puntos clave como el System ID, el Component ID, el Message ID y el papel del payload.
Qué es MAVLink y para qué se usa
MAVLink (Micro Air Vehicle Link) se define como un protocolo de mensajería muy ligero que intercambia tramas compactas entre un vehículo no tripulado y los sistemas que lo supervisan o apoyan. Su propósito principal es facilitar la comunicación entre la estación de control en tierra (GCS) y el vehículo, pero también se utiliza para la interconexión interna de los módulos del propio sistema de vuelo. En la práctica, por un lado se envían datos de telemetría como la actitud/orientación, la ubicación GPS y la velocidad, y por otro lado se cursan comandos y configuraciones.
Cada dispositivo que participa en la red se identifica con un par de valores: System ID (el sistema emisor) y Component ID (el componente emisor dentro de ese sistema). Estos dos campos permiten distinguir varios drones en la misma red y, dentro de uno de ellos, separar módulos como la IMU, el piloto automático o cualquier otro subsistema. El contenido específico de cada trama lo marca el Message ID: este identificador determina qué significado tiene la carga útil y cómo se debe decodificar. Dicho de otra forma, el Message ID es el que dice “este paquete contiene X”, y el payload guarda los datos concretos de ese X, que pueden ser desde un conjunto de lecturas de sensores hasta un estado de navegación o un comando.
Estructura de paquete en MAVLink 1.0
La versión 1.0 de MAVLink define una estructura de paquete muy conocida, compacta y fácil de parsear. Cada campo ocupa una posición fija (índice en bytes), y el conjunto describe el inicio de la trama, su longitud, quién la envía, qué mensaje porta, los datos y la verificación de integridad. El orden y el significado de los campos son los siguientes, con el valor concreto de inicio de trama en 0xFE para v1.0 y una longitud de payload variable n. Con esta definición se puede, por ejemplo, detectar pérdidas de paquetes y separar correctamente el flujo de datos. Cada byte tiene su razón de ser y, gracias al CRC, el receptor puede confirmar que el paquete está íntegro y que ambos extremos están hablando exactamente del mismo tipo de mensaje.
| Campo | Índice (byte) | Función |
|---|---|---|
| Inicio de trama | 0 | Marca el comienzo del paquete (v1.0: 0xFE) |
| Longitud de payload | 1 | Indica el tamaño de la carga útil (n) |
| Secuencia | 2 | Contador de paquetes por componente para detectar pérdidas |
| System ID | 3 | Identifica el sistema emisor en la red |
| Component ID | 4 | Identifica el componente emisor dentro del sistema |
| Message ID | 5 | Define el tipo de mensaje y cómo decodificar el payload |
| Payload | 6 a (n+6) | Datos del mensaje; su estructura depende del Message ID |
| CRC | (n+7) a (n+8) | Comprobación de integridad (LSB a MSB) |
En este formato, la secuencia de paquete es clave para saber si se han perdido tramas en el camino, y los campos de identificación permiten rutear y filtrar lo que importa a cada módulo. Si el Message ID corresponde a telemetría de navegación, por ejemplo, el payload contendrá el conjunto concreto de valores definido para ese mensaje. De hecho, hay mensajes muy utilizados cuyo ID es bien conocido; un caso típico es el mensaje con ID 24, en el que el contenido del payload es la información del GPS, y que al decodificarlo nos da la posición del dron en tiempo real.
Estructura de paquete en MAVLink 2
MAVLink 2 amplía la cabecera para añadir compatibilidad hacia adelante y hacia atrás, y opciones de seguridad. El valor de inicio de trama cambia a 0xFD y aparecen dos bytes reservados a indicadores de compatibilidad, además de ampliar el identificador de mensaje a 24 bits (tres bytes). Esto permite definir más mensajes y negociar características entre emisores y receptores. La firma criptográfica es opcional y, cuando se usa, añade un bloque final que permite verificar que los mensajes llegan de una fuente confiable. En resumen, la versión 2 mantiene la esencia del formato v1.0, pero suma control fino de compatibilidad y la capacidad de autenticar el origen de la trama, algo muy útil cuando quieres reducir el riesgo de mensajes espurios en enlaces compartidos o críticos y mantener el ecosistema interoperable.
| Campo | Índice (byte) | Función |
|---|---|---|
| Inicio de trama | 0 | Marca el comienzo del paquete (v2: 0xFD) |
| Longitud de payload | 1 | Tamaño del payload (n) |
| Flags de incompatibilidad | 2 | Indicadores que deben comprenderse para compatibilidad MAVLink |
| Flags de compatibilidad | 3 | Indicadores que pueden ignorarse si no se soportan |
| Secuencia | 4 | Contador de paquetes para detectar pérdidas |
| System ID | 5 | Identificación del sistema emisor |
| Component ID | 6 | Identificación del componente emisor |
| Message ID | 7 a 9 | Identificador de mensaje en 24 bits |
| Payload | 10 a (n+10) | Datos del mensaje definidos por el Message ID |
| CRC | (n+11) a (n+12) | Comprobación de integridad (LSB a MSB) |
| Firma (opcional) | (n+13) a (n+25) | Verificación de origen confiable del mensaje |
El añadido de banderas de compatibilidad agiliza la negociación entre módulos que pueden no soportar exactamente lo mismo. Si una parte no entiende un flag marcado como “incompatible”, sabe que no debe procesar ese paquete; si el flag está en el grupo de “compatibles”, puede ignorarlo. Y con la firma, cuando está activa, el receptor puede verificar que el emisor es quien dice ser. Todo ello con la misma idea base: seguir enviando mensajes concisos para controlar y monitorizar, manteniendo la robustez que ya ofrecían la secuencia de paquetes y el campo CRC.
Integridad de mensaje: CRC y valor semilla
Para asegurar la integridad, cada paquete MAVLink incluye una comprobación de redundancia cíclica (CRC) en los dos últimos bytes de la parte no firmada. Este CRC se calcula sobre los bytes del paquete exceptuando el indicador de inicio de trama. El algoritmo utilizado es el de la familia ITU X.25/SAE AS-4, de modo que ambos extremos, emisor y receptor, llegan al mismo resultado siempre que el mensaje esté intacto. Este mecanismo no solo detecta corrupción en tránsito; además ayuda a garantizar que ambos extremos están completamente alineados sobre el mensaje que se está intercambiando.
Hay un detalle importante: al cálculo del CRC se le suma un valor semilla específico de cada conjunto de mensajes del protocolo (conocido habitualmente como CRC extra). Esta semilla se concatena al final de los datos antes de calcular el CRC, y se deriva de las definiciones del mensaje en la especificación. Gracias a este truco, si por cualquier motivo el emisor y el receptor no comparten exactamente la misma definición de mensajes, el CRC no coincidirá y el receptor sabrá que algo no cuadra. Los sistemas que implementan MAVLink suelen disponer de una matriz precalculada para agilizar este paso.
Mensajes, ficheros XML y orden de campos
La carga útil de cada paquete contiene un mensaje MAVLink. El Message ID identifica qué mensaje es, y el payload incluye los datos en el formato que dicta su definición. Estas definiciones viven en ficheros XML mantenidos en la fuente del proyecto MAVLink: ahí se describen los campos, tipos y significados para cada mensaje. Es fundamental no confundir el “orden lógico” de los campos descrito en el XML con el “formato de cable” real: para reducir problemas de alineación, la representación en el cable (y la memoria) puede reordenar los campos. Esta diferencia es normal, pero puede resultar chocante al leer el código generado a partir de las definiciones.
Volviendo al ejemplo clásico, el mensaje con ID 24 contiene valores de GPS. Saber el ID te permite reconocer el tipo de contenido y decodificarlo correctamente. El valor del payload dependerá de ese ID, y la forma correcta de interpretarlo está en el XML. Al trabajar con bindings o librerías en distintos lenguajes, estos suelen generar estructuras y funciones a partir de esos ficheros XML, así que cuando mires el código, acuérdate de ese detalle del reordenamiento de campos que puede hacer que lo que ves no coincida 1:1 con la sección XML.
Ecosistema y componentes: autopilotos, GCS y librerías
En un dron típico, el piloto automático es el “cerebro” que toma decisiones a partir de sensores e instrucciones de misión: IMU, GPS, límites, batería, inclinaciones de ejes, condiciones externas como viento o presión, etc. Modelos muy populares como Pixhawk implementan firmwares de referencia como PX4 o ArduPilot (y sistemas como APM en contextos similares), todos con soporte de MAVLink. Ese autopiloto viaja “a bordo” del vehículo y, para controlarlo y monitorizarlo desde fuera, necesitas que hable MAVLink con la estación de tierra y con sus propios sensores y módulos. Dicho de forma práctica, MAVLink es la arteria por la que circulan datos y órdenes entre el autopiloto y el resto de piezas del sistema UAV.
La comunidad ha implementado MAVLink en múltiples lenguajes, lo que facilita desarrollar herramientas y aplicaciones. En Python, la librería de referencia es pymavlink, muy usada para scripts y utilidades; en Java existen opciones de generación de código y APIs que permiten integrar MAVLink en aplicaciones Android o de escritorio. Además, estaciones de control y proyectos conocidos se apoyan en estas implementaciones para enviar, recibir y visualizar telemetría y comandos de vuelo.
Ejemplo práctico: leer mensajes con Arduino y un Pixhawk
Imagina un escenario reducido pero ilustrativo: un Pixhawk con firmware compatible (por ejemplo, PX4 en una FMU de la familia V5) conectado por un puerto de telemetría a un Arduino Uno mediante enlace serie. En esta configuración, la placa Arduino puede escuchar los mensajes que el autopiloto emite de forma periódica y, usando la librería C de MAVLink incluida en el sketch, decodificarlos. Este ejemplo es útil para entender el flujo real: primero preparas el entorno para el enlace serie Arduino↔Pixhawk, luego lees bytes, detectas el inicio de trama, compruebas longitudes, verificas el CRC y, por último, obtienes la estructura decodificada del mensaje que te permitirá acceder a campos como latitud, longitud o velocidad.
El papel de MAVLink aquí es doble: por un lado, estandariza la forma en que el Pixhawk empaqueta los datos; por otro, facilita que un dispositivo modesto como Arduino los entienda con una librería ligera. En una aplicación más grande, ese receptor podría ser una GCS completa en un PC o una app móvil, pero el principio es el mismo: el Message ID nos dice qué es cada paquete, y el payload incluye los datos organizados según el XML, listos para ser usados por tu aplicación de control o monitorización.
Detección de pérdidas, compatibilidad y firma
Dentro de cada flujo, el campo de secuencia se incrementa en el emisor y permite al receptor detectar huecos: si recibe 10, 11, 13, sabrá que el 12 se perdió. Es una forma simple y eficaz de vigilar la calidad del enlace sin añadir demasiado coste. Además, diferenciando System ID y Component ID puedes gestionar redes con varios drones y componentes sin que se mezclen las conversaciones. En MAVLink 2, las banderas de compatibilidad añaden una capa adicional para coordinar versiones y capacidades, mientras que la firma opcional permite verificar el origen de los mensajes cuando se requiere confianza adicional en el canal.
Conviene tener presente que, aunque la firma es opcional, el CRC no lo es: sigue siendo el mecanismo principal de detección de corrupción, y su cálculo incluye ese valor semilla específico de cada conjunto de mensajes. Si por error tu emisor y receptor usan conjuntos distintos (o versiones incompatibles) de definiciones XML, lo normal es que el CRC no cuadre, y eso es bueno: evita que interpretes como válido algo que no lo es. En definitiva, entre secuencia, CRC y (si procede) firma, tienes un abanico sólido de mecanismos para mantener los enlaces de telemetría coherentes y fiables.
De dónde salen los mensajes: XML y generación de código
Las definiciones XML son el contrato que dice cómo es cada mensaje: nombres de campos, tipos, tamaños y significados. Desde ahí se generan librerías en distintos lenguajes, y esas librerías son las que usas en tus apps para codificar y decodificar. Un detalle que puede chocar es que el orden visible en el XML, que es lógico, puede no coincidir con el orden “on the wire”. Esto se hace para optimizar alineación y minimizar rellenos, algo que ayuda a que las estructuras en memoria sean eficientes. Cuando revises el código generado de una librería o una GCS, que no te extrañe ver ese reordenamiento: está contemplado y forma parte del diseño del protocolo para que el empaquetado sea compacto y estable.
Como orientación general, si necesitas inspeccionar un mensaje concreto, busca su ID en las definiciones, revisa los tipos de datos del payload y apóyate en las utilidades que las librerías proporcionan para serializar y deserializar. Para tareas rápidas y scripts, Python con pymavlink resulta cómodo; para integraciones en Android o Java desktop, las librerías Java disponibles te permiten generar clases a partir de los XML y ahorrarte manejar bytes a mano, manteniendo el soporte de todas las estructuras del protocolo.
Qué puedes transmitir: ejemplos y casos habituales
El abanico de mensajes MAVLink incluye desde telemetría básica (actitud, GPS, velocidades), estados de sistema y salud de sensores, hasta comandos de control y ajustes de parámetros. En los flujos habituales, el autopiloto emite a intervalos constantes los mensajes de estado, y la GCS responde con órdenes cuando el usuario lo decide o cuando una automatización lo requiere. Es relativamente común, por ejemplo, subscribirse a los mensajes de localización (como el del Message ID 24 para GPS), extraer posición y velocidad, y mostrarlas en una interfaz para el piloto o para registro de vuelos.
Además, MAVLink permite que módulos dentro del propio vehículo se comuniquen entre sí usando la misma gramática, lo cual simplifica la arquitectura: no necesitas reinventar un canal privado para que un sensor se coordine con el piloto automático si ya tienes un protocolo ligero, probado y con control de errores, diseñado para exactamente ese entorno. Eso reduce el acoplamiento y ayuda a que piezas de diferente procedencia (siempre que respeten el estándar) sean interoperables desde el minuto uno.
