Advertisement
neuroticfox

DraCon 5.0 [Experimental] (M-0.25-1-10-M)-2x

Jul 10th, 2021
125
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.84 KB | None | 0 0
  1. local component = require("component")
  2. local event = require("event")
  3. local term = require("term")
  4. local gpu = component.gpu
  5.  
  6. -- Safety Checks
  7.  
  8. if not component.isAvailable("draconic_reactor") then
  9. print("Reactor not connected. Please connect computer to reactor with an Adapter block.")
  10. os.exit()
  11. end
  12. reactor = component.draconic_reactor
  13. local flux_gates = {}
  14. for x,y in pairs(component.list("flux_gate")) do
  15. flux_gates[#flux_gates+1] = x
  16. end
  17. if #flux_gates < 2 then
  18. print("Not enough flux gates connected; please connect inflow and outflow flux gates with Adapter blocks.")
  19. os.exit()
  20. end
  21. flux_in = component.proxy(flux_gates[1])
  22. flux_out = component.proxy(flux_gates[2])
  23. if not flux_in or not flux_out then
  24. print("Not enough flux gates connected; please connect inflow and outflow flux gates with Adapter blocks.")
  25. os.exit()
  26. end
  27.  
  28. -- Functions
  29.  
  30. function exit_msg(msg)
  31. term.clear()
  32. print(msg)
  33. os.exit()
  34. end
  35.  
  36. function modify_temp(offset)
  37. local new_temp = ideal_temp + offset
  38. if new_temp > 13500 then
  39. new_temp = 13500
  40. elseif new_temp < 1500 then
  41. new_temp = 1500
  42. end
  43. ideal_temp = new_temp
  44. end
  45.  
  46. function modify_field(offset)
  47. local new_strength = ideal_strength + offset
  48. if new_strength > 100 then
  49. new_strength = 100
  50. elseif new_strength < 0.25 then
  51. new_strength = 0.25
  52. end
  53. ideal_strength = new_strength
  54. end
  55.  
  56. -- Buttons
  57.  
  58. local adj_button_width = 19
  59. local temp_adjust_x_offset = 68
  60. local temp_adjust_y_offset = 2
  61. local field_adjust_x_offset = temp_adjust_x_offset + adj_button_width + 2
  62. local field_adjust_y_offset = 2
  63.  
  64. local buttons = {
  65. start={
  66. x=42,
  67. y=2,
  68. width=24,
  69. height=7,
  70. text="Start",
  71. action=function()
  72. if safe then
  73. state = "Charging"
  74. reactor.chargeReactor()
  75. elseif shutting_down then
  76. state = "Active"
  77. reactor.activateReactor()
  78. end
  79. end,
  80. condition=function() return safe or shutting_down end
  81. },
  82. shutdown={
  83. x=42,
  84. y=12,
  85. width=24,
  86. height=7,
  87. text="Shutdown",
  88. action=function()
  89. state = "Manual Shutdown"
  90. reactor.stopReactor()
  91. end,
  92. condition=function() return running end
  93. },
  94. switch_gates={
  95. x=2,
  96. y=20,
  97. width=24,
  98. height=3,
  99. text="Swap flux gates",
  100. action=function()
  101. local old_addr = flux_in.address
  102. flux_in = component.proxy(flux_out.address)
  103. flux_out = component.proxy(old_addr)
  104. end,
  105. condition=function() return safe end
  106. },
  107. exit={
  108. x=42,
  109. y=12,
  110. width=24,
  111. height=7,
  112. text="Exit",
  113. action=function()
  114. event_loop = false
  115. end,
  116. condition=function() return safe end
  117. },
  118. temp_up_max={
  119. x=temp_adjust_x_offset,
  120. y=temp_adjust_y_offset,
  121. width=adj_button_width,
  122. height=1,
  123. text="Maximum",
  124. action=function() modify_temp(14000) end
  125. },
  126. temp_up_thousand={
  127. x=temp_adjust_x_offset,
  128. y=temp_adjust_y_offset,+2
  129. width=adj_button_width,
  130. height=1,
  131. text="+ 1000",
  132. action=function() modify_temp(1000) end
  133. },
  134. temp_up_hundred={
  135. x=temp_adjust_x_offset,
  136. y=temp_adjust_y_offset+4,
  137. width=adj_button_width,
  138. height=1,
  139. text="+ 100",
  140. action=function() modify_temp(100) end
  141. },
  142. temp_up_ten={
  143. x=temp_adjust_x_offset,
  144. y=temp_adjust_y_offset+6,
  145. width=adj_button_width,
  146. height=1,
  147. text="+ 10",
  148. action=function() modify_temp(10) end
  149. },
  150. temp_up_one={
  151. x=temp_adjust_x_offset,
  152. y=temp_adjust_y_offset+8,
  153. width=adj_button_width,
  154. height=1,
  155. text="+ 1",
  156. action=function() modify_temp(1) end
  157. },
  158. temp_down_thousand={
  159. x=temp_adjust_x_offset,
  160. y=temp_adjust_y_offset+18,
  161. width=adj_button_width,
  162. height=1,
  163. text="- 1000",
  164. action=function() modify_temp(-1000) end
  165. },
  166. temp_down_max={
  167. x=temp_adjust_x_offset,
  168. y=temp_adjust_y_offset+16,
  169. width=adj_button_width,
  170. height=1,
  171. text="Minimum",
  172. action=function() modify_temp(-14000) end
  173. },
  174. temp_down_hundred={
  175. x=temp_adjust_x_offset,
  176. y=temp_adjust_y_offset+14,
  177. width=adj_button_width,
  178. height=1,
  179. text=" - 100",
  180. action=function() modify_temp(-100) end
  181. },
  182. temp_down_ten={
  183. x=temp_adjust_x_offset,
  184. y=temp_adjust_y_offset+12,
  185. width=adj_button_width,
  186. height=1,
  187. text="- 10",
  188. action=function() modify_temp(-10) end
  189. },
  190. temp_down_one={
  191. x=temp_adjust_x_offset,
  192. y=temp_adjust_y_offset+10,
  193. width=adj_button_width,
  194. height=1,
  195. text="- 1",
  196. action=function() modify_temp(-1) end
  197. },
  198. field_up_ten={
  199. x=field_adjust_x_offset,
  200. y=field_adjust_y_offset+4,
  201. width=adj_button_width,
  202. height=1,
  203. text="+ 10",
  204. action=function() modify_field(10) end
  205. },
  206. field_up_one={
  207. x=field_adjust_x_offset,
  208. y=field_adjust_y_offset+6,
  209. width=adj_button_width,
  210. height=1,
  211. text="+ 0.25",
  212. action=function() modify_field(0.25) end
  213. },
  214. field_down_ten={
  215. x=field_adjust_x_offset,
  216. y=field_adjust_y_offset+12,
  217. width=adj_button_width,
  218. height=1,
  219. text="- 10",
  220. action=function() modify_field(-10) end
  221. },
  222. field_down_one={
  223. x=field_adjust_x_offset,
  224. y=field_adjust_y_offset+10,
  225. width=adj_button_width,
  226. height=1,
  227. text="- 0.25",
  228. action=function() modify_field(-0.25) end
  229. }
  230. }
  231.  
  232. -- main code
  233.  
  234. flux_in.setFlowOverride(0)
  235. flux_out.setFlowOverride(0)
  236. flux_in.setOverrideEnabled(true)
  237. flux_out.setOverrideEnabled(true)
  238.  
  239. local condition = reactor.getReactorInfo()
  240. if not condition then
  241. print("You Done Goofed Moron")
  242. os.exit()
  243. end
  244.  
  245. ideal_strength = 5
  246.  
  247. ideal_temp = 8000
  248. cutoff_temp = 13500
  249.  
  250. -- tweakable pid gains
  251.  
  252. inflow_P_gain = 1
  253. inflow_I_gain = 0.04
  254. inflow_D_gain = 0.1
  255.  
  256. outflow_P_gain = 500
  257. outflow_I_gain = 0.5
  258. outflow_II_gain = 0.0000003
  259. outflow_D_gain = 60000
  260.  
  261. -- initialize main loop
  262.  
  263. inflow_I_sum = 0
  264. inflow_D_last = 0
  265.  
  266. outflow_I_sum = 0
  267. outflow_II_sum = 0
  268. outflow_D_last = 0
  269.  
  270. state = "Standby"
  271. shutting_down = false
  272.  
  273. if condition.temperature > 25 then
  274. state = "Cooling"
  275. end
  276. if condition.temperature > 1499 then
  277. state = "Active"
  278. end
  279.  
  280. -- Possible states:
  281. --Standby
  282. --Charging
  283. --Active
  284. --Manual Shutdown
  285. --Emergency Shutdown
  286. --Cooling
  287.  
  288. event_loop = true
  289. while event_loop do
  290.  
  291. if not component.isAvailable("draconic_reactor") then
  292. exit_msg("Reactor disconnected, exiting")
  293. end
  294.  
  295. if not component.isAvailable("flux_gate") then
  296. exit_msg("Flux gates disconnected, exiting")
  297. end
  298.  
  299. local info = reactor.getReactorInfo()
  300.  
  301. local inflow = 0
  302. local outflow = 0
  303.  
  304. shutting_down = state == "Manual Shutdown" or state == "Emergency Shutdown"
  305. running = state == "Charging" or state == "Active"
  306. safe = state == "Standby" or state == "Cooling"
  307.  
  308. if state == "Charging" then
  309. inflow = 1500000
  310.  
  311. if info.temperature > 1499 then
  312. reactor.activateReactor()
  313. state = "Active"
  314. end
  315. elseif state == "Cooling" then
  316. if info.temperature < 25 then
  317. state = "Standby"
  318. end
  319. inflow = 10
  320. outflow = 20
  321. elseif state == "Standby" then
  322. inflow = 10
  323. outflow = 20
  324. else
  325. -- adjust inflow rate based on field strength
  326.  
  327. local field_error = (info.maxFieldStrength * (ideal_strength / 100)) - info.fieldStrength
  328. local proportional_field_error = field_error * inflow_P_gain
  329. inflow_I_sum = inflow_I_sum + field_error
  330. local integral_field_error = inflow_I_sum * inflow_I_gain
  331. local derivative_field_error = (field_error - inflow_D_last) * inflow_D_gain
  332. inflow_D_last = field_error
  333. local inflow_correction = proportional_field_error + integral_field_error + derivative_field_error
  334. if inflow_correction < 0 then
  335. inflow_I_sum = inflow_I_sum - field_error
  336. end
  337. inflow = inflow_correction
  338.  
  339. if not shutting_down then
  340.  
  341. -- adjust outflow rate based on core temperature
  342.  
  343. local temp_error = ideal_temp - info.temperature
  344. local proportional_temp_error = temp_error * outflow_P_gain
  345. outflow_I_sum = outflow_I_sum + temp_error
  346. local integral_temp_error = outflow_I_sum * outflow_I_gain
  347. if math.abs(temp_error) < 100 then
  348. outflow_II_sum = outflow_II_sum + integral_temp_error
  349. else
  350. outflow_II_sum = 0
  351. end
  352. local second_integral_temp_error = outflow_II_sum * outflow_II_gain
  353. local derivative_temp_error = (temp_error - outflow_D_last) * outflow_D_gain
  354. outflow_D_last = temp_error
  355. local outflow_correction = proportional_temp_error + integral_temp_error + second_integral_temp_error + derivative_temp_error
  356. if outflow_correction < 0 then
  357. outflow_I_sum = outflow_I_sum - temp_error
  358. end
  359. outflow = outflow_correction
  360.  
  361. -- cut off reactor in case of emergency
  362. local chaos = ((1 - info.fuelConversion / info.maxFuelConversion) * 100)
  363.  
  364. if chaos == 97.5 then
  365. print("Reactor Fuel Low, Shutting Down")
  366. outflow = 0
  367. state = "Emergency Shutdown"
  368. reactor.stopReactor()
  369. end
  370. else
  371. if info.temperature < 1499 then
  372. state = "Cooling"
  373. end
  374. end
  375. end
  376.  
  377. if state ~= "Active" and not shutting_down then
  378. inflow_I_sum = 0
  379. inflow_D_last = 0
  380. outflow_I_sum = 0
  381. outflow_II_sum = 0
  382. outflow_D_last = 0
  383. end
  384.  
  385. if inflow < 0 then
  386. inflow = 0
  387. end
  388. if outflow < 0 then
  389. outflow = 0
  390. end
  391.  
  392. inflow = math.floor(inflow)
  393. outflow = math.floor(outflow)
  394.  
  395. flux_in.setFlowOverride(inflow)
  396. flux_out.setFlowOverride(outflow)
  397.  
  398. -- Draw screen
  399.  
  400. if term.isAvailable() then
  401.  
  402. -- Draw Values
  403.  
  404. local left_margin = 2
  405. local spacing = 2
  406.  
  407. local values = {
  408. "Status: " .. state,
  409. "Field Strength: " .. ((info.fieldStrength / info.maxFieldStrength) * 100) .. "%",
  410. "Energy Saturation: " .. ((info.energySaturation / info.maxEnergySaturation) * 100) .. "%",
  411. "Fuel Concentration: " .. ((1 - info.fuelConversion / info.maxFuelConversion) * 100) .. "%",
  412. "Temperature: " .. info.temperature .. " F",
  413. "Reactor Efficiency: " .. info.fuelConversionRate .. " nb/t",
  414. "Energy Inflow Rate: " .. inflow .. " RF/t",
  415. "Energy Outflow Rate: " .. outflow .. " RF/t"
  416. "Total Power Output: " .. (outflow - inflow) .. " RF/t"
  417. }
  418.  
  419. if safe then
  420. values[#values+1] = "Click if flux gates need to be swapped"
  421. end
  422.  
  423. term.clear()
  424.  
  425. for i, v in ipairs(values) do
  426. term.setCursor(left_margin, i * spacing)
  427. term.write(v)
  428. end
  429.  
  430. -- Draw button values
  431.  
  432. term.setCursor(temp_adjust_x_offset, temp_adjust_y_offset+8)
  433. term.write("Target Temp: " .. ideal_temp .. " F")
  434. term.setCursor(field_adjust_x_offset, field_adjust_y_offset+8)
  435. term.write("Target Strength: " .. ideal_strength .. "%")
  436.  
  437. -- Draw Buttons
  438.  
  439. gpu.setForeground(0x000000)
  440.  
  441. for bname, button in pairs(buttons) do
  442. if button.depressed then
  443.  
  444. button.depressed = button.depressed - 1
  445. if button.depressed == 0 then
  446. button.depressed = nil
  447. end
  448. end
  449. if button.condition == nil or button.condition() then
  450. local center_color = 0xAAAAAA
  451. local highlight_color = 0xCCCCCC
  452. local lowlight_color = 0x808080
  453. if button.depressed then
  454. center_color = 0x999999
  455. highlight_color = 0x707070
  456. lowlight_color = 0xBBBBBB
  457. end
  458. gpu.setBackground(center_color)
  459. gpu.fill(button.x, button.y, button.width, button.height, " ")
  460. if button.width > 1 and button.height > 1 then
  461. gpu.setBackground(lowlight_color)
  462. gpu.fill(button.x+1, button.y+button.height-1, button.width-1, 1, " ")
  463. gpu.fill(button.x+button.width-1, button.y, 1, button.height, " ")
  464. gpu.setBackground(highlight_color)
  465. gpu.fill(button.x, button.y, 1, button.height, " ")
  466. gpu.fill(button.x, button.y, button.width, 1, " ")
  467. end
  468. gpu.setBackground(center_color)
  469. term.setCursor(button.x + math.floor(button.width / 2 - #button.text / 2), button.y + math.floor(button.height / 2))
  470. term.write(button.text)
  471. end
  472. end
  473.  
  474. gpu.setBackground(0x000000)
  475. gpu.setForeground(0xFFFFFF)
  476. end
  477.  
  478. -- Wait for next tick, or manual shutdown
  479.  
  480. local event, id, op1, op2 = event.pull(0.05)
  481. if event == "interrupted" then
  482. if safe then
  483. break
  484. end
  485. elseif event == "touch" then
  486.  
  487. -- Handle Button Presses
  488.  
  489. local x = op1
  490. local y = op2
  491.  
  492. for bname, button in pairs(buttons) do
  493. if (button.condition == nil or button.condition()) and x >= button.x and x <= button.x + button.width and y >= button.y and y <= button.y + button.height then
  494. button.action()
  495. button.depressed = 3
  496. end
  497. end
  498. end
  499. end
  500.  
  501. term.clear()
  502.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement