#169 startup rate high; also changed how clearing ASCRAM status and updating indicators works

This commit is contained in:
Mikayla Fischler 2023-02-19 12:20:16 -05:00
parent cc5ea0dbb0
commit 35dfd61df1
4 changed files with 89 additions and 55 deletions

View File

@ -8,7 +8,7 @@ local types = {}
-- CLASSES -- -- CLASSES --
---@class tank_fluid ---@class tank_fluid
---@field name string ---@field name fluid
---@field amount integer ---@field amount integer
-- create a new tank fluid -- create a new tank fluid
@ -222,6 +222,19 @@ types.ALARM_STATE = {
---| "sys_fail" ---| "sys_fail"
---| "force_disabled" ---| "force_disabled"
---@alias fluid
---| "mekanism:empty_gas"
---| "minecraft:water"
---| "mekanism:sodium"
---| "mekanism:superheated_sodium"
types.fluid = {
empty_gas = "mekanism:empty_gas",
water = "minecraft:water",
sodium = "mekanism:sodium",
superheated_sodium = "mekanism:superheated_sodium"
}
---@alias rtu_t string ---@alias rtu_t string
types.rtu_t = { types.rtu_t = {
redstone = "redstone", redstone = "redstone",

View File

@ -301,6 +301,7 @@ function facility.new(num_reactors, cooling_conf)
if (self.mode ~= PROCESS.MATRIX_FAULT_IDLE) and (self.mode ~= PROCESS.SYSTEM_ALARM_IDLE) then if (self.mode ~= PROCESS.MATRIX_FAULT_IDLE) and (self.mode ~= PROCESS.SYSTEM_ALARM_IDLE) then
-- auto clear ASCRAM -- auto clear ASCRAM
self.ascram = false self.ascram = false
self.ascram_reason = AUTO_SCRAM.NONE
end end
local blade_count = nil local blade_count = nil
@ -372,13 +373,19 @@ function facility.new(num_reactors, cooling_conf)
if self.mode == PROCESS.INACTIVE then if self.mode == PROCESS.INACTIVE then
if not self.units_ready then if not self.units_ready then
self.status_text = { "NOT READY", "assigned units not ready" } self.status_text = { "NOT READY", "assigned units not ready" }
elseif self.start_fail == START_STATUS.NO_UNITS and assign_count == 0 then else
-- clear ASCRAM once ready
self.ascram = false
self.ascram_reason = AUTO_SCRAM.NONE
if self.start_fail == START_STATUS.NO_UNITS and assign_count == 0 then
self.status_text = { "START FAILED", "no units were assigned" } self.status_text = { "START FAILED", "no units were assigned" }
elseif self.start_fail == START_STATUS.BLADE_MISMATCH then elseif self.start_fail == START_STATUS.BLADE_MISMATCH then
self.status_text = { "START FAILED", "turbine blade count mismatch" } self.status_text = { "START FAILED", "turbine blade count mismatch" }
else else
self.status_text = { "IDLE", "control disengaged" } self.status_text = { "IDLE", "control disengaged" }
end end
end
elseif self.mode == PROCESS.MAX_BURN then elseif self.mode == PROCESS.MAX_BURN then
-- run units at their limits -- run units at their limits
if state_changed then if state_changed then
@ -522,7 +529,7 @@ function facility.new(num_reactors, cooling_conf)
next_mode = self.return_mode next_mode = self.return_mode
log.info("FAC: exiting matrix fault idle state due to fault resolution") log.info("FAC: exiting matrix fault idle state due to fault resolution")
elseif self.ascram_reason == AUTO_SCRAM.CRIT_ALARM then elseif self.ascram_reason == AUTO_SCRAM.CRIT_ALARM then
next_mode = PROCESS.INACTIVE next_mode = PROCESS.SYSTEM_ALARM_IDLE
log.info("FAC: exiting matrix fault idle state due to critical unit alarm") log.info("FAC: exiting matrix fault idle state due to critical unit alarm")
end end
elseif self.mode == PROCESS.SYSTEM_ALARM_IDLE then elseif self.mode == PROCESS.SYSTEM_ALARM_IDLE then
@ -545,7 +552,6 @@ function facility.new(num_reactors, cooling_conf)
local astatus = self.ascram_status local astatus = self.ascram_status
if (self.mode ~= PROCESS.INACTIVE) and (self.mode ~= PROCESS.SYSTEM_ALARM_IDLE) then
if self.induction[1] ~= nil then if self.induction[1] ~= nil then
local matrix = self.induction[1] ---@type unit_session local matrix = self.induction[1] ---@type unit_session
local db = matrix.get_db() ---@type imatrix_session_db local db = matrix.get_db() ---@type imatrix_session_db
@ -565,11 +571,12 @@ function facility.new(num_reactors, cooling_conf)
end end
-- check for critical unit alarms -- check for critical unit alarms
astatus.crit_alarm = false
for i = 1, #self.units do for i = 1, #self.units do
local u = self.units[i] ---@type reactor_unit local u = self.units[i] ---@type reactor_unit
if u.has_critical_alarm() then if u.has_critical_alarm() then
log.info(util.c("FAC: emergency exit of process control due to critical unit alarm (unit ", u.get_id(), ")")) astatus.crit_alarm = true
break break
end end
end end
@ -592,8 +599,7 @@ function facility.new(num_reactors, cooling_conf)
astatus.matrix_dc = true astatus.matrix_dc = true
end end
-- log.debug(util.c("dc: ", astatus.matrix_dc, " fill: ", astatus.matrix_fill, " crit: ", astatus.crit_alarm, " gen: ", astatus.gen_fault)) if (self.mode ~= PROCESS.INACTIVE) and (self.mode ~= PROCESS.SYSTEM_ALARM_IDLE) then
local scram = astatus.matrix_dc or astatus.matrix_fill or astatus.crit_alarm or astatus.gen_fault local scram = astatus.matrix_dc or astatus.matrix_fill or astatus.crit_alarm or astatus.gen_fault
if scram and not self.ascram then if scram and not self.ascram then
@ -611,6 +617,7 @@ function facility.new(num_reactors, cooling_conf)
self.status_text = { "AUTOMATIC SCRAM", "critical unit alarm tripped" } self.status_text = { "AUTOMATIC SCRAM", "critical unit alarm tripped" }
log.info("FAC: automatic SCRAM due to critical unit alarm") log.info("FAC: automatic SCRAM due to critical unit alarm")
log.warning("FAC: emergency exit of process control due to critical unit alarm")
elseif astatus.radiation then elseif astatus.radiation then
next_mode = PROCESS.SYSTEM_ALARM_IDLE next_mode = PROCESS.SYSTEM_ALARM_IDLE
self.ascram_reason = AUTO_SCRAM.RADIATION self.ascram_reason = AUTO_SCRAM.RADIATION

View File

@ -14,7 +14,7 @@ local svsessions = require("supervisor.session.svsessions")
local config = require("supervisor.config") local config = require("supervisor.config")
local supervisor = require("supervisor.supervisor") local supervisor = require("supervisor.supervisor")
local SUPERVISOR_VERSION = "beta-v0.11.11" local SUPERVISOR_VERSION = "beta-v0.11.12"
local print = util.print local print = util.print
local println = util.println local println = util.println

View File

@ -109,12 +109,26 @@ function logic.update_annunciator(self)
self.db.annunciator.AutoReactorSCRAM = plc_db.rps_trip_cause == types.rps_status_t.automatic self.db.annunciator.AutoReactorSCRAM = plc_db.rps_trip_cause == types.rps_status_t.automatic
self.db.annunciator.RCPTrip = plc_db.rps_tripped and (plc_db.rps_status.ex_hcool or plc_db.rps_status.no_cool) self.db.annunciator.RCPTrip = plc_db.rps_tripped and (plc_db.rps_status.ex_hcool or plc_db.rps_status.no_cool)
self.db.annunciator.RCSFlowLow = plc_db.mek_status.ccool_fill < 0.75 or plc_db.mek_status.hcool_fill > 0.25 self.db.annunciator.RCSFlowLow = plc_db.mek_status.ccool_fill < 0.75 or plc_db.mek_status.hcool_fill > 0.25
self.db.annunciator.CoolantLevelLow = plc_db.mek_status.ccool_fill < 0.5
self.db.annunciator.ReactorTempHigh = plc_db.mek_status.temp > 1000 self.db.annunciator.ReactorTempHigh = plc_db.mek_status.temp > 1000
self.db.annunciator.ReactorHighDeltaT = _get_dt(DT_KEYS.ReactorTemp) > 100 self.db.annunciator.ReactorHighDeltaT = _get_dt(DT_KEYS.ReactorTemp) > 100
self.db.annunciator.FuelInputRateLow = _get_dt(DT_KEYS.ReactorFuel) < -1.0 or plc_db.mek_status.fuel_fill <= 0.01 self.db.annunciator.FuelInputRateLow = _get_dt(DT_KEYS.ReactorFuel) < -1.0 or plc_db.mek_status.fuel_fill <= 0.01
self.db.annunciator.WasteLineOcclusion = _get_dt(DT_KEYS.ReactorWaste) > 1.0 or plc_db.mek_status.waste_fill >= 0.85 self.db.annunciator.WasteLineOcclusion = _get_dt(DT_KEYS.ReactorWaste) > 1.0 or plc_db.mek_status.waste_fill >= 0.85
---@todo this is dependent on setup, i.e. how much coolant is buffered and the turbine setup
self.db.annunciator.HighStartupRate = not plc_db.mek_status.status and plc_db.mek_status.burn_rate > 40 -- this warning applies when no coolant is buffered (which we can't easily determine without running)
--[[
logic is that each tick, the heating rate worth of coolant steps between:
reactor tank
reactor heated coolant outflow tube
boiler/turbine tank
reactor cooled coolant return tube
so if there is a tick where coolant is no longer present in the reactor, then bad things happen.
such as when a burn rate consumes half the coolant in the tank, meaning that:
50% at some point will be in the boiler, and 50% in a tube, so that leaves 0% in the reactor
]]--
local heating_rate_conv = util.trinary(plc_db.mek_status.ccool_type == types.fluid.sodium, 200000, 20000)
local high_rate = (plc_db.mek_status.ccool_amnt / (plc_db.mek_status.burn_rate * heating_rate_conv)) < 4
self.db.annunciator.HighStartupRate = not plc_db.mek_status.status and high_rate
-- if no boilers, use reactor heating rate to check for boil rate mismatch -- if no boilers, use reactor heating rate to check for boil rate mismatch
if num_boilers == 0 then if num_boilers == 0 then