为什么救援会失败?
GPS Rescue 看起来很简单:触发后自动飞回家、下降、着陆。但它的内部是一个多阶段状态机,每个阶段都有严格的进入条件和失败判定。任何一个环节出问题,都可能让救援终止,甚至让飞机坠落。
把救援想象成一个"一旦报警就不可撤销"的系统。任何故障警报一响,即使原因马上消失,警报也不会自动解除,随时可能导致坠机。
救援失败大致可以归为六类原因:
启动救援就失败:没有 Home 点、距离太近、在地面上。
爬升失败:动力不足、气压计异常、强风。
转向失败:磁力计/IMU 朝向错误、GPS 方向错误。
返航失败:飞错方向、GPS 丢失、低卫星、强风、电池不足。
下降/着陆失败:下降受阻、着陆超时、撞击检测误判。
系统级失败:Sanity 模式过严、崩溃保护误触发、配置参数不当、传感器故障。

正文
第一章:先认识 GPS Rescue 的"大脑"——状态机
1.1 救援的完整阶段
IDLE(空闲)
INITIALIZE(初始化)
ATTAIN_ALT(爬升到返航高度)
ROTATE(原地转向家)
FLY_HOME(飞回家)
DESCENT(下降)
LANDING(着陆)
COMPLETE(完成)
但是隐藏了两个异常出口:
DO_NOTHING:半可控下降,20 秒后放弃。
ABORT:立即 disarm,动力输出切断。
1.2 两个关键"判决变量"
Phase:当前处于哪个阶段,状态机推进时被改
Failure:是否发生故障,各种检查触发时被改
规则:只要 failure 不是 HEALTHY,phase 就会被强制改成 DO_NOTHING 或 ABORT。
failure 一旦被置位,只有回到 IDLE 阶段才会清零。
说人话:
把救援想象成一个"一旦报警就不可撤销"的系统。任何故障警报一响,即使原因马上消失,警报也不会自动解除。所以,非必要不使用吧
第二章:启动阶段(INITIALIZE)的失败
2.1 没有 Home 点(NO_HOME_POINT)

