-------------------------------------------------------------------------------- -- 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