[BF学院_卷1] -- 第八讲:飞手打杆以后,飞控首先得到什么?

第八讲:飞手打杆以后,飞控首先得到什么?

  • Angle Mode(自稳模式)的控制链路总览
  • 飞手真正控制的是什么
  • 为什么遥控器不是直接控制电机
  • angleTarget(目标姿态角)的来源
  • angleTarget(目标姿态角)为什么这样计算
  • 控制链路正式开始

本讲对应 Betaflight 源码

源码文件

src/main/flight/pid.c

核心函数

pidLevel()

核心变量

currentPidSetpoint

angleTarget

本讲对应控制流程

RC(遥控器)
        │
        ▼
currentPidSetpoint
        │
        ▼
angleTarget(目标姿态角)

本讲学习目标

阅读完本讲以后,你应该能够回答:

□ 飞手真正控制的是什么?

□ currentPidSetpoint 从哪里来?

□ angleTarget(目标姿态角)是什么?

□ angleTarget 为什么这样计算?

□ 飞控为什么要先得到 angleTarget,而不是直接控制电机?


从这一讲开始,我们正式进入 Betaflight

前面的几讲,

我们一直讨论:

飞机应该怎样运动。

例如:

Yaw 应该绕 Earth Frame(地球坐标系)旋转。

Pitch Flip 为什么只能用于 180°。

这些内容,

都是为了建立:

空间直觉。

但是,

从这一讲开始,

我们正式进入:

Betaflight 源码。

我们的目标,

也发生了变化。

以后,

每一讲都会围绕一个核心问题:

飞控是怎样把飞手的控制意图,

一步一步翻译成电机控制命令的?

整个过程,

我们都会对应:

Betaflight 源码,

逐行理解。


飞手真正控制的是什么?

很多初学者,

都会认为:

飞手控制的是:

电机。

或者:

飞手控制的是:

飞机姿态。

其实,

这两种说法,

都不准确。

飞手真正控制的是:

遥控器摇杆。

例如:

Pitch(俯仰)

向前推一点。

飞控收到的,

只是:

一个摇杆输入。

此时,

飞控仍然不知道:

飞机应该转到多少度。

因此,

第一步,

必须把:

摇杆输入

翻译成:

飞机希望到达的姿态。

这个姿态,

就是:

angleTarget(目标姿态角)。

angleTarget(目标姿态角)到底来自哪里?

对应源码:

float angleTarget =
angleLimit
*
currentPidSetpoint
*
pidRuntime.maxRcRateInv[axis];

以后,

阅读源码,

我们遵循统一的方法。

首先,

回答第一个问题。


angleTarget(目标姿态角)是什么?

一句话来说:

angleTarget

=

飞手希望飞机最终停留的位置。

例如:

飞手希望:

Pitch = 30°

那么:

angleTarget

=

30°

注意:

这里仍然只是:

目标。

飞机,

此时,

还没有开始运动。

飞控,

只是知道:

飞手希望飞机,

最终停留在这里。

currentPidSetpoint 到底来自哪里?

继续看源码:

float angleTarget =
angleLimit
*
currentPidSetpoint
*
pidRuntime.maxRcRateInv[axis];

阅读源码时,

按照我们的新规范,

第二步要回答:

currentPidSetpoint

来自哪里?

答案是:

RC(遥控器)

更准确地说,

对应源码:

float currentPidSetpoint =
getSetpointRate(axis);

因此:

整个来源可以理解成:

RC(遥控器)

↓

getSetpointRate()

↓

currentPidSetpoint

这里,

我们暂时不用深入:

Rates(摇杆曲线)

因为:

它属于:

RC 输入模块。

后面会单独介绍。

目前,

只需要知道:

currentPidSetpoint

=

RC 当前摇杆输入。

angleLimit 是什么?

继续看:

angleLimit

它表示:

ANGLE 模式允许的最大姿态角。

例如:

如果:

angleLimit

=

55°

那么:

飞机最大只能飞到:

Pitch = ±55°

Roll = ±55°

即使:

飞手把摇杆推到底,

飞机也不会继续倾斜。

因此:

angleLimit

决定了:

ANGLE 模式的最大姿态角。

maxRcRateInv 又是什么?

最后还有:

pidRuntime.maxRcRateInv[axis]

名字看起来很复杂。

其实,

它只是:

maxRcRate

的倒数。

作用只有一个:

把 RC 输入,

转换成:

0~1 的比例。

例如:

假设:

最大 RC 输入

=

500°/s

那么:

摇杆当前:

250°/s

经过:

maxRcRateInv

以后:

得到:

0.5

也就是说:

当前摇杆,

推到了:

50%。

因此:

这一项,

真正表示的是:

RC 当前打杆比例。

为什么三者相乘?

现在,

三个变量,

已经全部认识了。

currentPidSetpoint

↓

当前 RC 输入
maxRcRateInv

↓

转换成打杆比例
angleLimit

↓

最大允许姿态角

于是:

整个公式:

angleTarget =
angleLimit
*
currentPidSetpoint
*
pidRuntime.maxRcRateInv[axis];

其实就是:

RC 当前比例

×

最大姿态角

得到:

Target Angle(目标姿态角)

例如:

ANGLE 最大姿态角

=

60°

飞手:

摇杆推到:

50%

那么:

angleTarget

=

30°

飞控立即知道:

飞手希望:

飞机最终停留在:

30°。

到这里,飞控真正完成了第一次翻译

飞手,

一直认为:

自己只是:

推了一下摇杆。

但是,

飞控已经完成了一次非常重要的翻译。

它把:

RC 输入

翻译成:

Target Angle(目标姿态角)

整个过程可以表示成:

RC(遥控器)

↓

currentPidSetpoint

↓

RC 当前比例

↓

angleTarget(目标姿态角)

这也是:

Angle Mode(自稳模式)

真正开始工作的第一步。


但是,还有一个问题

现在,

飞控已经知道:

Target Angle

=

30°

可是,

它仍然不能控制飞机。

原因非常简单。

飞控只知道:

希望飞机去哪里。

但是,

它还不知道:

飞机现在在哪里。

因此,

控制系统还缺少另一半信息:

Current Angle(当前姿态角)

只有:

Target Angle

+

Current Angle

同时存在,

飞控才能计算:

Angle Error(姿态角误差)

真正开始控制飞机。


本讲小结

这一讲,

飞控完成了控制链中的第一次翻译:

RC(遥控器)

↓

currentPidSetpoint

↓

angleTarget(目标姿态角)

其中:

currentPidSetpoint

=

RC 当前摇杆输入。
angleLimit

=

ANGLE 模式允许的最大姿态角。
maxRcRateInv

=

把 RC 输入转换成打杆比例。

最终:

飞控得到:

Target Angle(目标姿态角)

它表示:

飞手希望飞机最终停留的位置。

但是,

飞控仍然不知道:

飞机现在到底在哪里。

因此,

下一讲,

我们将继续寻找:

Current Angle(当前姿态角)

并计算:

Angle Error(姿态角误差)。

下一讲预告

下一讲,

我们将正式进入:

const float currentAngle =
(attitude.raw[axis]
-angleTrim->raw[axis])
/10.0f;

这一行源码。

重点理解:

Current Angle(当前姿态角)

到底来自哪里?

以及:

为什么:

Target Angle

-

Current Angle

就能够得到:

Angle Error(姿态角误差)。

posted on 2026-08-03 14:33  longyue  阅读(17)  评论(0)    收藏  举报

导航