我正在使用Teensy Atmega32u4的标准库实现PID控制。我的控制变量是PWM信号。我的过程变量是与10kohm电位计连接的直流电动机的当前角位置,该电位计的代码可读取0至270度刻度上的位置ADC输入。设定点是激光切割操纵杆,其手柄也连接到10kohm电位计,该电位计以与过程变量相同的方式读取角位置。
我的问题是如何实现控制方案的组成部分。积分项由下式给出:
Error = Set Point – Process Variable
Integral = Integral + Error
Control Variable = (Kp * Error) + (Ki * Integral)
但是我不确定如何计算积分部分。我们是否需要考虑样本之间经过的时间或仅考虑累积误差,然后将积分部分初始化为零,以便将其真正离散化?由于我使用的是C,因此积分项可以只是全局变量吗?
我在正确的轨道上吗?
答案 0 :(得分:0)
由于采样时间(计算PID的时间)始终是相同的,因此u是否用采样时间除以积分项并不重要,因为该采样时间只是一个Ki常数,但最好对积分进行除法用采样时间来表示,因此如果u更改采样时间,则PID随采样时间而变化,但这不是强制性的。
这是我为Python的Drone Robotics竞赛编写的PID_Calc函数。忽略“ [index]”,它是我制作的使我的代码通用的数组。
def pid_calculator(self, index):
#calculate current residual error, the drone will reach the desired point when this become zero
self.Current_error[index] = self.setpoint[index] - self.drone_position[index]
#calculating values req for finding P,I,D terms. looptime is the time Sample_Time(dt).
self.errors_sum[index] = self.errors_sum[index] + self.Current_error[index] * self.loop_time
self.errDiff = (self.Current_error[index] - self.previous_error[index]) / self.loop_time
#calculating individual controller terms - P, I, D.
self.Proportional_term = self.Kp[index] * self.Current_error[index]
self.Derivative_term = self.Kd[index] * self.errDiff
self.Intergral_term = self.Ki[index] * self.errors_sum[index]
#computing pid by adding all indiviual terms
self.Computed_pid = self.Proportional_term + self.Derivative_term + self.Intergral_term
#storing current error in previous error after calculation so that it become previous error next time
self.previous_error[index] = self.Current_error[index]
#returning Computed pid
return self.Computed_pid
这里是否链接到git hub中我的整个PID脚本。 看看对您有没有帮助。 按向上按钮ig = f喜欢答案,并像github中的脚本一样给我的Github存储库加注星标。 谢谢。
答案 1 :(得分:0)
要添加到先前的答案,还请考虑代码中整数结束的情况。如果出现结束,应该有某种机制可以重置积分项。另外,选择最大的可用数据类型以保留积分(和)项,以避免积分溢出(通常为long long
)。也要注意积分溢出。
如果您选择足够高的采样频率,则可以避免除法以减少所涉及的计算。但是,如果要尝试采样时间,则将采样时间保持为2的幂的倍数,以便可以通过移位运算来完成除法。例如,假设选择的采样时间为100ms,50ms,25ms,12.5ms。那么除法因子可以是1、1 << 1、1 << 2、1 << 4。
将PID控制器的所有关联变量都保留在单个struct
中,然后将此struct
用作在该PID上运行的函数中的参数非常方便。这样,代码将是模块化的,并且许多PID循环可使用相同的代码和struct
的不同实例在微控制器上同时运行。这种方法在大型机器人项目中特别有用,在该项目中,您可以使用单个CPU进行许多循环控制。