Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- keeps reactor working efficiently at all times; increases power load when necessary, goes idle at 90% power until below 10%
- -- updated to Bigger Reactors; see earlier versions for the big reactors versions (they exist)
- timer=nil
- local timeOperationTable={
- __sub=function(a,b)
- if not a or not b then return false end
- if b[2]>a[2] then
- return setmetatable({(a[1]-1)-b[1],(a[2]-b[2])%24},timeOperationTable)
- else
- return setmetatable({a[1]-b[1],a[2]-b[2]},timeOperationTable)
- end
- end,
- __tostring=function(t)
- return t[1]..' in-game days, ' .. math.floor(t[2]) ..' hours'
- end
- }
- local function findPeripherals() --searches around for reactor so the computer doesn't have to be placed in a particular way
- local reactor,terminal,monitor
- for k,v in pairs(peripheral.getNames()) do
- local t = peripheral.getType(v)
- if (t == "BiggerReactors_Reactor") then
- reactor = peripheral.wrap(v)
- print('reactor found!')
- elseif (peripheral.getType(v) == "openperipheral_glassesbridge") and (not terminal) then
- terminal = peripheral.wrap(v)
- print('terminal glasses terminal found!')
- elseif (peripheral.getType(v) == 'monitor') then
- monitor=peripheral.wrap(v)
- local x,y=monitor.getSize()
- monitor.setTextScale(math.min(5,math.max(x/60,0.5)))
- print('monitor found!')
- end
- end
- return reactor, terminal, monitor
- end
- local reactor,terminal,monitor=findPeripherals()
- local controlRodLevel,powerMode,tickCount,showAdvancedSettings=0,50,0,0,false
- local upTicks=0
- local integral=0
- local function powerPerc()
- return reactor.battery().stored()/reactor.battery().capacity()
- end
- local function reactivity()
- return reactor.fuelTank().fuelReactivity()
- end
- tempGuess = 1000
- tempGuessChange = 2
- reactivities = {}
- lastReactivity = 1
- bestFound = false
- powerMode = powerPerc() < 0.1
- local function reactorActivities()
- term.clear()
- tickCount=tickCount+1
- if powerMode and powerPerc()>0.99 then
- powerMode=false
- timeStarted={os.day(),os.time()} --I keep repeating this because not doing it (using a function) makes setmetatable apparently completely and utterly fail to work and gives me a bunch of other stupid crap
- setmetatable(timeStarted,timeOperationTable)
- elseif not powerMode and powerPerc()<0.1 then
- powerMode=true
- timeStarted={os.day(),os.time()}
- setmetatable(timeStarted,timeOperationTable)
- elseif powerPerc() < 0.001 then
- reactor.setActive(true)
- reactor.setAllControlRodLevels(0)
- end
- if powerMode then
- upTicks=upTicks+1
- reactor.setActive(true)
- local temperature = reactor.fuelTemperature()
- oldError=curError or 0
- curError = temperature - tempGuess or 0
- integral=integral+curError or 0
- derivative = tickCount>1 and curError - oldError or 0
- term.setCursorPos(1,1)
- term.write('Error: ' .. curError)
- term.setCursorPos(1,2)
- term.write('Integral: ' .. integral)
- term.setCursorPos(1,3)
- term.write('Derivative: ' .. derivative)
- term.setCursorPos(1,4)
- Kp=Kp or 0.1*interval
- Ki=Ki or 0.001*interval
- Kd=Kd or 0.001*interval
- local deltaControlRodLevel=(Kp*curError)+(Ki*integral)+(Kd*derivative)
- term.write('Control rod level change: ' .. deltaControlRodLevel)
- controlRodLevel = controlRodLevel+deltaControlRodLevel
- if controlRodLevel>100 or controlRodLevel<0 then
- integral=0
- end
- controlRodLevel = controlRodLevel>100 and 100 or controlRodLevel<0 and 0 or controlRodLevel
- term.setCursorPos(1,5)
- term.write('Current control rod level: ' .. controlRodLevel)
- term.setCursorPos(1,6)
- term.write('Uptime: ' .. timeOperationTable.__tostring(setmetatable({os.day(),os.time()},timeOperationTable)-timeStarted)) --wow the normal tostring should really work here
- term.setCursorPos(1,7)
- term.write('Uptime percentage: ' ..(upTicks*100)/tickCount..'%')
- if term.isColor() then
- term.setCursorPos(1,8)
- term.write('Error weight: ' .. Kp)
- term.setCursorPos(1,9)
- term.write('Integral weight: ' .. Ki)
- term.setCursorPos(1,10)
- term.write('Derivative weight: ' .. Kd)
- term.setCursorPos(1,11)
- term.write('Target temp: ' .. tempGuess)
- for i=8,11,1 do
- term.setCursorPos(30,i)
- term.write('+-')
- end
- end
- reactor.setAllControlRodLevels(controlRodLevel)
- else
- term.setCursorPos(1,1)
- term.write("Reactor's nearly full.")
- term.setCursorPos(1,2)
- term.write("Current status: off.")
- reactor.setActive(false)
- end
- end
- local function terminalActivities()
- terminal.clear()
- local fuel = reactor.fuelTank()
- local wastePercent=fuel.waste()/fuel.capacity()
- local fuelPercent=(fuel.waste()+fuel.fuel())/fuel.capacity()
- terminal.addBox(5,5,100,10,0xcc0000,0.8)
- terminal.addBox(5,5,math.floor(powerPerc()),10,0x00cc00,0.8)
- terminal.addBox(105,5,10,100,0xcccccc,0.8)
- terminal.addBox(105,5,10,controlRodLevel,0x303030,0.8)
- terminal.addBox(5,20,100,10,0x303030,0.8)
- terminal.addBox(5,20,math.min(math.floor(100*fuelPercent),100),10,0xcccc00,0.8)
- terminal.addBox(5,20,math.min(math.floor(100*wastePercent),100),10,0x00cccc,0.8)
- end
- local function monitorActivities()
- monitor.clear()
- monitor.setTextColor(colors.white)
- monitor.setCursorPos(1,1)
- monitor.write('Power mode: ')
- if powerMode then
- monitor.setTextColor(colors.green)
- monitor.write('On')
- monitor.setTextColor(colors.white)
- monitor.setCursorPos(1,4)
- monitor.write('Reactor working at ' .. 100-controlRodLevel .. '% capacity.')
- monitor.setCursorPos(1,5)
- monitor.write('Uptime: ' .. timeOperationTable.__tostring(setmetatable({os.day(),os.time()},timeOperationTable)-timeStarted))
- else
- monitor.setTextColor(colors.red)
- monitor.write('Off')
- monitor.setTextColor(colors.white)
- monitor.setCursorPos(1,4)
- monitor.write("Reactor's off.")
- monitor.setCursorPos(1,5)
- monitor.write('Downtime: ' .. timeOperationTable.__tostring(setmetatable({os.day(),os.time()},timeOperationTable)-timeStarted))
- end
- monitor.setCursorPos(1,2)
- monitor.write('Current temperature: ')
- monitor.setTextColor(curError>100 and colors.red or curError>10 and colors.orange or curError>-10 and colors.green or curError>-100 and colors.lightBlue or colors.cyan)
- monitor.write(reactor.fuelTemperature())
- monitor.setCursorPos(1,3)
- monitor.setTextColor(colors.white)
- monitor.write('Current energy storage: ' .. reactor.battery().stored())
- monitor.setCursorPos(1,6)
- monitor.write('Uptime percentage: ' ..(upTicks*100)/tickCount..'%')
- if monitor.isColor() then
- if showAdvancedSettings then
- monitor.setCursorPos(1,7)
- derweight='Derivative weight: ' .. Kd
- monitor.write('Error weight: ' .. Kp)
- monitor.setCursorPos(1,8)
- monitor.write('Integral weight: ' .. Ki)
- monitor.setCursorPos(1,9)
- monitor.write(derweight)
- monitor.setCursorPos(1,10)
- monitor.write("Target temp:" .. tempGuess)
- for i=7,10,1 do
- monitor.setCursorPos(string.len(derweight)+2,i)
- monitor.write('+-')
- end
- monitor.setCursorPos(1,11)--hate hardcoding hate hardcoding
- monitor.setTextColor(colors.yellow)
- monitor.write('Hide advanced settings')
- else
- monitor.setCursorPos(1,7)
- monitor.setTextColor(colors.yellow)
- monitor.write('Show advanced settings')
- end
- end
- end
- function monitorTouch(x,y)
- if showAdvancedSettings then -- all these global variables are going to make me sick
- if x==(string.len(derweight)>23 and string.len(derweight)+3 or string.len(derweight)+2) then
- if y==5 then
- Kp=Kp+0.05
- elseif y==6 then
- Ki=Ki+(0.005*interval)
- elseif y==7 then
- Kd=Kd+0.01
- elseif y==8 then
- tempGuess = tempGuess + 10
- end
- elseif x==((string.len(derweight)>22) and string.len(derweight)+4 or string.len(derweight)+3) then --in case you're wondering, I have no idea either, but it's necessary
- if y==5 then
- Kp=Kp-0.05
- elseif y==6 then
- Ki=Ki-(0.005*interval)
- elseif y==7 then
- Kd=Kd-0.01
- elseif y==8 then
- tempGuess = tempGuess - 10
- elseif y==9 then
- showAdvancedSettings=false
- end
- end
- else
- if y==5 then
- showAdvancedSettings=true
- end
- end
- end
- local args = {...}
- interval = args[1] or 0.5
- interval=tonumber(interval)
- if interval<0.5 then
- interval=0.5
- end
- local timeStarted={os.day(),os.time()}
- setmetatable(timeStarted,timeOperationTable)
- while reactor.connected() do
- if not timer then timer=os.startTimer(interval) end
- local event = {os.pullEvent()}
- if event[1]=='timer' and event[2]==timer then
- timer=nil
- pcall(reactorActivities)
- if terminal then
- pcall(terminalActivities)
- end
- if monitor then
- pcall(monitorActivities)
- end
- elseif event[1]=='mouse_click' then
- if event[2]=='1' then
- if event[3]==49 then
- if event[4]==5 then
- Kp=Kp+0.05
- elseif event[4]==6 then
- Ki=Ki+(0.005*interval)
- elseif event[4]==7 then
- Kd=Kd+0.01
- elseif event[4]==8 then
- tempGuess=tempGuess+10
- end
- elseif event[3]==50 then
- if event[4]==5 then
- Kp=Kp-0.05
- elseif event[4]==6 then
- Ki=Ki-(0.005*interval)
- elseif event[4]==7 then
- Kd=Kd-0.01
- elseif event[4]==8 then
- tempGuess=tempGuess-10
- end
- end
- end
- elseif event[1]=='monitor_touch' then
- pcall(monitorTouch,event[3],event[4])
- pcall(monitorActivities)
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement