直流电机的PID控制器

2024-05-18 19:55:45 发布

您现在位置:Python中文网/ 问答频道 /正文

我想创建一个PID控制器。

作为输入,我有两个csv文件,一个是我想要实现的行为,另一个是直流电机的电流和电压的实际值。我可以读取csv文件上的数据,然后使用PID控制器(代码如下)。

因为我刚开始使用Python,所以我想知道如何使用这个类(PID)来获取csv文件的每个电流和电压值,并绘制两个不同的轨迹(从我的一个输入文件中得到的期望轨迹以及带有PID控制器的实际轨迹)。

class PID:
    """
    Discrete PID control
    """

    def __init__(self, P=2.0, I=0.0, D=1.0, Derivator=0, Integrator=0, Integrator_max=500, Integrator_min=-500):

        self.Kp=P
        self.Ki=I
        self.Kd=D
        self.Derivator=Derivator
        self.Integrator=Integrator
        self.Integrator_max=Integrator_max
        self.Integrator_min=Integrator_min

        self.set_point=0.0
        self.error=0.0

    def update(self,current_value):
        """
        Calculate PID output value for given reference input and feedback
        """

        self.error = self.set_point - current_value

        self.P_value = self.Kp * self.error
        self.D_value = self.Kd * ( self.error - self.Derivator)
        self.Derivator = self.error

        self.Integrator = self.Integrator + self.error

        if self.Integrator > self.Integrator_max:
            self.Integrator = self.Integrator_max
        elif self.Integrator < self.Integrator_min:
            self.Integrator = self.Integrator_min

        self.I_value = self.Integrator * self.Ki

        PID = self.P_value + self.I_value + self.D_value

        return PID

    def setPoint(self,set_point):
        """
        Initilize the setpoint of PID
        """
        self.set_point = set_point
        self.Integrator=0
        self.Derivator=0

    def setIntegrator(self, Integrator):
        self.Integrator = Integrator

    def setDerivator(self, Derivator):
        self.Derivator = Derivator

    def setKp(self,P):
        self.Kp=P

    def setKi(self,I):
        self.Ki=I

    def setKd(self,D):
        self.Kd=D

    def getPoint(self):
        return self.set_point

    def getError(self):
        return self.error

    def getIntegrator(self):
        return self.Integrator

    def getDerivator(self):
        return self.Derivator

Tags: 文件csvselfreturnvaluedefintegratorerror
2条回答

基本上,它看起来是通过先用一些参数实例化它,然后反复调用update(val)来运行的。我想是这样的:

readings = [1, 3, 5, 7, 12, 15, 17, 19, 27, 24, 24, 26]
x = PID(2.5, .1, 1.5, Integrator_min=-100)

for reading in readings:
    current_pid = x.update(reading)
    # if you want to know something else, like the error, you do
    err = x.getError()

顺便说一下,它不是用很好的Python风格编写的。例如,所有这些setter和getter方法都会分散注意力。

我知道这是个老问题,但我会尽量补充@tom10的答案以供参考

如果你在树莓pi上尝试这个,我假设你想要一个速度PID控制器,你可以使用这个代码

你可以在这个优秀的教程中阅读中断是如何工作的

http://raspi.tv/2013/how-to-use-interrupts-with-python-on-the-raspberry-pi-and-rpi-gpio-part-2

您还可以看到如何在这个链接上使用PWM类

https://sourceforge.net/p/raspberry-gpio-python/wiki/PWM/

import pid
import time

dc_pid = pid.PID(2.5, .1, 1.5)


GPIO.setmode(GPIO.BOARD)
GPIO.setup(self.pin, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.add_event_detect(22, GPIO.FALLING, callback=self.interrupt_function,bouncetime=5) #GPIO where encoders signal is conected


def interrupt_function():

    """on this function you make calculations depending on what PID you are planning to use , for example if you are planning to do a Velocity PID , and the encoder signal is connected to a GPIO pin you should take time stamps and convert signal frecuency to velocity , save it as a variable and then update that value to the PID controller"""
   error = dc_pid.update(velocity) 
   #once you get your error you actuate it to your DC motor , via PWM , previously mapped function depending on your dc motor voltage and velocity it has depending on the PWM's duty cycle
   pwm.ChangeDutyCycle(error/15) # or whatever your convertion is 


readings = [1, 3, 5, 7, 12, 15, 17, 19, 27, 24, 24, 26]
initial_time = time.time
for reading in readings:
    dc_pid.setPoint(reading)
    time.sleep(10)

在新文件中使用此代码,它将基于每10秒的csv读数设置一个新的设定点,并启动该速度或位置,或您希望PID控制的任何东西,每次中断pin 22时更新其值

希望它能帮助未来想知道如何使用python实现PID的人

考虑到你应该首先设计你的控制回路,定义你的PID输入,以及如何管理输出

相关问题 更多 >

    热门问题