fixed process controller assuming ramp complete if burn rate setpoint was identical to setpoint before process control start

This commit is contained in:
Mikayla Fischler
2023-02-04 13:47:00 -05:00
parent ba8bfb6e14
commit b5c70b0d37
14 changed files with 225 additions and 159 deletions

View File

@@ -41,6 +41,7 @@ function facility.new(num_reactors, cooling_conf)
induction = {},
redstone = {},
status_text = { "START UP", "initializing..." },
all_sys_ok = false,
-- process control
units_ready = false,
mode = PROCESS.INACTIVE,
@@ -199,6 +200,11 @@ function facility.new(num_reactors, cooling_conf)
self.im_stat_init = false
end
self.all_sys_ok = true
for i = 1, #self.units do
self.all_sys_ok = self.all_sys_ok and not self.units[i].get_control_inf().degraded
end
-------------------------
-- Run Process Control --
-------------------------
@@ -570,6 +576,7 @@ function facility.new(num_reactors, cooling_conf)
-- get automatic process control status
function public.get_control_status()
return {
self.all_sys_ok,
self.units_ready,
self.mode,
self.waiting_on_ramp,

View File

@@ -59,6 +59,7 @@ function plc.new_session(id, for_reactor, in_queue, out_queue)
out_q = out_queue,
commanded_state = false,
commanded_burn_rate = 0.0,
auto_cmd_token = 0,
ramping_rate = false,
auto_scram = false,
auto_lock = false,
@@ -92,6 +93,7 @@ function plc.new_session(id, for_reactor, in_queue, out_queue)
-- session database
---@class reactor_db
sDB = {
auto_ack_token = 0,
last_status_update = 0,
control_state = false,
no_reactor = false,
@@ -305,18 +307,19 @@ function plc.new_session(id, for_reactor, in_queue, out_queue)
-- handle packet by type
if pkt.type == RPLC_TYPES.STATUS then
-- status packet received, update data
if pkt.length >= 4 then
if pkt.length >= 5 then
self.sDB.last_status_update = pkt.data[1]
self.sDB.control_state = pkt.data[2]
self.sDB.no_reactor = pkt.data[3]
self.sDB.formed = pkt.data[4]
self.sDB.auto_ack_token = pkt.data[5]
if not self.sDB.no_reactor and self.sDB.formed then
self.sDB.mek_status.heating_rate = pkt.data[5] or 0.0
self.sDB.mek_status.heating_rate = pkt.data[6] or 0.0
-- attempt to read mek_data table
if pkt.data[6] ~= nil then
local status = pcall(_copy_status, pkt.data[6])
if pkt.data[7] ~= nil then
local status = pcall(_copy_status, pkt.data[7])
if status then
-- copied in status data OK
self.received_status_cache = true
@@ -496,6 +499,11 @@ function plc.new_session(id, for_reactor, in_queue, out_queue)
-- get the session database
function public.get_db() return self.sDB end
-- check if ramping is completed by first verifying auto command token ack
function public.is_ramp_complete()
return (self.sDB.auto_ack_token == self.auto_cmd_token) and (self.commanded_burn_rate == self.sDB.mek_status.act_burn_rate)
end
-- get the reactor structure
function public.get_struct()
if self.received_struct then
@@ -618,6 +626,7 @@ function plc.new_session(id, for_reactor, in_queue, out_queue)
cmd.val = math.floor(cmd.val * 10) / 10 -- round to 10ths place
if cmd.val > 0 and cmd.val <= self.sDB.mek_struct.max_burn then
self.commanded_burn_rate = cmd.val
self.auto_cmd_token = 0
self.ramping_rate = false
self.acks.burn_rate = false
self.retry_times.burn_rate_req = util.time() + INITIAL_WAIT
@@ -630,6 +639,7 @@ function plc.new_session(id, for_reactor, in_queue, out_queue)
cmd.val = math.floor(cmd.val * 10) / 10 -- round to 10ths place
if cmd.val > 0 and cmd.val <= self.sDB.mek_struct.max_burn then
self.commanded_burn_rate = cmd.val
self.auto_cmd_token = 0
self.ramping_rate = true
self.acks.burn_rate = false
self.retry_times.burn_rate_req = util.time() + INITIAL_WAIT
@@ -640,14 +650,15 @@ function plc.new_session(id, for_reactor, in_queue, out_queue)
-- set automatic burn rate
if self.auto_lock then
cmd.val = math.floor(cmd.val * 10) / 10 -- round to 10ths place
if cmd.val > 0 and cmd.val <= self.sDB.mek_struct.max_burn then
if cmd.val >= 0 and cmd.val <= self.sDB.mek_struct.max_burn then
self.auto_cmd_token = util.time_ms()
self.commanded_burn_rate = cmd.val
-- this is only for manual control, only retry auto ramps
self.acks.burn_rate = not self.ramping_rate
self.retry_times.burn_rate_req = util.time() + INITIAL_AUTO_WAIT
_send(RPLC_TYPES.AUTO_BURN_RATE, { self.commanded_burn_rate, self.ramping_rate })
_send(RPLC_TYPES.AUTO_BURN_RATE, { self.commanded_burn_rate, self.ramping_rate, self.auto_cmd_token })
end
end
else
@@ -717,10 +728,19 @@ function plc.new_session(id, for_reactor, in_queue, out_queue)
if not self.acks.burn_rate then
if rtimes.burn_rate_req - util.time() <= 0 then
if self.auto_lock then
_send(RPLC_TYPES.AUTO_BURN_RATE, { self.commanded_burn_rate, self.ramping_rate })
else
if self.auto_cmd_token > 0 then
if self.auto_lock then
_send(RPLC_TYPES.AUTO_BURN_RATE, { self.commanded_burn_rate, self.ramping_rate, self.auto_cmd_token })
log.debug("retried auto burn rate?")
else
-- would have been an auto command, but disengaged, so stop retrying
self.acks.burn_rate = true
end
elseif not self.auto_lock then
_send(RPLC_TYPES.MEK_BURN_RATE, { self.commanded_burn_rate, self.ramping_rate })
else
-- shouldn't be in this state, just pretend it was acknowledged
self.acks.burn_rate = true
end
rtimes.burn_rate_req = util.time() + RETRY_PERIOD

View File

@@ -409,8 +409,7 @@ function unit.new(for_reactor, num_boilers, num_turbines)
---@return boolean complete
function public.a_ramp_complete()
if self.plc_i ~= nil then
local cur_rate = math.floor(self.plc_i.get_db().mek_status.burn_rate * 10)
return (cur_rate == self.ramp_target_br10) or (self.ramp_target_br10 == 0)
return self.plc_i.is_ramp_complete()
else return true end
end

View File

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