4. 模式切换触发机制:遥控器通道切换、地面站指令、任务脚本触发、故障保护自动切换

好,咱们接着聊飞控模式切换的触发机制。说实话,这部分是VTOL飞控里最容易出幺蛾子的地方。我见过不少项目,飞控算法写得漂漂亮亮,结果一上天,模式切换那一下直接翻车。为什么?因为触发条件没处理好。

模式切换的触发源,说白了就四种:遥控器通道、地面站指令、任务脚本、故障保护。咱们一个一个拆开讲。

4.1 遥控器通道切换

这是最常用的方式。飞手通过遥控器上的一个三段开关,直接告诉飞控“我要切模式了”。

我个人习惯把遥控器通道映射到AUX通道上。比如通道5,三个位置分别对应:位置1→多旋翼模式,位置2→过渡模式,位置3→固定翼模式。

这里有个坑——通道值的抖动。遥控器信号不是绝对稳定的,尤其是廉价遥控器。你明明拨到了位置2,但飞控可能瞬间读到位置1的值,然后又跳回位置2。这一下子就可能触发错误的模式切换。

⚠️ 我曾经遇到过:一个学员的飞机在过渡模式下突然切回多旋翼模式,就是因为通道值抖动。飞控检测到位置2→位置1→位置2的跳变,触发了两次模式切换。结果飞机在空中猛地一抖,差点炸机。

解决办法?加一个去抖滤波。我一般用连续采样法:连续读到同一个通道值超过50ms,才认为切换有效。代码大概长这样:

// 遥控器通道去抖示例
uint16_t rc_channel_value;
uint16_t stable_count = 0;
uint16_t last_valid_mode = current_mode;

void check_rc_mode_switch() {
    rc_channel_value = read_rc_channel(5);
    
    if (rc_channel_value == last_valid_mode) {
        stable_count++;
        if (stable_count > 5) {  // 连续5次采样一致
            set_flight_mode(rc_channel_value);
            stable_count = 0;
        }
    } else {
        stable_count = 0;  // 值变了,重新计数
    }
    last_valid_mode = rc_channel_value;
}

嗯,这里要注意:去抖时间不能太长,否则飞手会感觉“切模式有延迟”。50ms是个不错的折中值。

4.2 地面站指令切换

地面站指令,说白了就是通过数传链路,从电脑或平板上下发模式切换命令。这在自动化飞行中很常用,比如你想让飞机在某个航点自动切到固定翼模式。

地面站指令的优点是灵活。你可以随时下发指令,不受遥控器通道数量的限制。但缺点也很明显——通信延迟和丢包

我记得有一次做演示,地面站下发“切到悬停模式”的指令,结果数传链路刚好丢了一包数据。飞控没收到指令,飞机继续往前飞,差点撞到树。从那以后,我要求所有地面站指令必须带确认机制

  • 地面站发送指令后,等待飞控回复ACK
  • 如果超时未收到ACK,重发指令(最多3次)
  • 飞控收到指令后,先校验指令完整性,再执行切换
💡 小技巧:我习惯在地面站指令里加一个“预切换”状态。飞控收到指令后,先进入一个短暂的预切换状态(比如500ms),在这个状态里飞控会检查当前飞行状态是否允许切换。如果条件不满足,就拒绝切换并上报错误。这比直接切换安全得多。

4.3 任务脚本触发

任务脚本触发,是自动化飞行的核心。你写一个任务脚本,告诉飞控:飞到A点,切到固定翼模式;飞到B点,切回多旋翼模式;飞到C点,降落。

任务脚本通常用MAVLink的MISSION_ITEM协议实现。每个航点可以附带一个“动作”字段,比如MAV_CMD_DO_VTOL_TRANSITION。

这里有个关键点——触发时机。你想想看,飞机飞到A点上方,是“到达A点瞬间”就切模式,还是“到达A点后保持3秒”再切?

我个人建议:不要立即切换。飞机到达航点时,可能还有速度、姿态的偏差。立即切换模式,容易造成飞行状态突变。我一般会在任务脚本里加一个“到达航点后保持当前模式2秒”的延迟,等飞机稳定了再切。

