Более менее работающий шлюз
This commit is contained in:
508
AirlockRTL.lua
508
AirlockRTL.lua
@@ -1,258 +1,278 @@
|
|||||||
-- Airlock control v2.0
|
-- AirlockRTL.lua — Контроллер шлюза (State Machine)
|
||||||
-- Физическая раскладка шлюза:
|
-- =================================================
|
||||||
-- Слева — большая внешняя дверь (наружу, под воду)
|
--
|
||||||
-- Справа (изнутри) — стеклянная внутренняя дверь (внутрь станции)
|
-- Физическая схема:
|
||||||
-- Кнопки внутри шлюза (слева направо):
|
-- [Сухой отсек] — [Внутр.дверь] — [ШЛЮЗ] — [Наруж.дверь] — [Снаружи/вода]
|
||||||
-- Пин 3 = левая кнопка = внутренняя (вход 4)
|
--
|
||||||
-- Пин 4 = средняя кнопка = правая внутри (вход 3)
|
-- Входы:
|
||||||
-- Пин 5 = наружная правая кнопка снаружи (вход 5)
|
-- 1 — состояние наружней (левой) двери (1=открыта)
|
||||||
|
-- 2 — состояние внутренней (правой) двери (1=открыта)
|
||||||
-- === Состояния ===
|
-- 3 — кнопка внутри шлюза (слева) — вход в шлюз из сухого отсека
|
||||||
-- IDLE — вода ~0%, обе двери закрыты. Ожидание команды.
|
-- 4 — кнопка внутри шлюза (центр) — выход из шлюза (контекстно)
|
||||||
-- FLOODING — насос качает воду внутрь (подготовка к выходу). "Затопление"
|
-- 5 — кнопка снаружи — вход в шлюз снаружи
|
||||||
-- READY_OUT — вода ≥95%, внутр.дверь закрыта, внешн. закрыта. "Готов вых"
|
-- 6 — уровень воды в шлюзе (0 = пусто, 100 = полно)
|
||||||
-- READY_IN — вода ≥95%, внутр.дверь закрыта, внешн. ОТКРЫТА. "Готов Вх"
|
--
|
||||||
-- DRAINING — насос откачивает воду (после входа снаружи). "Осушение"
|
-- Выходы:
|
||||||
-- FAULT — нештатная ситуация. "Неисправен"
|
-- 1 — наружняя дверь (1=открыть, 0=закрыть)
|
||||||
|
-- 2 — внутренняя дверь (1=открыть, 0=закрыть)
|
||||||
-- === Входы ===
|
-- 3 — насос (1=вкл, 0=выкл)
|
||||||
-- 1 — левая дверь (внешняя): 0=закрыта, 1=открыта
|
-- 4 — целевой уровень воды (-100=осушить, +100=заполнить)
|
||||||
-- 2 — правая дверь (внутренняя): 0=закрыта, 1=открыта
|
|
||||||
-- 3 — правая кнопка (внутри, пин 4)
|
|
||||||
-- 4 — внутренняя кнопка (внутри, левая, пин 3)
|
|
||||||
-- 5 — наружная правая кнопка (снаружи, пин 5)
|
|
||||||
-- 6 — уровень воды в шлюзе (-100..100)
|
|
||||||
|
|
||||||
-- === Выходы ===
|
|
||||||
-- 1 — внешняя дверь: 1=открыть, 0=закрыть
|
|
||||||
-- 2 — внутренняя дверь: 1=открыть, 0=закрыть
|
|
||||||
-- 3 — насос: 1=вкл, 0=выкл
|
|
||||||
-- 4 — целевой уровень воды (-100 сухо, 100 заполнен)
|
|
||||||
-- 5 — текст статуса
|
-- 5 — текст статуса
|
||||||
-- 6 — цвет текста (rrr,ggg,bbb)
|
-- 6 — цвет текста (rrr,ggg,bbb)
|
||||||
|
--
|
||||||
|
-- Принцип: любое нажатие сначала управляет водой, затем дверью.
|
||||||
|
-- Слева всегда море (вода), справа отсек (сухо).
|
||||||
|
-- Направление (flow) запоминается при входе.
|
||||||
|
--
|
||||||
|
-- Сценарий FLOW_OUT (в море):
|
||||||
|
-- btn3 → если вода >10 осушить → открыть внутрь → войти
|
||||||
|
-- → btn4/timer → закрыть внутрь → осушить (btn4 = пропуск) → открыть внешнюю
|
||||||
|
-- → выйти → btn4/timer → закрыть внешнюю → IDLE
|
||||||
|
--
|
||||||
|
-- Сценарий FLOW_IN (в отсек):
|
||||||
|
-- btn5 → затопить (btn4 = пропуск) → открыть внешнюю → войти
|
||||||
|
-- → btn4/timer → закрыть внешнюю → осушить (btn4 = пропуск)
|
||||||
|
-- → открыть внутрь → войти → btn4/timer → закрыть внутрь → IDLE
|
||||||
|
--
|
||||||
|
-- btn4 из IDLE: направление по flow (запомнен при входе), иначе по воде.
|
||||||
|
|
||||||
|
-- Состояния автомата
|
||||||
|
local ST_IDLE = 0 -- Ожидание команд
|
||||||
|
local ST_OPEN_IN = 1 -- Открытие внутренней двери
|
||||||
|
local ST_WAIT_IN = 2 -- Ожидание прохода через внутреннюю дверь
|
||||||
|
local ST_CLOSE_IN = 3 -- Закрытие внутренней двери
|
||||||
|
local ST_DRAIN_EXIT = 4 -- Осушение для выхода наружу
|
||||||
|
local ST_FLOOD = 5 -- Заполнение для входа снаружи
|
||||||
|
local ST_DRAIN_RET = 6 -- Осушение для возврата в сухой отсек
|
||||||
|
local ST_OPEN_OUT = 7 -- Открытие внешней двери
|
||||||
|
local ST_WAIT_OUT = 8 -- Ожидание прохода через внешнюю дверь
|
||||||
|
local ST_CLOSE_OUT = 9 -- Закрытие внешней двери
|
||||||
|
|
||||||
|
-- Сценарии
|
||||||
|
local FLOW_NONE = 0
|
||||||
|
local FLOW_OUT = 1 -- Из сухого наружу
|
||||||
|
local FLOW_IN = 2 -- Снаружи в сухой
|
||||||
|
|
||||||
|
-- Параметры (шкала воды: 0 = пусто, 100 = полно)
|
||||||
|
local WAIT_TIMEOUT = 5 -- секунд ожидания у открытой двери
|
||||||
|
local DRAIN_THRESHOLD = 5 -- почти пусто (выход в море)
|
||||||
|
local INNER_THRESHOLD = 10 -- можно открыть внутрь (по запросу: вода ниже 10%)
|
||||||
|
local FLOOD_THRESHOLD = 95 -- почти полно (вход снаружи)
|
||||||
|
local WATER_OPEN_SAFE = 10 -- при btn3: если воды > 10%, сначала осушить
|
||||||
|
|
||||||
|
-- Переменные состояния
|
||||||
|
local state = ST_IDLE
|
||||||
|
local flow = FLOW_NONE
|
||||||
|
local timer = 0
|
||||||
|
|
||||||
|
-- Предыдущие значения кнопок для детекции фронта
|
||||||
|
local prev3 = false
|
||||||
|
local prev4 = false
|
||||||
|
local prev5 = false
|
||||||
|
|
||||||
|
-- Установка текста и цвета статуса
|
||||||
|
local function setStatus(text, color)
|
||||||
|
out[5] = text
|
||||||
|
out[6] = color
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Сброс в IDLE: закрыть двери, выключить насос, контекст (flow) сохраняется
|
||||||
|
local function goIdle()
|
||||||
|
out[1] = 0
|
||||||
|
out[2] = 0
|
||||||
|
out[3] = 0
|
||||||
|
setStatus("Готов", "0,255,0")
|
||||||
|
state = ST_IDLE
|
||||||
|
timer = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Инициализация при старте
|
||||||
|
out[1] = 0
|
||||||
|
out[2] = 0
|
||||||
|
out[3] = 0
|
||||||
|
setStatus("Готов", "0,255,0")
|
||||||
|
|
||||||
inp = {}
|
inp = {}
|
||||||
--out = {
|
|
||||||
--[1] = 0,
|
|
||||||
--[2] = 0,
|
|
||||||
--[3] = 0,
|
|
||||||
--[4] = 0,
|
|
||||||
--[5] = "",
|
|
||||||
--[6] = "100,180,100",
|
|
||||||
--}
|
|
||||||
|
|
||||||
-- Константы задержек (сек)
|
|
||||||
local MIN_FLOOD_TIME = 4.0
|
|
||||||
local MIN_DRAIN_TIME = 4.0
|
|
||||||
local INTERNAL_DOOR_DELAY = 4.0
|
|
||||||
local FAULT_HYSTERESIS = 2.0
|
|
||||||
|
|
||||||
local S = {
|
|
||||||
IDLE = 0,
|
|
||||||
FLOODING = 1,
|
|
||||||
READY_OUT = 2,
|
|
||||||
READY_IN = 3,
|
|
||||||
DRAINING = 4,
|
|
||||||
FAULT = 5,
|
|
||||||
}
|
|
||||||
|
|
||||||
local state = S.IDLE
|
|
||||||
local stateTimer = 0.0
|
|
||||||
local doorTimer = 0.0
|
|
||||||
local openIntDoor= false -- флаг: открыть внутреннюю дверь (пропустить человека)
|
|
||||||
|
|
||||||
-- Детекция фронта кнопок
|
|
||||||
local prevBtn = { [3] = 0, [4] = 0, [5] = 0 }
|
|
||||||
local btnEdge = { [3] = 0, [4] = 0, [5] = 0 }
|
|
||||||
|
|
||||||
local STATUS_TEXT = {
|
|
||||||
[S.IDLE] = "",
|
|
||||||
[S.FLOODING] = "Затопление",
|
|
||||||
[S.READY_OUT] = "Готов вых",
|
|
||||||
[S.READY_IN] = "Готов Вх",
|
|
||||||
[S.DRAINING] = "Осушение",
|
|
||||||
[S.FAULT] = "Неисправен",
|
|
||||||
}
|
|
||||||
|
|
||||||
local STATUS_COLOR = {
|
|
||||||
[S.IDLE] = "100,180,100",
|
|
||||||
[S.FLOODING] = "255,165,0",
|
|
||||||
[S.READY_OUT] = "0,200,50",
|
|
||||||
[S.READY_IN] = "0,200,200",
|
|
||||||
[S.DRAINING] = "0,100,255",
|
|
||||||
[S.FAULT] = "200,0,0",
|
|
||||||
}
|
|
||||||
|
|
||||||
local function setOutputs(d1, d2, pump, target)
|
|
||||||
out[1] = d1 and 1 or 0
|
|
||||||
out[2] = d2 and 1 or 0
|
|
||||||
out[3] = pump and 1 or 0
|
|
||||||
out[4] = target or 0
|
|
||||||
end
|
|
||||||
|
|
||||||
local function setStatus(s)
|
|
||||||
out[5] = STATUS_TEXT[s] or ""
|
|
||||||
out[6] = STATUS_COLOR[s] or STATUS_COLOR[S.FAULT]
|
|
||||||
end
|
|
||||||
|
|
||||||
local function gotoState(s)
|
|
||||||
if state == s then return end
|
|
||||||
state = s
|
|
||||||
stateTimer = 0.0
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Аварийные условия
|
|
||||||
local function checkFault(water, leftDoor, rightDoor)
|
|
||||||
if rightDoor == 1 and water > 10 then return true end
|
|
||||||
if leftDoor == 1 and rightDoor == 1 then return true end
|
|
||||||
if leftDoor == 1 and water < 50 then return true end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
|
-- Главная функция, вызывается каждый кадр
|
||||||
function upd(dt)
|
function upd(dt)
|
||||||
-- Чтение входов
|
dt = dt or 0
|
||||||
local leftDoor = inp[1] or 0
|
|
||||||
local rightDoor = inp[2] or 0
|
|
||||||
local btnRight = inp[3] or 0
|
|
||||||
local btnInternal= inp[4] or 0
|
|
||||||
local btnExternal= inp[5] or 0
|
|
||||||
local water = inp[6] or 0
|
|
||||||
|
|
||||||
-- Детекция фронтов
|
-- Чтение входов
|
||||||
for _, p in ipairs({3,4,5}) do
|
local doorOut = inp[1] == 1
|
||||||
local v = inp[p] or 0
|
local doorIn = inp[2] == 1
|
||||||
btnEdge[p] = (v == 1 and prevBtn[p] == 0) and 1 or 0
|
local btn3 = inp[3] == 1
|
||||||
prevBtn[p] = v
|
local btn4 = inp[4] == 1
|
||||||
end
|
local btn5 = inp[5] == 1
|
||||||
|
local water = inp[6] or 0
|
||||||
|
|
||||||
stateTimer = stateTimer + dt
|
-- Детекция фронта кнопок (только нажатие, не удержание)
|
||||||
|
local press3 = btn3 and not prev3
|
||||||
|
local press4 = btn4 and not prev4
|
||||||
|
local press5 = btn5 and not prev5
|
||||||
|
prev3 = btn3
|
||||||
|
prev4 = btn4
|
||||||
|
prev5 = btn5
|
||||||
|
|
||||||
-- === Аварийный контроль (высший приоритет) ===
|
-- Флаг: была ли кнопка 4 обработана в машине состояний
|
||||||
if checkFault(water, leftDoor, rightDoor) then
|
local press4consumed = false
|
||||||
gotoState(S.FAULT)
|
|
||||||
end
|
|
||||||
if state == S.FAULT and not checkFault(water, leftDoor, rightDoor)
|
|
||||||
and stateTimer > FAULT_HYSTERESIS then
|
|
||||||
gotoState(S.IDLE)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- === Логика состояний ===
|
-- === Машина состояний ===
|
||||||
|
|
||||||
-- IDLE
|
if state == ST_IDLE then
|
||||||
if state == S.IDLE then
|
-- IDLE: ожидание команд. Обе двери закрыты, оборудование выключено.
|
||||||
-- Если дверь открывали для пропуска — закрыть по таймеру
|
if press3 then
|
||||||
if openIntDoor then
|
-- Вход из сухого отсека: если есть вода — сначала осушаем, затем внутрь
|
||||||
doorTimer = doorTimer + dt
|
if water > WATER_OPEN_SAFE then
|
||||||
openIntDoor = doorTimer < INTERNAL_DOOR_DELAY
|
setStatus("Осушение перед входом...", "0,200,255")
|
||||||
end
|
|
||||||
|
|
||||||
if btnEdge[4] == 1 then
|
|
||||||
-- Внутренняя кнопка → подготовка к выходу (затопление)
|
|
||||||
setOutputs(false, false, true, 100)
|
|
||||||
gotoState(S.FLOODING)
|
|
||||||
|
|
||||||
elseif btnEdge[5] == 1 then
|
|
||||||
-- Наружная кнопка → открыть внешнюю дверь, впустить воду
|
|
||||||
setOutputs(true, false, false, 0)
|
|
||||||
gotoState(S.FLOODING)
|
|
||||||
|
|
||||||
elseif leftDoor == 1 then
|
|
||||||
-- Внешнюю открыли вручную — подтверждаем и начинаем заполнение
|
|
||||||
out[1] = 1
|
|
||||||
gotoState(S.FLOODING)
|
|
||||||
|
|
||||||
else
|
|
||||||
-- Ручное управление внутренней дверью (для пропуска)
|
|
||||||
setOutputs(false, openIntDoor, false, 0)
|
|
||||||
setStatus(S.IDLE)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- FLOODING
|
|
||||||
-- Внешнюю дверь НЕ трогаем — она уже установлена при входе в состояние:
|
|
||||||
-- закрыта (выход — закачка насосом) или открыта (вход — естественное заполнение)
|
|
||||||
elseif state == S.FLOODING then
|
|
||||||
out[2] = 0
|
|
||||||
out[3] = 1
|
out[3] = 1
|
||||||
out[4] = 100
|
out[4] = -100
|
||||||
-- Если дверь открыли вручную — подтверждаем, иначе привод будет бороться
|
flow = FLOW_OUT
|
||||||
if leftDoor == 1 then out[1] = 1 end
|
state = ST_DRAIN_RET
|
||||||
setStatus(S.FLOODING)
|
else
|
||||||
|
setStatus("Открытие внутр. двери...", "0,255,0")
|
||||||
if btnEdge[3] == 1 then
|
out[2] = 1
|
||||||
-- Правая кнопка → отмена, сброс
|
flow = FLOW_OUT
|
||||||
setOutputs(false, false, false, 0)
|
state = ST_OPEN_IN
|
||||||
gotoState(S.IDLE)
|
end
|
||||||
end
|
elseif press5 then
|
||||||
|
-- Вход снаружи → заполнить шлюз водой, затем открыть внешнюю дверь
|
||||||
if water >= 95 and stateTimer >= MIN_FLOOD_TIME then
|
setStatus("Заполнение шлюза...", "255,200,0")
|
||||||
if leftDoor == 1 then
|
out[3] = 1
|
||||||
-- Внешняя открыта, вода есть → готовность к входу
|
out[4] = 100
|
||||||
gotoState(S.READY_IN)
|
flow = FLOW_IN
|
||||||
else
|
state = ST_FLOOD
|
||||||
-- Внешняя закрыта, вода закачана насосом → готовность к выходу
|
elseif press4 then
|
||||||
gotoState(S.READY_OUT)
|
-- Выход из шлюза. Направление: flow (запомнен при входе), иначе уровень воды.
|
||||||
end
|
press4consumed = true
|
||||||
end
|
local dir = flow
|
||||||
|
if dir == FLOW_NONE then
|
||||||
-- READY_OUT
|
dir = (water <= DRAIN_THRESHOLD) and FLOW_OUT or FLOW_IN
|
||||||
-- Не перезаписываем out[1] — внешняя дверь открывается однократно по кнопке
|
flow = dir
|
||||||
elseif state == S.READY_OUT then
|
end
|
||||||
out[2] = 0
|
if dir == FLOW_OUT then
|
||||||
out[3] = 0
|
setStatus("Осушение для выхода...", "0,200,255")
|
||||||
out[4] = 100
|
out[3] = 1
|
||||||
setStatus(S.READY_OUT)
|
out[4] = -100
|
||||||
|
state = ST_DRAIN_EXIT
|
||||||
if btnEdge[3] == 1 then
|
else
|
||||||
out[1] = 1 -- открыть внешнюю дверь (выход)
|
setStatus("Осушение для отсека...", "0,200,255")
|
||||||
end
|
out[3] = 1
|
||||||
|
out[4] = -100
|
||||||
if leftDoor == 1 then
|
state = ST_DRAIN_RET
|
||||||
gotoState(S.READY_IN)
|
end
|
||||||
end
|
|
||||||
|
|
||||||
if btnEdge[4] == 1 then
|
|
||||||
out[1] = 0
|
|
||||||
out[3] = 1
|
|
||||||
out[4] = -100
|
|
||||||
gotoState(S.DRAINING)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- READY_IN
|
|
||||||
elseif state == S.READY_IN then
|
|
||||||
setOutputs(true, false, false, 100)
|
|
||||||
setStatus(S.READY_IN)
|
|
||||||
|
|
||||||
if leftDoor == 0 then
|
|
||||||
-- Внешняя закрыта (человек зашёл) → осушение
|
|
||||||
setOutputs(false, false, true, -100)
|
|
||||||
gotoState(S.DRAINING)
|
|
||||||
|
|
||||||
elseif btnEdge[3] == 1 then
|
|
||||||
-- Правая кнопка → закрыть внешнюю дверь и начать осушение
|
|
||||||
setOutputs(false, false, true, -100)
|
|
||||||
gotoState(S.DRAINING)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- DRAINING
|
|
||||||
elseif state == S.DRAINING then
|
|
||||||
setOutputs(false, false, true, -100)
|
|
||||||
setStatus(S.DRAINING)
|
|
||||||
|
|
||||||
if btnEdge[3] == 1 then
|
|
||||||
-- Правая кнопка → отмена осушения
|
|
||||||
setOutputs(false, false, false, 0)
|
|
||||||
gotoState(S.IDLE)
|
|
||||||
end
|
|
||||||
|
|
||||||
if water <= 5 and stateTimer >= MIN_DRAIN_TIME then
|
|
||||||
openIntDoor = true
|
|
||||||
doorTimer = 0.0
|
|
||||||
gotoState(S.IDLE)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- FAULT
|
|
||||||
elseif state == S.FAULT then
|
|
||||||
setOutputs(false, false, false, 0)
|
|
||||||
setStatus(S.FAULT)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
elseif state == ST_OPEN_IN then
|
||||||
|
-- Открытие внутренней двери. Ждём сигнала от двери.
|
||||||
|
out[2] = 1
|
||||||
|
if doorIn then
|
||||||
|
timer = 0
|
||||||
|
setStatus("Внутр. дверь открыта. Войдите.", "0,255,0")
|
||||||
|
state = ST_WAIT_IN
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif state == ST_WAIT_IN then
|
||||||
|
-- Внутренняя дверь открыта. Ждём прохода человека (btn4 или таймер).
|
||||||
|
out[2] = 1
|
||||||
|
timer = timer + dt
|
||||||
|
if press4 or timer >= WAIT_TIMEOUT then
|
||||||
|
press4consumed = press4
|
||||||
|
setStatus("Закрытие внутр. двери...", "255,200,0")
|
||||||
|
out[2] = 0
|
||||||
|
state = ST_CLOSE_IN
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif state == ST_CLOSE_IN then
|
||||||
|
-- Закрытие внутренней двери. Ждём полного закрытия.
|
||||||
|
if not doorIn then
|
||||||
|
if flow == FLOW_OUT then
|
||||||
|
-- Сценарий "в море": после входа → осушение и выход
|
||||||
|
setStatus("Осушение для выхода...", "0,200,255")
|
||||||
|
out[3] = 1
|
||||||
|
out[4] = -100
|
||||||
|
state = ST_DRAIN_EXIT
|
||||||
|
else
|
||||||
|
-- Вернулись в отсек: завершено
|
||||||
|
setStatus("Готов", "0,255,0")
|
||||||
|
flow = FLOW_NONE
|
||||||
|
state = ST_IDLE
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif state == ST_DRAIN_EXIT then
|
||||||
|
-- Осушение шлюза перед выходом в море.
|
||||||
|
out[3] = 1
|
||||||
|
out[4] = -100
|
||||||
|
if water <= DRAIN_THRESHOLD or press4 then
|
||||||
|
press4consumed = press4
|
||||||
|
setStatus("Открытие внеш. двери...", "0,200,255")
|
||||||
|
out[3] = 0
|
||||||
|
out[1] = 1
|
||||||
|
state = ST_OPEN_OUT
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif state == ST_FLOOD then
|
||||||
|
-- Заполнение шлюза для входа снаружи (уравнивание давления).
|
||||||
|
out[3] = 1
|
||||||
|
out[4] = 100
|
||||||
|
if water >= FLOOD_THRESHOLD or press4 then
|
||||||
|
press4consumed = press4
|
||||||
|
setStatus("Открытие внеш. двери...", "255,200,0")
|
||||||
|
out[3] = 0
|
||||||
|
out[1] = 1
|
||||||
|
state = ST_OPEN_OUT
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif state == ST_DRAIN_RET then
|
||||||
|
-- Осушение шлюза для входа в сухой отсек (можно раньше, порог INNER_THRESHOLD).
|
||||||
|
out[3] = 1
|
||||||
|
out[4] = -100
|
||||||
|
if water <= INNER_THRESHOLD or press4 then
|
||||||
|
press4consumed = press4
|
||||||
|
setStatus("Открытие внутр. двери...", "0,255,0")
|
||||||
|
out[3] = 0
|
||||||
|
out[2] = 1
|
||||||
|
state = ST_OPEN_IN
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif state == ST_OPEN_OUT then
|
||||||
|
-- Открытие внешней двери. Ждём сигнала от двери.
|
||||||
|
out[1] = 1
|
||||||
|
if doorOut then
|
||||||
|
timer = 0
|
||||||
|
setStatus("Внеш. дверь открыта. Выходите.", "0,200,255")
|
||||||
|
state = ST_WAIT_OUT
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif state == ST_WAIT_OUT then
|
||||||
|
-- Внешняя дверь открыта. Ждём прохода человека (btn4 или таймер).
|
||||||
|
out[1] = 1
|
||||||
|
timer = timer + dt
|
||||||
|
if press4 or timer >= WAIT_TIMEOUT then
|
||||||
|
press4consumed = press4
|
||||||
|
setStatus("Закрытие внеш. двери...", "255,200,0")
|
||||||
|
out[1] = 0
|
||||||
|
state = ST_CLOSE_OUT
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif state == ST_CLOSE_OUT then
|
||||||
|
-- Закрытие внешней двери. Ждём полного закрытия.
|
||||||
|
if not doorOut then
|
||||||
|
if flow == FLOW_IN then
|
||||||
|
-- Сценарий "снаружи": после закрытия — осушение и вход в отсек
|
||||||
|
setStatus("Осушение после входа...", "0,200,255")
|
||||||
|
out[3] = 1
|
||||||
|
out[4] = -100
|
||||||
|
state = ST_DRAIN_RET
|
||||||
|
else
|
||||||
|
-- Сценарий "наружу": завершён
|
||||||
|
setStatus("Готов", "0,255,0")
|
||||||
|
state = ST_IDLE
|
||||||
|
flow = FLOW_NONE
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.clear(inp)
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user