0

我正在使用 Teensy Atmega32u4 的标准库实现 PID 控制。我的控制变量是 PWM 信号。我的过程变量是直流电机的当前角位置,它与一个 10kohm 电位器接口,其代码读取 0 到 270 度范围内的位置 ADC 输入。设定点是一个激光切割操纵杆,其手柄也连接到一个 10kohm 电位器,该电位器以与过程变量相同的方式读取角位置。

我的问题是如何实现控制方案的组成部分。积分项由下式给出:

Error = Set Point – Process Variable

Integral = Integral + Error

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

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

我在正确的轨道上吗?

4

2 回答 2

0

要添加到先前的答案,还要考虑代码中积分结束的情况。如果发生饱和,应该有一些机制来重置积分项。还要选择最大的可用数据类型以保留整数(总和)项,以避免整数溢出(通常为long long)。还要注意积分溢出。

如果您选择了足够高的采样频率,则可以避免除法以减少所涉及的计算。但是,如果要对采样时间进行实验,请将采样时间保持为 2 的幂的倍数,以便通过移位操作完成除法。例如,假设选择的采样时间为 100ms、50ms、25ms、12.5ms。那么分割因子可以是1、1<<1、1<<2、1<<4。

将 PID 控制器的所有相关变量保存在一个 中很方便struct,然后将其struct用作在该 PID 上运行的函数中的参数。这样,代码将是模块化的,并且许多 PID 循环可以同时在微控制器上运行,使用相同的代码和不同的struct. 这种方法在大型机器人项目中特别有用,在这些项目中,您需要使用单个 CPU 控制多个循环。

于 2019-03-07T09:17:32.820 回答
0

由于采样时间(计算 PID 之后的时间)始终相同,因此是否将积分项除以采样时间并不重要,因为该采样时间将仅充当 Ki 常数,但最好将积分项除以采样时间,因此如果您更改采样时间,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=fu 喜欢答案,然后像 github 中的脚本一样为我的 Github 存储库加注星标。谢谢你。

于 2019-03-07T05:26:11.007 回答