4、主从选举机制:基于优先级的选举、基于健康度的选举、基于Raft的共识选举

说到冗余飞控,有个问题绕不开:谁说了算?

三套飞控同时在线,各自算各自的。万一结果不一样,听谁的?总不能三套一起输出,舵机得疯掉。所以必须有个主从选举机制,选出一个老大,其他当小弟。小弟们可以提意见,但最终决策权在老大手里。

我这些年做飞控系统,见过不少选举方案。说白了,就三大类:基于优先级基于健康度基于Raft共识。咱们一个一个聊。

4.1 基于优先级的选举:简单粗暴,但够用

这是最原始的办法。出厂前就给每套飞控定好优先级:1号最高,2号次之,3号最低。上电后,优先级最高的直接当主控。

听起来很合理对吧?但有个坑——优先级高的那套万一坏了呢?

我曾经在一个项目中遇到过这种情况:1号飞控的IMU(惯性测量单元)飘了,但它优先级最高,死活不肯让位。结果飞机在天上画起了龙。后来我们加了条规则:优先级高不等于永远当主,得定期报健康状态

核心逻辑:
  • 每套飞控有固定优先级(1 > 2 > 3)
  • 上电时,优先级最高的自动成为主控
  • 主控故障或失联时,次高优先级接替
  • 主控恢复后,是否夺回?看策略——我建议不夺回,避免频繁切换
我的经验:优先级选举适合双余度系统。三余度以上,优先级方案容易出问题。因为优先级是静态的,无法感知动态健康状态。

4.2 基于健康度的选举:谁状态好谁上

这个就聪明多了。每套飞控实时计算自己的健康度评分,分数最高的当选主控。

健康度怎么算?我一般用这几个维度:

维度 权重 说明
传感器自检 30% IMU、GPS、气压计是否正常
CPU负载 20% 负载过高说明计算压力大
通信延迟 20% 与其他飞控的同步延迟
历史故障 15% 最近10秒内是否出现过异常
电源稳定性 15% 电压波动是否在允许范围内

每套飞控每隔100ms广播一次自己的健康度。其他飞控收到后,对比一下。如果发现自己分数最高,就主动宣称自己是主控。

注意:健康度选举有个问题——分数震荡。两套飞控分数接近时,可能频繁切换主从。我见过最夸张的一次,1秒内切换了8次,舵机都快抖散架了。

解决办法?加个滞回比较器。比如当前主控的健康度必须比备选低10%以上,才允许切换。说白了,就是给切换加个死区。

4.3 基于Raft的共识选举:最可靠,但最复杂

如果你做的是高安全等级的飞控(比如载人无人机),我强烈建议用Raft。Raft是分布式系统里公认的共识算法,用在飞控上,说白了就是让三套飞控通过投票决定谁当主

Raft的核心流程,我简化一下:

  1. 选举阶段:每套飞控都是候选者,给自己投票,然后拉票
  2. 投票阶段:收到拉票请求的飞控,检查对方的日志是否比自己新
  3. 当选阶段:获得多数票(三余度就是2票)的飞控成为主控
  4. 心跳阶段:主控定期发心跳,备选收到后重置选举超时

这里有个关键点:日志新旧。Raft里不是谁健康谁当主,而是谁的日志最完整谁当主。为什么?因为主控要负责同步状态给备选,日志不完整会导致数据丢失。

Raft选举的伪代码:
// 候选者发起选举
if (election_timeout_expired) {
    current_term++;
    vote_for = self;
    votes_received = 1;
    send_request_vote_to_peers();
}

// 收到投票请求
if (request.term > current_term) {
    // 对方任期更新,我变成追随者
    current_term = request.term;
    vote_for = request.candidate_id;
    send_vote(true);
} else if (request.term == current_term && 
           !voted_in_this_term &&
           request.last_log_index >= last_log_index) {
    // 日志足够新,投票
    vote_for = request.candidate_id;
    send_vote(true);
}

我在实际项目中用Raft时,踩过一个坑:选举超时时间设置。三套飞控如果超时时间一样,会同时发起选举,谁也拿不到多数票。后来我让每套飞控的超时时间随机化(比如150ms±50ms),这样总有人先发起选举。

4.4 三种方案对比

方案 优点 缺点 适用场景
基于优先级 实现简单,延迟低 无法感知健康状态 双余度、低成本系统
基于健康度 动态适应,灵活 分数震荡,需滞回 三余度、中等安全等级
基于Raft 强一致性,高可靠 实现复杂,资源消耗大 载人、高安全等级

4.5 我的建议

如果你刚开始做冗余飞控,我建议从基于健康度的方案入手。它比优先级灵活,又比Raft简单。等系统跑稳定了,再考虑升级到Raft。

嗯,这里要注意:无论用哪种方案,切换逻辑一定要做硬件在环测试。我曾经在仿真里跑得好好的,一上真机就出问题——因为仿真里没有考虑通信延迟。你想想看,三套飞控之间通信延迟如果超过50ms,选举结果可能完全不一样。

避坑指南:我曾经在Raft选举中忘记处理脑裂场景。三余度系统里,如果两套飞控之间的通信中断,它们各自以为自己是主控,同时输出控制信号。结果舵机收到了两套指令,直接抖成了筛子。后来我加了心跳超时检测多数派确认,才彻底解决。

最后说一句:选举机制只是冗余飞控的一部分。选出了主控,还得保证主控和备选之间的状态同步。这个咱们下一章再聊。

主从选举机制对比 基于优先级 • 静态优先级(1>2>3) • 上电即确定主控 • 故障时次高接替 • 恢复后不夺回 优点:简单、延迟低 基于健康度 • 实时计算健康评分 • 分数最高者当选 • 多维度加权评估 • 需滞回防震荡 优点:动态适应 基于Raft共识 • 投票选举主控 • 日志最新者当选 • 心跳维持权威 • 多数派确认 优点:强一致性 关键对比维度 维度 优先级 健康度 Raft 实现难度 可靠性 适用余度 双余度 三余度 三余度+
专注资料整理