Key Takeaways
- ArduPilot implements a complete MAVLink 2.0 protocol stack across 33 source files in
libraries/GCS_MAVLink/, supporting 8 distinct vehicle types (Copter, Plane, Rover, Sub, Tracker, Blimp, Periph, Dummy) - The message routing system supports up to 20 concurrent routes with automatic route learning from received messages, heartbeat-based route discovery, and per-channel routing masks
- Message scheduling uses a 10-bucket deferred system with per-stream rate control (SR0_* parameters) and dynamic interval adjustment via
MAV_CMD_SET_MESSAGE_INTERVAL - Parameter protocol operates asynchronously with an I/O timer and thread-safe queues; parameter writes can be locked for safety
- Three independent mission item transfer protocols (Waypoints, Fence, Rally) are handled through a shared MissionItemProtocol base class
- MAVLink 2.0 signing, FTP file transfer, SERIAL_CONTROL passthrough, HIGH_LATENCY2 satellite mode, and 40+ MAV_CMD commands are all supported
- A clearly documented deprecation timeline exists for legacy features like MISSION_REQUEST and AUTOPILOT_VERSION_REQUEST messages
This article is generated from analysis of the ArduPilot master branch source code, providing a comprehensive deep-dive into MAVLink’s complete implementation architecture.
1. MAVLink Overview
MAVLink (Micro Air Vehicle Link) is the lightweight, open-source communication protocol standard for unmanned vehicles. ArduPilot implements the full MAVLink 2.0 protocol stack through its GCS_MAVLink library, supporting:
- Dual MAVLink 1.0 and 2.0 protocol coexistence with automatic negotiation
- Multi-channel concurrent communication (up to 16 channels in SITL, 5-8 on embedded hardware)
- Message routing and forwarding (up to 20 routing table entries)
- MAVLink 2.0 signing (security authentication)
- MAVLink FTP file transfer protocol
- HIGH_LATENCY2 (satellite/high-latency link support)
- SERIAL_CONTROL (serial port passthrough)
- CAN over MAVLink (CAN bus forwarding)
1.1 MAVLink Submodules
MAVLink header files are included as a Git submodule:
modules/mavlink/
├── mavlink/
# MAVLink 协议定义和代码生成
├── pymavlink/
# Python MAVLink 库
└── mavnative/
# C 原生 MAVLink 加速
ArduPilot uses include/mavlink/v2.0/ardupilotmega.xml as its message definition, which contains ArduPilot-specific extended messages.
2. Code Architecture
2.1 File Organization
libraries/GCS_MAVLink/
# 核心 MAVLink 库 (33 个文件)
├── GCS.h
# 核心类定义:GCS_MAVLINK 和 GCS 类
├── GCS.cpp
# GCS 全局实现
├── GCS_Common.cpp
# 消息处理分发 (245KB,最大文件)
├── GCS_MAVLink.h
# MAVLink 头文件包装
├── GCS_MAVLink.cpp
# 通道缓冲区管理
├── GCS_config.h
# 编译时功能开关
├── GCS_MAVLink_Parameters.cpp
# 流速率参数定义
├── GCS_Param.cpp
# 参数协议处理
├── GCS_FTP.h / .cpp
# MAVLink FTP 子协议
├── GCS_Signing.cpp
# MAVLink2 签名实现
├── GCS_serial_control.cpp
# SERIAL_CONTROL 处理
├── GCS_DeviceOp.cpp
# DEVICE_OP 远程 I2C/SPI 访问
├── GCS_Fence.cpp
# 围栏状态处理
├── GCS_ServoRelay.cpp
# 舵机/继电器命令
├── MAVLink_routing.h / .cpp
# 消息路由表实现
├── ap_message.h
# 内部消息 ID 枚举 (MSG_*)
├── MissionItemProtocol.h/.cpp
# 任务项传输协议基类
├── MissionItemProtocol_Waypoints.h/.cpp
# 航点协议
├── MissionItemProtocol_Fence.h/.cpp
# 围栏协议
├── MissionItemProtocol_Rally.h/.cpp
# Rally 点协议
├── GCS_Dummy.h / .cpp
# 测试桩
└── examples/routing/
# 路由示例
2.2 Class Hierarchy
GCS (全局单例)
├── _chan[MAVLINK_COMM_NUM_BUFFERS] → GCS_MAVLINK 对象数组
│
├── 车辆特定子类:
│ ├── GCS_Copter : GCS (ArduCopter/GCS_Copter.h)
│ ├── GCS_Plane : GCS (ArduPlane/GCS_Plane.h)
│ ├── GCS_Rover : GCS (Rover/GCS_Rover.h)
│ ├── GCS_Sub : GCS (ArduSub/GCS_Sub.h)
│ ├── GCS_Tracker : GCS (AntennaTracker/GCS_Tracker.h)
│ ├── GCS_Blimp : GCS (Blimp/GCS_Blimp.h)
│ ├── GCS_Periph : GCS (Tools/AP_Periph/)
│ └── GCS_Dummy : GCS (用于工具/测试)
│
└── GCS_MAVLINK (单通道 MAVLink 后端)
├── GCS_MAVLINK_Copter : GCS_MAVLINK
├── GCS_MAVLINK_Plane : GCS_MAVLINK
├── GCS_MAVLINK_Rover : GCS_MAVLINK
├── GCS_MAVLINK_Sub : GCS_MAVLINK
├── GCS_MAVLINK_Tracker : GCS_MAVLINK
├── GCS_MAVLINK_Blimp : GCS_MAVLINK
├── GCS_MAVLINK_Periph : GCS_MAVLINK
└── GCS_MAVLINK_Dummy : GCS_MAVLINK
-
全局单例:管理所有 MAVLink 通道
-
参数:SYSID_THISMAV、MAV_GCS_SYSID、MAV_OPTIONS、MAV_TELEM_DELAY
-
Statustext 队列:容量 10-30 条,线程安全
-
传感器状态:维护 present/enabled/health 三个 32 位掩码
-
串口透传:管理 UART 转发
-
高延迟:启用/管理高延迟连接
-
单通道管理:每个 UART 端口对应一个实例
-
消息接收/解码/路由
-
消息发送调度(bucket 系统)
-
流速率控制 (10 个数据流)
-
参数协议处理
-
签名管理
-
心跳生成
3. Protocol Version & Configuration
3.1 MAVLink 1.0 vs 2.0
// 协议版本自动协商
bool GCS_MAVLINK::sending_mavlink1() const;
// 数据包开销
static uint8_t packet_overhead_chan(mavlink_channel_t chan);
ArduPilot sends MAVLink 2.0 frames by default. If the remote end only supports MAVLink 1.0, it automatically downgrades. Buffer space is checked before sending via the HAVE_PAYLOAD_SPACE macro:
#define PAYLOAD_SIZE(chan, id) \
(unsigned(GCS_MAVLINK::packet_overhead_chan(chan) + MAVLINK_MSG_ID_
## id ## _LEN))
#define HAVE_PAYLOAD_SPACE(_chan, id) \
(comm_get_txspace(_chan) >= PAYLOAD_SIZE(_chan, id) ? true : \
(gcs_out_of_space_to_send(_chan), false))
3.2 Channel Configuration
// 根据硬件平台动态调整通道数
#if CONFIG_HAL_BOARD == HAL_BOARD_SITL
#define MAVLINK_COMM_NUM_BUFFERS 16 // SITL: 16通道
#elif HAL_PROGRAM_SIZE_LIMIT_KB > 1024
#define MAVLINK_COMM_NUM_BUFFERS 8 // 大内存平台: 8通道
#else
#define MAVLINK_COMM_NUM_BUFFERS 5 // 标准嵌入式: 5通道
#endif
3.3 Channel Options
enum class Option : uint16_t {
MAVLINK2_SIGNING_DISABLED = (1U << 0), // 禁用手动签名
NO_FORWARD = (1U << 1), // 禁止路由转发
NOSTREAMOVERRIDE = (1U << 2), // 忽略 GCS 速率覆盖
FORWARD_BAD_CRC = (1U << 3), // 转发 CRC 错误包
};
主要参数:
- SYSID_THISMAV — 本机系统 ID
- MAV_GCS_SYSID — 期望的 GCS 系统 ID
- MAV_OPTIONS — GCS_SYSID_ENFORCE 强制 GCS sysid 检查
4. Message Routing System
4.1 Routing Architecture
The routing system is implemented by the MAVLink_routing class (MAVLink_routing.h/.cpp), with this core structure:
#define MAVLINK_MAX_ROUTES 20
struct route {
uint8_t sysid; // 目标系统 ID
uint8_t compid; // 目标组件 ID
mavlink_channel_t channel; // 到达目标的通道
uint8_t mavtype; // MAV_TYPE (如 MAV_TYPE_GCS)
};
4.2 Routing Decision Flow
GCS::update_receive()
└── 遍历所有 GCS_MAVLINK 通道
└── GCS_MAVLINK::update_receive()
└── 从 UART 读取字节
└── mavlink_parse_char() 解码
└── 成功 → raw_packetReceived()
└── MAVLink_routing::check_and_forward()
├── 检查 framing_status (OK/BAD_CRC/BAD_SIGNATURE)
├── learn_route() — 学习发送者路由
├── handle_heartbeat() — 特殊心跳处理
└── forward() — 根据目标决定转发
└── packetReceived() (虚函数)
└── handle_message() — 消息分发
4.3 Forwarding Decision Rules
// ========== 转发决策规则 (check_and_forward / forward) ==========
// ---- 本地处理 (不转发) ----
if (!msg_has_target_system(msg)) // 1. 消息不含 target_system 字段
return HANDLE_LOCAL;
if (msg.target_system == 0) // 2. target_system == 0 (广播到所有)
return HANDLE_LOCAL;
if (msg.target_system == my_sysid
&& !msg_has_target_component(msg)) // 3. target_system == 本机 sysid 且无 target_component
return HANDLE_LOCAL;
if (msg.target_system == my_sysid
&& msg.target_component == my_compid) // 4. target_system/compid 都指向本机
return HANDLE_LOCAL;
if (msg.target_system == my_sysid
&& !route_seen(msg.sysid, msg.compid)) // 5. 对端 sysid/compid 组合未见过
return HANDLE_LOCAL;
// ---- 转发到其他链路 ----
if (!msg_has_target_system(msg)
|| msg.target_system == 0) {
broadcast_to_all_except_source(); // 无目标或广播 → 所有非源通道
} else if (msg.target_system != my_sysid
&& route_known(msg.target_system)) {
unicast_to_route(msg.target_system); // 目标非本机且路由已知 → 单播
} else if (msg.target_system == my_sysid
&& msg.target_component != my_compid) {
lookup_and_forward(msg.target_component); // 本机系统但不同组件 → 查路由表转发
}
4.4 Heartbeat Special Handling
Heartbeat messages bypass the regular routing logic:
- 通过所有非私有通道广播
- 排除已知源通道 (避免回环)
- 自动学习路由表
4.5 Routing Mask
// 屏蔽特定通道的路由转发
static void disable_channel_routing(mavlink_channel_t chan);
// no_route_mask 位掩码阻止该通道被转发
5. Message Scheduling & Send Mechanism
5.1 Bucket Scheduling System
ArduPilot uses the deferred message bucket system to schedule outgoing messages:
// 延迟消息桶 (10 个桶)
struct deferred_message_bucket_t {
Bitmask ap_message_ids; // 该桶中的消息 ID 集合
uint16_t interval_ms; // 发送间隔
uint16_t last_sent_ms; // 上次发送时间
};
deferred_message_bucket_t deferred_message_bucket[10];
Special messages (not subject to stream rate control):
struct deferred_message_t {
const ap_message id;
uint16_t interval_ms;
uint16_t last_sent_ms;
} deferred_message[3] = {
{ MSG_HEARTBEAT, },
{ MSG_NEXT_PARAM, },
{ MSG_HIGH_LATENCY2, }, // 仅当 HIGH_LATENCY2 启用
};
5.2 Message Send Timing
GCS::update_send()
└── 轮转 first_backend_to_send (防止饥渴)
└── 遍历所有活跃通道
└── GCS_MAVLINK::update_send()
├── 检查调度器剩余时间 > min_loop_time_remaining
├── 优先发送 pushed 消息 (HEARTBEAT 等)
├── 发送 deferred message (非流控消息)
└── 发送 bucket 中的流控消息
├── find_next_bucket_to_send()
├── 按速率依次发送
└── 缓冲区满 → stream_slowdown 降速
5.3 Stream Rate Control
10 个标准遥测数据流:
enum streams : uint8_t {
STREAM_RAW_SENSORS, // IMU、GPS 等原始传感器
STREAM_EXTENDED_STATUS, // 扩展状态
STREAM_RC_CHANNELS, // RC 通道值
STREAM_RAW_CONTROLLER, // 控制器原始输出
STREAM_POSITION, // 位置信息
STREAM_EXTRA1, // 额外数据 1
STREAM_EXTRA2, // 额外数据 2
STREAM_EXTRA3, // 额外数据 3
STREAM_PARAMS, // 参数流
STREAM_ADSB, // ADS-B 数据
NUM_STREAMS
};
每个流有对应的 SRx_* 参数控制速率(Hz)。
5.4 Messages per Stream
每个流包含一组内部消息 ID,定义在 all_stream_entries[] 中:
// ========== 各流包含的消息 ==========
STREAM_RAW_SENSORS // RAW_IMU, SCALED_IMU2/3, SCALED_PRESSURE2/3, BARO,
// AHRS2, SYS_STATUS, POWER_STATUS, MEMINFO, MCU_STATUS,
// ATTITUDE, ATTITUDE_QUATERNION, MAG_CAL_REPORT,
// BATTERY2, AIRSPEED
STREAM_EXTENDED_STATUS // SYS_STATUS, POWER_STATUS, MEMINFO, CURRENT_WAYPOINT,
// GPS_RAW, GPS_RTK, GPS2_RAW, GPS2_RTK,
// NAV_CONTROLLER_OUTPUT, FENCE_STATUS
STREAM_POSITION // GLOBAL_POSITION_INT, LOCAL_POSITION,
// HOME_POSITION, GPS_GLOBAL_ORIGIN
STREAM_RC_CHANNELS // RC_CHANNELS, RC_CHANNELS_RAW, SERVO_OUTPUT_RAW
STREAM_RAW_CONTROLLER // RC_CHANNELS
STREAM_EXTRA1 // ATTITUDE, SIMSTATE, AHRS2, PID_TUNING, RANGEFINDER
STREAM_EXTRA2 // VFR_HUD
STREAM_EXTRA3 // AHRS, SYSTEM_TIME, RANGEFINDER, WIND,
// DISTANCE_SENSOR, BATTERY2
STREAM_PARAMS // NEXT_PARAM
STREAM_ADSB // ADSB_VEHICLE, UAVIONIX_ADSB_OUT_STATUS
5.5 Stream Rate Parameters
参数格式:SR0_* 到 SRn_*,其中 n 对应通道号:
SR0_RAW_SENSORS → 原始传感器流频率 (Hz)
SR0_EXT_STAT → 扩展状态流频率
SR0_RC_CHAN → RC 通道流频率
SR0_RAW_CTRL → 原始控制流频率
SR0_POSITION → 位置流频率
SR0_EXTRA1 → 额外数据 1 频率
SR0_EXTRA2 → 额外数据 2 频率
SR0_EXTRA3 → 额外数据 3 频率
SR0_PARAMS → 参数流频率
SR0_ADSB → ADS-B 流频率
默认流速率在 GCS_MAVLink_Parameters.cpp 中定义:
// default_rates[]: {RAW_SENSORS, EXT_STAT, RC_CHAN, RAW_CTRL, POSITION, EXTRA1, EXTRA2, EXTRA3, PARAMS, ADSB}
const uint8_t default_rates[GCS_MAVLINK::NUM_STREAMS] = {
MAVLINK_STREAM_RAW_SENSORS_DEFAULT_RATE, // 2 Hz
MAVLINK_STREAM_EXTENDED_STATUS_DEFAULT_RATE, // 2 Hz
MAVLINK_STREAM_RC_CHANNELS_DEFAULT_RATE, // 5 Hz
MAVLINK_STREAM_RAW_CONTROLLER_DEFAULT_RATE, // 0 Hz (Copter/Rover) or 5 Hz (Plane)
MAVLINK_STREAM_POSITION_DEFAULT_RATE, // 2 Hz (Copter/Rover) or 3 Hz (Plane)
MAVLINK_STREAM_EXTRA1_DEFAULT_RATE, // 5 Hz (Copter) or 10 Hz (Plane/Rover)
MAVLINK_STREAM_EXTRA2_DEFAULT_RATE, // 5 Hz (Copter) or 10 Hz (Plane/Rover)
MAVLINK_STREAM_EXTRA3_DEFAULT_RATE, // 2 Hz (Copter) or 3 Hz (Plane/Rover)
MAVLINK_STREAM_PARAMS_DEFAULT_RATE, // 50 Hz (高优先级)
MAVLINK_STREAM_ADSB_DEFAULT_RATE, // 0 Hz
};
5.6 Dynamic Message Interval Control
支持通过 MAVLink 命令动态调整消息间隔:
// MAV_CMD_SET_MESSAGE_INTERVAL — 设置特定消息的发送间隔
MAV_RESULT set_message_interval(uint32_t msg_id, int32_t interval_us);
// MAV_CMD_REQUEST_MESSAGE — 请求单次消息
MAV_RESULT handle_command_request_message(const mavlink_command_int_t &packet);
5.7 Loading Interval Config from File
如果启用 HAL_MAVLINK_INTERVALS_FROM_FILES_ENABLED,可以从 SD 卡/ROMFS 加载消息间隔配置文件:
APM/MAVLink/message_interval.cfg — SD 卡配置
@ROMFS/message_interval.cfg — ROMFS 配置
文件格式:每行 mavlink_message_id interval_ms
6. Message Reception & Processing
6.1 handle_message() — Core Dispatch Function
消息在 GCS_Common.cpp 的 handle_message() 中通过 switch(msg.msgid) 分发到各处理函数:
void GCS_MAVLINK::handle_message(const mavlink_message_t &msg) {
switch (msg.msgid) {
case MAVLINK_MSG_ID_HEARTBEAT:
handle_heartbeat(msg);
break;
case MAVLINK_MSG_ID_RC_CHANNELS_OVERRIDE:
handle_rc_channels_override(msg);
break;
case MAVLINK_MSG_ID_PARAM_REQUEST_LIST:
handle_param_request_list(msg);
break;
case MAVLINK_MSG_ID_PARAM_SET:
handle_param_set(msg);
break;
case MAVLINK_MSG_ID_COMMAND_LONG:
handle_command_long(msg);
break;
case MAVLINK_MSG_ID_COMMAND_INT:
handle_command_int(msg);
break;
case MAVLINK_MSG_ID_MISSION_WRITE_PARTIAL_LIST:
handle_mission_write_partial_list(msg);
break;
// ... 80+ 消息类型
}
}
6.2 Message Category Overview
// ========== 消息分类总览 ==========
系统控制 // HEARTBEAT, SET_MODE, STATUSTEXT, PING, SYSTEM_TIME
参数 // PARAM_REQUEST_LIST, PARAM_REQUEST_READ, PARAM_SET, PARAM_VALUE
任务 // MISSION_REQUEST_LIST, MISSION_REQUEST_INT, MISSION_COUNT,
// MISSION_ITEM, MISSION_WRITE_PARTIAL_LIST, MISSION_CLEAR_ALL, MISSION_ACK
命令 // COMMAND_LONG, COMMAND_INT, COMMAND_ACK
RC 控制 // RC_CHANNELS_OVERRIDE, MANUAL_CONTROL, RADIO_RC_CHANNELS, RC_CHANNELS
遥测 // RADIO_STATUS, DISTANCE_SENSOR, OBSTACLE_DISTANCE
视觉 // VISION_POSITION_ESTIMATE, GLOBAL_VISION_POSITION_ESTIMATE,
// ATT_POS_MOCAP, ODOMETRY, LANDING_TARGET, VISION_SPEED_ESTIMATE,
// VICON_POSITION_ESTIMATE, VISION_POSITION_DELTA
传感器 // OPTICAL_FLOW, DISTANCE_SENSOR, OBSTACLE_DISTANCE, OBSTACLE_DISTANCE_3D
安全 // ADSB_VEHICLE, SETUP_SIGNING
设备 // SERIAL_CONTROL, DEVICE_OP_READ, DEVICE_OP_WRITE
相机/云台 // 通过 MOUNT 和 CAMERA 相关消息处理
其他 // TIMESYNC, NAMED_VALUE_FLOAT, OSD_PARAM_CONFIG,
// FILE_TRANSFER_PROTOCOL, DATA_PACKET
6.3 Command Handling (COMMAND_LONG / COMMAND_INT)
// COMMAND_LONG 自动转换为 COMMAND_INT 处理
void handle_command_long(const mavlink_message_t &msg);
void handle_command_int(const mavlink_message_t &msg);
// COMMAND_INT 各子命令处理
handle_command_int_packet() {
switch (packet.command) {
case MAV_CMD_COMPONENT_ARM_DISARM: // 解锁/上锁
case MAV_CMD_DO_SET_HOME: // 设置 Home 点
case MAV_CMD_NAV_TAKEOFF: // 起飞
case MAV_CMD_NAV_LAND: // 降落
case MAV_CMD_DO_SET_MODE: // 切换模式
case MAV_CMD_DO_FLIGHTTERMINATION: // 紧急停机
case MAV_CMD_PREFLIGHT_CALIBRATION: // 校准
case MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN:// 重启
case MAV_CMD_SET_MESSAGE_INTERVAL: // 设置消息间隔
case MAV_CMD_REQUEST_MESSAGE: // 请求消息
case MAV_CMD_DO_FENCE_ENABLE: // 围栏使能
case MAV_CMD_DO_SET_ROI: // 设置兴趣点
case MAV_CMD_DO_GRIPPER: // 夹爪
case MAV_CMD_DO_SPRAYER: // 喷洒
case MAV_CMD_DO_AUX_FUNCTION: // 辅助功能
case MAV_CMD_DO_FOLLOW: // Follow-me
case MAV_CMD_CAN_FORWARD: // CAN 转发
case MAV_CMD_RUN_PREARM_CHECKS: // 预解锁检查
case MAV_CMD_FLASH_BOOTLOADER: // 烧写 Bootloader
// ... 40+ 命令
}
}
7. Parameter Protocol
7.1 Overview
The parameter protocol is implemented in GCS_Param.cpp, operating flight controller parameters through the following MAVLink messages:
// ========== 参数协议消息 ==========
PARAM_REQUEST_LIST // 请求所有参数列表
PARAM_REQUEST_READ // 读取单个参数
PARAM_SET // 设置参数值
PARAM_VALUE // 参数值响应
7.2 Async Parameter I/O
Parameter read/write operates asynchronously via an I/O timer:
static bool param_timer_registered; // IO 定时器注册标志
void param_io_timer(void); // IO 定时器回调
// 请求和响应队列
static ObjectBuffer param_requests;
static ObjectBuffer param_replies;
7.3 Parameter Send Flow
GCS 请求 PARAM_REQUEST_LIST
└── handle_param_request_list(msg)
└── 遍历所有 AP_Param 条目
└── 加入 param_replies 队列
└── param_io_timer() 定时发送
└── send_parameter_value(name, type, value)
7.4 Parameter Set Safety Mechanism
// 全局控制:是否允许通过 MAVLink 设置参数
bool get_allow_param_set() const;
void set_allow_param_set(bool new_allowed);
// 参数错误响应
enum MAV_PARAM_ERROR {
MAV_PARAM_ERROR_NONE, // 成功
MAV_PARAM_ERROR_INVALID_TYPE, // 类型错误
// ...
};
8. Mission Protocol
8.1 Protocol Types
Three independent transfer protocols are handled through MissionItemProtocol:
// ========== 协议类型与对应类 ==========
航点 MAV_MISSION_TYPE_MISSION MissionItemProtocol_Waypoints
围栏 MAV_MISSION_TYPE_FENCE MissionItemProtocol_Fence
Rally点 MAV_MISSION_TYPE_RALLY MissionItemProtocol_Rally
8.2 Mission Message Handling
// 任务列表操作
handle_mission_request_list(msg); // MISSION_REQUEST_LIST
handle_mission_count(msg); // MISSION_COUNT
handle_mission_request_int(msg); // MISSION_REQUEST_INT
handle_mission_item(msg); // MISSION_ITEM_INT
handle_mission_write_partial_list(msg); // MISSION_WRITE_PARTIAL_LIST
handle_mission_clear_all(msg); // MISSION_CLEAR_ALL
8.3 Transfer Protocol Base Class
// MissionItemProtocol.h
class MissionItemProtocol {
// 核心方法
void handle_mission_request_list(...);
void handle_mission_count(...);
void handle_mission_request_int(...);
void handle_mission_item(...);
void queued_request_send(); // 发送队列中的任务请求
bool active() const; // 是否有活跃的传输
};
9. MAVLink FTP File Transfer
9.1 Overview
MAVLink FTP implements the FILE_TRANSFER_PROTOCOL message, enabling remote file system access over MAVLink.
Compile flag: AP_MAVLINK_FTP_ENABLED
Files: GCS_FTP.h / GCS_FTP.cpp
9.2 Architecture
class GCS_FTP {
// 单例模式
static GCS_FTP *ftp;
// 最多 5 个并发会话
Session sessions[AP_MAVLINK_FTP_MAX_SESSIONS]; // 默认 5
// 请求队列
ObjectBuffer requests{AP_MAVLINK_FTP_MAX_SESSIONS};
};
9.3 Supported Operations
enum class FTP_OP : uint8_t {
None, // 无操作
TerminateSession,// 终止会话
ResetSessions, // 重置所有会话
ListDirectory, // 列出目录
OpenFileRO, // 只读打开文件
ReadFile, // 读取文件
CreateFile, // 创建文件
WriteFile, // 写入文件
RemoveFile, // 删除文件
CreateDirectory, // 创建目录
RemoveDirectory, // 删除目录
OpenFileWO, // 只写打开文件
TruncateFile, // 截断文件
Rename, // 重命名
CalcFileCRC32, // 计算 CRC32
BurstReadFile, // 突发读取
Ack, // 确认
Nack, // 否认
};
9.4 Workflow
GCS 发送 FILE_TRANSFER_PROTOCOL
└── handle_file_transfer_protocol(msg, chan)
└── 加入请求队列
└── worker() 异步处理
├── 验证 session
├── 执行文件操作
└── 发送响应 (Ack/Nack + 数据)
9.5 Error Codes
enum class FTP_ERROR : uint8_t {
None, // 无错误
Fail, // 通用失败
FailErrno, // 系统错误 (含 errno)
InvalidDataSize, // 数据大小无效
InvalidSession, // 会话无效
NoSessionsAvailable, // 无可用会话
EndOfFile, // 文件结束
UnknownCommand, // 未知命令
FileExists, // 文件已存在
FileProtected, // 文件受保护
FileNotFound, // 文件未找到
};
10. Signing & Security
10.1 Overview
MAVLink 2.0 signing is implemented in GCS_Signing.cpp. Compile flag: AP_MAVLINK_SIGNING_ENABLED.
10.2 Signing Management
#if AP_MAVLINK_SIGNING_ENABLED
mavlink_signing_t signing; // 签名结构
static mavlink_signing_streams_t signing_streams; // 签名流
static uint32_t last_signing_save_ms; // 上次保存时间
// 存储访问
static StorageAccess _signing_storage;
static bool signing_key_save(const struct SigningKey &key);
static bool signing_key_load(struct SigningKey &key);
// 签名操作
void load_signing_key(void);
bool signing_enabled(void) const;
static void save_signing_timestamp(bool force_save_now);
static void update_signing_timestamp(uint64_t timestamp_usec);
#endif
10.3 SETUP_SIGNING Flow
GCS 发送 SETUP_SIGNING
└── handle_setup_signing(msg)
├── 读取初始时间戳
├── 加载/保存签名密钥
└── 启用签名
签名密钥持久化存储在飞控存储区中。
11. SERIAL_CONTROL Serial Passthrough
11.1 Function
GCS_serial_control.cpp implements SERIAL_CONTROL message handling, allowing GCS to remotely operate serial devices on the flight controller via MAVLink (e.g., configuring telemetry modules, RTK GPS, etc.).
11.2 Flags
// SERIAL_CONTROL_FLAG
SERIAL_CONTROL_FLAG_REPLY // 回复标志
SERIAL_CONTROL_FLAG_RESPOND // 要求响应
SERIAL_CONTROL_FLAG_EXCLUSIVE // 独占模式
SERIAL_CONTROL_FLAG_BLOCKING // 阻塞模式
SERIAL_CONTROL_FLAG_MULTI // 多设备
11.3 Exclusive Mode
当 SERIAL_CONTROL 设置独占模式时,对应的 MAVLink 通道会被锁定:
void lock(bool _lock) {
_locked = _lock;
}
A locked channel no longer processes MAVLink messages and is dedicated to passthrough.
12. High Latency Mode (HIGH_LATENCY2)
12.1 Overview
The HIGH_LATENCY2 message is designed for satellite/HF high-latency links (extremely low bandwidth, high latency), with a single message containing all critical flight data.
Compile flag: HAL_HIGH_LATENCY2_ENABLED
12.2 HIGH_LATENCY2 Message Fields
void send_high_latency2() const; // 发送高延迟消息
// 车辆需重写的辅助函数
virtual int16_t high_latency_target_altitude() const;
virtual uint8_t high_latency_tgt_heading() const;
virtual uint16_t high_latency_tgt_dist_dam() const;
virtual uint8_t high_latency_tgt_airspeed() const;
virtual uint8_t high_latency_wind_speed() const;
virtual uint8_t high_latency_wind_direction() const;
12.3 High Latency Control
// CONTROL_HIGH_LATENCY 命令处理
MAV_RESULT handle_control_high_latency(const mavlink_command_int_t &packet);
// 全局管理
void enable_high_latency_connections(bool enabled);
bool get_high_latency_status();
13. Compile-Time Configuration Options
All feature toggles are defined in GCS_config.h:
// ========== 编译时配置选项 ==========
HAL_GCS_ENABLED 1 全局 GCS 开关
HAL_MAVLINK_BINDINGS_ENABLED HAL_GCS_ENABLED MAVLink 绑定
AP_MAVLINK_SIGNING_ENABLED HAL_GCS_ENABLED 签名支持
HAL_HIGH_LATENCY2_ENABLED 1 高延迟模式
AP_MAVLINK_FTP_ENABLED HAL_GCS_ENABLED FTP 文件传输
AP_MAVLINK_MSG_SERIAL_CONTROL_ENABLED HAL_GCS_ENABLED 串口控制
AP_MAVLINK_MSG_DEVICE_OP_ENABLED HAL_GCS_ENABLED 设备 I2C/SPI 操作
AP_MAVLINK_SERVO_RELAY_ENABLED HAL_GCS_ENABLED && 舵机/继电器
AP_SERVORELAYEVENTS_ENABLED
AP_MAVLINK_COMMAND_LONG_ENABLED 1 COMMAND_LONG 支持
AP_MAVLINK_MSG_MISSION_REQUEST_ENABLED AP_MISSION_ENABLED MISSION_REQUEST (旧版)
AP_MAVLINK_MSG_RANGEFINDER_SENDING_ENABLED AP_RANGEFINDER_ENABLED RANGEFINDER 消息
AP_MAVLINK_MSG_HIGHRES_IMU_ENABLED >1024KB flash HIGHRES_IMU
AP_MAVLINK_MSG_FLIGHT_INFORMATION_ENABLED HAL_GCS_ENABLED && 飞行信息
AP_ARMING_ENABLED
AP_MAVLINK_MAV_CMD_GET_HOME_POSITION.. AP_AHRS_ENABLED GET_HOME_POSITION (即将移除)
AP_MAVLINK_AUTOPILOT_VERSION_REQUEST.. SITL only 旧版版本请求 (即将移除)
AP_MAVLINK_UTM_GLOBAL_POSITION_SENDING.. >2048KB flash UTM 位置
AP_MAVLINK_FAILURE_CREATION_ENABLED 1 开发者故障注入
AP_MAVLINK_SET_GPS_GLOBAL_ORIGIN.. HAL_GCS_ENABLED && GPS 原点设置消息 (即将移除)
AP_AHRS_ENABLED
HAL_MAVLINK_INTERVALS_FROM_FILES_ENABLED 文件系统 + >1024KB flash 从文件加载消息间隔
13.1 Deprecation Timeline
ArduPilot has a clear deprecation plan for legacy MAVLink features:
// ========== 废弃时间线 ==========
// 4.5 4.8 4.9 4.10
MISSION_REQUEST 默认开启 默认编译排除 代码移除 停止警告
AUTOPILOT_VERSION.. 可编译排除 默认编译排除 代码移除 ---
MAV_CMD_REQUEST_.. 可编译排除 默认编译排除 代码移除 ---
MAV_CMD_GET_HOME.. 默认开启 可编译排除 默认排除 代码移除
RANGEFINDER 正常 默认停止发送 代码移除 ---
SET_GPS_GLOBAL_ORIGIN 正常 开始警告 继续警告 默认排除
MISSION_SET_CURRENT 正常 --- --- ---
14. Internal Message ID Enumeration
Defined in ap_message.h for internal message scheduling. MSG_LAST marks the end of the enum (currently ~120 IDs).
14.1 Core Messages (Partial)
enum ap_message : uint8_t {
MSG_HEARTBEAT = 0,
MSG_AHRS = 1,
MSG_AHRS2 = 2,
MSG_ATTITUDE = 3,
MSG_ATTITUDE_QUATERNION = 4,
MSG_LOCATION = 5,
MSG_VFR_HUD = 6,
MSG_SYS_STATUS = 7,
MSG_POWER_STATUS = 8,
MSG_MEMINFO = 9,
MSG_NAV_CONTROLLER_OUTPUT = 10,
MSG_CURRENT_WAYPOINT = 11,
MSG_SERVO_OUTPUT_RAW = 12,
MSG_RC_CHANNELS = 13,
MSG_RC_CHANNELS_RAW = 14,
MSG_RAW_IMU = 15,
MSG_SCALED_IMU = 16,
MSG_SCALED_IMU2 = 17,
MSG_SCALED_IMU3 = 18,
MSG_SCALED_PRESSURE = 19,
MSG_SCALED_PRESSURE2 = 20,
MSG_SCALED_PRESSURE3 = 21,
MSG_GPS_RAW = 22,
MSG_GPS_RTK = 23,
MSG_GPS2_RAW = 24,
MSG_GPS2_RTK = 25,
MSG_SYSTEM_TIME = 26,
MSG_NEXT_MISSION_REQUEST_WAYPOINTS = 28,
MSG_NEXT_MISSION_REQUEST_RALLY = 29,
MSG_NEXT_MISSION_REQUEST_FENCE = 30,
MSG_NEXT_PARAM = 31,
MSG_FENCE_STATUS = 32,
MSG_SIMSTATE = 33,
MSG_SIM_STATE = 34,
MSG_WIND = 36,
// ... 相机/云台 ...
MSG_CAMERA_FEEDBACK = 42,
MSG_CAMERA_INFORMATION = 43,
MSG_CAMERA_SETTINGS = 44,
MSG_CAMERA_FOV_STATUS = 45,
MSG_CAMERA_CAPTURE_STATUS = 46,
MSG_CAMERA_THERMAL_RANGE = 47,
MSG_GIMBAL_DEVICE_ATTITUDE_STATUS = 48,
MSG_GIMBAL_MANAGER_INFORMATION = 49,
MSG_GIMBAL_MANAGER_STATUS = 50,
// ... 其他 ...
MSG_HIGH_LATENCY2 = 78,
MSG_MCU_STATUS = 90,
MSG_ATTITUDE_TARGET = 92,
MSG_HIGHRES_IMU = 96,
MSG_AIRSPEED = 97,
MSG_AVAILABLE_MODES = 98,
MSG_AVAILABLE_MODES_MONITOR = 99,
MSG_FLIGHT_INFORMATION = 100,
MSG_LAST // 枚举结束标记
};
14.2 Design Principles
- Each MSG_* corresponds to one MAVLink message, ensuring non-blocking sends
- For multiple messages of the same type, create new MSG_ IDs
- Compile flags control message inclusion (e.g., AP_MAVLINK_MSG_HIGHRES_IMU_ENABLED)
15. Heartbeat & System Status
15.1 Heartbeat Message
心跳是最高优先级的系统消息,不受流速率控制:
// 发送频率通过 deferred_message 固定
void send_heartbeat(void) const;
// 心跳包含的关键信息
// - type: MAV_TYPE (如 MAV_TYPE_QUADROTOR)
// - autopilot: MAV_AUTOPILOT_ARDUPILOTMEGA
// - base_mode: 是否解锁、自定义模式等
// - custom_mode: 车辆特定模式 (如 Copter::ALT_HOLD)
// - system_status: MAV_STATE (如 MAV_STATE_ACTIVE)
15.2 Heartbeat Reception
void handle_heartbeat(const mavlink_message_t &msg);
When a heartbeat is received:
15.3 System Status
// 由车辆子类实现
virtual MAV_STATE vehicle_system_status() const = 0;
// 状态枚举
enum MAV_STATE {
MAV_STATE_UNINIT, // 未初始化
MAV_STATE_BOOT, // 启动中
MAV_STATE_CALIBRATING, // 校准中
MAV_STATE_STANDBY, // 待命
MAV_STATE_ACTIVE, // 活跃
MAV_STATE_CRITICAL, // 危急
MAV_STATE_EMERGENCY, // 紧急
MAV_STATE_POWEROFF, // 断电
MAV_STATE_FLIGHT_TERMINATION, // 终止飞行
};
16. Camera & Gimbal Protocol
16.1 Camera Messages
ArduPilot sends the following camera-related MAVLink messages:
// ========== 相机消息 ==========
CAMERA_FEEDBACK // 相机拍照/录像反馈
CAMERA_INFORMATION // 相机设备信息
CAMERA_SETTINGS // 相机当前设置
CAMERA_FOV_STATUS // 视场角状态
CAMERA_CAPTURE_STATUS // 拍摄状态
CAMERA_THERMAL_RANGE // 热成像范围
16.2 Gimbal Messages
// ========== 云台消息 ==========
GIMBAL_DEVICE_ATTITUDE_STATUS // 云台姿态
GIMBAL_MANAGER_INFORMATION // 云台管理器信息
GIMBAL_MANAGER_STATUS // 云台管理器状态
16.3 Gimbal Control Commands
#if HAL_MOUNT_ENABLED
void handle_mount_message(const mavlink_message_t &msg);
virtual MAV_RESULT handle_command_mount(const mavlink_command_int_t &packet,
const mavlink_message_t &msg);
#endif
17. Command Processing System
17.1 Command Types
Two command message formats are supported:
- COMMAND_LONG — 传统命令格式(通过 try_command_long_as_command_int 转换为 COMMAND_INT)
- COMMAND_INT — 扩展命令格式(推荐使用)
17.2 Main Command List
// ========== 主要命令列表 ==========
MAV_CMD_COMPONENT_ARM_DISARM // handle_command_component_arm_disarm // 解锁/上锁
MAV_CMD_DO_SET_HOME // handle_command_do_set_home // 设置 Home
MAV_CMD_NAV_TAKEOFF // 车辆特定 // 起飞
MAV_CMD_NAV_LAND // 车辆特定 // 降落
MAV_CMD_DO_SET_MODE // handle_command_do_set_mode // 切换模式
MAV_CMD_DO_FLIGHTTERMINATION // handle_flight_termination // 紧急停机
MAV_CMD_PREFLIGHT_CALIBRATION // handle_command_preflight_calibration // 校准传感器
MAV_CMD_PREFLIGHT_REBOOT_SHUTDOWN // handle_preflight_reboot // 重启飞控
MAV_CMD_SET_MESSAGE_INTERVAL // handle_command_set_message_interval // 设置消息间隔
MAV_CMD_REQUEST_MESSAGE // handle_command_request_message // 请求指定消息
MAV_CMD_DO_FENCE_ENABLE // handle_command_do_fence_enable // 围栏使能
MAV_CMD_DO_SET_ROI // handle_command_do_set_roi // 设置兴趣点
MAV_CMD_DO_GRIPPER // handle_command_do_gripper // 夹爪控制
MAV_CMD_DO_SPRAYER // handle_command_do_sprayer // 喷洒器控制
MAV_CMD_DO_AUX_FUNCTION // handle_command_do_aux_function // 辅助功能
MAV_CMD_DO_FOLLOW // handle_command_do_follow // Follow-me
MAV_CMD_RUN_PREARM_CHECKS // handle_command_run_prearm_checks // 预解锁检查
MAV_CMD_FLASH_BOOTLOADER // handle_command_flash_bootloader // 烧写 Bootloader
MAV_CMD_CAN_FORWARD // handle_can_forward // CAN 总线转发
MAV_CMD_DO_SET_SAFETY_SWITCH_STATE // handle_do_set_safety_switch_state // 安全开关
MAV_CMD_BATTERY_RESET // handle_command_battery_reset // 电池计数重置
MAV_CMD_STORAGE_FORMAT // handle_command_storage_format // 格式化存储
MAV_CMD_DO_JUMP_TAG // handle_command_do_jump_tag // 任务跳转
MAV_CMD_DO_SET_MISSION_CURRENT // handle_command_do_set_mission_current // 设置当前任务项
MAV_CMD_DO_SET_GLOBAL_ORIGIN // handle_command_do_set_global_origin // 设置全局原点
MAV_CMD_AIRFRAME_CONFIGURATION // handle_command_airframe_configuration // 机身配置
MAV_CMD_CONTROL_HIGH_LATENCY // handle_control_high_latency // 高延迟控制
MAV_CMD_ACCELCAL_VEHICLE_POS // handle_command_accelcal_vehicle_pos // 加速度计校准位置
MAV_CMD_FIXED_MAG_CAL_YAW // handle_command_fixed_mag_cal_yaw // 固定磁罗盘校准
MAV_CMD_SET_EKF_SOURCE_SET // handle_command_set_ekf_source_set // 设置 EKF 源
MAV_CMD_DEBUG_TRAP // handle_command_debug_trap // 调试陷进
17.3 Command Execution Confirmation
// 长时间运行任务的进度反馈
class GCS_MAVLINK_InProgress {
enum class Type {
NONE,
AIRSPEED_CAL, // 空速校准
SD_FORMAT, // SD 卡格式化
};
bool conclude(MAV_RESULT result);
bool send_in_progress();
};
17.4 External Estimation Handling
// VIO/外部视觉位置估计
MAV_RESULT handle_command_int_external_position_estimate(const mavlink_command_int_t &packet);
MAV_RESULT handle_command_int_external_wind_estimate(const mavlink_command_int_t &packet);
18. Telemetry Streams
18.1 Stream to Message Mapping
Each streams enum value maps to a set of ap_message IDs via the stream_entries structure:
struct stream_entries {
const streams stream_id;
const ap_message *ap_message_ids;
const uint8_t num_ap_message_ids;
};
18.2 Time Synchronization (TIMESYNC)
void send_timesync(); // 发送时间同步请求
void handle_timesync(const mavlink_message_t &msg); // 处理时间同步
struct {
int64_t sent_ts1;
uint32_t last_sent_ms;
const uint16_t interval_ms = 10000; // 每 10 秒同步
} _timesync_request;
18.3 Jitter Correction
JitterCorrection lag_correction; // 延迟抖动修正
uint64_t timesync_receive_timestamp_ns() const;
uint64_t timesync_timestamp_ns() const;
18.4 Statustext Message Queue
// 线程安全的 statustext 队列
struct statustext_t {
mavlink_statustext_t msg;
uint16_t entry_created_ms;
mavlink_channel_mask_t bitmask;
};
// 容量: <=192KB 内存区 10 条,>192KB 内存区 30 条
static const uint8_t _status_capacity = 10; // 或 30
StatusTextQueue _statustext_queue{_status_capacity};
Text messages are sent using the GCS_SEND_TEXT() macro:
GCS_SEND_TEXT(MAV_SEVERITY_INFO, ”Altitude: %.1f m”, altitude);
GCS_SEND_TEXT(MAV_SEVERITY_WARNING, ”GPS glitch detected”);
GCS_SEND_TEXT(MAV_SEVERITY_CRITICAL, ”Battery low: %d%%”, percent);
18.5 Video Stream Information
MSG_VIDEO_STREAM_INFORMATION = 51,
// 编译开关: AP_MAVLINK_MSG_VIDEO_STREAM_INFORMATION_ENABLED
19. Vehicle-Specific Implementations
19.1 Copter (ArduCopter/)
// ArduCopter/GCS_Mavlink.cpp — 主要的 MAVLink 实现
// ArduCopter/GCS_Copter.h — GCS_Copter 类定义
class GCS_MAVLINK_Copter : public GCS_MAVLINK {
// 实现虚函数
void send_nav_controller_output() const override;
void send_pid_tuning() override;
uint8_t base_mode() const override;
MAV_STATE vehicle_system_status() const override;
uint8_t send_available_mode(uint8_t index) const override;
// 模式切换处理
void handle_guided_request(...);
void handle_change_alt_request(...);
// 手动控制
void handle_manual_control_axes(...) override;
};
19.2 Plane (ArduPlane/)
// ArduPlane/GCS_Mavlink.cpp — 主要的 MAVLink 实现
// ArduPlane/GCS_Plane.h — GCS_Plane 类定义
class GCS_MAVLINK_Plane : public GCS_MAVLINK {
// Plane 特有的遥测扩展
// 额外的状态消息发送
};
19.3 Rover (Rover/)
// Rover/GCS_Mavlink.cpp — 主要的 MAVLink 实现
// Rover/GCS_Rover.h — GCS_Rover 类定义
class GCS_MAVLINK_Rover : public GCS_MAVLINK {
// Rover 特有的 RANGEFINDER 逻辑
void send_rangefinder() const override;
};
19.4 AP_Periph (CAN Peripherals)
// Tools/AP_Periph/GCS_MAVLink.cpp — CAN 外设 MAVLink
class GCS_MAVLINK_Periph : public GCS_MAVLINK {
// 轻量级实现,通过 DroneCAN 通信
};
19.5 Message Differences by Vehicle
// ========== 各车辆发送消息差异 ==========
// Copter Plane Rover Sub Tracker Blimp
send_nav_ctrl 位置/速度 滚转/俯仰 转向/油门 深度控制 --- 位置/速度
send_pid_tuning 滚转/俯仰 滚转/俯仰 转向/速度 --- --- ---
send_rangefinder 下视测距 --- 所有测距 --- --- ---
send_attitude.. yes --- --- --- --- ---
send_winch.. yes --- yes --- --- ---
handle_manual.. yes yes yes yes --- ---
20. MAVLink Routing Table
20.1 Routing Table Structure
#define MAVLINK_MAX_ROUTES 20
class MAVLink_routing {
uint8_t num_routes;
struct route {
uint8_t sysid; // 系统 ID
uint8_t compid; // 组件 ID
mavlink_channel_t channel; // 到达该目标的通道
uint8_t mavtype; // MAV_TYPE (心跳中获取)
} routes[MAVLINK_MAX_ROUTES];
uint8_t no_route_mask; // 禁止路由的通道掩码
};
20.2 Route Learning
// 从接收到的消息中自动学习路由
void learn_route(GCS_MAVLINK &link, const mavlink_message_t &msg);
学习过程:
20.3 Route Lookup
// 按 MAV_TYPE 查找
static bool find_by_mavtype(uint8_t mav_type, uint8_t &sysid,
uint8_t &compid, mavlink_channel_t &channel);
// 按 MAV_TYPE + COMPID 查找
static bool find_by_mavtype_and_compid(uint8_t mav_type, uint8_t compid,
uint8_t &sysid, mavlink_channel_t &channel);
20.4 Send to Known Components
// 向所有已知组件发送消息(含路由信息)
static void send_to_components(uint32_t msgid, const char *pkt, uint8_t pkt_len);
20.5 Channel Types
// 活跃通道
static mavlink_channel_mask_t mavlink_active;
// 私有通道(不广播,不转发)
static mavlink_channel_mask_t mavlink_private;
// 正在发送的通道
static mavlink_channel_mask_t chan_is_streaming;
Appendix A: Key Data Flows
A.1 Inbound Message Flow
UART RX 中断
└── GCS_MAVLINK::update_receive(max_time_us=1000)
├── 循环读取字节
├── mavlink_parse_char() 状态机解码
│ ├── STX → LEN → SEQ → SYS → COMP → MSG → PAYLOAD → CKA → CKB → SIGNING
│ └── 成功 → raw_packetReceived(framing_status, status, msg)
├── raw_packetReceived()
│ ├── 检查 accept_packet() (GCS sysid 强制?)
│ ├── MAVLink_routing::check_and_forward()
│ │ ├── 帧状态检查 (OK/BAD_CRC/BAD_SIGNATURE)
│ │ ├── learn_route() 学习
│ │ ├── handle_heartbeat() 特殊处理
│ │ └── forward() 转发决策
│ └── packetReceived() 虚函数 → handle_message() 分发
└── handle_message()
├── HEARTBEAT → handle_heartbeat()
├── PARAM_* → handle_common_param_message()
├── MISSION_* → handle_common_mission_message()
├── COMMAND_LONG → handle_command_long()
├── COMMAND_INT → handle_command_int()
├── RC_CHANNELS_OVERRIDE → handle_rc_channels_override()
├── MANUAL_CONTROL → handle_manual_control()
└── ... (80+ 消息类型)
A.2 Outbound Message Flow
GCS::update_send()
└── 耗时控制: 循环直到 main loop 剩余时间 < min_loop_time_remaining
└── 遍历通道 (轮转 first_backend_to_send)
└── GCS_MAVLINK::update_send()
├── 1. 检查流速率 (+ stream_slowdown)
├── 2. 发送 deferred_message (HEARTBEAT, NEXT_PARAM, HIGH_LATENCY2)
├── 3. 发送 pushed_ap_message_ids
├── 4. 发送 bucket 中的流控消息
│ ├── find_next_bucket_to_send()
│ ├── 遍历 bucket 中消息
│ └── try_send_message(id)
└── 5. 队列发送 (参数、任务)
├── queued_param_send()
└── queued_mission_request_send()
A.3 COMMAND_INT Execution Flow
handle_command_int(msg)
└── handle_command_int_packet(packet, msg)
└── switch(packet.command)
├── MAV_CMD_COMPONENT_ARM_DISARM
│ └── handle_command_component_arm_disarm()
│ ├── 检查 magic force 值 (2989 / 21196)
│ ├── 检查 pre-arm checks
│ └── arm/disarm motors
├── MAV_CMD_DO_SET_MODE
│ └── handle_command_do_set_mode()
│ └── set_mode(base_mode, custom_mode)
├── MAV_CMD_SET_MESSAGE_INTERVAL
│ └── handle_command_set_message_interval()
│ └── set_ap_message_interval(id, interval_ms)
├── MAV_CMD_REQUEST_MESSAGE
│ └── handle_command_request_message()
│ └── pushed_ap_message_ids.set(id)
└── ...
└── 发送 COMMAND_ACK 确认
Appendix B: Common Macros & Utilities
B.1 Send Space Check Macros
// 基础检查
#define PAYLOAD_SIZE(chan, id) \
(unsigned(GCS_MAVLINK::packet_overhead_chan(chan) + MAVLINK_MSG_ID_
## id ## _LEN))
// 条件检查(有副作用,失败时递增计数器)
#define HAVE_PAYLOAD_SPACE(_chan, id) \
(comm_get_txspace(_chan) >= PAYLOAD_SIZE(_chan, id) ? true : \
(gcs_out_of_space_to_send(_chan), false))
// 在 GCS_MAVLINK 方法中使用
#define CHECK_PAYLOAD_SIZE(id) \
if (!check_payload_size(MAVLINK_MSG_ID_
## id ## _LEN)) return false
// 在任意上下文中使用(需要 chan 变量)
#define CHECK_PAYLOAD_SIZE2(id) \
if (!HAVE_PAYLOAD_SPACE(chan, id)) return false
// void 函数中使用
#define CHECK_PAYLOAD_SIZE2_VOID(chan, id) \
if (!HAVE_PAYLOAD_SPACE(chan, id)) return
B.2 Text Send Macros
// 标准文本发送
#define GCS_SEND_TEXT(severity, format, args...) \
gcs().send_text(severity, format, ##args)
// 消息发送
#define GCS_SEND_MESSAGE(msg) gcs().send_message(msg)
B.3 Channel Method Definition Macros
// 避免每个子类重复编写 chan() 方法
#define GCS_MAVLINK_CHAN_METHOD_DEFINITIONS(subclass_name) \
subclass_name *chan(const uint8_t ofs) override { ... } \
const subclass_name *chan(const uint8_t ofs) const override { ... }
Appendix C: Performance & Optimization
C.1 Scheduler Priority
MAVLink send priority is lower than the flight control loop:
// 飞行控制循环最少保留 200us
virtual uint16_t min_loop_time_remaining_for_message_send_us() const {
return 200;
}
C.2 Buffer Management
// txspace 上限 8192 字节,防止单循环发送过多
uint16_t txspace() const {
if (_locked) return 0;
return MIN(_port->txspace(), 8192U);
}
C.3 Flow Control Slowdown
// 当链路拥塞时,自动增加 slowdown 延迟
uint16_t stream_slowdown_ms;
uint16_t get_stream_slowdown_ms() const { return stream_slowdown_ms; }
C.4 Message Interval Cap
// 消息间隔不能超过 0.8 * SCHED_LOOP_RATE
uint16_t cap_message_interval(uint16_t interval_ms) const;
C.5 High vs Low Bandwidth Channels
// COMM_0 通常为 USB/高速数传
bool is_high_bandwidth() { return chan == MAVLINK_COMM_0; }
// 检查硬件流控
bool have_flow_control();
C.6 Debug Statistics
#if GCS_DEBUG_SEND_MESSAGE_TIMINGS
struct {
uint32_t longest_time_us;
ap_message longest_id;
uint32_t no_space_for_message;
uint16_t statustext_last_sent_ms;
uint32_t behind;
uint32_t out_of_time;
uint16_t fnbts_maxtime;
uint32_t max_retry_deferred_body_us;
} try_send_message_stats;
#endif
Need help implementing MAVLink-based communication for your UAV? Aomway specializes in ArduPilot integration, custom MAVLink extensions, and drone telemetry optimization. Contact us at [email protected] for expert support.
Appendix D: Related Tools & Scripts
D.1 MAVLink Code Generation
# 从 XML 定义生成 C 头文件
modules/mavlink/pymavlink/tools/mavgen.py
# ArduPilot 使用的消息定义
modules/mavlink/message_definitions/v1.0/ardupilotmega.xml
modules/mavlink/message_definitions/v1.0/common.xml
D.2 Autotest MAVLink Testing
# Tools/autotest/common.py — mavlink 连接管理和消息解析
# Tools/autotest/pymavlink/ — Python MAVLink 库
D.3 Routing Test Example
libraries/GCS_MAVLink/examples/routing/