[BF学院_卷1] -- 第27讲:PID Output 如何进入 Mixer —— 从控制需求到 motorMix
第27讲:PID Output 如何进入 Mixer —— 从控制需求到 motorMix
本讲知识点
- PID Output 在控制链中的位置;
- pidData[].Sum 代表什么控制需求;
- Roll / Pitch / Yaw PID Output 为什么需要限制;
- PID Mixer Scaling 的作用;
- scaledAxisPidRoll / Pitch / Yaw 的形成过程;
- PID 输出如何通过 motorMixer_t 转换为 motorMix;
- Mixer 如何完成控制需求到电机修正量的转换。
本讲对应 Betaflight 源码
主要函数:
mixTable(timeUs_t currentTimeUs)
核心代码:
const float scaledAxisPidRoll =
constrainf(pidData[FD_ROLL].Sum,
-currentPidProfile->pidSumLimit,
currentPidProfile->pidSumLimit)
/ PID_MIXER_SCALING;
const float scaledAxisPidPitch =
constrainf(pidData[FD_PITCH].Sum,
-currentPidProfile->pidSumLimit,
currentPidProfile->pidSumLimit)
/ PID_MIXER_SCALING;
float scaledAxisPidYaw =
constrainf(pidData[FD_YAW].Sum,
-yawPidSumLimit,
yawPidSumLimit)
/ PID_MIXER_SCALING;
以及:
float mix =
scaledAxisPidRoll * activeMixer[i].roll +
scaledAxisPidPitch * activeMixer[i].pitch +
scaledAxisPidYaw * activeMixer[i].yaw;
本讲学习目标
理解 Mixer 接收到的不是"某个电机应该转多少",
而是"飞机需要多少 Roll、Pitch、Yaw 控制力"。
Mixer 的职责是:将飞机级控制需求,通过每个电机不同的权重,转换为每个电机需要增加或者减少多少输出。
回顾上一讲
上一讲分析了 calculateThrottleAndCurrentMotorEndpoints(), 它负责建立 Mixer 使用的油门输出空间。
也就是说, Mixer 在计算电机输出之前,需要先知道当前油门应该映射到哪个电机输出范围。
为什么 PID Output 不能直接给电机?
PID Controller 输出的是:飞机需要的控制量。
例如:飞机发生向右倾斜,PID Controller 计算以后得到:
Roll PID Output = +50
这个 50 表示:飞机需要一个 Roll 修正力。
但是它没有说明:
- 哪个电机增加?
- 哪个电机减少?
- 增加多少?
- 减少多少?
控制链:
姿态误差
↓
PID Controller
↓
Roll / Pitch / Yaw 控制需求
↓
Mixer
↓
Motor Output
所以,PID Output 是: "飞机需要什么",
而 Mixer 输出的是:"每个电机应该做什么"
pidData[].Sum —— PID 输出来源
在 mixTable() 中:
pidData[FD_ROLL].Sum
pidData[FD_PITCH].Sum
pidData[FD_YAW].Sum
分别代表:
Roll PID 总输出
Pitch PID 总输出
Yaw PID 总输出
这里的 "Sum" 表示 PID Controller 最终合成后的输出。
它已经包含 P项 + I项 + D项 的计算结果。
PID Output 为什么需要限制?
观察源码:
constrainf(pidData[FD_ROLL].Sum, -currentPidProfile->pidSumLimit, currentPidProfile->pidSumLimit)
这里进行了限制。
原因是:PID 输出理论上可以无限增大, 比如:飞机受到强烈扰动。
PID Controller 可能认为:需要非常大的修正力量。
但是电机存在物理限制:最大输出有限。
如果 PID 输出过大,进入 Mixer 后,可能导致:
- 某些电机超过最大输出;
- 某些电机被压到最低输出;
- 三轴控制互相抢夺电机能力。
因此,Mixer 输入之前,需要限制 PID 输出范围。
控制思想:
无限控制需求 -> 限制到飞控允许范围 -> 进入 Mixer
PID Mixer Scaling —— 为什么需要缩放?
限制以后,源码继续:
/ PID_MIXER_SCALING
例如:
scaledAxisPidRoll = pidData[FD_ROLL].Sum / PID_MIXER_SCALING;
作用是:将 PID Controller 输出单位,转换为 Mixer 使用的控制空间。
因为PID Controller 内部使用的是PID 计算尺度,而 Mixer 使用的是电机输出混合尺度,二者不是同一个范围。
因此需要:
PID Output -> 缩放 -> Mixer 输入
最终得到:
scaledAxisPidRoll
scaledAxisPidPitch
scaledAxisPidYaw
scaledAxisPidRoll / Pitch / Yaw
经过限制和缩放以后,Mixer 得到三个核心输入:
scaledAxisPidRoll
表示:飞机需要多少 Roll 修正,
例如,正值:需要向正方向 Roll;负值:需要向反方向 Roll
scaledAxisPidPitch
表示:飞机需要多少 Pitch 修正
scaledAxisPidYaw
表示:飞机需要多少 Yaw 修正
注意:这里仍然不是电机输出,而是飞机级控制需求。
motorMix —— 控制需求转换为电机修正量
现在进入 Mixer 核心:
float mix =
scaledAxisPidRoll * activeMixer[i].roll +
scaledAxisPidPitch * activeMixer[i].pitch +
scaledAxisPidYaw * activeMixer[i].yaw;
这就是 Mixer 数学模型。
对于第 i 个电机:
Motor Mix = Roll需求 × Roll权重
+ Pitch需求 × Pitch权重
+ Yaw需求 × Yaw权重
例如:某个电机,
roll = 0.5
pitch = -0.5
yaw = 1.0
那么:
motorMix = Roll × 0.5 + Pitch × (-0.5) + Yaw × 1.0
这个结果表示:该电机需要因为姿态控制,增加多少,或者减少多少输出。
为什么每个电机需要不同权重?
因为电机的位置不同。
例如,
Roll 控制:左侧电机增加,右侧电机减少 -> 产生滚转力矩;
Pitch 控制:前后电机产生推力差 -> 产生俯仰力矩;
Yaw 控制:不同旋向电机改变输出 -> 改变反作用力矩。
所以,每个电机对应一个:
Roll 权重
Pitch 权重
Yaw 权重
Mixer 并不是创造控制需求。
它只是按照飞机结构,重新分配控制需求。
控制链推进
到这里,Mixer 已经完成:
PID Output -> motorMix
转换。
此时, motorMix[]里面保存的是:每个电机由于姿态控制产生的 "修正量"。
但是,它还没有加入 "Throttle", 也没有转换成最终 ESC 输出值。
下一步的问题, 如何把:
Throttle + motorMix
合成为真正的:
Motor Output
本讲小结
本讲完成了 Mixer 输入控制量的建立。
源码中的 pidData[].Sum 是 PID Controller 输出的三轴控制需求,它描述飞机需要多少 Roll、Pitch、Yaw 修正,而不是直接描述电机输出。
Mixer 首先对 PID 输出进行限制和缩放,形成 scaledAxisPidRoll、scaledAxisPidPitch、scaledAxisPidYaw,然后通过 motorMixer_t 中保存的权重,将三轴控制需求转换为每个电机对应的 motorMix 修正量。
至此,控制链完成了:
PID Controller
↓
Roll / Pitch / Yaw 控制需求
↓
Mixer 分配
↓
motorMix
下一讲预告
下一讲继续分析 mixTable()。
重点:
motorMix + Throttle -> Motor Output
也就是:Mixer 如何把姿态修正量和油门基础输出合成为最终电机输出。
浙公网安备 33010602011771号