// 任务脚本示例(伪代码)
MISSION_ITEM item1 = {
    .seq = 0,
    .command = MAV_CMD_NAV_WAYPOINT,
    .param1 = 0,  // 停留时间(秒)
    .x = 100.0,   // 经度
    .y = 200.0,   // 纬度
    .z = 50.0     // 高度
};

MISSION_ITEM item2 = {
    .seq = 1,
    .command = MAV_CMD_DO_VTOL_TRANSITION,
    .param1 = 1,  // 1=切到固定翼,2=切到多旋翼
    .x = 0,
    .y = 0,
    .z = 0
};
🔑 核心原则:任务脚本触发的模式切换,一定要考虑“切换前的状态检查”。飞机速度太快?高度太低?电池电压不够?这些条件不满足,坚决不切。

4.4 故障保护自动切换

这部分是最重要的,也是我花时间最多的。故障保护自动切换,说白了就是飞控自己判断“出事了,我得自己切模式保命”。

常见的故障保护场景:

  • GPS丢失:多旋翼模式下GPS丢了,飞控应该自动切到悬停模式(靠气压计和IMU维持高度和位置)
  • 遥控器信号丢失:RC信号丢了,飞控应该自动切到RTL(返航)模式
  • 电池电压过低:电压低于阈值,飞控应该自动切到降落模式
  • 空速计故障:固定翼模式下空速计坏了,飞控应该自动切回多旋翼模式

嗯,这里要注意:故障保护不能太敏感。我见过一个项目,GPS信号稍微差一点(比如从12颗星掉到8颗星),飞控就自动切到悬停模式。结果飞机在城市里飞,GPS信号本来就不好,飞控频繁切换模式,飞手根本控制不住。

⚠️ 我曾经踩过的坑:故障保护切换的优先级问题。有一次,飞机同时触发了“GPS丢失”和“RC信号丢失”两个故障。飞控先执行了GPS丢失的切换(切到悬停),然后又执行了RC信号丢失的切换(切到RTL)。两个切换指令打架,飞机直接失控。

解决办法:建立故障优先级表。我一般这样设计:

优先级 故障类型 切换目标模式 说明
1(最高) 电池电压过低 降落模式 保命第一,立即降落
2 RC信号丢失 RTL(返航) 让飞机自己飞回来
3 GPS丢失 悬停模式 稳住姿态,等待指令
4 空速计故障 多旋翼模式 固定翼飞不了,切回多旋翼
5(最低) IMU温度过高 当前模式 只报警,不切换

当多个故障同时发生时,飞控只执行优先级最高的那个切换。等最高优先级的故障处理完了,再检查下一个故障。

4.5 四种触发机制的协同工作

这四种触发机制不是孤立的。它们之间会有冲突,需要一套仲裁逻辑来决定“听谁的”。

我一般这样设计仲裁规则:

  1. 故障保护优先级最高——任何情况下,故障保护切换可以覆盖其他所有切换指令
  2. 地面站指令优先级次之——地面站指令可以覆盖遥控器通道和任务脚本
  3. 遥控器通道和任务脚本平级——谁先触发谁生效,但任务脚本可以设置“不允许遥控器打断”的标记

举个例子:飞机正在执行任务脚本,脚本里写着“飞到B点切到固定翼模式”。但飞手觉得不对劲,拨动遥控器开关想切回多旋翼模式。这时候听谁的?

我个人习惯:默认听飞手的。飞手是最终决策者。但任务脚本可以设置一个“锁定模式”标记,一旦设置,遥控器通道切换无效。这个功能在自主巡检任务中很常用——防止飞手误操作打断任务。

🔑 总结一下:模式切换触发机制的核心,不是“怎么切”,而是“什么时候切”和“听谁的”。把触发条件、去抖滤波、优先级仲裁这三个问题想清楚,你的飞控切换逻辑就稳了。

好了,这部分内容就到这里。下一章咱们聊聊模式切换过程中的状态机设计——那才是真正考验飞控工程师功底的地方。


公众号:蓝海资料掘金营,微信deep3321