AlexMastang

RC_RBMK

Aug 24th, 2025
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.97 KB | None | 0 0
  1. local comp = require("component")
  2. local side = require("sides")
  3. local term = require("term")
  4. local os   = require("os")
  5.  
  6. local batteria = comp.ntm_energy_storage
  7. local reattore = comp.rbmk_console
  8. local red_funz = comp.proxy("e9456b26-31d7-484f-8f07-958b6075c0c7")
  9. local red_alar = comp.proxy("3d402465-3c61-4050-9abf-9144189821a0")
  10.  
  11.  
  12. -- bat_ora: livello della batteria attuale
  13. -- bat_max: livello massimo della batteria
  14. -- bat_old: livello della batteria vecchio
  15. -- bat_dif: differenza tra i livelli della batteria
  16. -- bat_vel: velocità media
  17. -- bat_per: percentuale della batteria
  18. local bat_ora, bat_max, bat_old, bat_dif, bat_vel, bat_per
  19.  
  20. -- rea_cor: livello del refrigerante attuale
  21. -- rea_cmx: livello del refrigerante massimo
  22. -- rea_hor: livello del refrigerante caldo attuale
  23. -- rea_hmx: livello del refrigerante caldo massimo
  24. -- rea_cop: percentuale di refrigerante (core)
  25. -- rea_hop: percentuale di refrigerante (hull)
  26. -- rea_flx: flusso neutronico attuale nel reattore
  27. -- rea_per: percentuale di combustibile utilizzabile
  28. -- rea_cap: capacità del reatore (n. elementi combustibile)
  29. -- rea_con: livello barre di controllo
  30. -- rea_cal: livello barre di controllo (calcolato)
  31. -- rea_hec: calore del reattore (core) (°C)
  32. -- rea_heh: calore del reattore (hull) (°C)
  33. -- rea_hcx: calore del reattore (core max) (°C)
  34. -- rea_hhx: calore del reattore (hull max) (°C)
  35. -- rea_hpc: percentuale di calore (core)
  36. -- rea_hph: percentuale di colare (hull)
  37. -- rea_old: valore di combustibile precedente
  38. -- rea_vel: velocità di consumo del carburante
  39. -- nuke: tutti i dati grezzi del reattore raccolti in una tavola
  40. local rea_flx, rea_per, rea_cap, rea_con, rea_cal
  41. local rea_cor, rea_cmx, rea_hor, rea_hmx, rea_cop, rea_hop, rea_vel
  42. local rea_hec, rea_heh, rea_hpc, rea_hph, rea_hcx, rea_hhx
  43. local rea_old
  44. local nuke = {}
  45.  
  46. -- controlla se pulire o meno lo schermo (era utile per i primi debug,
  47. -- ora è obsoleta, specialmente per gli schermi più piccoli)
  48. local mezzo = false
  49.  
  50. -- purtroppo non si possono estrarre direttamente questi dati per rendere modulare il programma :/ (10-07-2024)
  51. rea_cmx = 10000
  52. rea_hmx = 100000
  53. rea_hhx = 1500.0
  54.  
  55. local x, y, w, h
  56. local bk, bj, rk, rj
  57. local t_off = 1.0
  58. local auto = true
  59. local bc = false
  60. local t_op = 0.0
  61.  
  62. local n = 10
  63. local v_bt = {}
  64. local v_rt = {}
  65. local SB, SR
  66. SB = 0.0
  67.  
  68. -- allocazione degli spazi dei vettori
  69. for i=1,n,1 do
  70.   v_bt[i] = 0.0
  71.   v_rt[i] = 0.0
  72. end
  73.  
  74.  
  75. -- crea un divisore
  76. local function divisore(char)
  77.   local W = term.window.width
  78.   local X, Y = term.getCursor()
  79.   for i=0, W-X, 1 do
  80.     term.write(char)
  81.   end
  82.   print()
  83.  
  84.   return
  85. end
  86.  
  87. -- prende i dati necessari dal reattore
  88. local function RBMK(reactor)
  89.   local X = 0
  90.   local Y = 0
  91.   local colonna
  92.   local totale = {}
  93.   -- reset tavola
  94.   totale.hullTemp = 0.0
  95.   totale.coreSkinTemp = 0.0
  96.   totale.coreMaxTemp = 0.0
  97.   totale.enrichment = 0.0
  98.   totale.flux = 0.0
  99.   totale.level = 0.0
  100.   totale.water = 0
  101.   totale.steam = 0
  102.   totale.fuel = 0
  103.   totale.control = 0
  104.   totale.boiler = 0
  105.   totale.total = 0
  106.  
  107.   -- lettura del reattore
  108.   -- asse Y (0-14)
  109.   while (Y < 15) do
  110.     X = 0
  111.     -- asse X (0-14)
  112.     while (X < 15) do
  113.       colonna = reactor.getColumnData(X, Y)
  114.       -- controlla che non ci siano spazi vuoti
  115.       if (colonna ~= nil) then
  116.         totale.hullTemp = totale.hullTemp + colonna.hullTemp
  117.         -- contatori
  118.         if (colonna.type == "FUEL") then
  119.           -- carburante
  120.           totale.coreSkinTemp = totale.coreSkinTemp + colonna.coreSkinTemp
  121.           totale.coreMaxTemp = totale.coreMaxTemp + colonna.coreMaxTemp
  122.           totale.enrichment = totale.enrichment + colonna.enrichment
  123.           totale.flux = totale.flux + colonna.fluxSlow
  124.  
  125.           totale.fuel = totale.fuel + 1
  126.         elseif (colonna.type == "CONTROL") then
  127.           -- barre di controllo
  128.           totale.level = totale.level + colonna.level
  129.  
  130.           totale.control = totale.control + 1
  131.         elseif (colonna.type == "BOILER") then
  132.           -- generatori di vapore (boiler)
  133.           totale.water = totale.water + colonna.water
  134.           totale.steam = totale.steam + colonna.steam
  135.  
  136.           totale.boiler = totale.boiler + 1
  137.         end
  138.         -- coontatore elementi del reattore
  139.         totale.total = totale.total + 1
  140.       end
  141.       X = X + 1
  142.     end
  143.     Y = Y + 1
  144.   end
  145.  
  146.   -- colcolo delle medie
  147.   -- tutto
  148.   totale.hullTemp = totale.hullTemp / totale.total
  149.   -- carburante
  150.   totale.coreSkinTemp = totale.coreSkinTemp / totale.fuel
  151.   totale.coreMaxTemp = totale.coreMaxTemp / totale.fuel
  152.   totale.enrichment = totale.enrichment / totale.fuel
  153.   totale.flux = totale.flux / totale.fuel
  154.   -- barre di controllo
  155.   totale.level = totale.level / totale.control
  156.   -- generatori di vapore (boiler)
  157.   totale.water = totale.water / totale.boiler
  158.   totale.steam = totale.steam / totale.boiler
  159.  
  160.   return totale
  161. end
  162.  
  163. local function SCRAM()
  164.   local t = os.clock()
  165.   divisore("=")
  166.   print("SEQUENZA DI SCRAM INIZIATA")
  167.  
  168.   reattore.setLevel(0.0)
  169.   reattore.pressAZ5()
  170.  
  171.   print("SEQUENZA DI SCRAM FINITA")
  172.   print("Tempo impiegato: " .. os.clock()-t)
  173.   os.exit(1)
  174. end
  175.  
  176.  
  177. w = term.window.width
  178. h = term.window.height
  179. x, y = term.getCursor()
  180.  
  181. -- se il cursore si trova a metà o più dell'altezza del monitor, lo schermo viene pulito ed il cursore resettato all'inizio
  182. if (y >= h/2 and mezzo) then
  183.   term.clear()
  184.   term.setCursor(1, 1)
  185. end
  186.  
  187. x, y = term.getCursor() -- prende la posizione del cursore
  188.  
  189. print("Statistiche Centrale")
  190. divisore("=")
  191. term.setCursor(1, y+3)
  192. divisore("-")
  193. print("> Batteria")
  194. term.setCursor(1, y+8)
  195. divisore("-")
  196. print("> Reattore")
  197.  
  198.  
  199. bat_old = 0
  200. rea_old = 0.0
  201.  
  202. -- CICLO PRINCIPALE
  203. while (true) do
  204.   -- calcoli
  205.   t_op = os.clock() -- inizio calcolo del tempo di calcolo
  206.  
  207.   -- SETTORE INTERFACCE REDSTONE
  208.   -- SCRAM
  209.   if (red_funz.getInput(side.west) ~= 0) then
  210.     SCRAM()
  211.   end
  212.  
  213.   -- controllo della modalità auto
  214.   if (red_funz.getInput(side.east) == 0) then
  215.     auto = false
  216.   else
  217.     auto = true
  218.   end
  219.  
  220.   -- controllo della disattivazione del reattore
  221.   if (red_funz.getInput(side.north) ~= 0) then
  222.     auto = false
  223.     reattore.setLevel(0.0)
  224.   end
  225.   -- FINE SETTORE INTERFACCE REDSTONE
  226.  
  227.   bat_ora, bat_max = batteria.getEnergyInfo()
  228.   bat_per = bat_ora / bat_max
  229.   bat_dif = bat_ora - bat_old
  230.  
  231.   nuke = RBMK(reattore)
  232.   rea_cap = nuke.fuel
  233.   rea_per = 1.0 - nuke.enrichment
  234.   rea_con = nuke.level
  235.   rea_flx = nuke.flux
  236.  
  237.   rea_cor = nuke.water
  238.   rea_hor = nuke.steam
  239.   rea_cop = rea_cor / rea_cmx
  240.   rea_hop = rea_hor / rea_hmx
  241.   rea_hec = nuke.coreSkinTemp
  242.   rea_hcx = nuke.coreMaxTemp
  243.   rea_heh = nuke.hullTemp
  244.   rea_hpc = rea_hec / rea_hcx
  245.   rea_hph = rea_heh / rea_hhx
  246.  
  247.   -- calcolo velocità media
  248.   bk = 0.0
  249.   bj = 0
  250.   rk = 0.0
  251.   rj = 0
  252.  
  253.   for i=n,1,-1 do
  254.     v_bt[i] = v_bt[i-1]
  255.     v_rt[i] = v_rt[i-1]
  256.   end
  257.  
  258.   v_bt[1] = math.abs(bat_old - bat_ora) / t_off
  259.   v_rt[1] = math.abs(rea_old - rea_per) / t_off
  260.  
  261.   for i=1,n,1 do
  262.     -- batteria
  263.     if (v_bt[i] ~= 0.0) then
  264.       bk = bk + v_bt[i]
  265.       bj = bj + 1
  266.     end
  267.     -- reattore
  268.     if (v_rt[i] ~= 0.0) then
  269.       rk = rk + v_rt[i]
  270.       rj = rj + 1
  271.     end
  272.   end
  273.  
  274.   if (bj <= 0) then bj = 1 end
  275.   if (rj <= 0) then rj = 1 end
  276.  
  277.   bat_vel = bk / bj
  278.   rea_vel = rk / rj
  279.  
  280.   SB = (bat_max - bat_ora) / (math.abs(bat_vel)+1.0)
  281.   SR = rea_per / (math.abs(rea_vel)+1.0)
  282.  
  283.   -- stima livello delle barre di controllo (in funzione del livello della batteria e temperatura del core)
  284.   rea_cal = 1.0 - (bat_per + ((rea_hpc >= rea_hph) and rea_hpc or rea_hph))^2.0 -- nelle parentesi interne viene scelto uno dei 2 valori, in quanto core e hull possono avere valori non concordanti
  285.   if (auto) then
  286.     reattore.setLevel(rea_cal)
  287.   end
  288.  
  289.   -- ALLARMI
  290.   -- livello refrigerante basso
  291.   if (rea_cop < 0.2) then
  292.     if (auto) then reattore.setLevel(rea_cal) end
  293.     red_alar.setOutput(side.east, 15)
  294.   elseif (rea_cop > 0.5) then
  295.     red_alar.setOutput(side.east, 0)
  296.   end
  297.  
  298.   -- temperatura critica
  299.   if (rea_hpc > 0.8 or rea_hph > 0.8) then
  300.     red_alar.setOutput(side.west, 15)
  301.     if (auto) then SCRAM() end -- Disattivazione automatica
  302.   elseif (rea_hpc < 0.5 and rea_hph < 0.5) then
  303.     red_alar.setOutput(side.west, 0)
  304.   end
  305.   -- FINE ALLARMI
  306.  
  307.   -- stampa
  308.   term.setCursor(w-16, y)
  309.   print(os.date())
  310.  
  311.   term.setCursor(1, y+2)
  312.   print(("Battito: %1s | TDC: %7.5f s | Auto: %3s | Attività: %3s"):format((bc and "*" or " "), os.clock()-t_op, (auto and "ON" or "OFF"), (rea_con < 100 and "ON" or "OFF")))
  313.  
  314.   term.setCursor(1, y+5)
  315.   print(("Carica:     %6.2f%s  "):format(bat_per*100.0, "%"))
  316.   print(("Velocità: %1s%6.2f MHE/s      "):format((bat_dif >= 0 and "+" or "-"), math.abs(bat_dif/1000000.0)))
  317.   print(("Tempo di %9s: %2d %2d:%2d:%2d     "):format((bat_dif >= 0 and "ricarica" or "discarica"), math.floor(SB/86400), math.floor((SB/3600)%24), math.floor((SB/60)%60), math.floor(SB%60)))
  318.  
  319.   term.setCursor(1, y+9)
  320.   print(("Combustibile: %3d -> %6.2f%s"):format(rea_cap, (1.0-rea_per)*100.0, "%"))
  321.   print(("Vel. Esaurimento: %6.2f Dur/s | %2d %2d:%2d:%2d     "):format(rea_vel, math.floor(SR/86400), math.floor((SR/3600)%24), math.floor((SR/60)%60), math.floor(SR%60)))
  322.   print(("Flusso Neutronico: %.2f          "):format(rea_flx))
  323.   print(("Livello Barre di Controllo (Stimato): %7.3f%s"):format((1.0-rea_cal)*100.0, "%"))
  324.   print(("Livello Barre di Controllo (Attuale): %7.3f%s"):format((1.0-rea_con)*100.0, "%"))
  325.  
  326.   print(("Calore Core: %6.2f%s (%7.2f / %7.2f °C) "):format(rea_hpc*100.0, "%", rea_hec, rea_hcx))
  327.   print(("Calore Hull: %6.2f%s (%7.2f / %7.2f °C) "):format(rea_hph*100.0, "%", rea_heh, rea_hhx))
  328.   print(("Refrigerante Freddo: %6.2f%s (%6.0f / %6.0f mB) "):format(rea_cop*100.0, "%", rea_cor, rea_cmx))
  329.   print(("Refrigerante Caldo:  %6.2f%s (%6.0f / %6.0f mB) "):format(rea_hop*100.0, "%", rea_hor, rea_hmx))
  330.  
  331.   -- calcoli finali
  332.   bat_old = bat_ora
  333.   rea_old = rea_per
  334.   bc = not bc
  335.  
  336.   os.sleep(t_off-(os.clock()-t_op))
  337. end
Advertisement
Add Comment
Please, Sign In to add comment