1
0
mirror of https://github.com/metrostroi-repo/MetrostroiAddon.git synced 2026-05-02 00:42:29 +00:00
This commit is contained in:
g_brzhezinskiy
2021-01-02 12:51:45 +03:00
commit 1d05caf866
613 changed files with 337020 additions and 0 deletions

View File

@@ -0,0 +1,403 @@
--------------------------------------------------------------------------------
-- 81-714 Moscow and SPB 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_714_Electric")
TRAIN_SYSTEM.MVM = 1
TRAIN_SYSTEM.LVZ_1 = 2
TRAIN_SYSTEM.LVZ_2 = 3
TRAIN_SYSTEM.LVZ_3 = 4
TRAIN_SYSTEM.DOT_2 = 5
function TRAIN_SYSTEM:Initialize(typ1,typ2)
self.TrainSolver = "81_717"
self.ThyristorController = true
self.Type = self.Type or self.MVM
-- Load all functions from base
Metrostroi.BaseSystems["Electric"].Initialize(self)
for k,v in pairs(Metrostroi.BaseSystems["Electric"]) do
if not self[k] and type(v) == "function" then
self[k] = v
end
end
self.SolvePowerCircuits = Metrostroi.BaseSystems["81_717_Electric"].SolvePowerCircuits
self.SolveThyristorController = Metrostroi.BaseSystems["81_717_Electric"].SolveThyristorController
self.Think = Metrostroi.BaseSystems["81_717_Electric"].Think
end
if CLIENT then return end
function TRAIN_SYSTEM:Inputs(...)
return { "Type", "NoRT2", "HaveRO", "GreenRPRKR","X2PS", "HaveVentilation" }
end
function TRAIN_SYSTEM:Outputs(...)
return Metrostroi.BaseSystems["81_717_Electric"].Outputs(self,...)
end
function TRAIN_SYSTEM:TriggerInput(name,value)
if name == "Type" then
self.Type = value
end
if name == "NoRT2" then self.NoRT2 = value > 0 end
if name == "HaveRO" then self.HaveRO = value > 0 end
if name == "GreenRPRKR" then self.GreenRPRKR = value > 0 end
if name == "X2PS" then self.X2PS = value > 0 end
if name == "HaveVentilation" then self.Vent = value > 0 end
end
-- Node values
local S = {}
-- Converts boolean expression to a number
local function C(x) return x and 1 or 0 end
local min = math.min
local max = math.max
function TRAIN_SYSTEM:SolveAllInternalCircuits(Train,dT,firstIter)
local P = Train.PositionSwitch
local RheostatController = Train.RheostatController
local RK = RheostatController.SelectedPosition
local B = (Train.Battery.Voltage > 55) and 1 or 0
local BO = B*Train.VB.Value
local T = Train.SolverTemporaryVariables
local isMVM = self.Type == 1
local isDot2 = self.Type == 5
local Panel = Train.Panel
Panel.V1 = BO
--Поездная часть
S["33D"] = T[10]*Train.A54.Value*Train.A84.Value
Train:WriteTrainWire(1, S["33D"]*C(Train.RV.Value~=1))
Train:WriteTrainWire(20,S["33D"]*C(Train.RV.Value~=1))
Train:WriteTrainWire(4, S["33D"]*C(Train.RV.Value==2)*Train.Start.Value)
Train:WriteTrainWire(5, S["33D"]*C(Train.RV.Value==0)*Train.Start.Value)
Train:WriteTrainWire(17,S["33D"]*Train.VozvratRP.Value)
if isMVM then
Train:WriteTrainWire(71,S["33D"]*Train.OtklBV.Value)
end
--Вагонная часть
S["10A"] = BO*Train.A30.Value
S["ZR"] = (1-Train.RRP.Value)+(B*Train.A39.Value*(1-Train.RPvozvrat.Value)*Train.RRP.Value)*-1
S["1A"] = T[1]*Train.A1.Value*Train.IGLA_PCBK.KVC
S["6A"] = T[6]*Train.A6.Value
Train.TR1:TriggerInput("Set",S["6A"])
--1A-PMU-1T-NR/RPU-1P(6^)
S["1P"] = S["1A"]*P.PM*(Train.NR.Value+Train.RPU.Value)+S["6A"]*P.PT
--1P-RK1-18-AVT-!RP-RKR-DR1-DR2-1G
S["1G"] = S["1P"]*C(1 <= RK and RK <= 18)*Train.AVT.Value*(1-Train.RPvozvrat.Value)*Train.RKR.Value--FIXME
S["1L"] = S["1G"]*C(RK==1)*(Train.KSB1.Value+Train.KSH1.Value)*Train.LK2.Value
S["1Zh"] = (S["1L"]+S["1G"]*Train.LK3.Value)*S["ZR"]
Train.LK1:TriggerInput("Set",S["1Zh"]*P.PM)
Train.LK3:TriggerInput("Set",S["1Zh"])
Train.LK4:TriggerInput("Set",S["1Zh"]*Train.LK3.Value)
S["3A"] = T[3]*Train.A3.Value
S["6G1"] = S["6A"]*P.PT*C(RK==1)
self.ThyristorControllerWork = S["6G1"]*(Train.KSB1.Value+Train.KSB2.Value)*Train.LK2.Value
S["6G2"] = S["6G1"]*(1-Train.RSU.Value)
Train.KSB1:TriggerInput("Set",S["6G2"])
Train.KSB2:TriggerInput("Set",S["6G2"])
--20-A20-20A-Rp-20B
S["20A"] = T[20]*Train.A20.Value*Train.IGLA_PCBK.KVC
--Train.RPL:TriggerInput("Set",--[[ S["20A"]--]] BO*(1-Train.RPvozvrat.Value)*(Train.DR1.Value+Train.DR2.Value+(1-Train.BV.State)))
if not isDot2 then
Train.RPL:TriggerInput("Set",S["20A"]*(1-Train.RPvozvrat.Value)*(Train.DR1.Value+Train.DR2.Value+(1-Train.BV.State)))
end
S["20B"] = S["20A"]*(1-Train.RPvozvrat.Value)
S["20K"] = S["20B"]*P.PS
Train.LK2:TriggerInput("Set",S["20K"]*S["ZR"])
Train.LK5:TriggerInput("Set",S["20B"]*Train.LK1.Value*S["ZR"])
if self.X2PS then
S["1M"] = C(1<=RK and RK<=5)*S["3A"]+S["20A"]*Train.KSH2.Value
S["1R"] = (S["1A"]*C(RK==1)+S["1M"]*P.PP)*S["ZR"]
Train.KSH1:TriggerInput("Set",S["1R"])
Train.KSH2:TriggerInput("Set",S["1R"])
P:TriggerInput("PP",S["3A"]*Train.LK5.Value*C(RK==18)*S["ZR"])--1A-1D
else
S["1M"] = C(1<=RK and RK<=5)*S["3A"]+T[10]*Train.KSH2.Value
S["1R"] = (S["1A"]*C(RK==1)*P.PS + S["1M"]*P.PP)*S["ZR"]
Train.KSH1:TriggerInput("Set",S["1R"])
Train.KSH2:TriggerInput("Set",S["1R"])
P:TriggerInput("PP",S["1A"]*C(RK==18)*S["ZR"])--1A-1D
end
local Reverser = Train.Reverser
S["4A"] = T[4]*Train.A4.Value
Reverser:TriggerInput("NZ",S["4A"]*Reverser.VP*(1-Train.LK1.Value)*S["ZR"])
S["5A"] = T[5]*Train.A5.Value
Reverser:TriggerInput("VP",S["5A"]*Reverser.NZ*(1-Train.LK1.Value)*S["ZR"])
--Train.RKR:TriggerInput("Set",(S["4A"]*Reverser.NZ+S["5A"]*Reverser.VP)) --81-717.5(м) МСК
if isDot2 then
Train.RKR:TriggerInput("Set",(S["4A"]*Reverser.NZ+S["5A"]*Reverser.VP)*S["ZR"]) --81-717.5 Харько*S["ZR"]в
else
Train.RKR:TriggerInput("Set",(S["4A"]*Reverser.NZ+S["5A"]*Reverser.VP)*Train.BV.State*S["ZR"]) --81-717.5 Харько*S["ZR"]в
end
--+B
S["1N"] = C(11<=RK and RK<=18)*(1-Train.LK4.Value)
Train.RR:TriggerInput("Set",S["10A"]*S["1N"] + P.PS*Train.LK4.Value)
S["5Zh"] = S["10A"]*(1-Train.LK3.Value)
P:TriggerInput("PS",S["5Zh"]*(P.PP))
P:TriggerInput("PM",S["5Zh"]*(1-Train.TR1.Value)*Train.KSH2.Value)
P:TriggerInput("PT",S["5Zh"]*(P.PM)*(1-Train.KSH2.Value))
--P:TriggerInput("PP",S["5Zh"]*(P.PM))
S["2A"] = (T[2]+T[-2])*Train.A2.Value
S["2T"] = S["2A"]*Train.TR1.Value
Train.RSU:TriggerInput("Set",S["2T"]*Train.ThyristorBU5_6.Value)
Train.RU:TriggerInput("Set",S["2T"])
S["2B"] = S["2A"]*((1-Train.KSB1.Value)*(1-Train.KSB2.Value)+(1-Train.TR1.Value))
S["2Ca"] = P.PS*C(1<=RK and RK<=17)*Train.RR.Value --CHECK
S["2Cb"] = P.PP*(C(6<=RK and RK<=18)+C(2<=RK and RK<=5)*Train.KSH1.Value)*(1-Train.RR.Value) --CHECK
S["2C"] = S["2B"]*(S["2Ca"]+S["2Cb"])*Train.LK4.Value
S["10R"] = S["10A"]*(1-Train.LK3.Value)*C(2<=RK and RK<=18)*(1-Train.LK4.Value)
S["2U"] = S["10R"]+S["2C"]*S["ZR"]
Train.SR1:TriggerInput("Set",S["2U"])
Train.RV1:TriggerInput("Set",S["2U"])
S["2Zh"] = T[2]*Train.A2.Value*Train.TR1.Value*C(17<=RK and RK<=18)
if self.NoRT2 then
Train.PneumaticNo1:TriggerInput("Set",S["2Zh"]+T[48]*Train.A72.Value)
Train:WriteTrainWire(-2,Train.A2.Value*Train.TR1.Value*C(17<=RK and RK<=18)*T[48]*Train.A72.Value)
else
Train.PneumaticNo1:TriggerInput("Set",S["2Zh"]+T[48]*Train.A72.Value*(1-Train.RT2.Value))
Train:WriteTrainWire(-2,Train.A2.Value*Train.TR1.Value*C(17<=RK and RK<=18)*T[48]*Train.A72.Value*(1-Train.RT2.Value))
end
if isMVM then --UNREALISTIC
S["8A"] = T[8]*Train.A8.Value*(1-Train.RV1.Value)*(1-Train.RT2r.Value)*(1-Train.RV3.Value)
else
S["8A"] = T[8]*Train.A8.Value*(1-Train.RV1.Value)*(1-Train.RT2.Value)*(1-Train.RV3.Value)
end
Train.PneumaticNo2:TriggerInput("Set",S["8A"]+T[39]*Train.A52.Value)
Train.RV3:TriggerInput("Set",T[19]*Train.A19.Value)
S["25A"] = T[25]*Train.A25.Value
S["10X"] = (--[[ S["1N"]*P.PS+--]] Train.LK4.Value+C(RK==1)*Train.LK2.Value)
Train["RRTpod"] = S["10A"]*RheostatController.RKM2*S["10X"]
Train["RRTuderzh"] = S["25A"]
Train["RUTpod"] = S["10A"]*RheostatController.RKM1*S["10X"]
Train["RUTavt"] = Train.A70.Value*B
Train.RRT:TriggerInput("Close",Train.RRTuderzh*Train.RRTpod)
Train.RRT:TriggerInput("Open",(1-Train.RRTuderzh))
Train.RRP:TriggerInput("Set",T[14]*Train.A14.Value)--14A
--СДРК Б+ провод
S["10A3"] = BO*Train.A28.Value
S["10BG"] = S["10A3"]*(Train.TR1.Value + Train.RV1.Value)
RheostatController:TriggerInput("MotorCoilState",min(1,S["10A"]*(S["10BG"]*Train.RR.Value - S["10BG"]*(1-Train.RR.Value))))
Train.RVO:TriggerInput("Set",S["10A3"]*Train.NR.Value)
self.ThyristorControllerPower = S["10A3"]
--[[ S["10Ra"] = T[10]*RheostatController.RKM1
S["10Rb"] = T[10]*Train.SR1.Value
S["10RbA"] = S["10Rb"]*(1-Train.RRT.Value)*(1-Train.RUT.Value)+S["10Ra"]
S["10RbB"] = S["10Rb"]*Train.RUT.Value
S["10RB"] = S["10RbA"]+S["10RbB"]*Train.RRT.Value+S["10RbB"]*(1-Train.SR1.Value)
S["10Rc"] = T[10]*Train.LK3.Value*C(RK>=18 or RK<=1)
S["10RS"] = S["10Ra"]+S["10RB"]*(1-RheostatController.RKP)*S["10Rc"]--]]
S["10Yu"] = S["10A"]*Train.SR1.Value
S["10M"] = S["10Yu"]*(1-Train.RRT.Value)*(1-Train.RUT.Value)
S["10N"] = S["10A"]*RheostatController.RKM1+S["10M"]
S["10T"] = (Train.RUT.Value+Train.RRT.Value+(1-Train.SR1.Value))*(RheostatController.RKP)+S["10A"]*Train.LK3.Value*C(RK>=18 and RK<=1)
RheostatController:TriggerInput("MotorState",S["10N"]+S["10T"]*(-10))
Train.RZ_2:TriggerInput("Set",T[24]*(1-Train.LK4.Value))
S["17A"] = T[17]*Train.A18.Value
if not isDot2 then
Train.BV:TriggerInput("Power",BO*Train.A80.Value)
Train.BV:TriggerInput("Enable",S["17A"])
end
if isMVM then
Train.BV:TriggerInput("Disable",T[71]*Train.A66.Value)
end
Train.RPvozvrat:TriggerInput("Open",S["17A"]) --FIXME Mayve more right RP code
--
--Вспом цепи
Train:WriteTrainWire(10,BO*Train.A56.Value)
if self.NoRT2 then
Train:WriteTrainWire(48,Train.A72.Value*S["2Zh"]) --FIXME ARS
else
Train:WriteTrainWire(48,Train.A72.Value*S["2Zh"]*(1-Train.RT2.Value)) --FIXME ARS
end
Train:WriteTrainWire(22,T[10]*Train.A10.Value*Train.AK.Value)
S["UO"] = T[10]*Train.A27.Value
Train:WriteTrainWire(27,S["UO"]*Train.L_1.Value)
S["36N"] = BO*Train.A45.Value
Train:WriteTrainWire(36,S["36N"]*Train.BPSNon.Value)
Train:WriteTrainWire(37,S["36N"]*Train.ConverterProtection.Value)
if self.GreenRPRKR then
S["10AN"] = Train.RPvozvrat.Value+(1-Train.RKR.Value) --81-717 Харьков
else
S["10AN"] = Train.RPvozvrat.Value --81-717 МСК
end
S["18A"] = (S["10AN"]*100+(1-Train.LK4.Value))*Train.A38.Value
Train:WriteTrainWire(18,S["18A"])
Panel.TW18 = S["18A"]
Panel.GreenRP = S["10AN"]*S["UO"]
--S["36N"] = BO*Train.A45.Value
--Train:WriteTrainWire(37,Train.ConverterProtection.Value)
--Train:WriteTrainWire(36,S["36N"]*(1-Train.BPSNon.Value))
--Train:WriteTrainWire(69,T[36]*Train.BPSNon.Value)
S["B9"] = B*Train.A53.Value
S["B9a"] = S["B9"]*Train.VB.Value
Train.KVC:TriggerInput("Set",S["B9a"])
--Train.KUP:TriggerInput("Set",S["B9a"]*Train.A75.Value)
S["D4"] = BO*Train.A13.Value
Panel.RZP = T[36]*T[61]
--[[S["14b"] = S["14a"]*Train.A17.Value
S["D1"] = ["10"]*Train.A21.Value*KV["D-D1"]+S["14b"]*KRU["11/3-D1/1"]
if isLVZ then
Train:WriteTrainWire(16,S["D1"]*(Train.VUD1.Value*Train.VUD2.Value+AVO["16"]*RC2))
else
Train:WriteTrainWire(16,S["D1"]*(Train.VUD1.Value*Train.VUD2.Value))
end
Train:WriteTrainWire(12,S["D1"]*Train.KRZD.Value)
S[31] = S["D1"]*(1-Train.DoorSelect.Value)
S[32] = S["D1"]*Train.DoorSelect.Value
Train:WriteTrainWire(31,S[31]*(Train.KDL.Value+Train.KDLR.Value+Train.VDL.Value))
Train:WriteTrainWire(32,S[32]*Train.KDP.Value)
S["F7"] = T[10]*Train.A29.Value*KV["F-F7"]+S["14b"]*KRU["11/3-FR1"]
S["F1"] = S["B9"]*KV["B9-F1"]--]]
Train:WriteTrainWire(34,Train.RKTT.Value+Train.DKPT.Value)
Train:WriteTrainWire(28,T[-28]*Train.RD.Value)
S[64] = S["UO"]*Train.BPT.Value
Train:WriteTrainWire(64,S[64])
Panel.BrW = S[64]
--Вспом цепи приём
if isDot2 then
Panel.EmergencyLights = T[11]*Train.A15.Value*(1-Train.KPP.Value)
else
Panel.EmergencyLights = BO*Train.A49.Value*Train.A15.Value
end
Train.RPU:TriggerInput("Set",T[37]*Train.A37.Value)
S["D6"] = S["D4"]*Train.BD.Value
Train.RD:TriggerInput("Set",S["D6"])
Panel.DoorsW = S["D4"]*(1-Train.RD.Value)
Train.VDZ:TriggerInput("Set",T[16]*Train.A16.Value*(1-Train.RD.Value))
S["12A"] = T[12]*Train.A12.Value
S["31A"] = T[31]*Train.A31.Value
S["32A"] = T[32]*Train.A32.Value
Train.VDOL:TriggerInput("Set",S["31A"]+S["12A"])
Train.VDOP:TriggerInput("Set",S["32A"]+S["12A"])
Train:WriteTrainWire(31,S["12A"]*Train.A31.Value)
Train:WriteTrainWire(32,S["12A"]*Train.A32.Value)
S["36A"] = T[36]*Train.A51.Value*Train.RVO.Value--36
Train.KVP:TriggerInput("Set",S["36A"]*Train.KPP.Value)
Train.KPP:TriggerInput("Set",S["36A"]*(1-Train.RZP.Value)*Train.KVC.Value)
S["27A"] = T[27]*Train.A50.Value
Train.KO:TriggerInput("Set",S["27A"])
--S["22A"] = (T[23]*Train.A23.Value+T[22]*Train.A22.Value) --FIXME 714
Train.RV2:TriggerInput("Set",T[23]*Train.A23.Value)
Train.KK:TriggerInput("Set",(
T[22]*Train.A22.Value*(1-Train.RV2.Value)+
T[23]*Train.A23.Value*Train.RV2.Value
)*(1-Train.TRK.Value))
--if isMVM then
Panel.AnnouncerPlaying = T[13]
Panel.AnnouncerBuzz = T[-13]
--end
--BPSN
local BPSN = Train.PowerSupply
Train.Battery:TriggerInput("Charge",BPSN.X2_2*Train.A24.Value*BO)
BPSN:TriggerInput("5x2",BO*Train.A65.Value*Train.KVP.Value)
Panel.MainLights = BPSN.X6_2*Train.KO.Value
Train.RPU:TriggerInput("Set",T[37]*Train.A37.Value)
Train.RZP:TriggerInput("Open",T[37]*Train.A37.Value*Train.RPU.Value)
Train:WriteTrainWire(61,Train.RZP.Value)
if self.Vent then
Train.KV1:TriggerInput("Set",T[59]*Train.AV4.Value*Train.RVO.Value)
Train.KV2:TriggerInput("Set",T[60]*Train.AV5.Value)
Train.KV3:TriggerInput("Set",T[58]*Train.AV6.Value)
S["AV2"] = T[10]*Train.AV2.Value
Panel.M1_3 = S["AV2"]*Train.KV1.Value
Panel.M4_7 = S["AV2"]*Train.KV2.Value+B*Train.AV3.Value*Train.KV3.Value
Train.R1:TriggerInput("Set",S["AV2"]*C(Panel.M1_3 > 0.5 and Panel.M4_7 > 0.5))
Train:WriteTrainWire(57,T[59]*(1-Train.R1.Value))
end
return S
end
function TRAIN_SYSTEM:SolveRKInternalCircuits(Train,dT,firstIter)
local P = Train.PositionSwitch
local RheostatController = Train.RheostatController
local RK = RheostatController.SelectedPosition
local B = (Train.Battery.Voltage > 55) and 1 or 0
local BO = B*Train.VB.Value
local T = Train.SolverTemporaryVariables
--Вагонная часть
S["10A"] = BO*Train.A30.Value
S["ZR"] = (1-Train.RRP.Value)+(B*Train.A39.Value*(1-Train.RPvozvrat.Value)*Train.RRP.Value)*-1
S["1N"] = C(11<=RK and RK<=18)*(1-Train.LK4.Value)
Train.RR:TriggerInput("Set",S["10A"]*S["1N"] + P.PS*Train.LK4.Value)
S["2A"] = (T[2]+T[-2])*Train.A2.Value
S["2B"] = S["2A"]*((1-Train.KSB1.Value)*(1-Train.KSB2.Value)+(1-Train.TR1.Value))
S["2Ca"] = P.PS*C(1<=RK and RK<=17)*Train.RR.Value --CHECK
S["2Cb"] = P.PP*(C(6<=RK and RK<=18)+C(2<=RK and RK<=5)*Train.KSH1.Value)*(1-Train.RR.Value) --CHECK
S["2C"] = S["2B"]*(S["2Ca"]+S["2Cb"])*Train.LK4.Value
S["10R"] = S["10A"]*(1-Train.LK3.Value)*C(2<=RK and RK<=18)*(1-Train.LK4.Value)
S["2U"] = (S["10R"]+S["2C"])*S["ZR"]
Train.SR1:TriggerInput("Set",S["2U"])
Train.RV1:TriggerInput("Set",S["2U"])
S["25A"] = T[25]*Train.A25.Value
S["10X"] = (Train.LK4.Value+C(RK==1)*Train.LK2.Value)
Train["RRTpod"] = S["10A"]*RheostatController.RKM2*S["10X"]
Train["RRTuderzh"] = S["25A"]
Train["RUTpod"] = S["10A"]*RheostatController.RKM1*S["10X"]
Train.RRT:TriggerInput("Close",Train.RRTuderzh*Train.RRTpod)
Train.RRT:TriggerInput("Open",(1-Train.RRTuderzh))
--СДРК Б+ провод
S["10A3"] = BO*Train.A28.Value
S["10BG"] = S["10A3"]*(Train.TR1.Value + Train.RV1.Value)
RheostatController:TriggerInput("MotorCoilState",min(1,S["10A"]*(S["10BG"]*Train.RR.Value - S["10BG"]*(1-Train.RR.Value))))
S["10Yu"] = S["10A"]*Train.SR1.Value
S["10M"] = S["10Yu"]*(1-Train.RRT.Value)*(1-Train.RUT.Value)
S["10N"] = S["10A"]*RheostatController.RKM1+S["10M"]
S["10T"] = (Train.RUT.Value+Train.RRT.Value+(1-Train.SR1.Value))*(RheostatController.RKP)+S["10A"]*Train.LK3.Value*C(RK>=18 and RK<=1)
RheostatController:TriggerInput("MotorState",S["10N"]+S["10T"]*(-10))
return S
end
local wires = {10,11,1,6,3,20,4,5,-2,2,48,8,39,19,25,13,-13,14,24,17,71,36,-28,37,16,12,31,32,69,27,23,22,23,37,59,60,58,61}
function TRAIN_SYSTEM:SolveInternalCircuits(Train,dT,firstIter)
local T = Train.SolverTemporaryVariables
if not T then
T = {}
for i,v in ipairs(wires) do T[v] = 0 end
Train.SolverTemporaryVariables = T
end
if firstIter then
for i,v in ipairs(wires) do T[v] = min(Train:ReadTrainWire(v),1) end
self:SolveAllInternalCircuits(Train,dT)
else
self:SolveRKInternalCircuits(Train,dT)
end
end