mirror of
https://github.com/metrostroi-repo/MetrostroiAddon.git
synced 2026-05-02 00:42:29 +00:00
190 lines
5.9 KiB
Lua
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
|