-------------------------------------------------------------------------------- -- 81-720 wagon control unit -------------------------------------------------------------------------------- -- Copyright (C) 2013-2018 Metrostroi Team & FoxWorks Aerospace s.r.o. -- Contains proprietary code. See license.txt for additional information. -------------------------------------------------------------------------------- Metrostroi.DefineSystem("81_720_BUV") TRAIN_SYSTEM.DontAccelerateSimulation = true function TRAIN_SYSTEM:Initialize() if not TURBOSTROI then self.TrainIndex = self.Train:GetWagonNumber() end self.Battery = false self.Power = 0 self.States = {} self.Commands = {} self.Slope = false self.BBE = 0 self.MK = 0 self.Reverser = 0 self.PN2 = 0 self.Brake = 0 self.Drive = 0 self.DriveStrength = 0 self.Disassembly = 0 self.Vent1 = 0 self.Vent2 = 0 self.CurTime = CurTime() self.FirstHalf = false end function TRAIN_SYSTEM:Outputs() return {"Brake", "Drive", "DriveStrength", "Disassembly" ,"BBE","MK","Vent1","Vent2"} end function TRAIN_SYSTEM:Inputs() return {} end function TRAIN_SYSTEM:CState(name,value) if self.CurrentBUP and (self.Reset or self.States[name] ~= value) then self.States[name] = value self.Train:CANWrite("BUV",self.Train:GetWagonNumber(),"BUKP",self.CurrentBUP,name,value) end end -- Door8Closed t/f -- Door7Closed t/f -- Door6Closed t/f -- Door5Closed t/f -- Door4Closed t/f -- Door3Closed t/f -- Door2Closed t/f -- Door1Closed t/f -- NoAssembly t/f -- ParkingBrakeEnabled t/f -- BEPPBroken t/f -- EmergencyBrake t/f -- ReserveChannelBraking t/f -- PTEnabled t/f -- PTBad t/f -- PTReady t/f -- PTReplace t/f -- TLPressure 0-10 -- BLPressure 0-10 -- BCPressure 0-6 -- HPPressure 0-6 -- WeightLoad 0-1 -- PantDisabled t/f -- EnginesBroken t/f -- BBEEnabled t/f -- BBEBroken t/f -- HVBad t/f -- LVBad t/f -- EnginesDone t/f -- EnginesBrakeBroke t/f -- PassLightEnabled t/f -- BVEnabled t/f -- DriveStrength ~ -- BrakeStrength ~ -- VagEqConsumption 0-60A -- HVVoltage 0-1500A -- LVVoltage 0-100A -- MKVoltage 0-50A -- VentEnabled t/f -- HeatEnabled t/f -- MKWork --Исправность МК -- BUVWork --Исправность БУВ -- WagNOrientated t/f -- Orientation t/f function TRAIN_SYSTEM:CANReceive(source,sourceid,target,targetid,textdata,numdata) if textdata == "BUPWork" and not numdata then self.Commands[sourceid] = {} elseif textdata == "Orientate" then self.OrientateBUP = sourceid self.FirstHalf = numdata self.Reset = CurTime() elseif self.CurrentBUP then if not self.Commands[sourceid] then self.Commands[sourceid] = {} end self.Commands[sourceid][textdata] = numdata end end function TRAIN_SYSTEM:Get(id) local Commands = self.Commands[self.CurrentBUP] if Commands then return Commands[id] end end function TRAIN_SYSTEM:TriggerInput(name,value) end function TRAIN_SYSTEM:Think() if CurTime()-self.CurTime < 0.1 then return end self.DeltaTime = CurTime()-self.CurTime self.CurTime = CurTime() local Train = self.Train local wagcount = #Train.WagonList self.Power = Train.Electric.Battery80V > 62 and 1 or 0 self.State = self.Power > 0 and Train.SFV2.Value > 0.5 if self.State then if not self.States.BUVWork then self.Train:CANWrite("BUV",Train:GetWagonNumber(),"BUKP",nil,"Get",1) end for i=1,4 do self:CState("Door"..i.."Closed", Train.Pneumatic.LeftDoorState[i] == 0) self:CState("Door"..(i+4).."Closed", Train.Pneumatic.RightDoorState[i] == 0) end self:CState("DoorTorec", Train.RearDoor or Train.FrontDoor) self:CState("DoorBack", Train.PassengerDoor or Train.CabinDoorLeft or Train.CabinDoorRight) self:CState("EmPT",Train:ReadTrainWire(28) > 0) self:CState("NoAssembly", Train.KMR1.Value == 0 and Train.KMR2.Value == 0 or Train.K2.Value == 0 and Train.K3.Value==0) self:CState("ParkingBrakeEnabled", Train.Pneumatic.ParkingBrakePressure < 3) self:CState("BEPPBroken", false) self:CState("EmergencyBrakeGood", Train.Pneumatic.BrakeCylinderPressure >= (2.6+Train.Pneumatic.WeightLoadRatio*0.6)-0.1) self:CState("EmergencyBrake", self.States.EmergencyBrakeGood--[[ and Train:ReadTrainWire(27) == 0--]] ) self:CState("ReserveChannelBraking", Train:ReadTrainWire(28)>0) self:CState("PTEnabled", Train.Pneumatic.BrakeCylinderPressure > 0.2) self:CState("PTBad", false) self:CState("PTReady", Train.Pneumatic.AirDistributorPressure >= (2.6+Train.Pneumatic.WeightLoadRatio*0.6)-0.1) self:CState("PTReplace", self.PTReplace and CurTime()-self.PTReplace > 1.5) self:CState("BTBReady", Train.Pneumatic.BTBReady) self:CState("TLPressure", math.Round(Train.Pneumatic.TrainLinePressure,1)) self:CState("BLPressure", math.Round(Train.Pneumatic.BrakeLinePressure,1)) self:CState("BCPressure", math.Round(Train.Pneumatic.BrakeCylinderPressure,1)) self:CState("HPPressure", math.Round(Train.Pneumatic.AirDistributorPressure,1)) self:CState("WeightLoad", math.Round(Train.Pneumatic.WeightLoadRatio,2)) self:CState("PantDisabled", self.Pant) self:CState("EnginesBroken", false) self:CState("BBEEnabled", self.BBE) self:CState("BBEBroken", false) self:CState("HVBad", Train.Electric.Power750V < 550) self:CState("LVBad", Train.Electric.Battery80V < 62) self:CState("EnginesDone", self.EnginesDone)-- and math.abs(Train.Speed) < 7.5) --self:CState("EnginesBrakeBroke", (self:Get("Brake") or 0) > 0 and Train.BV.Value == 0 or Train.Electric.IT > 0 and Train.K3.Value == 0) self:CState("EnginesBrakeBroke", (self:Get("Brake") or 0) > 0 and (Train.BV.Value == 0 or Train.K3.Value == 0)) self:CState("PassLightEnabled", self.MainLights) self:CState("BVEnabled", Train.BV.Value > 0) self:CState("DriveStrength", math.min(0,Train.Engines.BogeyMoment*2)) self:CState("BrakeStrength", math.max(0,Train.Engines.BogeyMoment*2)) self:CState("VagEqConsumption", 15)--15-25 self:CState("I13", math.Round(Train.Electric.I13,1)) self:CState("I24", math.Round(Train.Electric.I24,1)) self:CState("HVVoltage", math.floor(Train.Electric.Main750V)) self:CState("LVVoltage", math.floor(Train.Electric.Battery80V)) self:CState("MKVoltage", math.Round(Train.Electric.BVKA_KM1*math.Rand(9,13),1)) self:CState("Vent1Enabled", Train.Electric.Vent1>0) self:CState("Vent2Enabled", Train.Electric.Vent2>0) self:CState("HeatEnabled", false) self:CState("MKWork", Train.Pneumatic.Compressor) self:CState("BUVWork", true) self:CState("WagNOrientated", self.Orientation == self.RevOrientation) self:CState("Orientation", self.Orientation) self:CState("BadCombination", (Train:ReadTrainWire(3)*Train:ReadTrainWire(4)) > 0) else self:CState("BUVWork", false) for k,v in pairs(self.Commands) do self.Commands[k] = false end end if self.Reset and self.Reset ~= CurTime() then self.Reset = nil end local NoHV = Train.Electric.Main750V < 650 or Train.Electric.Main750V > 975 self.BBE = ((not self:Get("PVU8") and self:Get("BBE")) and 1 or (Train.BBER and Train.BBER.Value or 0))*Train.SFV7.Value if NoHV then self.BBE = 0 end if self.BBE == 0 and self.MainLights and not self.MainLightsTimer then self.MainLightsTimer = CurTime() end if self.BBE > 0 or not self.MainLights or self.MainLightsTimer and CurTime()-self.MainLightsTimer > 27 then self.MainLightsTimer = nil end if (self:Get("BVOn") or Train:ReadTrainWire(2) > 0) then Train.BV:TriggerInput("Close",Train.SFV8.Value*Train.SFV9.Value) end if self:Get("BVOff") and Train.SFV8.Value > 0 or self:Get("PVU1") then Train.BV:TriggerInput("Open",1) end self.MainLights = not self:Get("PVU5") and (self.BBE > 0 or self.MainLightsTimer) and Train.SFV19.Value > 0.5 and self:Get("PassLight") if self:Get("Slope") then self.Slope = CurTime() end if not self:Get("Slope") and self.Slope and Train.Pneumatic.BrakeCylinderPressure < 0.5 then self.Slope = false end --self.Reverser = Train:ReadTrainWire(12) local brake = self:Get("Brake") or 0 local strength = not self:Get("PVU9") and (self.Slope or brake>0 and Train.Pneumatic.BrakeCylinderPressure < 1.5 or brake==0 and Train.Pneumatic.BrakeCylinderPressure < 0.5) and self:Get("DriveStrength") or 0 local drive = math.min(1,(1-brake)*strength) if strength == 0 then brake=0 drive=0 end if brake>0 and Train.BPTI.State~=-1 and math.abs(Train.Speed) < 10 then self.Brake = 0 else self.Brake = brake end self.Drive = drive self.BlockTorec = not self:Get("PVU6") and self:Get("DoorTorec") and Train.SFV15.Value > 0 self.DriveStrength = strength if brake == 0 then self.EnginesDone = false elseif Train.BPTI.State == -1 and (Train.BPTI.RNState == 1 and Train.Electric.I13>math.min(-130,-Train.Electric.ISet*0.75)) or Train.BPTI.State~=-1 and math.abs(Train.Speed) < 10 then self.EnginesDone = true end local PTReplace = self.States.EnginesBrakeBroke if PTReplace and not self.PTReplace then self.PTReplace = CurTime() if Train.K3.Value*Train.BV.Value ~= 0 then self.PTReplace = self.PTReplace + 1.3 end if Train.BV.Value == 0 or self:Get("PVU9") then self.PTReplace = self.PTReplace - 1.2 end end if not PTReplace and self.PTReplace then self.PTReplace = nil end local PN = self.PTReplace and CurTime()-self.PTReplace > 1.2 or self.States.EnginesDone self.PN1 = (self:Get("PN1") and self:Get("PN1") > 0) or PN and (self:Get("DriveStrength") and self:Get("DriveStrength") > 0) self.PN2 = (self:Get("PN2") and self:Get("PN2") > 0) or PN and (self:Get("DriveStrength") and self:Get("DriveStrength") > 2) self.MK = not self:Get("PVU3") and self:Get("Compressor") and 1 or 0 self.OpenLeft = not self:Get("PVU2") and self:Get("OpenLeft") and self.Orientation or self:Get("OpenRight") and not self.Orientation self.OpenRight = not self:Get("PVU2") and self:Get("OpenRight") and self.Orientation or self:Get("OpenLeft") and not self.Orientation self.CloseDoors = self:Get("PVU2") or self:Get("CloseDoors") self.Vent1 = not self:Get("PVU7") and self:Get("Vent1") and 1 or 0 self.Vent2 = not self:Get("PVU7") and self:Get("Vent1") and self:Get("Vent2") and not NoHV and 1 or 0 self.Orientation = Train:ReadTrainWire(3) > 0 self.RevOrientation = Train:ReadTrainWire(4) > 0 local BadOrientation = self.Orientation and self.Orientation == self.RevOrientation if self.State and self.Orientation ~= self.RevOrientation then if not self.BadOrientation and self.OrientateBUP and (not self.Commands[self.OrientateBUP] or self.Orientation and self.Commands.Forward ~= self.OrientateBUP or self.RevOrientation and self.Commands.Back ~= self.OrientateBUP) then if self.Orientation then self.Commands.Forward = self.OrientateBUP else self.Commands.Back = self.OrientateBUP end self.OrientateBUP = nil end end local ReOrientation = self.State and (self.Orientation or self.RevOrientation) and (self.Orientation ~= self.PrevOrientation or self.RevOrientation ~= self.PrevRevOrientation or self.CurrentBUP ~= (self.Orientation and self.Commands.Forward or self.Commands.Back)) if ReOrientation then self.CurrentBUP = self.Orientation and self.Commands.Forward or self.Commands.Back self.Reset = CurTime() if self.CurrentBUP then self.Commands[self.CurrentBUP] = {} Train:CANWrite("BUV",Train:GetWagonNumber(),"BUKP",self.CurrentBUP,"Get") end end self.BadOrientation = BadOrientation self.PrevOrientation = self.Train:ReadTrainWire(3) > 0 self.PrevRevOrientation = self.Train:ReadTrainWire(4) > 0 if Train.SFV29.Value > 0 then if self:Get("PVU4") or --[[ Train.Electric.Main750V < 20 and --]] (self:Get("TP1") and self.FirstHalf or self:Get("TP2") and not self.FirstHalf) then self.Pant = true else self.Pant = false end end end