MAVLink Protocol Implementation in ArduPilot
Implementation Location
MAVLink transmission and control in ArduPilot are primarily implemented in libraries/GCS_MAVLink and vehicle-specific directories (e.g., Ardusub/). Library modules contain core functionality, while vehicle directories implement specialized subclasses inheriting from base classes.
Transmission Control
Interface Parameter Definition
The GCS_MAVLink class manages MAVLink transmission, while the GCS class emulates ground station functionality internally. In GCS.h:
_chanis a pointer array toGCS_MAVLinkobjects- Maximum channels: 5 (hardware) or 7 (SITL)
#if CONFIG_HAL_BOARD == HAL_BOARD_SITL
#define MAVLINK_CHANNEL_COUNT 7
#else
#define MAVLINK_CHANNEL_COUNT 5
#endif
MAVLink Initialization Sequence
AP_Vehicle::setup()invokesgcs().init()- System ID configuraton:
void GCS::initialize() {
mavlink_system.sysid = fetch_current_system_id();
}
- Default system ID (7,1) overridden by vehicle parameter
SYSID_THISMAV - Serial port initialization via
serial_manager.init() - Primary channel setup:
void GCS::configure_primary_port() {
AP_HAL::UARTDriver* serial_device =
AP::serial_manager().find_serial(
AP_SerialManager::MAVLinkProtocol, 0);
if(serial_device) {
initialize_mavlink_backend(port_params[0], *serial_device);
}
}
- Secondary channels initialized via
setup_auxiliary_ports() - Delay callback registration for packet processing:
hal.scheduler->register_delay_handler(packet_processor, 5);
Message Handling
Reception Process
- Periodic execution (400Hz) via scheduler tasks:
SCHED_TASK(update_receive, 400, 180),
SCHED_TASK(update_transmit, 400, 550)
- Channel processing:
void GCS::process_incoming() {
for(uint8_t i=0; i<channel_count(); i++) {
channel(i)->parse_incoming();
}
}
- Packet decoding and routing:
void MAVLinkHandler::decode_packet(const mavlink_status_t& status,
const mavlink_message_t& msg) {
if(valid_packet(status, msg)) {
route_message(msg);
process_message(msg);
}
}
- Vehicle-specfiic message handling:
void CopterGCS::process_message(const mavlink_message_t& msg) {
switch(msg.msgid) {
case MAVLINK_MSG_ID_MANUAL_CONTROL:
decode_manual_input(msg);
break;
// Additional cases
}
}
Transmission Mechanism
- Message scheduling:
void GCS::update_transmit() {
for(uint8_t i=0; i<channel_count(); i++) {
channel(i)->queue_messages();
}
}
- Payload preparation:
bool MAVLinkHandler::prepare_message(ap_message_id msg_type) {
switch(msg_type) {
case ATTITUDE_DATA:
return encode_attitude();
// Additional cases
}
}
- Attitude message encoding:
void MAVLinkHandler::encode_attitude() {
const AHRS& orientation = AP::ahrs();
mavlink_msg_attitude_send(
channel_index,
AP_HAL::millis(),
orientation.roll,
orientation.pitch,
orientation.yaw,
gyro.x, gyro.y, gyro.z
);
}
Custom Message Support
- XML definition per MAVLink specification
- Message registry updates:
#include <custom_messages/mavlink_msg_custom.h>
- Transmission implementation:
void transmit_custom_data(float param1, int16_t param2) {
mavlink_msg_custom_send(
channel_index,
param1, param2
);
}