neuroticfox

AA reactorTest Redux

Jul 10th, 2022 (edited)
473
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.95 KB | None | 0 0
  1. os.execute(cls)
  2. local component = require("component")
  3. local tty       = require("tty")
  4.  
  5. -- Wrap Reactor Components -------------------------------------------------
  6. local reactor     = component.draconic_reactor
  7.  
  8. --Change the addresses to match the ones you get from using the analyzer on the adapters connected to your flux gates
  9. local flux_gates = {}
  10. for x,y in pairs(component.list("flux_gate")) do
  11.   flux_gates[#flux_gates+1] = x
  12. end
  13. if #flux_gates < 2 then
  14.   print("Not enough flux gates connected; please connect inflow and outflow flux gates with Adapter blocks.")
  15.   os.exit()
  16. end
  17. local inputFlux = component.proxy(flux_gates[1])
  18. local outputFlux = component.proxy(flux_gates[2])
  19. outputFlux.setOverrideEnabled(true)
  20. inputFlux.setOverrideEnabled(true)
  21.  
  22. -- Control Variables--------------------------------------------------------
  23. local tArgs = {...}
  24. local targetTemp = tonumber(tArgs[1]) or 8000  -- Desired temperature
  25. local targetShieldPercent = tonumber(tArgs[2]) or 15 -- Desired shield strength
  26. local swapFlux = tonumber(tArgs[3]) or 1 -- Swap input and output flux gates
  27. local reactorOutputMultiplier = tonumber(tArgs[4]) or 1 -- Reactor output multiplier (mod cfg)
  28. local targetShield = (targetShieldPercent / 100)
  29. if targetTemp < 2500 then targetTemp = 2500 elseif targetTemp > 15000 then targetTemp = 15000 end
  30. if targetShield < 0.00001 then targetShield = 0.00001 elseif targetShield > 1 then targetShield = 1 end
  31. if swapFlux < 1 then swapFlux = 1 elseif swapFlux > 2 then swapFlux = 2 end
  32.  
  33. -- Swap Flux Gates----------------------------------------------------------
  34.  
  35. local oldAddress = inputFlux.address
  36. if swapFlux == 2 then
  37.      inputFlux = component.proxy(outputFlux.address)
  38.      outputFlux = component.proxy(oldAddress)
  39.  end
  40.  
  41.  
  42. -- This is 1 by default, but changes based on modpack.
  43. -- Check "Mod Options > Draconic Evolution > Tweaks > reactorOutputMultiplier" to find what it is and change the variable below to match.
  44.  
  45. local function update()
  46.  
  47.   while true do
  48.     tty.clear()
  49.      
  50.     local reactorInfo = reactor.getReactorInfo() -- Get reactor status
  51.  
  52.     if reactorInfo.temperature < 2000 then
  53.         reactor.chargeReactor()
  54.      end
  55.      if reactorInfo.temperature >= 2000 and reactorInfo.status ~= "stopping"  then
  56.         reactor.activateReactor()
  57.     end
  58.  
  59.     -- CALCULATIONS ---------------------------------------
  60.  
  61.     -- Reactor equation variables
  62.     local targetTemp50  = math.min((targetTemp / 10000) * 50, 99)
  63.     local coreSat       = reactorInfo.energySaturation / reactorInfo.maxEnergySaturation
  64.     local convLVL       = (reactorInfo.fuelConversion / reactorInfo.maxFuelConversion * 1.3) - 0.3
  65.  
  66.     -- Calculate the temperature rise resistance for the reactor at the desired temperature.
  67.     local targetTempResist = ((targetTemp50^4) / (100 - targetTemp50))
  68.           print(string.format("Temp Resist for target temp %d (%d): %.2f", targetTemp, targetTemp50, targetTempResist))
  69.  
  70.     -- Calculate the temperature rise exponential needed to reach the desired temperature
  71.     local targetTempExpo = -(targetTempResist*convLVL) - 1000*convLVL + targetTempResist
  72.           print(string.format("Temp expo for convLVL %.2f: %.2f", convLVL, targetTempExpo))
  73.  
  74.     -- Calculate the saturation level needed to produce the required tempRiseExpo
  75.     local term1 = 1334.1-(3*targetTempExpo)
  76.     local term2 = (1200690-(2700*targetTempExpo))^2
  77.     local term3 = ((-1350*targetTempExpo)+(((-4*term1^3+term2)^(1/2))/2)+600345)^(1/3)
  78.     local targetNegCSat = -(term1/(3*term3))-(term3/3)
  79.           print(string.format("NegCSat for tempExpo %.2f: %.2f", targetTempExpo, targetNegCSat))
  80.  
  81.     -- Saturation received from above equation needs to be reformatted to a more useful form
  82.     local targetCoreSat = 1 - (targetNegCSat/99)
  83.     local targetSat = targetCoreSat * reactorInfo.maxEnergySaturation
  84.           print(string.format("Saturation needed for zero rise: %d (%3.2f%%)", targetSat, targetCoreSat*100))
  85.  
  86.     -- Calculate the difference between where saturation is and where it needs to be
  87.     local saturationError = reactorInfo.energySaturation - targetSat
  88.           print(string.format("Error between current saturation and target saturation: %d\n", saturationError))
  89.  
  90.     -- Calculate field drain
  91.     local tempDrainFactor = 0
  92.     if reactorInfo.temperature > 8000 then
  93.       tempDrainFactor = 1 + ((reactorInfo.temperature-8000)^2 * 0.0000025)
  94.     elseif reactorInfo.temperature > 2000 then
  95.       tempDrainFactor = 1
  96.     elseif reactorInfo.temperature > 1000 then
  97.       tempDrainFactor = (reactorInfo.temperature-1000)/1000
  98.     end
  99.     print(string.format("Current temp drain factor for temp %d is %1.2f", reactorInfo.temperature, tempDrainFactor))
  100.    
  101.     local baseMaxRFt = (reactorInfo.maxEnergySaturation / 1000) * reactorOutputMultiplier * 1.5
  102.     local fieldDrain = math.min(tempDrainFactor * math.max(0.01, (1-coreSat)) * (baseMaxRFt / 10.923556), 2147000000)
  103.           print(string.format("Current field drain is %d RF/t", reactorInfo.fieldDrainRate))
  104.     local fieldNegPercent = 1 - targetShield
  105.           print(string.format("fieldNegPercent is %d", fieldNegPercent))
  106.     --local fieldInputRate = fieldDrain / fieldNegPercent
  107.     local fieldStrengthError = (reactorInfo.maxFieldStrength * targetShield) - reactorInfo.fieldStrength
  108.           print(string.format("Error between current field strength and target strength: %d", fieldStrengthError))
  109.     local requiredInput = math.min((reactorInfo.maxFieldStrength * reactorInfo.fieldDrainRate) / (reactorInfo.maxFieldStrength - reactorInfo.fieldStrength), reactorInfo.maxFieldStrength - reactorInfo.fieldStrength)
  110.           print(string.format("Required input to counter field drain: %d RF/t\n", requiredInput))
  111.  
  112.     -------------------------------------------------------    
  113.  
  114.     if reactorInfo.status == "running" then
  115.  
  116.       if reactorInfo.fuelConversion / reactorInfo.maxFuelConversion > 0.85 then
  117.         reactor.stopReactor()
  118.       end
  119.  
  120.       -- Control the output gate to drain the reactor to needed saturation,
  121.       -- min function used to prevent from draining the reactor too fast
  122.       local outputNeeded = math.min(saturationError, (reactorInfo.maxEnergySaturation/40))-- + reactorInfo.generationRate
  123.       outputFlux.setFlowOverride(outputNeeded)
  124.       print(string.format("Setting output flux gate to %d RF/t", outputNeeded))
  125.  
  126.       inputFlux.setFlowOverride(math.min(fieldStrengthError + requiredInput, reactorInfo.maxFieldStrength))
  127.       print(string.format("Setting input flux gate to %d RF/t", requiredInput))
  128.  
  129.     elseif reactorInfo.status == "warming_up" then
  130.  
  131.       outputFlux.setFlowOverride(0)
  132.       inputFlux.setFlowOverride(5000000)
  133.       print(string.format("Reactor Charging; flooding reactor"))
  134.  
  135.     elseif reactorInfo.status == "stopping" then
  136.  
  137.       outputFlux.setFlowOverride(0)
  138.       inputFlux.setFlowOverride(requiredInput)
  139.       print(string.format("Setting input flux gate to %d RF/t", inputFlux.getSignalLowFlow()))
  140.  
  141.     end
  142.  
  143.     os.sleep(0.05)
  144.   end
  145. end
  146.  
  147. update()
Add Comment
Please, Sign In to add comment