第四章:状态转移条件详解

各位工程师朋友,今天我们来聊聊状态机里最核心的部分——状态转移条件。说白了,就是什么情况下飞机会从当前模式切换到另一个模式。

我个人习惯把转移条件分成两大类:外部触发条件内部检测条件。外部触发比如遥控器信号、用户指令;内部检测比如电量、GPS、高度、速度。这两类条件在工程实现上,处理方式完全不同。

4.1 遥控器信号丢失

这是最紧急的情况。我在项目中遇到过几次遥控器突然断连,飞机直接进入失控保护模式。

信号丢失的判断逻辑其实不复杂:

// 伪代码示例:遥控器信号丢失检测
if (rx_lost_time > RX_LOST_THRESHOLD_MS) {
    // 连续丢失超过2秒,判定为信号丢失
    if (current_mode == MODE_MANUAL) {
        transition_to(MODE_RTH);  // 返航
    } else if (current_mode == MODE_AUTO) {
        // 自动模式下保持当前任务
        // 但降低飞行速度
        set_speed_limit(SAFE_SPEED);
    }
}

嗯,这里要注意一个细节:信号丢失的阈值不能设得太短。我曾经见过有人设了500ms,结果遥控器电池稍微接触不良就触发返航,反而更危险。我个人建议设2-3秒比较合理。

⚠️ 避坑指南:我曾经在项目中遇到过遥控器信号短暂丢失又恢复的情况。如果每次丢失都触发返航,飞机会频繁切换模式。建议加入「去抖逻辑」——连续丢失超过阈值才触发转移。

4.2 电量过低

电量管理是飞行安全的底线。你想想看,电池没电了,什么模式都没用。

我一般把电量分成三个等级:

电量等级 剩余电量 触发动作
低电量警告 30% - 20% 限制最大速度,提示用户返航
严重低电量 20% - 10% 强制切换为返航模式
临界电量 < 10% 强制降落,无视用户指令

这里有个坑:电池电压在负载下会瞬间跌落。我记得有一次测试,飞机急加速时电压瞬间掉到3.3V,触发了低电量保护。但实际上电池还有40%的电量。所以建议用「滑动平均滤波」处理电压采样值。

4.3 GPS信号强弱

GPS信号直接影响定位精度。说白了,信号不好时,返航模式就是瞎飞。

我习惯用HDOP(水平精度因子)来量化信号质量:

  • HDOP < 1.0:优秀,可以执行高精度任务
  • 1.0 ≤ HDOP < 2.0:良好,正常飞行
  • 2.0 ≤ HDOP < 3.0:一般,限制自动模式使用
  • HDOP ≥ 3.0:差,强制切换为姿态模式或悬停
💡 个人经验:在城市峡谷或高架桥下飞行时,GPS信号经常跳变。我建议在状态机里加入「GPS信号质量保持时间」条件——信号变差后持续5秒才触发转移,避免频繁切换。

4.4 高度限制

高度限制分两种:硬限制软限制

硬限制是法规要求的,比如中国规定120米。软限制是用户自己设置的,比如在树林里飞,设个30米就够了。

// 高度限制处理逻辑
if (current_altitude > HARD_LIMIT_ALT) {
    // 硬限制:立即执行
    set_throttle(-MAX_CLIMB_RATE);
    transition_to(MODE_ALT_HOLD);
    log_event("硬高度限制触发");
} else if (current_altitude > user_limit_alt) {
    // 软限制:提示用户
    send_warning("接近用户设置高度上限");
    // 但不强制切换模式
}

嗯,这里要注意:硬限制触发后,不要直接切到降落模式。我见过有人这么设计,结果飞机在120米高空直接开始降落,反而更危险。正确的做法是限制爬升,保持当前高度。

4.5 速度限制

速度限制和高度限制类似,但更复杂一些。因为速度有水平速度和垂直速度之分。

我个人习惯这样处理:

  • 水平速度超限:降低油门,限制倾斜角度
  • 垂直速度超限:限制爬升/下降速率
  • 同时超限:优先处理垂直速度,因为高度失控更危险
🔧 小技巧:速度限制最好用「渐变式」处理,而不是「开关式」。比如超过速度限制后,不是立刻刹车,而是逐渐降低油门。这样飞行体验更平滑,也减少机械冲击。

4.6 用户指令切换

用户指令是最特殊的转移条件。因为它不是自动触发的,而是人为干预。

我设计状态机时,会给用户指令一个最高优先级。但有个例外——当飞机处于临界电量或信号丢失状态时,用户指令会被忽略。

为什么会这样?你想想看,如果电池只剩5%了,用户还强行要飞远,那不是找死吗?

// 用户指令处理优先级
if (battery_level < CRITICAL_BATTERY) {
    // 忽略用户指令
    return;
}
if (rx_signal_lost) {
    // 忽略用户指令
    return;
}
// 正常处理用户指令
handle_user_command(cmd);

知识体系总览

下面这张图总结了本章的核心逻辑:

状态转移条件总览 飞行模式状态机 遥控器信号丢失 电量过低 GPS信号强弱 高度限制 速度限制 用户指令切换 外部触发条件:遥控器信号丢失、用户指令切换 内部检测条件:电量过低、GPS信号强弱、高度限制、速度限制 优先级排序 临界电量 > 信号丢失 > 用户指令 > 高度/速度限制 > GPS信号

这张图把六个条件分成了两大类。你注意看底部的优先级排序——临界电量永远排第一。这是血的教训换来的经验。

📌 核心要点:
  • 每个转移条件都要加「去抖逻辑」,避免频繁切换
  • 优先级排序要合理,安全相关的条件永远优先
  • 用户指令不是万能的,在极端情况下要强制覆盖
  • 条件触发后不要立即执行极端操作,用渐变式处理更安全

好了,这一章的内容就到这里。状态转移条件看似简单,但实际工程中坑很多。我建议你在设计状态机时,先把这六个条件列出来,然后逐个分析它们的优先级和互斥关系。这样写出来的代码才经得起考验。

专注资料整理