MAVLink - Step-by-Step
by Pedro Albuquerque
This post result from my struggle to find information about the subject to understand the concept, and developing a basic concept test.
My background - I have been using Ardupilot software on Multirotors and airplanes for 1 year.
I learned to program C (C86, Microsoft C, Turbo C) 30 year ago (yes 1986) , i've been away from programming in C, eventually only reading some code since then , and recently (2 month ago) I got to know arduino and its IDE.
back to the subject.
A message system
MAVLink is a message protocol, designed to exchange information between a UAV and a GCS or a subsystem (ex:gimbal controller), using a serial communication channel.
The base structure of the protocol is the message. For perfomance reasons it is binary information, so , eventually not readable by humans without some interpretation.
A simple message with acknowledge
this is an example of a message (WAYPOINT_CLEAR_ALL) sent by the GCS to a UAV. The UAV receives and executes, and responds with another message (WAYPOINT_ACK).
After sending the initial message, the GCS starts a timer to decide for a timeout state if no ACK messages is received .
System ID, subsystem ID and Message ID
Most messages will indicate source(originating) system ID (sysid) , subsystem ID (compid), destination system ID, destination subsystem/component ID and a message type ID
GCS system ID should be 255 (see here)
Vehicle ID should be 1
(see here the parameter on Ardupilot http://ardupilot.org/copter/docs/parameters.html?highlight=parameters#sysid-thismav-mavlink-system-id-of-this-vehicle)
Some subsystem codes are already reserved. look for MAV_COMPONENT on this page https://pixhawk.ethz.ch/mavlink/
Source sysID , compID and MSG are all encoded in the message header.
Destination sysID , compID when necessary will be part of the payload.
The payload content/structure for each MSG is defined here (keep calm… will get into practical details later)
A library is available to help prepare a message to be sent or to decode a message just received.
Actually, you will have to build your library following this instruction https://github.com/mavlink/mavlink to adjust it to your platform and your programming language.
You end up with a folder with your library called mavlink (or the name you decide eventually)
example Steps (performed on a Mac):
download the zip from github to a folder named mavlink-master
On a terminal windows , change to that folder and execute the command
“python -m mavgenerate”
on the new window choose
xml folder: …/tmp/mavlink-master/message_definitions/v1.0/ardupilotmega.xml
out folder: …/tmp/MAVLink
How to use the result
Once the folder has been generated I moved it to the library folder , in my case as I am using an arduino as a auxiliar system I installed it at
and include it like
But what does it contain ?
This was something I really strived to discover
Remember, what we want - compose messages to send and receive messages and interpret them.
The message is the focal point.
So before going into coding, we need to first know what messages are available and their meaning/purpose.
The general message list can be found starting here-> https://pixhawk.ethz.ch/mavlink/#HEARTBEAT
Every platform may choose to implement a sub-set and/or additional messages. Arduplilot implemented messages can be found at http://ardupilot.org/dev/docs/mavlink-commands.html
Any message is composed of several fields(struct in C), and is a mavlink_message_t type .
Additionally each specific message has associated with it:
* a type def for the structure to hold the payload fields
* a pack function to load the message with the data
* a decode function to translate the message and load the payload structure (specific for each message)
All of this is defined in a include file with the same name as the message.
(When you include the mavlink.h in your code you are also including all the include files for each message.)
definition file is common/mavlink_msg_heartbeat.h
note: the location of the file can be on platform folder or in common. they are on platform folder if they have some modified from the common definition.
type def: mavlink_heartbeat_t
packing function: mavlink_msg_heartbeat_pack() - load the mavlink_message_t type object with all the necessary information so that it can be sent
decoding function: mavlink_msg_heartbeat_decode() - decode the message and fill the mavlink_hearbeat_t type object with received message information
Note that this definition file serves both purposes, to prepare a message to be sent or to decode a message received.
Is that all?
We are almost there (able to write a sketch to receive and send a MAVLink message).
Receiving a message
we need to write a function to read the message from serial com and decode it.
now you just call it when you fill appropriate.
Sending a message
Sending a message is a bit more tricky.
The system running our software need to have a SysID and a CompID, so we have to decide one.
choose any SysID except 1 ou 255
choose compID 1 is case no match found to reserved codes.
CC_SYSID and CC_COMPID were defined by me for the source system, and I’m sending a message to a ardupilot system (the target system) that has SYSID = 1 and if not for specific component, then use the main that is CompID = 1
msg is an empty object of type mavlink_message_t that will be filled by the pack function
param_id is a char array with the name of the parameter
param_index if set to -1 will use the name, other wise we need to know the index of the parameter in the target system.
copy the message to a byte buffer which is sized to the largest message MAVlink will allow.
finally , just send it to com port.
Note: Remember each message has its own propose and its own payload data, so we need to check os it’s include message file what field do we need as I could not find any other documentation for it.
What you should achieve
- Understand what Mavlink is
- understand the concept and structure of a generic message
- know how to generate and install a library to deal with MAVLink messages
- Know where to find the available messages, and the implemented message in Ardupilot
- know were to look for message definition
- construct your MAVLink message receive and send routine.
Feel free to send feedback on how to improve this introductory document. Keep in mind that it is meant to help developers get into MAVLink concept and use.