4. 开发环境搭建
MAVSDK 是一组面向 MAVLink 协议的现代开发库,它把底层消息打包、心跳维持、超时重传、任务协议等细节封装成简洁的异步 API,让开发者可以用 Python、C++、C#、Java 等语言直接控制 PX4 或 ArduPilot 飞控。本节的目标是搭建一条“开发机 → MAVSDK → 飞控(仿真或真机)”的完整链路,并跑通第一个可观测的示例程序。理解这条链路的层次关系,比记住零散命令更重要。
一、核心原理:MAVSDK 在链路中的位置
飞控与地面端之间使用 MAVLink 协议通信,它是一套二进制消息格式,包含心跳、姿态、位置、任务、参数等数百种消息。直接手写 MAVLink 需要处理序列号、校验、超时和状态机,成本很高。MAVSDK 位于应用层与 MAVLink 之间,向上提供 System、Action、Telemetry、Mission 等对象,向下负责连接管理、心跳检测和消息收发。
因此,一个 MAVSDK 程序的最小闭环是:创建 System 并连接到指定地址,等待飞控心跳,调用 Action 解锁与起飞,通过 Telemetry 订阅姿态和位置,最后降落并释放连接。仿真环境(SITL)本质上是一个运行在开发机上的“虚拟飞控”,它同样输出 MAVLink 消息,因此 MAVSDK 代码在仿真与真机之间几乎不需要修改,只需更换连接地址。
二、方法流程:四步搭建可运行环境
- 安装 MAVSDK:推荐使用 Python 版本,便于快速验证。使用虚拟环境隔离依赖,避免污染系统 Python。
- 配置仿真环境:安装 PX4 或 ArduPilot 的 SITL,并配合 Gazebo 或 jMAVSim 提供物理仿真。
- 连接飞控:仿真时连接
udp://:14540;真机时使用串口或网络地址,并确认波特率与端口。 - 运行第一个示例:从官方示例
takeoff_and_land.py入手,观察日志中的连接、解锁、起飞、降落全过程。
# 1. 创建虚拟环境并安装 MAVSDK
python3 -m venv mavsdk-env
source mavsdk-env/bin/activate
pip install mavsdk
# 2. 启动 PX4 SITL(在 PX4-Autopilot 目录下)
make px4_sitl gazebo
# 3. 另开终端,运行第一个示例
python takeoff_and_land.py
三、连接 PX4 与 ArduPilot 的差异
PX4 与 ArduPilot 都支持 MAVLink,但默认端口和部分行为不同。PX4 SITL 默认在 14540 端口提供 MAVSDK 连接,14580 用于地面站;ArduPilot SITL 常用 14550 作为地面站端口,MAVSDK 连接时通常指定 udp://:14550 或使用 --out 参数转发。真机场景下,PX4 常用 TELEM1 对应 /dev/ttyS0,ArduPilot 常用 /dev/ttyACM0 或 /dev/ttyUSB0,波特率常见为 57600 或 921600。
| 对比项 | PX4 | ArduPilot |
|---|---|---|
| 仿真启动命令 | make px4_sitl gazebo |
sim_vehicle.py -v ArduCopter |
| MAVSDK 默认连接 | udp://:14540 |
udp://:14550 |
| 真机串口示例 | /dev/ttyS0 |
/dev/ttyACM0 |
| 常用波特率 | 57600 / 921600 | 57600 / 115200 |
| 解锁方式 | 支持 arm() 直接解锁 |
部分机型需先设置模式 |
四、案例:第一个示例程序的执行过程
下面是一个典型的起飞降落示例,它覆盖了 MAVSDK 最常用的几个对象。运行后,终端会依次输出连接成功、解锁成功、起飞高度、降落完成等日志。
import asyncio
from mavsdk import System
async def run():
drone = System()
await drone.connect(system_address="udp://:14540")
print("等待飞控连接...")
async for state in drone.core.connection_state():
if state.is_connected:
print("飞控已连接")
break
print("解锁中...")
await drone.action.arm()
print("起飞到 5 米...")
await drone.action.takeoff()
await asyncio.sleep(8)
print("降落中...")
await drone.action.land()
asyncio.run(run())
如果一切正常,日志中会出现 飞控已连接、解锁中...、起飞到 5 米...、降落中...。若卡在“等待飞控连接”,说明 MAVSDK 没有收到心跳,应检查仿真是否启动、端口是否匹配、防火墙是否拦截 UDP。
五、常见误区与复盘
- 误区一:仿真没启动就运行程序。 MAVSDK 会一直等待心跳,表现为程序无输出或超时。应先确认 SITL 已进入
Ready for takeoff状态。 - 误区二:端口写错。 PX4 与 ArduPilot 默认端口不同,混用会导致连接失败。建议在代码中把地址提取为变量,便于切换。
- 误区三:忽略解锁条件。 真机上电池电压低、GPS 未定位、遥控器未校准都会导致解锁失败,日志中通常有明确原因。
- 误区四:在异步函数中使用阻塞调用。 MAVSDK Python 是异步 API,应使用
await和asyncio.sleep,避免使用time.sleep阻塞事件循环。
完成本节后,你应当能够独立完成“安装 MAVSDK → 启动 SITL → 连接飞控 → 运行起飞降落示例”的完整流程,并能根据日志判断问题出在连接层、解锁层还是控制层。这套环境是后续任务规划、航点飞行和编队控制的基础,建议把连接地址、端口和启动命令整理成自己的速查清单。