Skip to content

Instantly share code, notes, and snippets.

@lashtear
Created March 14, 2017 09:08
Show Gist options
  • Save lashtear/350f6529209005237a086c08e00a3c47 to your computer and use it in GitHub Desktop.
Save lashtear/350f6529209005237a086c08e00a3c47 to your computer and use it in GitHub Desktop.
Darklight's reactor pid stuff
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