概述
在无人机执行完航线任务后,如何实现一键精准降落到指定位置(如移动车辆或特定标记点),一直是自主作业中的难点。最初我们尝试直接使用 DJI SDK 提供的 FlyTo 功能,但在实测中发现部分机型(如 M3E)并不支持该接口。
为此,我们设计了一套完整的自主降落方案:通过虚拟摇杆模拟导航飞向目标区域,再利用视觉识别系统计算实时偏移量,结合高度自适应策略控制下降速度与精度,最终实现安全、精确的定点着陆。
核心亮点:
- 虚拟摇杆导航替代受限的 FlyTo 功能
- 双轴 (X/Y) 位置偏移实时闭环调整
- 高度分段自适应降落策略
- 视觉识别引导精确定位
- 智能避障管理与停桨逻辑
系统架构与流程
整个降落过程分为四个主要阶段:远距离导航、接近判断、视觉引导降落、以及着陆清理。逻辑上采用状态机管理,确保各阶段平滑切换。
- 导航阶段:当用户触发返航指令时,获取当前 GPS 坐标,计算与目标点的距离。若距离大于阈值,启动虚拟摇杆导航,以 5m/s 速度飞向目标上方。
- 接近判断:持续监测剩余距离,当小于 10 米时,判定为到达目标区域,停止水平导航,进入降落模式。
- 降落阶段:根据当前高度动态调整下降速度和水平修正力度。高空允许较大误差快速下降,低空则严格限制偏移并减速。若偏移过大,暂停下降仅做水平对齐。
- 着陆清理:高度低于 5 米时关闭下视避障防止误判,触地后自动停桨并释放资源。
技术实现细节
1. 导航与接近:虚拟摇杆方案
由于 FlyTo 功能不可用,我们采用虚拟摇杆(Virtual Stick)模拟飞行控制。核心思路是计算当前位置到目标位置的方位角,将其分解为南北和东西方向的速度分量,持续发送控制指令。
方位角计算 利用三角函数计算两点间的方位角,归一化至 0-360 度范围。
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 // 归一化到 0-360 度
return bearing // 0°=正北,90°=正东,180°=正南,270°=正西
}