原因:
解锁时 GPS 还没定位(卫星数不够、无 3D fix)。
gps_set_home_point_once 配置问题。
Home 点被意外清除。
后果:取决于 Sanity 模式,可能直接 disarm,或进入 20 秒半可控下降。
2.2 起飞点太近且在地面原因:
在距 Home 5 米内、高度低于目标着陆高度时触发救援。
常见于误触救援开关、在地面测试。
后果:立即 ABORT ,动力切断。
2.3 初始距离小于 minStartDistM
if (distanceToHomeM < gpsRescueConfig()->minStartDistM) {
pitchAdjustment = 1500.0f; // 15 度前倾
}
原因:
触发救援时离 Home 太近。
GPS 位置漂移,导致 distanceToHomeM 一直小于 minStartDistM。
后果:
飞机会持续前倾飞离,试图拉开距离。
若 GPS 不更新,会卡在 ATTAIN_ALT 阶段,一直飞离。
若 Home 点错误,可能朝错误方向飞远。
总结:
解锁前一定要等 GPS 定位稳定、返航点确认。在起飞点附近误触救援,可能直接被 disarm。
近距离触发救援,飞机会先"故意飞远"再返航,这是设计行为,不是故障。
第三章:爬升阶段(ATTAIN_ALT)的失败
3.1 爬升受阻(ratio 检查)
const float ratio = actualAltitudeChange / targetAltitudeChange;
rescueState.intent.secondsFailing += ratio > 0.5f ? -1 : 1;
if (secondsFailing >= 10) {
rescueState.phase = RESCUE_LANDING;
}
判定逻辑:实际爬升量 / 目标爬升量 ≤ 0.5,持续 10 秒 → 强制进入 LANDING。
常见原因:
动力不足:电池电量低、电机/桨叶故障、电调过热。
气压计异常:getAltitude() 读数有问题。
强风下压:逆风爬升效率低。
油门受限:throttleMax 配置过低、throttleHover 不准。
目标高度过高:MAX 模式下取历史最大高度 + 初始爬升,低电量时无法到达。
后果:10 秒后进入 LANDING,配合撞击检测尝试降落。若此时远离返回点,会摔在异地。
3.2 目标高度设置不当
case GPS_RESCUE_ALT_MODE_MAX:
rescueState.intent.returnAltitudeCm = maxAltitudeCm + initialClimbCm;
MAX 模式:返航高度 = 历史最大高度 + initialClimbM。
如果之前飞得极高(如 500m),返航目标也极高,低电量时无法到达。
FIXED 模式:固定高度,若设置过高也有同样问题。
总结:
爬升阶段最怕"上不去"。电池不足、强风都会让飞机爬不到返航高度。
10 秒爬不上去,系统就认为"没救了",转入着陆模式。所以返航高度不要设太高,电池要留余量。
第四章:旋转对准阶段(ROTATE)的失败
4.1 偏航角误差始终无法小于 30 度
if (rescueState.sensor.absErrorAngle < GPS_RESCUE_ALLOWED_YAW_RANGE)
rescueState.phase = RESCUE_FLY_HOME;
判定:机头朝向与"家"的方向误差必须小于 30 度,才进入 FLY_HOME。
原因:
磁力计未校准/受干扰(useMag 开启时):电调线、电源线、磁干扰。
IMU yaw 漂移(无 mag 时):依赖 GPS 地速修正,低速下修正不准。
GPS 方向计算错误:Home 点错误、GPS 定位跳动。
强风:机头朝向与实际航向严重不一致。
yawAttenuator 反复被削弱:状态在 ROTATE 与其它阶段间抖动。
后果:永远停在 ROTATE,油门维持悬停,最终电量耗尽坠落。
4.2 yaw 权限累积问题
if (rescueState.intent.yawAttenuator < 1.0f) {
rescueState.intent.yawAttenuator += rescueState.sensor.gpsRescueTaskIntervalSeconds;
}
每次进入 ROTATE 从 0 开始,1 秒内到 1.0。
若在 ROTATE 与其它阶段反复切换,yaw 权限反复被削弱,对准变慢。
章节总结:
旋转阶段最怕"转不过去"。磁力计不干净、IMU 漂移、强风都会让飞机找不到家的方向。
如果你用磁力计,一定要校准并验证;如果不用,返航速度不要太低,否则 IMU 修正不准。
第五章:返航阶段(FLY_HOME)的失败
5.1 Flyaway 检测触发(30 秒不接近 Home)
if (rescueState.phase == RESCUE_FLY_HOME) {
const float velocityToHomeCmS = previousDistanceToHomeCm - rescueState.sensor.distanceToHomeCm;
rescueState.intent.secondsFailing += (velocityToHomeCmS < 0.1f * targetVelocityCmS) ? 1 : -1;
if (secondsFailing >= 30) {
// 若开了 mag 且未强制禁用 → 禁用 mag 重试一次
else rescueState.failure = RESCUE_FLYAWAY;
}
}
原因:
IMU 严重偏航:yaw 估计完全错误,飞机朝错误方向飞。
强风 > 返航速度:velocityToHomeCmS 为负。
磁力计被干扰:导致 yaw 错误。
GPS 地速方向与机头方向不一致:roll mix 不足以纠正。
GPS 数据中断:velocityToHomeCmS = 0,持续累计。
处理策略:
系统会先禁用磁力计重新尝试返航(仅一次)。
仍失败 →调用 FLYAWAY()→ 根据 Sanity 进入 DO_NOTHING(降落) 或 ABORT(终止)。
5.2 GPS 完全丢失(GPSLOST)
if (!rescueState.sensor.healthy) {
rescueState.failure = RESCUE_GPSLOST;
}
判定:gpsIsHealthy() 返回 false,通常是几百毫秒无数据包。
关键:failure 一旦置位,只有回到 IDLE 才清零。
后果(取决于 Sanity 模式):同时osd页面会闪烁RESCUE N/A
Sanity 模式GPS 丢失后行为:
SANITY_ON 立即 ABORT → disarm
SANITY_FS_ONLY 非硬失控 → DO_NOTHING;硬失控 → ABORT
OFF 一般 DO_NOTHING,20 秒后 ABORT
注意:GPS 恢复后不会回到原阶段,因为 failure 没有清零分支(警报不会消失)。
5.3 短暂性丢星数(LOWSATS)
secondsLowSats += (!STATE(GPS_FIX) || (gpsSol.numSat < GPS_MIN_SAT_COUNT)) ? 1 : -1;
if (secondsLowSats == 10) rescueState.failure = RESCUE_LOWSATS;
判定:连续 10 秒无定位或卫星数不足。
与 GPSLOST 的区别:
GPSLOST:完全无数据,立即触发。
LOWSATS:有数据但无效,10 秒后触发。
乐观情况:4~5 秒的无效数据不会触发 LOWSATS,状态机继续运行。
5.4 返航速度设置过高
groundSpeedCmS 设得大(如 1000cm/s = 10m/s),阻力大、耗电快。
逆风时 velocityToHomeCmS 上不去,触发 flyaway 判定。
5.5 速度 PID 的 I 项累积问题
rescueState.intent.velocityItermAttenuator = 4.0f / (groundspeedErrorRatio + 4.0f);
IMU 错误(groundspeedErrorRatio 大)时 I 项被大幅削弱,稳态误差无法消除,返航速度偏低 → 触发 flyaway。
反之,I 项累积过多又遇 IMU 突然纠正,会过冲,可能飞过 Home。
章节总结:
返航阶段最怕"飞错方向"和"GPS 丢失"。
飞错方向:多半是磁力计/IMU 问题,30 秒不接近家就判定 flyaway。
GPS 丢失:完全无数据立即报警,有数据但无效宽容 10 秒。
强风、电池不足也会让返航速度上不去,触发 flyaway。Flyaway标记后同样进入 performSanityChecks() 的故障处理流程,后果和 RESCUE_GPSLOST 一样,取决于 sanityChecks 配置
第六章:下降阶段(DESCENT)的失败
6.1 下降受阻(ratio 检查)
case RESCUE_DESCENT:
rescueState.intent.secondsFailing += ratio > 0.5f ? -1 : 1;
if (secondsFailing >= 10) {
rescueState.phase = RESCUE_LANDING;
secondsFailing = 0;
}
判定:实际下降量 / 目标下降量 ≤ 0.5,持续 10 秒 → 强制进入 LANDING。
原因:
气压计漂移。
油门过高(悬停油门不准)。
下洗气流、上升气流。
下降率设置过大但实际跟不上。
6.2 下降率与高度不匹配
altitudeStep *= descentRateAttenuator; // returnAltitude 低时减慢
altitudeStep *= 1.0f + 2.0f * descentRateMultiplier; // 高空加快
returnAltitudeCm 很低(<5m):下降率被压到 1/4,可能下降极慢,超时。
targetAltitudeCm 很高:下降率 3x,可能下降过快导致坠地冲击。
6.3 偏航角超范围时速度目标归零
if (absErrorAngle > GPS_RESCUE_ALLOWED_YAW_RANGE)
targetVelocityCmS = 0;
下降过程中若 yaw 误差大(IMU 漂移、风),水平速度被清零,飞机原地下降,可能落在远离 Home 的位置。
给飞手的话
下降阶段最怕"下不去"或"下太快"。
下不去:10 秒后强制着陆。
下太快:可能硬着陆。
下降时如果方向不对,飞机会原地下降,可能随着风力落在离家很远的地方。
第七章:着陆阶段(LANDING)的失败
7.1 着陆超时(10 秒)
case RESCUE_LANDING:
secondsFailing += ratio > 0.5f ? -1 : 1;
if (secondsFailing >= 10) rescueState.phase = RESCUE_ABORT;
判定:10 秒内高度没有明显下降 → ABORT → disarm。
原因:
油门卡在悬停以上。
气压计读数不降。
强上升气流。
后果:若此时还在空中,直接坠落。
7.2 撞击检测阈值不当
if (accMagnitude > disarmThreshold) disarmOnImpact();
accMagnitude 计算假设飞机水平(Z 轴减 1G)。若着陆时姿态倾斜,计算不准。
阈值问题:
太高 → 落地后不 disarm,电机继续转,可能翻倒。
太低 → 飞行中震动/机动误触发 disarm,空中停车。
7.3 着陆点不水平/有障碍
代码无法感知地面情况。若 Home 点上方有树、斜坡、水面,着陆会失败或损坏。
章节总结:
着陆阶段最怕"落不下来"和"误判撞击"。
落不下来:10 秒后 disarm,可能空中掉下来;误判撞击:空中震动可能导致 disarm。
所以 降落速度要调好,Home 点要选平坦开阔的地方。
第八章:系统级失败
8.1 Sanity 模式设置不当
case RESCUE_SANITY_ON: phase = RESCUE_ABORT; // 任何 failure 立即 abort
case RESCUE_SANITY_FS_ONLY: if (hardFailsafe) abort;
default: phase = RESCUE_DO_NOTHING;
SANITY_ON:任何小 failure(如瞬时 LOWSATS)都会导致 disarm,可能在远离 Home 处坠落。
DO_NOTHING:rescueThrottle = throttleHover - 100,若悬停油门不准,可能上升或快速下降。
8.2 崩溃保护误触发
if (crashRecoveryModeActive()) {
disarm(DISARM_REASON_CRASH_PROTECTION);
rescueStop();
}
翻滚检测(crash flip)误触发 → 直接 disarm,救援终止。
常见于剧烈机动、强烈震动、加速度计噪声。
8.3 硬失控判定抖动
const bool hardFailsafe = !rxIsReceivingSignal();
接收机间歇性丢包 → hardFailsafe 在 true/false 间跳变。
配合 SANITY_FS_ONLY 可能反复进入/退出 ABORT。
8.4 RESCUE_COMPLETE 未被使用
case RESCUE_COMPLETE:
rescueStop();
break;
代码中没有任何地方设置 phase = RESCUE_COMPLETE,可能是遗留代码。
总结:
Sanity 模式决定了系统对故障的"容忍度"。
SANITY_ON:最严格,一点小问题就放弃。
SANITY_FS_ONLY:只在真正失控时放弃。通常CLI页面设置了此命令
第九章:传感器与配置相关
9.1 气压计问题
getAltitude() 依赖气压计。
气压计未校准、受气流/温度影响漂移 → currentAltitudeCm 错误 → 爬升/下降 ratio 计算错误 → 误判 failure。
无气压计仅靠 GPS 高度时,更新率低(1~10Hz),altitudeDataIntervalSeconds 大,PID 响应差。
9.2 磁力计问题
useMag 开启但 mag 未校准/受干扰 → yaw 错误 → ROTATE 卡住或 FLY_HOME 飞错方向,magForceDisable 机制只在 flyaway 30 秒后触发一次,且不可逆。
9.3 IMU yaw 估计
无 mag 时,地速 > 2m/s 才用 GPS 地速修正 yaw。返航速度设置过低(<2m/s)时 yaw 修正失效,IMU 漂移累积。imuYawCogGain 逻辑在 IMU 错误时衰减 velocity I 项,可能过度抑制导致速度上不去。
9.4 GPS 数据率与延迟
gpsDataIntervalSeconds 范围 10ms~1000ms。
低数据率(如 1Hz)时:velocityToHomeCmS 计算粗糙。
PID 的 D 项噪声大。
newGPSData 触发频率低,状态机推进慢。
GPS 位置延迟会导致过冲 Home 点,尤其在高速返航时。
9.5 newGPSData 标志的时序
gpsRescueNewGpsData() 设置 newGPSData = true,在 gpsRescueUpdate() 末尾清零。
若 GPS 数据在两次 gpsRescueUpdate() 之间到达多次,只处理一次。
若 GPS 数据在 sensorUpdate() 之后、newGPSData = false 之前到达,会被清零但未使用。
9.6 配置参数不当
参数 不当设置的后果
throttleHover 不准 → 高度控制差,DO_NOTHING 阶段下降异常
throttleMin/Max 范围过窄 → 无法应对极端情况
maxRescueAngle 过小 → 抗风能力差
groundSpeedCmS 过大/过小 → 耗电或飞太慢
descentDistanceM 过大 → 下降开始太早,可能落在远离 Home 处
minStartDistM 过大 → 近距离救援时长时间前倾飞离
disarmThreshold 不当 → 着陆不 disarm 或空中误 disarm
targetLandingAltitudeM 不当 → 着陆判定错误
returnAltitudeM 过高 → 爬升耗电;过低 → 撞障碍
GPS_MIN_SAT_COUNT 过低 → 无效数据被当有效;过高 → 容易 LOWSATS
给飞手的话:
传感器和配置是救援失败的"隐形杀手"。
气压计、磁力计、IMU 任何一个不准,都可能让救援失败。
GPS 数据率低、延迟大,救援精度就差。
配置参数不是默认就好,要根据自己的飞机和环境调整。
第十章:环境与外部因素
10.1 强风
逆风返航:地速上不去 → 触发flyaway 判定。
侧风:航向与机头不一致 → yaw 误差大 → ROTATE 卡住或 roll mix 过度。
下降时风切变:高度控制容易震荡,可能导致空中上锁。
10.2 GPS 信号遮挡/多径
城市、峡谷、树林 → 卫星数下降 → LOWSATS。
10.3 电池电压骤降
大油门爬升/返航时电压跌落 → 动力不足 → 爬升/返航失败。
若触发电压 failsafe 且不是 GPS Rescue 模式,可能直接坠落。
10.4 Home 点错误
解锁时 GPS 尚未稳定,Home 点记录在错误位置。
后果:整个救援方向错误,飞向错误地点,可能触发 flyaway 或飞丢。
代码注释也警告:"Some GPS units give false Home values! Always check the arrow points to home on leaving home."
给飞手的话
环境是救援失败的外因。
强风、遮挡、多径都会让 GPS 和 IMU 出错。
Home 点错误最致命,解锁前一定确认箭头指向真正的家,并且要以一定速度直线飞行一百米让箭头更准确。
第十一章:状态机相关的隐蔽问题
11.1 阶段切换条件苛刻
ROTATE → FLY_HOME:要求 absErrorAngle < 30°,强风/IMU 误差下难以满足。
FLY_HOME → DESCENT:要求 distanceToHomeM <= descentDistanceM,GPS 距离跳动可能反复切换。
DESCENT → LANDING:要求 currentAltitudeCm < targetLandingAltitudeCm,气压计漂移可能提前或延迟。
11.2 failure 状态无恢复机制
一旦置位,只有回到 IDLE 才清零,短暂故障也会导致救援终止。
11.3 DO_NOTHING 的 20 秒倒计时不可逆
即使 GPS 恢复,也不会重置 secondsDoingNothing,除非用户手动切出救援模式。
给飞手的话
状态机的"单行道"设计,意味着任何故障都不可逆。
理解这一点,能帮你在遇到"小问题导致救援失败"时,知道背后发生了什么。
第十二章:完整时间线——一次 4~5 秒 GPS 丢失的全过程
假设:救援正在 FLY_HOME 阶段,Sanity = OFF,GPS 完全中断 5 秒后恢复。如果是 SANITY_ON:T=0,GPS发生中断,触发ABORT,立即 disarm,自由落体
如果是"GPS 有数据但无效"
时间 事件 failure phase 飞机在做什么
T=0 数据无效 HEALTHY FLY_HOME 继续飞,但速度计算可能异常
T=5s 数据恢复 HEALTHY FLY_HOME 正常继续返航
T=10s 若持续无效 LOWSATS DO_NOTHING 10 秒后才触发
给飞手的话
同样是"GPS 丢了几秒",结果完全不同:
完全无数据 + SANITY_ON = 秒掉。
完全无数据 + SANITY_OFF = 20 秒后掉。
有数据但无效 = 大概率能撑过去。
第十三章:救援失败原因总表
阶段 失败场景 主要原因 后果
启动 无 Home 点 GPS 未定位就解锁 ABORT 或 DO_NOTHING
启动 距 Home 5m 内且在地面 误触救援 立即 ABORT
启动 初始距离 < minStartDistM 触发太近 持续前倾飞离
爬升 爬升受阻 动力不足、气压计异常、强风 10s 后转 LANDING
爬升 目标高度过高 MAX 模式 + 低电量 无法到达
转向 偏航误差 > 30° 磁力计/IMU 错误、强风 卡在 ROTATE
返航 Flyaway IMU 错误、强风、磁干扰 30s 后 FLYAWAY
返航 GPS 完全丢失 模块故障、遮挡 立即 GPSLOST
返航 低卫星数 城市峡谷、树冠 10s 后 LOWSATS
返航 速度上不去 强风、电池不足、I 项问题 触发 flyaway
下降 下降受阻 气压计漂移、油门过高 10s 后转 LANDING
下降 下降率不匹配 高度设置不当 超时或硬着陆
下降 方向错误 IMU 漂移、风 原地下降,落偏远
着陆 着陆超时 油门卡高、气压计不降 10s 后 ABORT
着陆 撞击检测误判 阈值不当 不 disarm 或空中 disarm
着陆 着陆点不佳 树、斜坡、水面 损坏
系统 Sanity 过严 SANITY_ON 小故障即 disarm
系统 崩溃保护误触发 震动、机动 直接 disarm
系统 硬失控抖动 接收机丢包 反复 ABORT
传感器 气压计漂移 未校准、气流 高度控制错误
传感器 磁力计干扰 电调线、电源线 yaw 错误
传感器 IMU yaw 漂移 无 mag、低速 飞错方向
传感器 GPS 数据率低 1Hz 模块 PID 精度差
配置 参数不当 throttleHover、groundSpeed 等 各种失败
环境 强风 逆风、侧风、风切变 返航/下降失败
环境 GPS 遮挡 城市、树林 LOWSATS
环境 电池骤降 大油门 动力不足
环境 Home 点错误 解锁时 GPS 未稳 飞错方向
扫码查看6条评论