c - 如何正确归一化 q15 定点中的 pid 系数
问题描述
我正在使用 STM32F4 微控制器上的 CMSIS 库开发 PID 控制器。我无法真正理解 PID 参数的归一化。现在我有了 PID 控制器的三个 Kp、Ki、Kd 参数,我必须将它们放入系统中。我知道他们需要标准化,所以我必须从整数转换为 q15。问题来了。就我而言,我有:
kp = 2.7056
ki = 0.085
kd = 0
据我了解,我需要找到一个因子以使这些数字在 -32768...32767 中可表示,因此我将2^13
其用作因子:
kp = 2.7056 * 2^13 = 22164
ki = 0.085 * 2^13 = 696
我不明白是否需要除以PID计算的结果。如果我除法,当误差较低时,pid 输出为零:让我们有一个恒定的误差 e(n) = 2。在 PID 计算中(我使用函数 arm_pid_q15() 中描述的公式):
y(n) = y(n-1) + (kp+ki)*e(n) - kp*e(n-1)
y(n) = y(n-1) + (22164+696)*2 - 22164*2 = y(n-1) + 1392
如果y(n-1) = 0
,y(n) = 1392
。如果我除以2^13
因子,我有y(n) = 0
(整数)。
另一方面,如果我不除PID输出,就像将比例增益乘以2^13
因子。
有人可以帮助我理解这一点吗?谢谢。
解决方案
我绝不是控制理论方面的专家,但这是一种实用的方法。
这些浮点数只是通用数字,在您定义一个之前没有任何意义。通常,您会在编译时将它们与有意义的常量相乘,然后在编译时也转换为定点。
该常数应该是诸如 PWM、ADT 的分辨率或您希望整数值表示的任何值。定义这些值的确切含义,例如 PWM 占空比滴答声。使用方便 MCU 的单元。
你应该有一些类似的东西:
#define kp (int32_t)(2.7056f * PID_SCALE)
#define ki (int32_t)(0.0850f * PID_SCALE)
#define kd (int32_t)(0.0000f * PID_SCALE)
(注意:这可能会或可能不会强制/需要浮点库来与您的程序链接,即使您实际上并没有使用它。)
其中 PID_SCALE 是一些合适的整数常量。请注意,如果您正在寻找纯定点调节器,则不应在除上述定义之外的任何地方使用浮点类型。我怀疑您的问题可能与此有关,在这种情况下,问题在于 C 代码实现而不是控制理论和数学。
在伪代码中,您最终会得到以下内容:
p = kp * error
check that p is in range, if not set it to min/max
i = prev_i + error
check that i is in range, if not set it to min/max
prev_i = i
i = ki * i
pi = (p + i) / PID_SCALE
这样,您将每个项与常数相乘,分别跟踪I
,并在计算完成时进行除法。
推荐阅读
- javascript - 在 discord.js 中获取频道名称
- php - Google 日历 API 更新不会为已删除的事件返回错误
- jquery - 如何在电子中定义一个端点来监听一个发布请求?
- javascript - 连接丢失 - 套接字挂断
- visual-studio - 如何在 Visual Studio 中设置调试工作目录的默认路径
- matlab - 循环中的 if 语句
- next.js - Tailwind 的 JIT 模式在 Next JS 的本地主机预览中不起作用
- javascript - 将 Skype for Business 与我的 Web 应用程序集成
- bash - 如何将 let 命令输出分配给变量?
- ruby-on-rails - 迭代期间的 Ruby/Rails 6 求和