Ubicoders - skill up coding skills ubiquitously!

Mavlink and PX4 Autopilot 4: Mavlink Definition

Exploring the Intricacies of Mavlink XMLs: Crafting Custom Messages for Enhanced Drone Capabilities

Picture of the author
Elliot Lee - Dec.5, 2023

Table of Contents

  1. Introduction
  2. General Pattern of Message Protocols
  3. Mavlink's Approach
  4. Components of Mavlink Definitions
  5. Conclusion


In our ongoing series about Mavlink and PX4 Autopilot, we've explored various aspects including initial setup, data collection, and the intricacies of Mavlink encryption and decryption. In this article, we shift our focus to the creation of custom Mavlink messages, a pivotal functionality for advanced drone operations.

General Pattern of Message Protocols

Message protocols typically adhere to a standard structure, starting with an Interface Definition Language (IDL) file. This IDL file is then used to generate language-specific message files.

General Pattern of Message Protocols

For instance, a Protobuf IDL file might resemble the following:


Line #:

syntax = "proto2"; package tutorial; // Example of a Protobuf IDL message Person { optional string name = 1; optional int32 id = 2; optional string email = 3; ... }

After defining the IDL, it's compiled into a set of library files for the target programming language.

Mavlink mirrors this pattern, but with a key difference: it utilizes XML format for message definitions. These XML files are processed through tools like Pymavlink, resulting in the creation of usable library files.


Line #:

