Archives
Trending
Support
Login
clear text
XML
Django
JavaScript
MATLAB
C
C++
C#
Python
SQL
Shell
Bash
Markdown
YAML
JSON
HTML
CSS
PHP
Java
Ruby
Go
Rust
Swift
Kotlin
Arduino
TypeScript
Perl
Autohotkey
Lua
SQF
R
Scala
Haskell
Groovy
Dart
Clojure
VB.NET
Objective-C
PowerShell
Bash
CoffeeScript
Verilog
--[[ 神龙反应堆控制器(ComputerCraft: Tweaked 版) 作者:ChatGPT 结构:双PID + 预测辅助安全限幅 依赖接口: reactor: activateReactor(), chargeReactor(), getReactorInfo(), stopReactor(), toggleFailSafe() flow_gate: getFlow(), setFlowOverride(), setOverrideEnabled(), getOverrideEnabled() --]] -- ===== 手动 peripheral 配置 ===== local reactor = peripheral.wrap("reactor_0") local inGate = peripheral.wrap("flow_gate_in") local outGate = peripheral.wrap("flow_gate_out") local monitor = peripheral.wrap("monitor_0") -- 可选 -- ===== 参数配置 ===== local TARGET_TEMP = 8000 local TARGET_FIELD = 0.05 local SAFETY_TEMP = 8300 local MIN_FIELD = 0.02 local CHARGE_INPUT_MAX = 64000000 local MAIN_SLEEP = 0.2 local GUI_UPDATE_INTERVAL = 0.5 local PREDICT_STEPS = 10 local ALLOW_TOUCH_START = true -- ===== 反应堆信息封装 ===== local function info() return reactor.getReactorInfo() end local function temp() return info().temperature or 0 end local function field() return info().fieldStrength or 0 end local function fieldMax() return info().maxFieldStrength or 1 end local function energy() return info().energySaturation or 0 end local function energyMax() return info().maxEnergySaturation or 1 end local function genRate() return info().generationRate or 0 end local function status() return tostring(info().status) end -- ===== PID 控制 ===== local function newPID(kp,ki,kd) return {kp=kp,ki=ki,kd=kd,lastErr=0,int=0,step=function(self,target,cur,dt) local e=target-cur self.int=self.int+e*dt local d=(e-self.lastErr)/dt self.lastErr=e return self.kp*e+self.ki*self.int+self.kd*d end} end -- 主PID(温控基于能空率) local pidTemp = newPID(0.5,0.02,0.3) -- 次PID(场强维持) local pidField = newPID(20000000,10000,0) -- ===== 预测模块(辅助限幅) ===== local function predict(steps) local t=temp() local f=field() local e=energy() local fmax=fieldMax() local emax=energyMax() for _=1,steps do local erate=(1-e/emax)*99 local trate=(t/20000)*50 local upIndex=(erate^3)/(100-erate+1e-9)+444.7 local upResist=(trate^4)/(100-trate+1e-9) local rise=(upIndex+upResist*(0.5-1))/1000+0.5 t=t+rise f=f-(1-e/emax) e=e+(1-(e/emax))*5000 end return t,f end -- ===== 控制函数 ===== local function setIn(v) if not inGate then return end if v<0 then v=0 end if v>CHARGE_INPUT_MAX then v=CHARGE_INPUT_MAX end inGate.setFlowOverride(v) inGate.setOverrideEnabled(true) end local function setOut(v) if not outGate then return end if v<0 then v=0 end if v>CHARGE_INPUT_MAX then v=CHARGE_INPUT_MAX end outGate.setFlowOverride(v) outGate.setOverrideEnabled(true) end -- ===== 状态机 ===== local function emergency(reason) print("!!! 紧急停机: "..reason) setOut(0) setIn(CHARGE_INPUT_MAX) reactor.stopReactor() end local function tryActivate() local fi=field()/fieldMax() local ei=energy()/energyMax() if fi>=0.5 and ei>=0.5 and temp()>=2500 then reactor.activateReactor() return true end end -- ===== GUI ===== local function draw() if not monitor then return end monitor.setTextScale(1) monitor.clear() monitor.setCursorPos(1,1) monitor.write("神龙反应堆控制") monitor.setCursorPos(1,2) monitor.write("状态: "..status()) monitor.setCursorPos(1,3) monitor.write(string.format("温度: %.1fC",temp())) monitor.setCursorPos(1,4) monitor.write(string.format("场强: %.2f%%",(field()/fieldMax())*100)) monitor.setCursorPos(1,5) monitor.write(string.format("能量: %.2f%%",(energy()/energyMax())*100)) monitor.setCursorPos(1,7) monitor.write("[触摸底部启动/停止]") end -- ===== 主循环 ===== local manualStart, manualStop=false,false local function monitorTouch() if not monitor then return end while true do local _,side,x,y=os.pullEvent("monitor_touch") if y>=7 then if status()=="running" then manualStop=true else manualStart=true end end end end local function main() local running=false while true do draw() local st=status() local T=temp() local fRatio=field()/fieldMax() local eRatio=energy()/energyMax() -- 安全检查 if st=="running" and (T>=SAFETY_TEMP or fRatio
=SAFETY_TEMP) local outAdj=pidTemp:step(TARGET_TEMP,T,MAIN_SLEEP) if predictedOverheat then outAdj=outAdj*0.2 -- 限幅抑制 end local outFlow=math.max(0,math.min(CHARGE_INPUT_MAX,genRate()+outAdj*1000)) setOut(outFlow) -- 次PID:控制场强维持 local inAdj=pidField:step(TARGET_FIELD,fRatio,MAIN_SLEEP) if predF/fieldMax()
Mark as private (unlisted)
for 30 minutes
for 6 hours
for 1 day
for 1 week
for 1 month
for 1 year
everlasting (like CCCP)