-------------------------------------------------------------------------------- -- 81-722 electric schemes -------------------------------------------------------------------------------- -- Copyright (C) 2013-2018 Metrostroi Team & FoxWorks Aerospace s.r.o. -- Contains proprietary code. See license.txt for additional information. -------------------------------------------------------------------------------- Metrostroi.DefineSystem("81_722_Electric") TRAIN_SYSTEM.DontAccelerateSimulation = false local function Clamp(val,min,max) return math.max(min,math.min(max,val)) end TRAIN_SYSTEM.T722 = 0 TRAIN_SYSTEM.T723 = 1 TRAIN_SYSTEM.T724 = 2 function TRAIN_SYSTEM:Initialize() self.Type = self.Type or self.T722 self.HaveBUKP = 0--self.HaveBUKP or self.Type==self.T722 and 1 or 0 self.HaveAsyncInverter = 0--self.HaveAsyncInverter or self.Type 0 then Train:WriteTrainWire(5,Train.SF1.Value*(Train.BattOn.Value+BO*(1-Train.Battery.Value))) Train:WriteTrainWire(6,BO*Train.SF1.Value*(Train.BattOff.Value+Train.BatteryOff.Value)) S["RU"] = BO*Train.SF4.Value*C(Train.VRU.Value==0) self.CabActiveVRU = BO*C(Train.VRU.Value==2)*Train.SF2.Value self.CabActive = BO*C(Train.VRU.Value>0)*((self.CabActiveVRU+Train.BUKP.Active)*Train.SF3.Value+S["RU"])*Train.SF2.Value Panel.LRU = BO*(1-self.CabActive) Panel.AVS = BO*Train.Pneumatic.SD2 Panel.EmergencyDriveL = S["RU"] Panel.EmergencyBrakeTPlusL = S["RU"] S["RV"] = BO*self.CabActive*Train.SF2.Value Train:WriteTrainWire(4,S["RV"]*Train.SF21.Value) Train:WriteTrainWire(3,0) S["RVnE"] = BO*self.CabActive*Train.SF2.Value Train:WriteTrainWire(12,math.max(S["RV"]*C(Train.KRO.Value==2)+S["RU"])) Train:WriteTrainWire(13,S["RVnE"]*C(Train.KRO.Value==0)) Train:WriteTrainWire(36,BO*Train.SF3.Value*C(Train.VRU.Value >0)*self.CabActive) Train:WriteTrainWire(34,S["RU"]) Train:WriteTrainWire(19,S["RU"]*Train.EmergencyDrive.Value) Train:WriteTrainWire(27,BO*S["RU"]) Train:WriteTrainWire(29,self.BTB*S["RU"]*(C(Panel.Controller<=-2)+Train.EmergencyBrakeTPlus.Value)) Train:WriteTrainWire(30,self.BTB*S["RU"]*C(Panel.Controller<=-1)) Panel.V4 = (S["RVnE"]*C(Train.KRO.Value~=1)+S["RU"])*Train.SF6.Value Train:WriteTrainWire(-8,BO*min(1,(S["RV"]+S["RU"]))*Train.SF7.Value) Train:WriteTrainWire(9,W[8]*(1-self.CabActive)*C(Train.VRU.Value==1)*Train.SF7.Value) self.LSD = W[9]*Train.SF7.Value S["V6m"] = min(1,Train.BARS.EPK*Train.RCARS.Value+(1-Train.RCARS.Value)*(Train.PB.Value+Train.VAH.Value)) local BTB = Panel.V4*(1-Train.Pneumatic.SD2)*S["V6m"] --Train:WriteTrainWire(24,BTB*(1-Train.EmergencyBrake.Value)) --Train:WriteTrainWire(25,BTB == 0 and W[26] > 0 and W[24]*self.BTB or 0) self.V6Power = BO*Train.SF5.Value*S["V6m"] if BTB > 0 then if self.BTBTimer == nil then self.BTBTimer = CurTime() end if self.BTBTimer and CurTime()-self.BTBTimer>0.3 then self.BTBTimer = false end else self.BTBTimer = nil end self.BTBPower = BTB self.BTB = min(1,(self.BTBTimer~=false and 1 or 0)+self.BTB*W[26]) if BTB > 0 and W[26]==0 and not self.TestTimer then self.TestTimer = CurTime() elseif W[26]>0 and self.TestTimer then self.TestTimer = nil end S["NEmergencyBrake"] = (1-Train.EmergencyBrake.Value)*C(Panel.Controller~=-3) Train:WriteTrainWire(26,(1-BTB)*W[24]*S["NEmergencyBrake"]) Train:WriteTrainWire(24,BTB*S["NEmergencyBrake"]) Train:WriteTrainWire(25,BTB*self.BTB*(self.KTR==3 and 0 or 1)) Train:WriteTrainWire(37,(S["RU"]+Train.BUKP.DoorRight)*Train.SF7.Value*Train.DoorRight.Value) Train:WriteTrainWire(38,(S["RU"]+Train.BUKP.DoorLeft)*Train.SF7.Value*(Train.DoorLeft1.Value+Train.DoorLeft2.Value)) Train:WriteTrainWire(39,S["RU"]*Train.SF7.Value*C(Train.DoorClose.Value==0)) Panel.BattOn = BO Panel.BattOff = BO*Train.BatteryOff.Value Panel.RC = Train.EmergencyRadioPower.Value Panel.CabLights = (BO*Train.CabinLight.Value/2+Panel.RC*0.5--[[ *(0.5-Train.PanelLight.Value/4)--]] )*Train.SF25.Value Panel.VPR1 = (BO+Panel.RC)*Train.SF14.Value Panel.VPR2 = (BO+Panel.RC)*Train.SF15.Value Panel.PanelLights = BO*Train.PanelLight.Value*Train.SF25.Value Panel.Headlights1 = (S["RV"]+S["RU"])*C(Train.KRO.Value==2)*Train.SF22.Value*C(Train.Headlights.Value==1) Panel.Headlights2 = (S["RV"]+S["RU"])*C(Train.KRO.Value==2)*Train.SF22.Value*C(Train.Headlights.Value==2) Panel.RedLights = (BO*Train.SF22.Value+Train.VKF.Value*Train.SF23.Value)*(1-S["RVnE"]+C(Train.KRO.Value<2)) Panel.SOSD = S["RV"]*Train.SF7.Value*Train.SF24.Value*Train.BUKP.SOSD*(1-self.LSD) Panel.BARSPower = BO*min(1,(Train.SF8.Value*C(Train.BARSMode.Value > 0)+Train.SF9.Value*C(Train.BARSMode.Value < 2))*Train.RCARS.Value) Panel.ARSPower = Panel.BARSPower*(1-Train.BUKP.Back)*Train.ARS.Value Panel.ALSPower = BO*(1-Train.BUKP.Back)*Train.ALS.Value Panel.UPOPower = BO*S["RV"]*Train.R_UPO.Value Train:WriteTrainWire(15,BO*(Train.UPO.LineOut*Train.SarmatUPO.UPOActive+Train.SarmatUPO.LineOut)) --print(W[15],Train.UPO.LineOut*Train.SarmatUPO.UPOActive,Train.SarmatUPO.LineOut) self.Emer = S["RU"] end S["DoorsP"] = BO*Train.SF36.Value Train:WriteTrainWire(8,W[-8]*S["DoorsP"]*Train.S1.Value) Panel.DoorsW = S["DoorsP"]*(1-Train.S1.Value) Panel.BrW = BO*Train.SF36.Value*Train.Pneumatic.SD3 Panel.AnnouncerPlaying = W[15] S["WagP"] = Train.Battery.Value*Train.SF33.Value if self.HaveAsyncInverter > 0 then local Async = Train.AsyncInverter local HV = BO*C(550 < self.Aux750V and self.Aux750V < 975) self.AsyncEmer = W[34]*Train.SF59.Value self.AsyncActive = min(1,W[36]*Train.SF58.Value+self.AsyncEmer) self.Reverser = self.AsyncActive*(W[12]-W[13]) Panel.GRP = BO*((1-Train.SF56.Value)+BUKV.DisableTP) Async:TriggerInput("Power",BO*Train.SF56.Value*(1-BUKV.DisableTP)) local speed = math.abs(Async.Speed) if self.AsyncEmer > 0 then Async:TriggerInput("Drive",W[19]) Async:TriggerInput("Brake",0) if W[19] > 0 then Async:TriggerInput("TargetTorque",(1.0+Clamp(speed/15,0,1)-Clamp((speed-30)/38,0,2))*(3)) else Async:TriggerInput("TargetTorque",0) end else Async:TriggerInput("Drive",BUKV.Drive) Async:TriggerInput("Brake",BUKV.Brake) local command = (BUKV.Strength/100)*(BUKV.Drive-BUKV.Brake) if command > 0 then Async:TriggerInput("TargetTorque",(math.abs(command)^0.5)*(1.0+Clamp(speed/15,0,1)-Clamp((speed-30)/38,0,2))*(1+Train.Pneumatic.WeightLoadRatio*0.3)) elseif command < 0 then Async:TriggerInput("TargetTorque",Clamp((speed-1)/4,0,1)*math.abs(command)*2.4*(1+Train.Pneumatic.WeightLoadRatio*0.3)) else Async:TriggerInput("TargetTorque",0) end end self.PSN = HV*(1-BUKV.DisablePSN) self.LightsHV = min(1,self.PSN+self.LightsHV)*BUKV.EnableLights if self.PSN == 0 then if not self.PassLightsTimer then self.PassLightsTimer = CurTime() end if self.PassLightsTimer and CurTime()-self.PassLightsTimer > 20 then self.LightsHV = 0 end elseif self.PassLightsTimer then self.PassLightsTimer = nil end Train:WriteTrainWire(32,self.LightsHV) Train:WriteTrainWire(33,self.PSN) self.MK = self.PSN*BUKV.EnableMK self.DisablePant = BO*BUKV.DisablePant*Train.SF37.Value self.EnergyChange = Async.Mode>0 and (Async.Current^2)*2.8 or 0 self.Itotal = Async.Current --[[ if self.Main750V > 900 or Async.Mode>0 then self.Recurperation = false elseif self.Main750V < 875 and Async.Mode<0 then end--]] if Async.Mode<0 and Async.State>0 then self.Recurperation = self.Main750V < 940 and 1 or 0 self.Iexit = self.Iexit+(-Async.Current*2*self.Recurperation-self.Iexit)*dT*2 --[[ if self.Main750V>550 then self.Iexit = self.Iexit+(-Async.Current*2*self.Recurperation-self.Iexit)*dT*2 else self.Iexit = 0 end--]] self.Chopper = (self.Main750V>910 or self.Main750V<550) and 1 or 0 else self.Recurperation = 0 self.Iexit = 0 self.Chopper = 0 end --print(self.Recurperation,self.Iexit,self.Main750V) self.ElectricEnergyUsed = self.ElectricEnergyUsed + math.max(0,self.EnergyChange)*dT self.ElectricEnergyDissipated = self.ElectricEnergyDissipated + math.max(0,-self.EnergyChange)*dT end local vent = Train.BUKV.VentMode self.Vent1 = (BO*C(vent==-1)+W[33]*C(vent>0))*Train.SF47.Value self.Vent2 =W[33]*C(vent>1)*Train.SF48.Value Panel.MainLights = W[32]*Train.SF45.Value*(1-BUKV.DisableLights) Panel.EmergencyLights = S["WagP"]*Train.SF45.Value*Train.SF46.Value self.BUFT = BO*Train.SF55.Value Train.BatteryOn:TriggerInput("Set",W[5]*Train.SF32.Value) Train.BatteryOff:TriggerInput("Set",W[6]*Train.SF32.Value) local BatterySound = (1-Train.Battery.Value)*Train.BatteryOn.TargetValue+Train.Battery.Value*Train.BatteryOff.TargetValue if BatterySound~=self.BatterySound then self.BatterySound = BatterySound if BatterySound>0 then Train:PlayOnce("battery_pneumo","bass",1) end end Train.Battery:TriggerInput("Close",Train.BatteryOn.Value) Train.Battery:TriggerInput("Open",Train.BatteryOff.Value) Train:WriteTrainWire(50,Train.Battery.Value) Panel.PassSchemePowerL = BO*Train.SF34.Value Panel.PassSchemePowerR = BO*Train.SF35.Value --self.Train:LoadSystem("BatteryOn","Relay",nil,{open_time=0.6,close_time=8}) --self.Train:LoadSystem("BatteryOff","Relay",nil,{open_time=0.6,close_time=8}) --[[ --OU Train:WriteTrainWire(34,P*(Train.RV["KRO1-2"]*Train.SF2.Value + Train.RV["KRR1-2"]*Train.SF3.Value)) --RU Train:WriteTrainWire(36,Train.SF3.Value*Train.EmergencyControls.Value) --XOD1 Train:WriteTrainWire(19,P*Train.RV["KRR7-8"]*Train.SF10.Value*Train.BARS.BTB*Train.EmerX1.Value) --XOD2 Train:WriteTrainWire(45,P*Train.RV["KRR7-8"]*Train.SF10.Value*Train.BARS.BTB*Train.EmerX2.Value) --ORIENTATION --PARKING Train:WriteTrainWire(11,P*Train.ParkingBrake.Value) local KM1 = P*Train.SF6.Value*Train.RV["KRO11-12"] local KM2 = P*Train.SF6.Value*Train.RV["KRO15-16"] --REVERSER Train:WriteTrainWire(12,P*(Train.RV["KRR3-4"]+KM1)*Train.SF11.Value) Train:WriteTrainWire(13,P*(Train.RV["KRR9-10"]+KM2)*Train.SF11.Value) --EMER BRAKE --BTB Train:WriteTrainWire(10,P*Train.EmergencyCompressor.Value) Train:WriteTrainWire(40,P*Train.EmergencyDoors.Value) Train:WriteTrainWire(39,P*Train.SF22.Value*Train.EmerCloseDoors.Value) Train:WriteTrainWire(38,P*Train.SF21.Value*Train.DoorLeft.Value) Train:WriteTrainWire(37,P*Train.SF21.Value*Train.DoorRight.Value) --]] end