mirror of
https://github.com/metrostroi-repo/MetrostroiAddon.git
synced 2026-05-02 00:42:29 +00:00
init
This commit is contained in:
300
lua/metrostroi/systems/sys_ars_mp.lua
Normal file
300
lua/metrostroi/systems/sys_ars_mp.lua
Normal file
@@ -0,0 +1,300 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- ARS-MP safety system
|
||||
--------------------------------------------------------------------------------
|
||||
-- Copyright (C) 2013-2018 Metrostroi Team & FoxWorks Aerospace s.r.o.
|
||||
-- Contains proprietary code. See license.txt for additional information.
|
||||
--------------------------------------------------------------------------------
|
||||
Metrostroi.DefineSystem("ARS_MP")
|
||||
TRAIN_SYSTEM.DontAccelerateSimulation = false
|
||||
|
||||
function TRAIN_SYSTEM:Initialize()
|
||||
self.Train:LoadSystem("UOS","Relay","Switch", {bass = true})
|
||||
self.Train:LoadSystem("ALSFreq","Relay","Switch",{bass=true})
|
||||
self.Train:LoadSystem("AB1","Relay","Switch",{bass=true})
|
||||
self.Train:LoadSystem("AB2","Relay","Switch",{bass=true})
|
||||
self.Train:LoadSystem("EPKContacts","Relay","",{close_time = 3})
|
||||
self.Train:LoadSystem("ROT1","Relay","", { bass = true})
|
||||
self.Train:LoadSystem("ROT2","Relay","", { bass = true})
|
||||
|
||||
self.Train:LoadSystem("EPKC","Relay")
|
||||
-- Internal state
|
||||
self.SpeedLimit = 0
|
||||
self.NextLimit = 0
|
||||
self.AB = 0
|
||||
self.AV = 0
|
||||
self.AV1 = 0
|
||||
self.ARSRing = 0
|
||||
self.KRT = 0
|
||||
self.KRO = 0
|
||||
self.KRH = 0
|
||||
--[[ self.Overspeed = false
|
||||
self.RUVD = false
|
||||
self.PneumaticBrake1 = false
|
||||
self.PneumaticBrake2 = true
|
||||
self.AttentionPedal = false--]]
|
||||
|
||||
self.KVT = false
|
||||
self.LN = 0
|
||||
self["2"] = 0
|
||||
self["25"] = 0
|
||||
self["20"] = 0
|
||||
self["33G"] = 0
|
||||
self["33"] = 0
|
||||
self["17"] = 0
|
||||
self["8"] = 0
|
||||
self["44"] = 0
|
||||
self["48"] = 0
|
||||
|
||||
self.EK = 1
|
||||
|
||||
self.F6 = 0
|
||||
self.F5 = 0
|
||||
self.PrevF5 = 0
|
||||
self.F4 = 0
|
||||
self.F3 = 0
|
||||
self.F2 = 0
|
||||
self.F1 = 0
|
||||
self.NoFreq = 0
|
||||
self.PrevNoFreq = 0
|
||||
|
||||
self.ARS = 0
|
||||
self.AB = 0
|
||||
self.AV = 0
|
||||
self.AV1 = 0
|
||||
|
||||
self.ABReady = 0
|
||||
|
||||
-- Lamps
|
||||
---self.LKT = false
|
||||
self.LVD = 0
|
||||
self.Ring = 0
|
||||
end
|
||||
|
||||
function TRAIN_SYSTEM:Outputs()
|
||||
return {
|
||||
--"2","25","20","33G","33","17","8","44","48",
|
||||
"NoFreq","F1","F2","F3","F4","F5","F6","LN","ARS","AB","KT","LVD","ABReady"
|
||||
}
|
||||
end
|
||||
|
||||
function TRAIN_SYSTEM:Inputs()
|
||||
return { "IgnoreThisARS","AttentionPedal","Ring" }
|
||||
end
|
||||
|
||||
function TRAIN_SYSTEM:TriggerInput(name,value)
|
||||
end
|
||||
|
||||
|
||||
function TRAIN_SYSTEM:Think(dT)
|
||||
local Train = self.Train
|
||||
local ALS = Train.ALSCoil
|
||||
local speed = math.Round(ALS.Speed or 0,1)
|
||||
|
||||
local power = self.GE > 0
|
||||
local TwoToSix = self.Freq > 0
|
||||
-- ALS, ARS state
|
||||
|
||||
if power and not self.EnableARSTimer then
|
||||
self.EnableARSTimer = CurTime()+1+math.random()*9
|
||||
elseif not power and self.EnableARSTimer then
|
||||
self.EnableARSTimer = nil
|
||||
end
|
||||
|
||||
if ALS.Enabled~=self.ALS then
|
||||
ALS:TriggerInput("Enable",self.ALS)
|
||||
end
|
||||
local Power = self.EnableARSTimer and CurTime()-self.EnableARSTimer > 0
|
||||
|
||||
local KVT = self.KB > 0
|
||||
|
||||
local F1 = ALS.F1*self.ALS
|
||||
local F2 = ALS.F2*self.ALS
|
||||
local F3 = ALS.F3*self.ALS
|
||||
local F4 = ALS.F4*self.ALS
|
||||
local F5 = ALS.F5*self.ALS
|
||||
local F6 = ALS.F6*self.ALS
|
||||
local FreqCount = F1+F2+F3+F4+F5+F6
|
||||
local TwoFreq = FreqCount==2
|
||||
if self.AB > 0 then
|
||||
if FreqCount>0 then self.AB = 0 end
|
||||
F1 = 1
|
||||
F2 = 0
|
||||
F3 = 0
|
||||
F4 = 0
|
||||
F5 = 0
|
||||
F6 = 0
|
||||
elseif TwoToSix and not TwoFreq then
|
||||
F1 = 0
|
||||
F2 = 0
|
||||
F3 = 0
|
||||
F4 = math.min(1,F1+F2+F3+F4)
|
||||
elseif not TwoToSix and TwoFreq then
|
||||
F1 = 0
|
||||
F2 = 0
|
||||
F3 = 0
|
||||
F4 = 0
|
||||
F5 = 0
|
||||
F6 = 0
|
||||
end
|
||||
local FreqCode = bit.bor(F1*1,F2*2,F3*4,F4*8,F5*16,F6*32,self.ALS*64,self.GE*128)
|
||||
if self.FreqCode ~= FreqCode then
|
||||
if not self.FreqCodeTimer then self.FreqCodeTimer = CurTime() end
|
||||
if self.FreqCodeTimer and CurTime()-self.FreqCodeTimer>0.8 then
|
||||
self.FreqCode = FreqCode
|
||||
self.FreqCodeTimer = nil
|
||||
|
||||
self.F1 = F1
|
||||
self.F2 = F2
|
||||
self.F3 = F3
|
||||
self.F4 = F4
|
||||
self.F5 = F5
|
||||
self.F6 = F6
|
||||
self.NoFreq = (1-math.min(1,(self.F1+self.F2+self.F3+self.F4+self.F5+self.F6)))*math.min(1,self.ALS+self.GE)
|
||||
end
|
||||
elseif self.FreqCodeTimer then
|
||||
self.FreqCodeTimer = nil
|
||||
end
|
||||
if power or self.ALS > 0 --[[ or self.AB > 0--]] then
|
||||
local Vlimit = 20
|
||||
if self.F4 > 0 then Vlimit = 40 end
|
||||
if self.F3 > 0 then Vlimit = 60 end
|
||||
if self.F2 > 0 then Vlimit = 70 end
|
||||
if self.F1 > 0 then Vlimit = 80 end
|
||||
-- Determine next limit and current limit
|
||||
self.SpeedLimit = Vlimit
|
||||
|
||||
self.NextLimit = Vlimit
|
||||
if self.F1 > 0 then self.NextLimit = 80 end
|
||||
if self.F2 > 0 then self.NextLimit = 70 end
|
||||
if self.F3 > 0 then self.NextLimit = 60 end
|
||||
if self.F4 > 0 then self.NextLimit = 40 end
|
||||
if self.F5 > 0 then self.NextLimit = 20 end
|
||||
|
||||
if self.F4 > 0 and self.F6 > 0 then
|
||||
self.NG = true
|
||||
end
|
||||
if TwoToSix and self.LN==0 and self.AB==0 then self.SpeedLimit=20 end
|
||||
if KVT and self.SpeedLimit <= 40 then self.SpeedLimit = 20 end
|
||||
if KVT and self.SpeedLimit > 40 then self.SpeedLimit = 40 end
|
||||
else
|
||||
self.F1 = 0
|
||||
self.F2 = 0
|
||||
self.F3 = 0
|
||||
self.F4 = 0
|
||||
self.F5 = 0
|
||||
self.F6 = 0
|
||||
self.SpeedLimit = 0
|
||||
self.NextLimit = 0
|
||||
self.NoFreq = 0
|
||||
self.FreqCodeTimer = nil
|
||||
self.FreqCode = 0
|
||||
end
|
||||
if Power then
|
||||
self.ABReady = (1-self.AB)*(FreqCount*self.ALS == 0 and 1 or 0)
|
||||
local ABAccept = self.ABReady > 0 --self.NoFreq--[[ *ALS.Enabled--]] > 0
|
||||
if ABAccept and not self.ABPressed1 and Train.AB1.Value > 0 then self.ABPressed1 = CurTime() end
|
||||
if ABAccept and not self.ABPressed2 and Train.AB2.Value > 0 then self.ABPressed2 = CurTime() end
|
||||
if not ABAccept or Train.AB1.Value == 0 then self.ABPressed1 = nil end
|
||||
if not ABAccept or Train.AB2.Value == 0 then self.ABPressed2 = nil end
|
||||
if self.ABPressed1 and self.ABPressed2 and math.abs(self.ABPressed1-self.ABPressed2) < 1 then
|
||||
self.AB = 1
|
||||
end
|
||||
self.ARS = 1-self.AB
|
||||
local NoFreq = (self.Freq>0 and self.LN==0) or self.NoFreq>0
|
||||
self.BR2 = KVT and NoFreq and not self.BR1
|
||||
self.BR1 = KVT and (self.BR1 or not NoFreq) and not self.BR2
|
||||
|
||||
|
||||
local SpeedLimit = self.SpeedLimit
|
||||
if (speed > SpeedLimit) and not self.RUVD or SpeedLimit<=20 and not (self.BR1 or self.BR2) then
|
||||
self.RUVD = true
|
||||
self.RNT = self.RNT or self.KRT==0
|
||||
elseif speed < SpeedLimit-0.5 and self.RUVD and not self.RNT then
|
||||
self.RUVD = false
|
||||
end
|
||||
if (self.BR1 or self.BR2) and self.RNT then
|
||||
self.RNT = false
|
||||
end
|
||||
if self.RO==true and self.KRH > 0 then
|
||||
self.RO = CurTime()
|
||||
end
|
||||
if self.RO and self.RO~=true and CurTime()-self.RO >7 then
|
||||
self.RO = false
|
||||
if speed<5 and not NoFreq then self.ROBrake = true end
|
||||
end
|
||||
if self.RO and speed > 5 then self.RO = false end
|
||||
if self.RO~=true and speed <= 5 and self.KRH == 0 then self.RO = true end
|
||||
if self.RO and self.BR2 then self.RO = false end
|
||||
|
||||
if self.RUVD then
|
||||
if not self.PN1Timer then self.PN1Timer = CurTime()+3.5-math.max(0,(speed-20))/60*2.5 end
|
||||
if not self.TW8Timer then self.TW8Timer = self.SpeedLimit<=20 and CurTime()-3 or CurTime() end
|
||||
end
|
||||
if not self.RUVD then
|
||||
if self.PN1Timer then self.PN1Timer = false end
|
||||
if self.TW8Timer then self.TW8Timer = false end
|
||||
end
|
||||
|
||||
local brake = (self.RUVD or self.ROBrake) and 1 or 0
|
||||
local pn1 = (self.RO == true or (self.PN1Timer and CurTime()-self.PN1Timer < 0)) and 1 or 0
|
||||
local pn2 = (self.TW8Timer and CurTime()-self.TW8Timer > 2.7) and 1 or 0
|
||||
|
||||
self["33"] = (1-self.LVD)
|
||||
self["33G"] = brake
|
||||
self["17"] = (1-self.LVD)
|
||||
self["2"] = brake*self.KRT
|
||||
self["20"] = brake
|
||||
self["25"] = (1-self.LVD)
|
||||
self["44"] = pn1
|
||||
self["48"] = pn1
|
||||
self["8"] = brake*pn2
|
||||
self.Ring = self.RNT and 1 or 0
|
||||
|
||||
local delay = 3.5
|
||||
if 10 < speed and speed < 30 then delay = 5.5 end
|
||||
if speed < 3 then delay = 10 end
|
||||
if (self.RUVD or speed<5 and not NoFreq) and self.KT == 0 then
|
||||
if not self.EPKTimer then self.EPKTimer = CurTime() end
|
||||
else
|
||||
self.EPKTimer = nil
|
||||
end
|
||||
if self.EPKTimer and CurTime()-self.EPKTimer > delay then
|
||||
self.EK = 0
|
||||
end
|
||||
self.LVD = math.min(1-self.KRO,self.LVD+brake)
|
||||
self.LN = self.NG and self.Freq or 0
|
||||
else
|
||||
self.BR1 = 0
|
||||
self.BR2 = 0
|
||||
self.EK = 1
|
||||
self.AB = 0
|
||||
self.ARS = 0
|
||||
self.LN = 0
|
||||
self.NG = false
|
||||
self.ABPressed1 = nil
|
||||
self.ABPressed2 = nil
|
||||
self.Ring = 0
|
||||
self.ROBrake = false
|
||||
self.LVD = 0
|
||||
self.ABReady = 0
|
||||
|
||||
self.RUVD = true
|
||||
self.RNT = true
|
||||
|
||||
self["33"] = 0
|
||||
self["33G"] = 0
|
||||
self["17"] = 0
|
||||
self["2"] = 0
|
||||
self["20"] = 0
|
||||
self["25"] = 0
|
||||
self["44"] = 0
|
||||
self["48"] = 0
|
||||
self["8"] = 0
|
||||
end
|
||||
|
||||
|
||||
self.EPK = self.GE*self.EK
|
||||
--Train:WriteTrainWire(90,self.EPK*(1-Train.ARS.Value))
|
||||
--Train.EPKC:TriggerInput("Set",self.EPK+Train:ReadTrainWire(90))
|
||||
Train.EPKC:TriggerInput("Set",self.EPK)
|
||||
end
|
||||
Reference in New Issue
Block a user