![]() |
|
PID Problem - Printable Version +- LogicMachine Forum (https://forum.logicmachine.net) +-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1) +--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8) +--- Thread: PID Problem (/showthread.php?tid=3167) |
PID Problem - MantasJ - 13.02.2021 Hello guys, I'm trying to create a PID controller. I need to have 12 controllers - 1 P, 1 PI and 10 PID with D gain values ranging from 0.1 to 1. P and PI controllers has to have P gain according to 6K, and PI controller I gain has to be according to 150min, so (6K/150min). Here is my script: Code: local P_value = 6
local I_value = 150
local kp = 1/P_value
local ki = (kp/(I_value*60))*100
if not P then
P = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_P_Output',
kp = kp,
ki = 0,
kd = 0
})
end
P:run()
if not PI then
PI = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PI_Output',
kp = kp,
ki = ki,
kd = 0
})
end
PI:run()
if not PID then
for i = 1, 10, 1 do
PID = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID' .. i .. '_Output',
kp = kp,
ki = ki,
kd = 0.1 * i
})
PID:run()
end
endWhat I end up getting on P and PI controller outputs is 0, and on PID outputs I don't get anything with current setpoint being 24C while current temperature is 22.5C, so it's not correct. My resident script sleep time is 10sec, I have added PID algorithm in library so the problem is not coming from there. What is going on here? What am I missing? RE: PID Problem - MantasJ - 13.02.2021 So I've changed the script a bit, it now looks like this: Code: local P_value = 6
local I_value = 150
local kp_value = 0.16
local ki_value = 0.0017
if not P then
P = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_P_Output',
kp = kp_value,
ki = 0,
kd = 0
})
PI = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PI_Output',
kp = kp_value,
ki = ki_value,
kd = 0
})
PID1 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID1_Output',
kp = kp_value,
ki = ki_value,
kd = 0.1
})
PID2 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID2_Output',
kp = kp_value,
ki = ki_value,
kd = 0.2
})
PID3 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID3_Output',
kp = kp_value,
ki = ki_value,
kd = 0.3
})
PID4 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID4_Output',
kp = kp_value,
ki = ki_value,
kd = 0.4
})
PID5 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID5_Output',
kp = kp_value,
ki = ki_value,
kd = 0.5
})
PID6 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID6_Output',
kp = kp_value,
ki = ki_value,
kd = 0.6
})
PID7 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID7_Output',
kp = kp_value,
ki = ki_value,
kd = 0.7
})
PID8 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID8_Output',
kp = kp_value,
ki = ki_value,
kd = 0.8
})
PID9 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID9_Output',
kp = kp_value,
ki = ki_value,
kd = 0.9
})
PID10 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID10_Output',
kp = kp_value,
ki = ki_value,
kd = 1
})
end
P:run()
PI:run()
PID1:run()
PID2:run()
PID3:run()
PID4:run()
PID5:run()
PID6:run()
PID7:run()
PID8:run()
PID9:run()
PID10:run()Setpoint is 23C and current temperature is 22.3C. All controllers give out 0 percent. Why? I have tried enabling/disabling the script, changing kp and ki values with and without calculation formula (example above is without) - didn't help. RE: PID Problem - admin - 15.02.2021 Your Kp value is too low. Set all gains to 1 and see how the system operates. Note that for correct PID loop operation it must be connected an actual output that affects the temperature, otherwise it's pointless. RE: PID Problem - MantasJ - 15.02.2021 Hello, admin, Thanks for the response! What do you mean by kp value too low? As I've mentioned before, I'm trying to achieve (6K/150min) control, which would translate to kp value being 0.16 (1/6K-->0.16), or I'm calculating something wrong? I've tried putting in kp equal to 1, but all outputs still give out 0. Current temp - 22.5C, setpoint - 23C. I'm trying to simulate different controls, output isn't connected to valves right now, but I just need some information from trend logs for now. I also added 1sec delay after each run: Code: local P_value = 6
local I_value = 150
local kp_value = 1
local ki_value = 0.0017
local delay = 1
if not P then
P = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_P_Output',
kp = kp_value,
ki = 0,
kd = 0
})
PI = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PI_Output',
kp = kp_value,
ki = ki_value,
kd = 0
})
PID1 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID1_Output',
kp = kp_value,
ki = ki_value,
kd = 0.1
})
PID2 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID2_Output',
kp = kp_value,
ki = ki_value,
kd = 0.2
})
PID3 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID3_Output',
kp = kp_value,
ki = ki_value,
kd = 0.3
})
PID4 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID4_Output',
kp = kp_value,
ki = ki_value,
kd = 0.4
})
PID5 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID5_Output',
kp = kp_value,
ki = ki_value,
kd = 0.5
})
PID6 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID6_Output',
kp = kp_value,
ki = ki_value,
kd = 0.6
})
PID7 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID7_Output',
kp = kp_value,
ki = ki_value,
kd = 0.7
})
PID8 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID8_Output',
kp = kp_value,
ki = ki_value,
kd = 0.8
})
PID9 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID9_Output',
kp = kp_value,
ki = ki_value,
kd = 0.9
})
PID10 = PID:init({
current = 'RTC05_Current_Temperature',
setpoint = 'RTC05_Setpoint_Temperature_Status',
output = 'BD_PID10_Output',
kp = kp_value,
ki = ki_value,
kd = 1
})
end
P:run()
os.sleep(delay)
PI:run()
os.sleep(delay)
PID1:run()
os.sleep(delay)
PID2:run()
os.sleep(delay)
PID3:run()
os.sleep(delay)
PID4:run()
os.sleep(delay)
PID5:run()
os.sleep(delay)
PID6:run()
os.sleep(delay)
PID7:run()
os.sleep(delay)
PID8:run()
os.sleep(delay)
PID9:run()
os.sleep(delay)
PID10:run()Update: Okay, so I've set ki to 1 aswell, and now PI and PID controllers give out 11 percent, and add 10 percent every minute, which is way too fast. How do I achieve (6K/150min) control? And why P controller still gives out 0? RE: PID Problem - admin - 15.02.2021 Since the output is not connected your test won't show any real data because PID requires feedback from the system to operate. As I've mentioned start with a single PID controller with all 3 gains set to 1. You have to see how it operates in real conditions before applying any tuning. Trend log will help you to see how high the system oscillations are. RE: PID Problem - MantasJ - 15.02.2021 Ok, but still, I don't understand some points:
RE: PID Problem - admin - 15.02.2021 When only Kp is set each run will change the output value by the delta between the current temperature and the setpoint. You might need several runs for the output value to change if the delta is small. Resident script sleep time controls how frequently the algorithm runs. You can edit the PID library and add log(self.output) before self etoutput() to see the raw output value (floating point).As I've already told simulating PID like this is pointless. In real world situation changing the output value will change the temperature so the algorithm will produce different output values based on how the temperature changes. It's possible to make a script that will change the temperature based on the output value to check how gain values affect the speed of change. But you need a different sets of objects for each PID controller and it will still be very approximate unless you have some complex calculations that can simulate system inertia which is quite big for underfloor heating. |