基于大疆 MSDK 的无人机视觉引导自适应降落实现
背景与需求
在无人机执行完航线任务后,往往需要自动降落到指定位置(如汽车或特定载具)。最初的想法是直接调用 DJI SDK 的 FlyTo 功能,但在实际测试中发现,部分机型(如 M3E)并不支持该接口。此外,单纯依赖 GPS 定位存在精度不足(±3 米)和受风力影响漂移的问题。
因此,我们设计了一套完整的自主降落方案:
- 虚拟摇杆导航:替代不可用的 FlyTo 功能,将无人机飞至目标点附近。
- 视觉识别引导:利用摄像头识别地面标记,计算 X/Y 轴偏移量进行微调。
- 高度自适应策略:根据当前高度动态调整下降速度和容错阈值,确保安全与精确。
- 避障管理:处理下视避障对低空降落的干扰。
系统架构流程
整个降落过程分为四个主要阶段:
- 远程导航:从当前位置飞向目标点上方(约 5m/s),距离小于 10 米时停止。
- 接近判断:持续监测 GPS 距离,触发视觉引导模式。
- 精确定位:结合视觉偏移量与高度信息,动态计算水平调整量和垂直下降速度。
- 着陆完成:高度低于 0.1 米时关闭动力,清理资源。
在高度控制上,我们采用了分段逻辑:
- 高空 (>50m):允许较大偏移,快速下降。
- 中空 (20-50m):降低下降速度,收紧偏移阈值。
- 低空 (5-20m):进一步减速,严格对齐。
- 极低空 (<5m):关闭下视避障,极慢速下降直至触地。
技术实现细节
1. 虚拟摇杆导航替代 FlyTo
由于 FlyTo 不可用,我们通过计算方位角(Bearing),将其分解为南北(Pitch)和东西(Roll)方向的速度分量,持续发送虚拟摇杆指令。
private fun calculateBearing(latA: Double, lonA: Double, latB: Double, lonB: Double): Double {
val lat1 = Math.toRadians(latA)
val lat2 = Math.toRadians(latB)
val dLon = Math.toRadians(lonB - lonA)
val y = Math.sin(dLon) * Math.cos(lat2)
val x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon)
var bearing = Math.toDegrees(Math.atan2(y, x))
bearing = (bearing + 360) % 360
bearing
}