<message id="24" name="GPS_RAW_INT"> <description>The global position, as returned by the Global Positioning System (GPS). This is NOT the global position estimate of the system, but rather a RAW sensor value. See message GLOBAL_POSITION_INT for the global position estimate.</description> <field type="uint64_t" name="time_usec" units="us">Timestamp (UNIX Epoch time or time since system boot). The receiving end can infer timestamp format (since 1.1.1970 or since system boot) by checking for the magnitude of the number.</field> <field type="uint8_t" name="fix_type" enum="GPS_FIX_TYPE">GPS fix type.</field> <field type="int32_t" name="lat" units="degE7">Latitude (WGS84, EGM96 ellipsoid)</field> <field type="int32_t" name="lon" units="degE7">Longitude (WGS84, EGM96 ellipsoid)</field> <field type="int32_t" name="alt" units="mm">Altitude (MSL). Positive for up. Note that virtually all GPS modules provide the MSL altitude in addition to the WGS84 altitude.</field> <field type="uint16_t" name="eph" invalid="UINT16_MAX">GPS HDOP horizontal dilution of position (unitless * 100). If unknown, set to: UINT16_MAX</field> <field type="uint16_t" name="epv" invalid="UINT16_MAX">GPS VDOP vertical dilution of position (unitless * 100). If unknown, set to: UINT16_MAX</field> <field type="uint16_t" name="vel" units="cm/s" invalid="UINT16_MAX">GPS ground speed. If unknown, set to: UINT16_MAX</field> <field type="uint16_t" name="cog" units="cdeg" invalid="UINT16_MAX">Course over ground (NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. If unknown, set to: UINT16_MAX</field> <field type="uint8_t" name="satellites_visible" invalid="UINT8_MAX">Number of satellites visible. If unknown, set to UINT8_MAX</field> <extensions/> <field type="int32_t" name="alt_ellipsoid" units="mm">Altitude (above WGS84, EGM96 ellipsoid). Positive for up.</field> <field type="uint32_t" name="h_acc" units="mm">Position uncertainty.</field> <field type="uint32_t" name="v_acc" units="mm">Altitude uncertainty.</field> <field type="uint32_t" name="vel_acc" units="mm">Speed uncertainty.</field> <field type="uint32_t" name="hdg_acc" units="degE5">Heading / track uncertainty</field> <field type="uint16_t" name="yaw" units="cdeg" invalid="0">Yaw in earth frame from north. Use 0 if this GPS does not provide yaw. Use UINT16_MAX if this GPS is configured to provide yaw and is currently unable to provide it. Use 36000 for north.</field> </message>

The full definition is available at the Mavlink GitHub Repository.

Mavlink definition XMLs encompass three primary components:

  1. Messages: The core of Mavlink definitions. Each 'message' tag consists of 'field' tags, specifying variable types and structures.

    For instance, the messge is the actual Mavlink definition. The "message" tag has "field" tags which defines the variable types. The types can be primitive types such as int32_t as well as Enums. The Enum type is the same purpose as the normal programing languages. It contains the type of the cases or so.


Line #:

<message id="24" name="GPS_RAW_INT"> <!-- Detailed Mavlink message structure --> ... </message>
  1. Enums: Enums are utilized for defining allowable values for various fields in the messages.

    For instance, from the above "message" definition, there is a line saying.


Line #:

<field type="uint8_t" name="fix_type" enum="GPS_FIX_TYPE">GPS fix type.</field>

The Enum, "GPS_FIX" is defined above the file. Simply the enums are defined earlier than the "message" tags has the "message" tags need to know the enums before using it.

a. Usually, enum is for “field” of the message like below. This shows that the field value can only be one of the enum value that is defined in “Enum”. Yet, when you pack and parse, you can just use [enum.name] in the code. Enums are typically declared before 'message' tags as they are referenced within these messages.


Line #:

<enum name="GPS_FIX_TYPE"> <description>Type of GPS fix</description> <entry value="0" name="GPS_FIX_TYPE_NO_GPS"> <description>No GPS connected</description> </entry> <entry value="1" name="GPS_FIX_TYPE_NO_FIX"> <description>No position information, GPS is connected</description> </entry> <entry value="2" name="GPS_FIX_TYPE_2D_FIX"> <description>2D position</description> </entry> <entry value="3" name="GPS_FIX_TYPE_3D_FIX"> <description>3D position</description> </entry> <entry value="4" name="GPS_FIX_TYPE_DGPS"> <description>DGPS/SBAS aided 3D position</description> </entry> <entry value="5" name="GPS_FIX_TYPE_RTK_FLOAT"> <description>RTK float, 3D position</description> </entry> <entry value="6" name="GPS_FIX_TYPE_RTK_FIXED"> <description>RTK Fixed, 3D position</description> </entry> <entry value="7" name="GPS_FIX_TYPE_STATIC"> <description>Static fixed, typically used for base stations</description> </entry> <entry value="8" name="GPS_FIX_TYPE_PPP"> <description>PPP, 3D position.</description> </entry> </enum>

  1. Commands: These are specific actions encapsulated in the "MAV_CMD" enum. Commands can accept up to seven parameters, functioning similarly to arguments in a programming function.

Commands are entryvalues of enum named “MAV_CMD”.


Line #:

<enum name="MAV_CMD"> <description>Commands to be executed by the MAV. They can be executed on user request, or as part of a mission script. If the action is used in a mission, the parameter mapping to the waypoint/mission message is as follows: Param 1, Param 2, Param 3, Param 4, X: Param 5, Y:Param 6, Z:Param 7. This command list is similar what ARINC 424 is for commercial aircraft: A data format how to interpret waypoint/mission data. NaN and INT32_MAX may be used in float/integer params (respectively) to indicate optional/default values (e.g. to use the component's current yaw or latitude rather than a specific value). See https://mavlink.io/en/guide/xml_schema.html#MAV_CMD for information about the structure of the MAV_CMD entries</description> <entry value="16" name="MAV_CMD_NAV_WAYPOINT" hasLocation="true" isDestination="true"> <description>Navigate to waypoint. This is intended for use in missions (for guided commands outside of missions use MAV_CMD_DO_REPOSITION).</description> <param index="1" label="Hold" units="s" minValue="0">Hold time. (ignored by fixed wing, time to stay at waypoint for rotary wing)</param> <param index="2" label="Accept Radius" units="m" minValue="0">Acceptance radius (if the sphere with this radius is hit, the waypoint counts as reached)</param> <param index="3" label="Pass Radius" units="m">0 to pass through the WP, if &gt; 0 radius to pass by WP. Positive value for clockwise orbit, negative value for counter-clockwise orbit. Allows trajectory control.</param> <param index="4" label="Yaw" units="deg">Desired yaw angle at waypoint (rotary wing). NaN to use the current system yaw heading mode (e.g. yaw towards next waypoint, yaw to home, etc.).</param> <param index="5" label="Latitude">Latitude</param> <param index="6" label="Longitude">Longitude</param> <param index="7" label="Altitude" units="m">Altitude</param> </entry> ...


Understanding the intricacies of Mavlink Definition XMLs is crucial for those looking to fully leverage the Mavlink protocol in drone technology. This knowledge allows for the creation of customized messages, enhancing the capabilities and integration of the PX4 Autopilot system in various drone applications.