Created
March 14, 2017 09:08
-
-
Save lashtear/350f6529209005237a086c08e00a3c47 to your computer and use it in GitHub Desktop.
Darklight's reactor pid stuff
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local component = require("component") | |
local computer = require("computer") | |
function getPIDObject(kp, ki, kd, minclamp, maxclamp, inputMethod, outputMethod) | |
local retObj = {} | |
retObj.kp = kp | |
retObj.ki = ki | |
retObj.kd = kd | |
retObj.minclamp = minclamp | |
retObj.maxclamp = maxclamp | |
retObj.setPoint = 0 | |
retObj.inputMethod = inputMethod | |
retObj.outputMethod = outputMethod | |
retObj.outputValue = 0 | |
retObj.localErrorSum = 0 | |
retObj.localErrorLast = 0 | |
retObj.localLastUpdateTime = computer.uptime() | |
retObj.debug = false | |
retObj.update = function() | |
--K component | |
local error = retObj.setPoint - retObj.inputMethod() | |
local timeChange = computer.uptime() - retObj.localLastUpdateTime | |
--D component | |
local deriv = 0 | |
if (timeChange > 0) then | |
deriv = (error - retObj.localErrorLast) / timeChange | |
end | |
if (retObj.debug) then | |
print("error: " .. error) | |
print("timeChangeL " .. timeChange) | |
print("ki: " .. retObj.ki) | |
end | |
retObj.localErrorSum = retObj.localErrorSum + (error * timeChange * retObj.ki) | |
--I component | |
if (retObj.localErrorSum > retObj.maxclamp) then | |
retObj.localErrorSum = retObj.maxclamp | |
end | |
if (retObj.localErrorSum < retObj.minclamp) then | |
retObj.localErrorSum = retObj.minclamp | |
end | |
retObj.outputValue = retObj.kp * error + retObj.localErrorSum - kd * deriv | |
if (retObj.outputValue > retObj.maxclamp) then | |
retObj.outputValue = retObj.maxclamp | |
end | |
if (retObj.outputValue < retObj.minclamp) then | |
retObj.outputValue = retObj.minclamp | |
end | |
if (retObj.outputMethod ~= nil) then | |
if (retObj.debug) then | |
print("Outputting " .. retObj.outputValue) | |
end | |
retObj.outputMethod(retObj.outputValue) | |
end | |
if (retObj.debug) then | |
print("kp: " .. (error * retObj.kp)) | |
print("ki: " .. retObj.localErrorSum) | |
print("kd: " .. deriv * retObj.kd) | |
end | |
retObj.localLastUpdateTime = computer.uptime() | |
retObj.localErrorLast = error | |
end | |
retObj.set = function(newSetPoint) | |
retObj.setPoint = newSetPoint | |
end | |
retObj.getOutput = function() | |
return outputValue | |
end | |
return retObj | |
end | |
if not (component.isAvailable("br_reactor")) then | |
print("Reactor not detected") | |
return 0 | |
end | |
if not (component.isAvailable("br_turbine")) then | |
print("Turbine not detected") | |
return 0 | |
end | |
local reactor = component["br_reactor"] | |
local turbine = component["br_turbine"] | |
local turbineSpeedPID = getPIDObject(1, 1, 1, 0, 1000, turbine.getRotorSpeed, turbine.setFluidFlowRateMax) | |
local reactorTempPID = getPIDObject(-0.1, -0.1, -0.1, 0, 100, reactor.getFuelTemperature, reactor.setAllControlRodLevels) | |
local reactorSteamPID = getPIDObject(0.01, 0.001, 0.01, 99, 250, reactor.getHotFluidAmount, function(newOutput) reactorTempPID.setPoint = newOutput end) | |
turbineSpeedPID.setPoint = 900 | |
reactorTempPID.setPoint = 200 | |
reactorSteamPID.setPoint = reactor.getHotFluidAmountMax() / 2 | |
function updateLoop() | |
turbineSpeedPID.update() | |
reactorSteamPID.update() | |
reactorTempPID.update() | |
print("CurrentTemp: " .. reactor.getFuelTemperature()) | |
print("SetTemp: " .. reactorTempPID.setPoint) | |
print("Steam: " .. (reactor.getHotFluidAmount() * 100 / reactor.getHotFluidAmountMax())) | |
end | |
while true do | |
updateLoop() | |
os.sleep(0.5) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment