1
0
mirror of https://github.com/metrostroi-repo/MetrostroiAddon.git synced 2026-05-02 00:42:29 +00:00
Files
MetrostroiAddon/lua/metrostroi/systems/sys_81_502_ars.lua
g_brzhezinskiy 1d05caf866 init
2021-01-02 12:51:45 +03:00

190 lines
5.9 KiB
Lua

--------------------------------------------------------------------------------
-- 81-502 NVL-Type safety system
--------------------------------------------------------------------------------
-- Copyright (C) 2013-2018 Metrostroi Team & FoxWorks Aerospace s.r.o.
-- Contains proprietary code. See license.txt for additional information.
--------------------------------------------------------------------------------
Metrostroi.DefineSystem("81_502_ARS")
function TRAIN_SYSTEM:Initialize()
self.KVD = 0
self.Power = 0
self.F6 = 0
self.F5 = 0
self.F4 = 0
self.F3 = 0
self.F2 = 0
self.F1 = 0
self.NoFreq = 0
self.RPB = 0
--Inputs
self.F1 = 0
self["1"] = 0
self["17"] = 0
self["6"] = 0
self["6R"] = 0
self["2"] = 0
self["20"] = 0
self["25"] = 0
self["3"] = 0
self[44] = 0
self[48] = 0
--Outputs
self[1] = 0
self[2] = 0
self[3] = 0
self[6] = 0
self[8] = 0
self[17] = 0
self[20] = 0
self[25] = 0
self.Ring = 0
self.BrakeT = 0
end
function TRAIN_SYSTEM:ClientInitialize()
end
function TRAIN_SYSTEM:Inputs()
return {}
end
function TRAIN_SYSTEM:Outputs()
return { "Power","Speed", "F6","F5","F4","F3","F2","F1","NoFreq","KVD" }
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
function TRAIN_SYSTEM:Think(dT)
local Train = self.Train
if Train.Electric.Type ~= 1 then return end
local ALS = Train.ALSCoil
local speed = math.Round(ALS.Speed or 0,1)
local Power = self.Power > 0
local VRD = Train.VRD.Value > 0
-- ALS, ARS state
--local EnableARS = power and RVForward and (not Train.A42 or Train.A42.Value > 0) and Train.ARS.Value > 0
--local EnableALS = power and (not Train.A43 or Train.A43.Value > 0) and Train.ALS.Value > 0
if self.ALS ~= ALS.Enabled then
ALS:TriggerInput("Enable",self.ALS)
end
self.RPB = self.Power
self.F6 = ALS.F6
self.F5 = ALS.F5
self.F4 = ALS.F4
self.F3 = ALS.F3
self.F2 = ALS.F2
self.F1 = ALS.F1
self.NoFreq = (1-math.min(1,(self.F1+self.F2+self.F3+self.F4+self.F5+self.F6)))*math.min(1,self.ALS+self.Power)
--ALS
if Power then
local Vlimit = -10
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
if VRD and Vlimit > 20 then Vlimit = 20 end
-- Determine next limit and current limit
self.SpeedLimit = Vlimit
else
self.SpeedLimit = 0
end
local KVT = Train.KB.Value+Train.PB.Value > 0
if Power then
if self.NoFreq ~= self.PrevNoFreq then
self.IgnorePedal = CurTime()
self.PrevNoFreq = self.NoFreq
end
if not KVT and self.IgnorePedal then self.IgnorePedal = false end
if self.IgnorePedal and CurTime()-self.IgnorePedal > 2 then KVT = false end
local zero = self.F5 > 0 and self.F6 == 0
if not VRD or not zero then self.VRD = false end
if VRD and zero and speed == 0 then self.VRD = true end
local SpeedLimit = self.SpeedLimit
if (self.F6 > 0 or self.NoFreq > 0 or self.VRD) and KVT then SpeedLimit = 20 end
if self.Started and speed > 0.1 then SpeedLimit = 0 end
if self.Started and speed <= 0.1 then self.Started = false end
-- Enable PV1 and disassembly when we overspeed
SpeedLimit = SpeedLimit*1.03
if speed > SpeedLimit+0.5 and not self.ElectricBrake then
self.ElectricBrake = true
self.ARSRing = speed > 0
end
--We can disable brake, if speed < Vdop and electric brake
if self.ARSRing and KVT then self.ARSRing = false end
if speed <= SpeedLimit and self.ElectricBrake and not self.ARSRing then
self.ElectricBrake = false
end
if speed < 3 and self["1"] == 0 then self.RO = true end
if self["1"] > 0 then self.RO = false end
if self.NoFreq > 0 and KVT then self.RO = false end
local Brake = (self.ElectricBrake or (Power and self.ALS+self.NoFreq==0)) and 1 or 0
local Drive = 1*(1-Brake)
if Drive == 0 then self.KVD = 1
elseif self["6"] == 0 then self.KVD = 0 end
if Brake > 0 and self.BrakeT == 0 and not self.BrakeTTimer then self.BrakeTTimer= CurTime() end
if Brake <= 0 and self.BrakeTTimer then
self.BrakeTTimer = nil
end
if self["6R"] == 0 and SpeedLimit <= 20 or self.BrakeTTimer and CurTime()-self.BrakeTTimer > 3.5 then
self.BrakeT = 1
elseif not self.BrakeTTimer then self.BrakeT = 0 end
if self.ElectricBrake and (self["6"] > 0 and not self.PN1Timer or self["6"] == 0) then
self.PN1Timer = CurTime()
self.PN1OffTimer = 3.5-math.max(0,(speed-20))/60*2.5
end
if not self.ElectricBrake then self.PN1Timer = false end
self[1] = self["1"]*Drive*(1-self.KVD)
self[2] = self["2"]+Brake
self[3] = Brake
self[6] = Brake
self[8] = Brake*self.BrakeT
self[17] = self["17"]*(1-Brake)
self[20] = self["20"]+Brake
self[25] = self["25"]*(1-Brake)
self[44] = (self.RO or self.PN1Timer and CurTime()-self.PN1Timer < self.PN1OffTimer) and 1 or 0
self[48] = self[44]
self.Ring = (self.ARSRing) and 1 or 0
else
self.ElectricBrake = true
self.ARSRing = true
self.Started = true
self.RO = false
self.VRD = false
self.BrakeT = 0
self.PN1Timer = false
self[1] = 0
self[2] = self["2"]
self[3] = 0
self[6] = 0
self[8] = 0
self[17] = self["17"]
self[20] = self["20"]
self[25] = self["25"]
self[44] = 0
self[48] = 0
self.KVD = 0
self.Ring = 0
end
end