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?
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
.