mirror of
https://github.com/metrostroi-repo/MetrostroiAddon.git
synced 2026-05-02 00:42:29 +00:00
271 lines
9.5 KiB
Lua
271 lines
9.5 KiB
Lua
--------------------------------------------------------------------------------
|
|
-- Блок контроля безопасности движения 718
|
|
--------------------------------------------------------------------------------
|
|
Metrostroi.DefineSystem("81_718_BKBD")
|
|
|
|
function TRAIN_SYSTEM:Initialize()
|
|
self.Train:LoadSystem("ALSCoil")
|
|
self.Power = 0
|
|
self.FMM1 = 0
|
|
|
|
self.KB = 0
|
|
self.Ring = 0
|
|
self.KRH = 0
|
|
self.Drive = 0
|
|
self.Brake = 0
|
|
self.EPKContacts = 0
|
|
self.V0 = 0
|
|
|
|
self.F1 = 0
|
|
self.F2 = 0
|
|
self.F3 = 0
|
|
self.F4 = 0
|
|
self.F5 = 0
|
|
self.F6 = 0
|
|
self.RealF5 = 0
|
|
self.NoFreq = 0
|
|
-- Реле педали бдительности (РПБ)
|
|
self.Train:LoadSystem("RPB","Relay","REV-813T", { bass = true, open_time = 2.5,})
|
|
self.Train:LoadSystem("ROT1","Relay","", { bass = true})
|
|
self.Train:LoadSystem("ROT2","Relay","", { bass = true})
|
|
|
|
|
|
self.Train:LoadSystem("ARS_NG","Relay","")
|
|
self.Train:LoadSystem("ARS_NH","Relay","")
|
|
self.Train:LoadSystem("KPK1","Relay","")
|
|
self.Train:LoadSystem("KPK2","Relay","")
|
|
end
|
|
|
|
function TRAIN_SYSTEM:Inputs()
|
|
return { }
|
|
end
|
|
|
|
local outputs = {"NoFreq","F5","F4","F3","F2","F1"}
|
|
function TRAIN_SYSTEM:Outputs()
|
|
return outputs
|
|
end
|
|
|
|
function TRAIN_SYSTEM:TriggerInput(name,value)
|
|
end
|
|
if not math.Round then
|
|
function math.Round( num, idp )
|
|
|
|
local mult = 10 ^ ( idp or 0 )
|
|
return math.floor( num * mult + 0.5 ) / mult
|
|
|
|
end
|
|
end
|
|
|
|
--A48-self.PBPower
|
|
--KRU*A42+A48*KV*A79 - self.FMM1
|
|
--KRU*A17+A48*KV*A29- self.FMM2
|
|
function TRAIN_SYSTEM:Think()
|
|
local Train = self.Train
|
|
local ALS = Train.ALSCoil
|
|
local speed = math.Round(ALS.Speed or 0,1)
|
|
local BUP = Train.BUP
|
|
local EnableALS = (Train.BKBD.Power75V+self.Power)
|
|
|
|
Train.FMM1:TriggerInput("Set",self.FMM1)
|
|
Train.FMM2:TriggerInput("Set",self.FMM2)
|
|
self.PBPower = 1
|
|
self.KPK1 = self.FMM1
|
|
if EnableALS ~= ALS.Enabled then
|
|
ALS:TriggerInput("Enable",EnableALS)
|
|
end
|
|
if self.Power12V > 0 then
|
|
self.NoFreq = ALS.NoFreq
|
|
self.F1 = ALS.F1*(1-self.NoFreq)
|
|
self.F2 = ALS.F2*(1-self.NoFreq)
|
|
self.F3 = ALS.F3*(1-self.NoFreq)
|
|
self.F4 = ALS.F4*(1-self.NoFreq)
|
|
self.F5 = ALS.F5*(1-self.NoFreq)
|
|
self.F6 = ALS.F6*(1-self.NoFreq)
|
|
self.RealF5 = self.F5*(1-(self.F4+self.F3+self.F2+self.F1))
|
|
self.NoFreq = self.NoFreq + (1-math.min(1,self.F5+self.F4+self.F3+self.F2+self.F1))
|
|
else
|
|
self.F1 = 0
|
|
self.F2 = 0
|
|
self.F3 = 0
|
|
self.F4 = 0
|
|
self.F5 = 0
|
|
self.F6 = 0
|
|
self.RealF5 = 0
|
|
self.NoFreq = 0
|
|
end
|
|
|
|
-- ARS system placeholder logic
|
|
if EnableALS then
|
|
local TwoToSix = self.TwoToSix > 0
|
|
if (ALS.F1+ALS.F2+ALS.F3+ALS.F4+ALS.F5+ALS.F6+self.NoFreq) == 0 then self.NoFreq = 1 end
|
|
local Vlimit = 0
|
|
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 not TwoToSix and (self.NextLimit ~= math.max(20,Vlimit) or self.F6 > 0) then
|
|
self.SpeedLimit = 0
|
|
self.NextLimit = self.SpeedLimit
|
|
self.NoFreq = 1
|
|
self.F1 = 0
|
|
self.F2 = 0
|
|
self.F3 = 0
|
|
self.F4 = 0
|
|
self.F5 = 0
|
|
self.F6 = 0
|
|
self.RealF5 = 0
|
|
elseif TwoToSix and (self.NextLimit == math.max(20,Vlimit) and self.F6 == 0) then
|
|
self.SpeedLimit = math.min(40,self.SpeedLimit)
|
|
self.NextLimit = math.min(40,self.NextLimit)
|
|
end
|
|
if self.AttentionPedal then self.SpeedLimit = self.SpeedLimit > 40 and 40 or 0 end
|
|
if TwoToSix and self.F4 > 0 and self.F6 > 0 then
|
|
self.LN = 1
|
|
elseif not TwoToSix then
|
|
self.LN = 0
|
|
end
|
|
else
|
|
local V = math.floor(speed +0.05)
|
|
self.SpeedLimit = 0
|
|
self.NextLimit = 0
|
|
end
|
|
|
|
if self.Power > 0 then
|
|
self.KVT = self.KB>0
|
|
--[[ if PB and not self.AttentionPedalTimer and not self.Overspeed then
|
|
self.AttentionPedalTimer = CurTime() + 1
|
|
end
|
|
|
|
if PB and self.AttentionPedalTimer and (CurTime() - self.AttentionPedalTimer) > 0 then
|
|
self.AttentionPedal = true
|
|
end
|
|
if not PB and (self.AttentionPedalTimer or self.AttentionPedal) then
|
|
self.AttentionPedal = false
|
|
self.AttentionPedalTimer = nil
|
|
end
|
|
if PB or Train.SB9.Value > 0.5 then self.KVT = true end
|
|
if not PB and Train.SB9.Value < 0.5 then self.KVT = false end
|
|
--]]
|
|
-- Ignore pedal
|
|
--[[ if self.IgnorePedal and self.KVT then
|
|
self.KVT = false
|
|
else
|
|
self.IgnorePedal = false
|
|
end--]]
|
|
|
|
--if self.EnableARS ~= EnableARS then Train.EPKContacts:TriggerInput("Set",Train.EPKContacts.Value) end
|
|
local SpeedLimit = self.LN == 0 and TwoToSix and self.SpeedLimit > 40 and 40 or self.SpeedLimit
|
|
if SpeedLimit < 20 and self.KVT then SpeedLimit = 20 end
|
|
-- Check absolute stop
|
|
if self.NoFreq ~= self.PrevNoFreq and BUP.IT < 1 then
|
|
self.IgnorePedal = self.NoFreq > 0 and BUP.IT < 1
|
|
self.PrevNoFreq = self.NoFreq
|
|
end
|
|
local zero = (self.NoFreq+self.RealF5) > 0
|
|
-- Enable PV1 and disassembly when we overspeed
|
|
if speed > SpeedLimit+0.5 and not self.Disassembly then
|
|
if zero then
|
|
self.Disassembly = CurTime()-2
|
|
else
|
|
self.Disassembly = CurTime()
|
|
end
|
|
self.ElectricBrake = true
|
|
self.ARSRing = true
|
|
end
|
|
if self.KVT and self.ARSRing then self.ARSRing = false end
|
|
--We can disable brake, if speed < Vdop-3 and electric brake
|
|
if not self.ARSRing and speed <= SpeedLimit-3 and self.ElectricBrake then
|
|
self.ElectricBrake = false
|
|
self.Disassembly = false
|
|
self.PneumaticBrake2 = false
|
|
end
|
|
--We can disable ring if speed < Vdop and not electric brake
|
|
if self.KVT and speed <= SpeedLimit and not self.ElectricBrake and self.ARSRing then self.ARSRing = false end
|
|
--Disable PN1 when we overspeed and time of overspeed < 1.5
|
|
--[[ if speed <= SpeedLimit and self.Disassembly and CurTime()-self.Disassembly < 1.5 then
|
|
self.Disassembly = false
|
|
self.ElectricBrake = false
|
|
end--]]
|
|
--PN2 when we brake to 0 speed
|
|
if self.Disassembly and self.ElectricBrake and speed < 0.25 then self.PneumaticBrake2 = true end
|
|
|
|
-- AntiRolling
|
|
local Drive = self.KRH > 0
|
|
-- Engage RO
|
|
if speed < 3 and self.RO ~= true and not Drive and self.KDReadyToRelease ~= false then self.RO = true end
|
|
-- Check RO when we starting
|
|
if self.RO and self.RO ~= true and (speed > 5 or CurTime()-self.RO > 7) then
|
|
self.RO = nil
|
|
self.PneumaticBrake2 = self.NoFreq == 0 and speed <= 5
|
|
self.KDReadyToRelease = nil
|
|
end
|
|
-- Disable PN1 and start RO timer
|
|
if Drive and self.RO == true then
|
|
self.RO = CurTime()
|
|
end
|
|
|
|
-- Kiyv door close cancel pneumatic brake 1 command trigger
|
|
--[[ if self.KiyvMode then
|
|
-- Prepare
|
|
if Train.KD.Value == 0 then self.KDReadyToRelease = true end
|
|
-- Release brakes and give RO additional time
|
|
if (Train.KD.Value == 1) and self.KDReadyToRelease then
|
|
self.KDReadyToRelease = false
|
|
self.RO = CurTime() + 1.5
|
|
end
|
|
end--]]
|
|
|
|
--[[ local delay = 3.5
|
|
if 10 < speed and speed < 30 then delay = 5.5 end
|
|
if speed < 3 then delay = 10 end
|
|
if (self.ElectricBrake or speed < 0.2) and Train:ReadTrainWire(34) == 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 Train.EPKContacts:TriggerInput("Open",1) end
|
|
--]]
|
|
-- ARS signals
|
|
local Ebrake, Abrake, Pbrake1,Pbrake2 =
|
|
((self.ElectricBrake) and 1 or 0),
|
|
((self.Disassembly or self.ARSRing or self.ElectricBrake or zero and not self.KVT) and 1 or 0),
|
|
((self.Disassembly and (zero or CurTime()-self.Disassembly < 1.5) or self.RO == true) and 1 or 0),
|
|
((self.PneumaticBrake2 or zero and not self.KVT) and 1 or 0)
|
|
-- Apply ARS system commands
|
|
|
|
self.Drive = 1-(Ebrake+Abrake)
|
|
self.DriveR = self.Drive
|
|
self.Brake = Ebrake
|
|
self.EPKContacts = 1
|
|
self.OKT = self.IKT
|
|
self.Ring = self.ARSRing and 1 or 0
|
|
self.V0 = self.RO == true and 1 or 0
|
|
else
|
|
--if Train.EPK.Value == 0 then Train.EPKContacts:TriggerInput("Set",1) end
|
|
self.ARSRing = true
|
|
self.ElectricBrake = true
|
|
self.PneumaticBrake1 = false
|
|
self.PneumaticBrake2 = true
|
|
self.Disassembly = CurTime()-5
|
|
self.EPKTimer = false
|
|
self.RO = true
|
|
|
|
self.Drive = 0
|
|
self.Brake = 0
|
|
--self.DriveR = 0
|
|
self.EPKContacts = 0
|
|
self.IKT = 0
|
|
self.OKT = 0
|
|
self.Ring = 0
|
|
self.V0 = 0
|
|
end
|
|
end
|