我正在使用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
,并在计算完成后除法。
在开发定点PID补偿器时,将根据每个参数所需的调谐范围以及误差信号的大小/范围来选择2^13
。无论哪种情况,PID补偿器的输出都将是-32768...32767(或-1.0至1.0(,它将直接缩放以适应控制输出(即12位PWM寄存器0至4096,0至100%(。
通常,不会将 PID 补偿器的输出转换回浮点数,除非出于遥测目的。
此外,正如其他人所说,请注意补偿器本身的溢出/饱和点,否则一个项可能会主导您的输出。