pythonobjectmodulepid-controller

How do i run part of a python module only once?


I'm making a PID controller for an RC car for cruise control in python, and wanted to separate it into a module, so the code main code looks cleaner. I can do this, but the problem would be that i have to create an object once for the PID controller and set its constants, and the remaining part of the code should run every time the function is called

This is my code for the PID controller:

from simple_pid import PID

def PID(rpm_array1, target_speed):
    Kp = 80
    Ki = 60
    Kd = 0.01
    Kf = 180 / target_speed

    pid = PID(Kp, Ki, Kd)
    pid.sample_time = 0.05

    avg_rpm_rear = (rpm_array1[2]+rpm_array1[3])/2
    speed = (avg_rpm_rear/60)*0.355; 

    pid.setpoint = target_speed

    x = pid(speed)

    pid_output = x + (target_speed * Kf)
    if(pid_output>0):
        throttle_target = pid_output+1455

    if throttle_target >= 2500 :
        throttle_target = 2500
    elif throttle_target <= 1455 :
        throttle_target = 1455

    return throttle_target

And i would like to use it like this:

import PID_module

while True:
    target_throttle = PID_module.PID(rpm_array1, target_speed)

What would be the proper way to do this?


Solution

  • I'm not really sure if this is what you're after but hopefully this gives you some idea of how to solve your problem.

    class PID:
        def __init__(self, Kp, Ki, Kd):
            self.Kp = Kp
            self.Ki = Ki
            self.Kd = Kd
    
        def throttle_target(self, rpm_array, target_speed):
            Kf = 180/target_speed
            avg_rpm_rear = (rpm_array[2]+rpm_array[3])/2
            speed = (avg_rpm_rear/60)*0.355
            pid_output = speed + (target_speed * Kf)
            if (pid_output > 0):
                target_throttle = pid_output + 1455
            
            if (target_throttle >= 2500):
                target_throttle = 2500
            elif (target_throttle <= 1455):
                target_throttle = 1455
            return target_throttle
    

    Run some test case:

    import numpy as np
    pid = PID(80, 60, 0.01)
    rpm_array = np.array([0,10,20,30,40,50])
    target_speed = 50
    x = pid.throttle_target(rpm_array, target_speed)
    print(x)
    

    This gives 1635.15.