第四章:状态转移条件详解
各位工程师朋友,今天我们来聊聊状态机里最核心的部分——状态转移条件。说白了,就是什么情况下飞机会从当前模式切换到另一个模式。
我个人习惯把转移条件分成两大类:外部触发条件和内部检测条件。外部触发比如遥控器信号、用户指令;内部检测比如电量、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:差,强制切换为姿态模式或悬停
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);
知识体系总览
下面这张图总结了本章的核心逻辑:
这张图把六个条件分成了两大类。你注意看底部的优先级排序——临界电量永远排第一。这是血的教训换来的经验。
- 每个转移条件都要加「去抖逻辑」,避免频繁切换
- 优先级排序要合理,安全相关的条件永远优先
- 用户指令不是万能的,在极端情况下要强制覆盖
- 条件触发后不要立即执行极端操作,用渐变式处理更安全
好了,这一章的内容就到这里。状态转移条件看似简单,但实际工程中坑很多。我建议你在设计状态机时,先把这六个条件列出来,然后逐个分析它们的优先级和互斥关系。这样写出来的代码才经得起考验。