用一个四旋翼 X 构型的完整数值例子,手把手拆解两代混控架构的计算逻辑差异。
以下所有例子都基于同一个飞行场景,方便直接对比两套系统在同一输入下的行为差异。
一架标准 X 型四旋翼正在悬停,姿态控制器检测到需要向右滚转修正,同时保持俯仰、偏航稳定。控制器输出如下归一化指令:
旧版的核心逻辑极其简洁:读取一张写死的权重表,然后做矩阵乘法。
.mix 文件中的权重表系统启动时,读取 quad_x.main.mix 文件。对于四旋翼 X 构型,R: 4x 语法会被展开为以下固定权重表:
.mix 文件(quad_x、hex_x、octa_+……)。想换构型?换文件、重启。
把控制器输出 [roll, pitch, yaw, thrust] 和权重矩阵相乘,就得到各电机输出:
代入具体数值 roll=0.30, pitch=0.00, yaw=0.05, thrust=0.60:
右前 (CCW):(-1.0)×0.30 + (+1.0)×0.00 + (-1.0)×0.05 + (+1.0)×0.60
= -0.30 + 0 - 0.05 + 0.60 = 0.25
左后 (CCW):(+1.0)×0.30 + (-1.0)×0.00 + (-1.0)×0.05 + (+1.0)×0.60
= +0.30 + 0 - 0.05 + 0.60 = 0.85
左前 (CW):(+1.0)×0.30 + (+1.0)×0.00 + (+1.0)×0.05 + (+1.0)×0.60
= +0.30 + 0 + 0.05 + 0.60 = 0.95
右后 (CW):(-1.0)×0.30 + (-1.0)×0.00 + (+1.0)×0.05 + (+1.0)×0.60
= -0.30 + 0 + 0.05 + 0.60 = 0.35
初始输出结果(范围 0~1):
✅ 本例中所有电机都在 [0, 1] 范围内,无需饱和处理。左侧电机(M2、M3)转速更高以产生向右滚转的力矩——符合物理直觉。
如果控制指令更大(比如 roll=0.50, thrust=0.75),某些电机就会超限:
先正常计算:
(-1.0)×0.50 + 0 + (-1.0)×0.05 + (+1.0)×0.75 = 0.20
(+1.0)×0.50 + 0 + (-1.0)×0.05 + (+1.0)×0.75 = 1.20 ⚠
(+1.0)×0.50 + 0 + (+1.0)×0.05 + (+1.0)×0.75 = 1.30 ⚠
(-1.0)×0.50 + 0 + (+1.0)×0.05 + (+1.0)×0.75 = 0.30
等比缩小 roll/pitch/yaw 分量:最大超限量 0.30(M3 超了 1.0),将所有电机的姿态控制分量等比缩小,使最大值恰好 = 1.0。
缩放因子 ≈ 0.77 → roll 实际效果被削弱为 0.38
如果有电机低于下限:所有电机整体上移,保证 min(output) ≥ 0。
最终输出:
新版把同一个问题建模成矩阵方程,用优化方法求解。同样的输入,思路完全不同。
不再读 .mix 文件,而是读取每个电机的物理参数(位置 x/y、推力系数、偏航系数),在运行时计算 B 矩阵。
代码根据这些物理参数,实时计算效能矩阵 B:
| M1 右前 | M2 左后 | M3 左前 | M4 右后 | |
|---|---|---|---|---|
| Roll | +0.707 | −0.707 | −0.707 | +0.707 |
| Pitch | −0.707 | +0.707 | −0.707 | +0.707 |
| Yaw | −0.05 | −0.05 | +0.05 | +0.05 |
| Thrust | 1.0 | 1.0 | 1.0 | 1.0 |
每列 = 一个电机对四个控制轴的贡献能力。例如 M1 的 Roll 行为 +0.707,表示 M1 转速提高时会产生正 roll(右倾)力矩。
已知期望控制量 v 和效能矩阵 B,求电机输出 u 使得 B · u = v。
代入 v = [0.30, 0.00, 0.05, 0.60]ᵀ 求解:
标准对称四轴在正常工况下,两套系统输出非常接近。真正的差距在饱和处理和非标构型。
同样的极端场景 roll=0.50, thrust=0.75,新版的处理完全不同:
初始伪逆求解:
⚠ M2、M3 超限
固定饱和执行器:将 M2 钳位到 1.0,M3 钳位到 1.0。计算残差控制量:
v_残差 = v_期望 − B · u_已钳位
"M2、M3 被限制了,有一部分控制量没实现,这部分残差交给 M1、M4 补偿。"
按优先级重新分配(这是核心差异!):
用 M1、M4 的效能子矩阵,对残差控制量再次伪逆求解,迭代直到所有输出合法。
最终输出:
推力得到了更好的保持,roll 被适度削减,yaw 被优先牺牲——这正是我们想要的。
不同拓扑和工况下,两套系统的具体行为差异。
旧版
混控器完全不知道 M3 已经停了——权重表里 M3 的系数还在。系统继续给 M3 分配一个非零输出值,但实际产生不了推力。
姿态控制器只能通过反馈环路慢慢"追"偏差,响应滞后严重,飞行器剧烈抖动甚至翻转坠机。
❌ 无前馈适应,依赖反馈纠错(通常来不及)
新版
检测到 M3 失效后,将 B 矩阵中 M3 对应的列全部清零,用剩余 3 个电机的子矩阵重新计算伪逆。
系统在同一控制周期内就切换到 3 电机模式——自动放弃 yaw 控制(欠驱动),但保住推力和 roll/pitch。
✅ 前馈级适应,亚毫秒响应
旧版
需要两套独立 mixer:mc_group 控制电机,fw_group 控制舵面。过渡期通过权重线性混合:
❌ 两套独立系统线性混合,易冲突
新版
统一的 B 矩阵同时包含电机列和舵面列,过渡期间效能系数连续变化:
✅ 统一优化,过渡平滑无冲突
旧版
没有现成的 R: 语法,需要手动计算权重,用 S: 逐行写 .mix 文件,刷固件,试飞,发现不对再改……
❌ 需手算权重、刷固件、反复迭代
新版
在 QGC 参数界面中填写每个电机的物理坐标和旋转方向,系统自动生成 B 矩阵:
✅ 描述几何 → 自动算 → 实时生效
| 维度 | 旧版 Mixer ≤ v1.12 | 新版 Control Allocation ≥ v1.13 |
|---|---|---|
| 配置方式 | .mix 文本文件,每种机架一个 | CA_* 参数族(QGC 可视化配置) |
| 核心数据结构 | 权重表 W(人工定义 ±1.0) | 效能矩阵 B(从几何坐标自动计算) |
| 求解方法 | 线性加权求和(矩阵乘法) | 伪逆 / 顺序去饱和 / 加权最小二乘 |
| 饱和处理 | 等比缩放所有姿态轴(启发式) | 固定饱和器 → 残差重分配(迭代最优) |
| 优先级 | 不支持(一视同仁缩放) | Thrust > Roll/Pitch > Yaw(可配置) |
| 构型扩展 | 每种构型一个 .mix,需刷固件重启 | 改参数即生效,支持任意几何布局 |
| 电机失效 | 无感知,完全依赖反馈 | 可清零 B 列,同周期内切换分配 |
| VTOL 过渡 | 两套 mixer 线性混合,互不通信 | 统一 B 矩阵,效能系数连续变化 |
| uORB 消息 | actuator_controls → actuator_outputs | torque/thrust_setpoint → actuator_motors/servos |
| 代码位置 | src/lib/mixer/ | src/modules/control_allocator/ |
| 版本状态 | v1.9~v1.12(v1.14 起完全移除) | v1.13 引入,v1.14+ 为唯一方案 |
CA_ROTOR* 参数族。