我正在使用Teensy Atmega32u4的标准库实现PID控制。我的控制变量是PWM信号。我的过程变量是直流电动机的当前角位置,该直流电动机与10kohm电位计连接,电位计的代码读取0至270度范围内的位置ADC输入。设定点是一个激光切割操纵杆,其手柄也连接到一个10kohm电位计,该电位计以与过程变量相同的方式读取角位置。
我的问题是如何实施控制方案的组成部分。积分项由下式给出:
Error = Set Point – Process Variable
Integral = Integral + Error
Control Variable = (Kp * Error) + (Ki * Integral)
但我不确定如何计算积分部分。我们是否需要考虑样本之间经过的时间量,或者仅仅是累积误差,并将积分部分初始化为零,这样它才是真正的离散化?因为我使用C,积分项可以只是一个全局变量吗?
我说的对吗?
2条答案
按热度按时间uqjltbpv1#
由于采样时间(计算PID的时间)总是相同的,因此u是否将积分项除以采样时间并不重要,因为该采样时间将仅充当Ki常数,但是最好将积分项除以采样时间,使得如果u改变采样时间,则PID随采样时间而改变,但这不是强制性的。
这是我为我的无人机机器人竞赛用Python编写的PID_Calc函数。忽略“[index]”,这是我为使代码通用而创建的数组。
这里是我在git hub中的整个PID脚本的链接。看看这是否对你有帮助。按下向上按钮IG=f u,就像答案一样,并像github中的脚本一样,在我的Github存储库i u上星号。谢谢你。
mqkwyuun2#
为了补充前面的答案,还考虑在代码中积分结束的情况。如果出现饱和,应该有某种机制来重置积分项。还要选择最大的可用数据类型来保留整数(和)项,以避免整数溢出(通常为
long long
)。还要注意积分溢出。如果选择足够高的采样频率,则可以避免除法,以减少所涉及的计算。但是,如果要试验采样时间,请将采样时间保持为2的幂的倍数,以便可以通过移位运算完成除法。例如,假设所选择的采样时间是100 ms、50 ms、25 ms、12.5ms。则划分因子可以是1、1<<1、1<<2、1<<4。
将PID控制器的所有相关变量保存在单个
struct
中,然后将此struct
用作对该PID进行操作的函数中的参数,这是很方便的。这样,代码将是模块化的,许多PID回路可以同时在微控制器上运行,使用相同的代码和不同的struct
示例。这种方法在大型机器人项目中特别有用,在这些项目中,您需要使用单个CPU来控制许多循环。