Python中的PID库

  • Post author:
  • Post category:python




Python中的PID库

@(树莓派学习笔记)



PID

加入了条件积分抗积分饱和,加入了一阶低通滤波滤除高频噪声。

链接:https://github.com/EduardoNigro/Things-DAQ-Code/blob/main/Digital-PID/gpiozero_extended.py




simple_pid(连续PID)

API文档:

https://simple-pid.readthedocs.io/en/latest/simple_pid.html#module-simple_pid.PID

源码文档:

https://simple-pid.readthedocs.io/en/latest/_modules/simple_pid/PID.html#PID.

call



介绍


class simple_pid.PID.PID(Kp=1.0, Ki=0.0, Kd=0.0, setpoint=0, sample_time=0.01, output_limits=(None, None), auto_mode=True, proportional_on_measurement=False, error_map=None)


Parameters:


Kp

:比例增益 Kp 的值


Ki

: 积分增益 Ki 的值


Kd

:导数增益 Kd 的值


setpoint

:PID 将尝试达到的初始设定值


sample_time

:控制器在生成新输出值之前应等待的时间(以秒为单位)。PID在不断调用时(例如在循环期间)效果最佳,但设置了采样时间,以便每次更新之间的时间差(接近)恒定。如果设置为“None”,则 PID 将在每次调用时计算新的输出值。


output_limits

:要使用的初始输出限制,以具有 2 个元素的可迭代形式给出,例如:(下部、上部)。输出永远不会低于下限或高于上限。也可以将任一限制设置为“None”,以在该方向上没有限制。设置输出限值还可以避免积分饱和,因为积分项永远不会超过极限。


auto_mode

:是否应启用控制器(自动模式)或不使用控制器(手动模式)


proportional_on_measurement

:是否应直接在输入上计算比例项,而不是在误差上计算(这是传统方法)。使用按比例测量可避免某些类型系统的过冲。


error_map

:将错误值转换为另一个受约束值的函数。


reset()

:重置 PID 控制器内部。

这会将每个项设置为 0,并清除积分、最后一个输出和最后一个输入(导数计算)。


set_auto_mode(enabled, last_output=None)

:启用或禁用 PID 控制器,可选择设置最后一个输出值。如果某些系统已被手动控制并且PID应该接管,这将非常有用。在这种情况下,通过将自动模式设置为 False 来禁用 PID,稍后当 PID 应重新打开时,传递最后一个输出变量(控制变量),当 PID 设置为自动模式时,它将被设置为起始 项。


tunings

:控制器用作元组的调优:(Kp,Ki,Kd)。


from simple_pid import PID
pid = PID(1, 0.1, 0.05, setpoint=1)
v = controlled_system.update(0)
while True:
control = pid(v)
v = controlled_system.update(control)



示例

import time
import matplotlib.pyplot as plt
from simple_pid import PID


class WaterBoiler:
    """
    Simple simulation of a water boiler which can heat up water
    and where the heat dissipates slowly over time
    """

    def __init__(self):
        self.water_temp = 20

    def update(self, boiler_power, dt):
        if boiler_power > 0:
            # Boiler can only produce heat, not cold
            self.water_temp += 1 * boiler_power * dt

        # Some heat dissipation
        self.water_temp -= 0.02 * dt
        return self.water_temp


if __name__ == '__main__':
    boiler = WaterBoiler()
    water_temp = boiler.water_temp

    pid = PID(5, 0.01, 0.1, setpoint=water_temp)
    pid.output_limits = (0, 100)

    start_time = time.time()
    last_time = start_time

    # Keep track of values for plotting
    setpoint, y, x = [], [], []

    while time.time() - start_time < 10:
        current_time = time.time()
        dt = current_time - last_time

        power = pid(water_temp)
        water_temp = boiler.update(power, dt)

        x += [current_time - start_time]
        y += [water_temp]
        setpoint += [pid.setpoint]

        if current_time - start_time > 1:
            pid.setpoint = 100

        last_time = current_time

    plt.plot(x, y, label='measured')
    plt.plot(x, setpoint, label='target')
    plt.xlabel('time')
    plt.ylabel('temperature')
    plt.legend()
    plt.show()



pyPID(离散PID)

链接:https://github.com/egrissino/pyPID




ivPID(连续PID)

链接:https://github.com/ivmech/ivPID



版权声明:本文为m0_57608081原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。