C语言 在Teensy Atmega 32u4上实现PI控制

zd287kbt  于 2023-05-28  发布在  其他
关注(0)|答案(2)|浏览(223)

我正在使用Teensy Atmega32u4的标准库实现PID控制。我的控制变量是PWM信号。我的过程变量是直流电动机的当前角位置,该直流电动机与10kohm电位计连接,电位计的代码读取0至270度范围内的位置ADC输入。设定点是一个激光切割操纵杆,其手柄也连接到一个10kohm电位计,该电位计以与过程变量相同的方式读取角位置。
我的问题是如何实施控制方案的组成部分。积分项由下式给出:

Error = Set Point – Process Variable

Integral = Integral + Error

Control Variable = (Kp * Error) + (Ki * Integral)

但我不确定如何计算积分部分。我们是否需要考虑样本之间经过的时间量,或者仅仅是累积误差,并将积分部分初始化为零,这样它才是真正的离散化?因为我使用C,积分项可以只是一个全局变量吗?
我说的对吗?

uqjltbpv

uqjltbpv1#

由于采样时间(计算PID的时间)总是相同的,因此u是否将积分项除以采样时间并不重要,因为该采样时间将仅充当Ki常数,但是最好将积分项除以采样时间,使得如果u改变采样时间,则PID随采样时间而改变,但这不是强制性的。
这是我为我的无人机机器人竞赛用Python编写的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 u,就像答案一样,并像github中的脚本一样,在我的Github存储库i u上星号。谢谢你。

mqkwyuun

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来控制许多循环。

相关问题