MAVLink Micro Air Vehicle Communication Protocol
MAVLink is a very lightweight, header-only message marshalling library for micro air vehicles.
It can pack C-structs over serial channels with high effiency and send these packets to the ground control station. It is extensively tested on the PX4, PIXHAWK, APM and Parrot AR.Drone platforms and serves there as communication backbone for the MCU/IMU communication as well as for Linux interprocess and ground link communication.
The MAVLink generator was first released early 2009 by Lorenz Meier under LGPL license. The generated output was always considered equal to the input message spec and has since been clarified to be MIT.
Message Specification
Integration Tutorials
These tutorials show how to integrate MAVLink with your autopilot or Linux robot.
MAVLink Messages / MAVLink API Documentation
Message documentation is generated for all MAVLink messages automatically and always up-to-date. To get the details of a MAVLink message, please refer to the message lists below. You can additionally generate Doxygen API docs from the MAVLink source.
Protocol Internals
QGroundControl users: Although MAVLink itself does not rely on it, QGroundControl adjusts its views and settings based on the HEARTBEAT MAVLink message. QGroundControl uses this message also to track if a system is alive or if the connection broke. Therefore make sure to send a heartbeat every 60, 30, 10 or 1 second (1 Hz is recommended, but not required)
MAVLink Code and Generator
There is a “common message set” containing widely used messages, which is distributed as header-only C library. If you like to use your own custom messages, you can generate these with the MAVLink Generator (C/C++, Python) or QGroundControl.
The MAVLink message definitions and generator code is hosted at:
Installation / usage instructions can be found at:
Instructions how to use the generator can be found at:
Instructions how to package MAVLink releases (developers only) can be found here:
MAVLink Ecosystem
There are by now many systems and software packages using MAVLink:
MAVLink Mailing List and Developers
Autopilots using MAVLink
Software packages using MAVLink
MAVProxy (allows to connect multiple UDP/serial links, including flightgear):
git://git.samba.org/tridge/UAV/MAVProxy.git
Projects using MAVLink
License
The MAVLink generator is LGPL licensed and its output is MIT licensed and can therefore be used as a library royalty-free in closed-source and open-source applications.
Frequently Asked Questions (FAQ)
Upgrading from 0.9.0 to 1.0.0
Q: Is the upgrade easily done? - Yes, v.1.0.0 is almost fully
API-compatible with v.0.9.0. Only a few messages have changed, all protocol-functions like the message parsing (mavlink_parse_char) are fully compatible.
Q: What are the main benefits from upgrading? - 1. MAVLink now uses the little-endian wire encoding, which makes is a lot more efficient on most platforms. It still supports little and big endian platforms. 2. It now checks the packet format of each message, so if two communication partners have different formats for the same message it will detect this mismatch. 3. It now has support for smaller message buffers. 4. The parameter protocol now supports 32 unsigned and signed integer and float values. 5. MAVLink now supports IEEE 754 double precision floating point numbers. 6. All messages are tested with an automatically generated test suite, making the protocol even safer to use. 7. Some messages have been cleaned up to better suit actual flight use. 8. MAVLink comes per default now with C/C++ and Python support.
Q: Is the new version to be used soon? - Yes, QGroundControl is fully ported to it and ArduPilotMega and PIXHAWK already are porting their software. Soon all adopters will have ported to the new version, simply because it is not too much effort.
Users
Q: How many aircraft does MAVLink support? - 255 aircraft, ranging from 1 to 255. 0 is not a valid aircraft id.
Q: How efficient is MAVLink? - With just 8 bytes overhead per packet, including start sign and packet drop detection, MAVLink is a very efficient protocol.
Q: Where can I use MAVLink? - MAVLink has been shown to work on multiple microcontrollers and operating systems, including ARM7, ATMega, dsPic, STM32 and Windows, Linux, MacOS and iOS.
Q: How safe is MAVLink? - MAVLink has been used for more than two years in the PIXHAWK MAV project in flight and relies on the well-established ITU X.25 checksum for packet corruption detection.
Developers
Q: Can I use MAVLink in a closed source application without copyright issues? - Yes, without any limitations. The
LGPL license only requires you to contribute changes to MAVLink itself to the community, not any code that uses MAVLink. So you are not required to publish any of your application code.
Q: MAVLink uses only one start sign - isn't this less safe than using two or three start signs? - No. A packet start sign is always used to “sync up” to the start of a message. To actually “prove” that the received data is a message and not random noise, the message length and check sum is needed. Using more start signs would allow to better “guess” a packet start in a random noise channel. Since MAV telemetry is however not random noise, using more start signs does not help to increase the certainty about a packet start, because if the decoding state machine does only depend on the packet start sign, it will reject all packets containing the start sign in their payload. Example: Most protocols encode payload length and message id in the header, often as continuing fields. If the start sign is e.g. (0x35 0x55) (two bytes), which is in decimal (53 85), a packet with length 53 and ID 85 will always be rejected by the decoder. To circumvent these systematic faults, the message should only be rejected if the checksum mismatches. Given these constraints, one can as well just use one packet start sign and save unneccesary bytes on the communication link.
Q: How does MAVLink detect and decode messages in the byte stream? - MAVLink waits for the packet start sign, then reads the packet length and matches the checksum after n bytes. If the checksum matches, it returns the decoded packet and waits again for the start sign. If bytes are altered or lost, it will drop the current message and continue the next try on the following message.
Q: What use do the system and component IDs have? - The system ID reflects the current aircraft. MAVLink can be used with multiple aircraft simultaneously. The component ID reflects the onboard component, e.g. the IMU, the autopilot or the onboard computer. This allows to use MAVLink both for onboard-communication and for off-board telemetry.
Q: MAVLink contains a sequence number in the header - is this really necessary? - Yes. MAVLink is part of the safety critical components of an unmanned air system. A bad communication link dropping many packets can endanger the flight safety of the aircraft and has to be monitored. Having the sequence in the header allows MAVLink to continously provide feedback about the packet drop rate and thus allows the aircraft or ground control station to take action.
Q: I would like to help improve the decoding/encoding routines or other features. Can MAVLink be changed? - Yes, but only very, very carefully with safety testing. MAVLink is by now used as a safety-critical component in many autopilot systems and has undergone more than two years of testing. Please suggest new features on the
MAVLink mailing list.
Packet Anatomy
This is the anatomy of one packet. It is inspired by the CAN and SAE AS-4 standards.
Byte Index | Content | Value | Explanation |
0 | Packet start sign | v1.0: 0xFE (v0.9: 0x55) | Indicates the start of a new packet. |
1 | Payload length | 0 - 255 | Indicates length of the following payload. |
2 | Packet sequence | 0 - 255 | Each component counts up his send sequence. Allows to detect packet loss |
3 | System ID | 1 - 255 | ID of the SENDING system. Allows to differentiate different MAVs on the same network. |
4 | Component ID | 0 - 255 | ID of the SENDING component. Allows to differentiate different components of the same system, e.g. the IMU and the autopilot. |
5 | Message ID | 0 - 255 | ID of the message - the id defines what the payload “means” and how it should be correctly decoded. |
6 to (n+6) | Data | (0 - 255) bytes | Data of the message, depends on the message id. |
(n+7) to (n+8) | Checksum (low byte, high byte) | ITU X.25/SAE AS-4 hash, excluding packet start sign, so bytes 1..(n+6) Note: The checksum also includes MAVLINK_CRC_EXTRA (Number computed from message fields. Protects the packet from decoding a different version of the same packet but with different variables). |
Supported data types
MAVLink supports fixed-size integer data types, IEEE 754 single precision floating point numbers, arrays of these data types (e.g. char[10]) and the special mavlink_version field, which is added automatically by the protocol. These types are available:
char - Characters / strings
uint8_t - Unsigned 8 bit
int8_t - Signed 8 bit
uint16_t - Unsigned 16 bit
int16_t - Signed 16 bit
uint32_t - Unsigned 32 bit
int32_t - Signed 32 bit
uint64_t - Unsigned 64 bit
int64_t - Signed 64 bit
float - IEEE 754 single precision floating point number
double - IEEE 754 double precision floating point number
uint8_t_mavlink_version - Unsigned 8 bit field automatically filled on sending with the current MAVLink version - it cannot be written, just read from the packet like a normal uint8_t field
Performance
This protocol was totally geared towards two properties: Transmission speed and safety. It allows to check the message content, it also allows to detect lost messages but still only needs six bytes overhead for each packet.
Transmission examples
Link speed | Hardware | Update rate | Payload | Float values |
115200 baud | XBee Pro 2.4 GHz | 50 Hz | 224 bytes | 56 |
115200 baud | XBee Pro 2.4 GHz | 100 Hz | 109 bytes | 27 |
57600 baud | XBee Pro 2.4 GHz | 100 Hz | 51 bytes | 12 |
9600 baud | XBee Pro XSC 900 | 50 Hz | 13 bytes | 3 |
9600 baud | XBee Pro XSC 900 | 20 Hz | 42 bytes | 10 |
Future Work / Ideas
Variable length arrays
Support for bitfields (e.g. packing 8 boolean values into one uint8_t, but providing C-function calls to all eight booleans. So users would not have to fiddle with shifting / masking themselves.)
Variable header, allowing to set target system and target component (no change to protocol, only convenience functions to access it)