-------------------------------------------------------------------------------- -- 81-719 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_719_Electric") TRAIN_SYSTEM.DontAccelerateSimulation = false function TRAIN_SYSTEM:Initialize() -- General power output Metrostroi.BaseSystems["81_718_Electric"].Initialize(self) for k,v in pairs(Metrostroi.BaseSystems["81_718_Electric"]) do if not self[k] and type(v) == "function" then self[k] = v end end end function TRAIN_SYSTEM:Inputs() return { } end function TRAIN_SYSTEM:Outputs() return { "I13","I24","Itotal", "Main750V", "Power750V", } end function TRAIN_SYSTEM:TriggerInput(name,value) end -------------------------------------------------------------------------------- function TRAIN_SYSTEM:Think(dT,iter) local Train = self.Train -- local dT = dT/8 ---------------------------------------------------------------------------- -- Voltages from the third rail ---------------------------------------------------------------------------- self.Main750V = Train.TR.Main750V self.Aux750V = Train.TR.Main750V self.Power750V = self.Main750V*Train.GV.Value ---------------------------------------------------------------------------- -- Information only ---------------------------------------------------------------------------- self.Aux80V = BBE and 82 or 65 self.Lights80V = BBE and 82 or 0 self.Battery80V = 65--(Train.VB.Value > 0) and (BBE and 82 or 65) or 0 ---------------------------------------------------------------------------- -- Some internal electric ---------------------------------------------------------------------------- local P = self.Battery80V > 62 and 1 or 0 local HV = 550 < self.Main750V and self.Main750V < 975 and 1 or 0 ---------------------------------------------------------------------------- -- Solve circuits ---------------------------------------------------------------------------- self:SolvePowerCircuits(Train,dT) if iter == 1 then self:SolveControlCircuits(Train,dT) end ---------------------------------------------------------------------------- -- Calculate current flow out of the battery ---------------------------------------------------------------------------- --local totalCurrent = 5*A30 + 63*A24 + 16*A44 + 5*A39 + 10*A80 --local totalCurrent = 20 + 60*DIP end local S = {} local wires = {1,2,3,4,5,6,7,8,9,10,11,-11,12,13,14,15,16,17,18,19,20,22,23,24,26,27,28,29,30,31,32,33,34,35,36,37,38,40,41,42,44,45,47,48,49,50,51,-51,54,55,56,57,58,59,67,74,83,84,87,88,89,90,-34,} local min = math.min local max = math.max local function clamp(val) return max(-1,min(1,val)) end function TRAIN_SYSTEM:SolveControlCircuits(Train,dT) local B = (Train.Battery.Voltage > 62) and 1 or 0 local T = Train.SolverTemporaryVariables if not T then T = {} for i,v in ipairs(wires) do T[v] = 0 end Train.SolverTemporaryVariables = T end for i,v in ipairs(wires) do T[v] = min(Train:ReadTrainWire(v),1) end local BUP = Train.BUP local BUV = Train.BUV local BKVA = Train.BKVA local BUVS = Train.BUVS local BBE = Train.BBE local Panel = Train.Panel --S[303] = B*Train.VB.Value S[305] = clamp(B+T[50]*Train.SF2.Value)*Train.VB.Value --S[305] = S[303] --S[310] = B*Train.VB.Value S[550] = S[305]*Train.SF2.Value --310 Train:WriteTrainWire(50,S[550]) --S[311] = B*Train.VB.Value S[334] = S[305]*Train.SF45.Value --311 S[312] = S[305]*Train.SF3.Value --311 BBE.KMPower = S[334] BBE.Power = S[305] Panel.V1 = S[312] --1.2. Цепи заряда аккумуляторной батареи. Включение ББЭ. Страница 7 BBE.Activate = T[18]*Train.SF12.Value--S[324] --Включение ББЭ --1.5. Аварийное отключение ББЭ и сигнализации Страница 9 Train:WriteTrainWire(20,BBE.Error) BBE.Deactivate = T[19]*Train.SF13.Value --Включение ББЭ --2.1. Освещение вагонов основное. Страница 9 BBE.KM2Power = T[38]*Train.SF16.Value Panel.EL7_30 = S[305]*BBE.KM2*Train.SF44.Value--S[409] --2.2. Аварийное освещение салонов и кабины. Страница 10 --S[407] = S[312]*Train.SF44.Value Panel.EL3_6 = S[312]*Train.SF44.Value S[322] = T[50]*Train.SF11.Value Panel.EL1 = S[322] S[321] = T[50]*Train.SF10.Value --2.4. Подсветка прибора. Страница 10 S[328] = T[50]*Train.SF72.Value Train:WriteTrainWire(29,Train.SF56.Value*T[50]*Train.SP1.Value) --S[529] BKVA.KM2 = clamp(T[29]+T[30]*Train.SF22.Value)--[[*тепловое реле]] Train.KK:TriggerInput("Set",(self.Main750V > 200 and 1 or 0)*BKVA.KM2)--S[208] --5.1. Вентиляция салонов. Страница 13 S[307] = S[312]*Train.SF34.Value BUVS.KM1 = T[40]*Train.SF23.Value BUVS.KV1 = S[307]*BUVS.KM1 --Контроль Train:WriteTrainWire(42,1-BUVS.KV1)--Сигнализация BUVS.KM2 = T[41]*Train.SF23.Value BUVS.KV2 = S[307]*BUVS.KM2 --Контроль Train:WriteTrainWire(49,1-BUVS.KV2) --Сигнализация --352-353-354 S[354] =(1-BKVA.KM4) Train.U1:TriggerInput("Set", T[32]*S[354]) S[358] = T[33]*Train.SF19.Value --[[ S[357] = T[36]*Train.SF18.Value+S[358] S[359] = T[37]*Train.SF20.Value+S[358] Train.U2:TriggerInput("Set",S[357]) Train.U3:TriggerInput("Set",S[359])--]] Train.U2:TriggerInput("Set",T[36]*Train.SF18.Value+S[358]) Train.U3:TriggerInput("Set",T[37]*Train.SF20.Value+S[358]) --8.3. Контроль положения дверей. Страницы 19-20 --312-SA15..SA22-351 BKVA.KM4 = S[312]*Train.SAD.Value--S[351] Train:WriteTrainWire(34,T[-34]*Train.SAD.Value) --Разрыв питания онцевых переключателей Panel.HL13 = S[312]*S[354] --9. БЛОКИРОВКА ПОСТОВ УПРАВЛЕНИЯ И ФОРМИРОВАНИЕ ЦЕПЕЙ УПРАВЛЕНИЯ ДВИЖЕНИЕМ СОСТАВА --Страница 20-21 --9.4 --[[ S[335] = T[15]*Train.SF14.Value S[337] = T[16]*Train.SF5.Value BKVA.KM3 = S[335]+S[337]--]] BKVA.KM3 = T[15]*Train.SF14.Value+T[16]*Train.SF5.Value --S[517] = (1-BKVA.KM3) Train:WriteTrainWire(17,(1-BKVA.KM3))--S[517] --10. ЦЕПИ БЕЛЫХ ФАР И ЛАМП СИГНАЛИЗАЦИИ СТОЯНОЧНОГО ТОРМОЗА --Страница 322 --316-SF41-365-KM2/6-390 --390-SA1/1(SA2/1)-367(368)-R9(R10)-HL17-19(HL20-22) S[512] = S[328]*Train.SQ1.Value Train:WriteTrainWire(12,S[512]) Panel.HL46 = S[512] --11. ЗАЩИТА СИЛОВЫХ ЦЕПЕЙ. ЦЕПИ КОНТРОЛЯ СОСТОЯНИЯ ЗАЩИТЫ. --11.1. Цепи быстродействующих автоматических выключателей. --Страница 23 S[306] = S[312]*Train.SF27.Value Train.BVA.Power = S[306] S[3061] = S[306]*Train.SF46.Value Train.BVA.ControlPower = S[3061] --312=314 S[314] = clamp(S[312]*Train.SF4.Value*BKVA.KM3+S[3061]*BUV.O75V) BUV.Power = S[314] Train.BSKA.Power = S[314] Train.PTTI.Power = S[314] --S[526] = T[45]*Train.SB12.Value Train.BVA.Reset = T[26] --11.4 Train.BVA.Disable = T[22] Panel.HL25 = S[3061]*BUV.ORP --Мы получаем землю S[528] = Panel.HL25*100+BUV.OIZ Train:WriteTrainWire(28,S[528]) Panel.HL6 = T[28] Panel.TW28= S[528] --14.1. Ходовые режимы основного управления. Страница 32-33 Train.KMR1:TriggerInput("Set",BUV.OVP*(1-Train.KMR2.Value)*S[314]) Train.KMR2:TriggerInput("Set",BUV.ONZ*(1-Train.KMR1.Value)*S[314]) BUV.IRV = S[314]*Train.KMR1.Value BUV.IRN = S[314]*Train.KMR2.Value BUV.IRV = S[314]*Train.KMR1.Value BUV.IRN = S[314]*Train.KMR2.Value Train.K1:TriggerInput("Set",S[314]*BUV.OLK) Train.K2:TriggerInput("Set",S[314]*BUV.OKX) Train.K3:TriggerInput("Set",S[314]*BUV.OKT) BUV.IKX = Train.K2.Value BUV.IKT = Train.K3.Value BUV.ILT = Train.K1.Value --15. УПРАВЛЕНИЕ СИЛОВЫМ ПРИВОДОМ В ТОРМОЗНЫХ РЕЖИМАХ Страница 36-37 --КТ --БКБД головного-511-К4БУВС-БКБД хвостового --S[5092] = S[5091]+T[08]*(1-BUVS.KM3) --S[5092] = T[09]*Train.SF26.Value+T[08]*(1-BUVS.KM3) BUVS.KM3 = S[314]*BUV.ORMT BUVS.KM4 = S[314]*BUV.ORKT Train.U6:TriggerInput("Set",T[09]*Train.SF26.Value+T[08]*(1-BUVS.KM3))--S[5092] Train:WriteTrainWire(11,BUVS.KM4+Train.SP4.Value) Train.U7:TriggerInput("Set",T[10]+Train.SF29.Value*BUV.OV1) Train:WriteTrainWire(23,BUV.Power*BUV.OSN) --19. УПРАВЛЕНИЕ ОТЖАТИЕМ ТОКОПРИЕМНИКОВ Train.U5:TriggerInput("Set",T[24]*T[59]) Panel.AnnouncerPlaying = T[51] Panel.AnnouncerBuzz = T[-51] --Передача сигналов с поездных проводов в БУВ local BUVPower = BUV.Power BUV.IX = BUVPower*T[01] BUV.IT = BUVPower*T[02] BUV.IU1 = BUVPower*T[03] BUV.IU2 = BUVPower*T[04] BUV.IVP = BUVPower*T[05] BUV.INZ = BUVPower*T[06] BUV.ITARS = BUVPower*T[07] BUV.ITEM = BUVPower*T[14] BUV.IM = BUVPower*T[13] BUV.IVZ = BUVPower*T[26] BUV.IPROV = BUVPower*T[27] BUV.IPROV0 = BUVPower*T[47] BUV.IXP = BUVPower*T[55] BUV.IU1R = BUVPower*T[56] BUV.IVR = BUVPower*T[57] BUV.INR = BUVPower*T[58] BUV.IAVR = BUVPower*(1-Train.SP3.Value) --737-700 14.3. Режим "МАНЕВР". --BUV. = BUVPower*Train:ReadTrainWire(45) self.Schemes = S end --[=[ -------------------------------------------------------------------------------- function TRAIN_SYSTEM:SolvePowerCircuits(Train,dT) -- Apply K2, K3 contactors self.R1 = self.R1 + 1e9*(1 - math.min(1,Train.K2.Value+Train.K3.Value)) self.R2 = self.R2 + 1e9*(1 - math.min(1,Train.K2.Value+Train.K3.Value)) -- Thyristor contrller self.Rs1 = Train.PTTI.RVResistance or 1e9 self.Rs2 = Train.PTTI.RVResistance or 1e9 -- Calculate total resistance of engines winding local RwAnchor = Train.Engines.Rwa*2 -- Double because each set includes two engines local RwStator = Train.Engines.Rws*2 -- Total resistance of the stator + shunt self.Rstator13 = (RwStator^(-1) + self.Rs1^(-1))^(-1) self.Rstator24 = (RwStator^(-1) + self.Rs2^(-1))^(-1) -- Total resistance of entire motor self.Ranchor13 = RwAnchor self.Ranchor24 = RwAnchor -- Calculate electric power network --FIXME if Train.PTTI.State < 0 then self:SolvePT(Train) else self:SolvePP(Train) end -- Calculate current through rheostats 1, 2 self.IR1 = self.I13 self.IR2 = self.I24 -- Calculate induction properties of the motor self.I13SH = self.I13SH or self.I13 self.I24SH = self.I24SH or self.I24 -- Time constant local T13const1 = math.max(16.00,math.min(28.0,(self.R13^2) * 2.0)) -- R * L local T24const1 = math.max(16.00,math.min(28.0,(self.R24^2) * 2.0)) -- R * L -- Total change local dI13dT = T13const1 * (self.I13 - self.I13SH) * dT local dI24dT = T24const1 * (self.I24 - self.I24SH) * dT -- Limit change and apply it if dI13dT > 0 then dI13dT = math.min(self.I13 - self.I13SH,dI13dT) end if dI13dT < 0 then dI13dT = math.max(self.I13 - self.I13SH,dI13dT) end if dI24dT > 0 then dI24dT = math.min(self.I24 - self.I24SH,dI24dT) end if dI24dT < 0 then dI24dT = math.max(self.I24 - self.I24SH,dI24dT) end self.I13SH = self.I13SH + dI13dT self.I24SH = self.I24SH + dI24dT self.I13 = self.I13SH self.I24 = self.I24SH --FIXME if Train.PTTI.State > 0 then -- PS self.I13 = self.I13 * Train.K2.Value * Train.K1.Value self.I24 = self.I24 * Train.K2.Value * Train.K1.Value self.Itotal = Train.Electric.I13 + Train.Electric.I24 else -- PT self.I13 = self.I13 * Train.K3.Value self.I24 = self.I24 * Train.K3.Value self.Itotal = Train.Electric.I13 + Train.Electric.I24 end -- Calculate extra information self.Uanchor13 = self.I13 * self.Ranchor13 self.Uanchor24 = self.I24 * self.Ranchor24 ---------------------------------------------------------------------------- -- Calculate current through stator and shunt self.Ustator13 = self.I13 * self.Rstator13 self.Ustator24 = self.I24 * self.Rstator24 self.Ishunt13 = self.Ustator13 / self.Rs1 self.Istator13 = self.Ustator13 / RwStator self.Ishunt24 = self.Ustator24 / self.Rs2 self.Istator24 = self.Ustator24 / RwStator --FIXME if Train.PTTI.State < 0 then local I1,I2 = self.Ishunt13,self.Ishunt24 self.Ishunt13 = -I2 self.Ishunt24 = -I1 I1,I2 = self.Istator13,self.Istator24 self.Istator13 = -I2 self.Istator24 = -I1 end -- Sane checks if self.R1 > 1e5 then self.IR1 = 0 end if self.R2 > 1e5 then self.IR2 = 0 end -- Calculate power and heating --FIXME local K = 12.0*1e-5 local H = (10.00+(15.00*Train.Engines.Speed/80.0))*1e-3 self.P1 = (self.IR1^2)*self.R1 self.P2 = (self.IR2^2)*self.R2 self.T1 = (self.T1 + self.P1*K*dT - (self.T1-25)*H*dT) self.T2 = (self.T2 + self.P2*K*dT - (self.T2-25)*H*dT) self.Overheat1 = math.min(1-1e-12, self.Overheat1 + math.max(0,(math.max(0,self.T1-750.0)/400.0)^2)*dT ) self.Overheat2 = math.min(1-1e-12, self.Overheat2 + math.max(0,(math.max(0,self.T2-750.0)/400.0)^2)*dT ) -- Energy consumption self.ElectricEnergyUsed = self.ElectricEnergyUsed + math.max(0,self.EnergyChange)*dT self.ElectricEnergyDissipated = self.ElectricEnergyDissipated + math.max(0,-self.EnergyChange)*dT end function TRAIN_SYSTEM:SolvePP(Train) -- Calculate total resistance of each branch local R1 = self.Ranchor13 + self.Rstator13 local R2 = self.Ranchor13 + self.Rstator13 local CircuitClosed = (self.Power750V*Train.K1.Value > 0) and 1 or 0 -- Main circuit parameters local V = self.Power750V*Train.K1.Value*Train.PTTI.RNState local E1 = Train.Engines.E13 local E2 = Train.Engines.E24 -- Calculate current through engines 13, 24 self.I13 = math.max(0,((V - E1)/R1)*CircuitClosed) self.I24 = math.max(0,((V - E2)/R2)*CircuitClosed) -- Total resistance (for induction RL circuit) self.R13 = R1 self.R24 = R2 -- Calculate everything else self.U13 = self.I13*R1 self.U24 = self.I24*R2 self.Utotal = (self.U13 + self.U24)/2 self.Itotal = Train.Electric.I13 + Train.Electric.I24 -- Energy consumption self.EnergyChange = math.abs((self.I13^2)*R1) + math.abs((self.I24^2)*R2) end function TRAIN_SYSTEM:SolvePT(Train) -- Winding resistances local R1 = self.Ranchor13 + self.Rstator13 local R2 = self.Ranchor24 + self.Rstator24 -- Total resistance of the entire braking rheostat local R3 = --[[ (1.730+0.4)*--]] 2.8*(1-0.95*Train.PTTI.RNState)--0.84 -- Main circuit parameters local V = self.Power750V*Train.K1.Value local E1 = Train.Engines.E13 local E2 = Train.Engines.E24 -- Calculate current through engines 13, 24 self.I13 = -((E1*R2 + E1*R3 - E2*R3 - R2*V)/(R1*R2 + R1*R3 + R2*R3)) self.I24 = -((E2*R1 - E1*R3 + E2*R3 - R1*V)/(R1*R2 + R1*R3 + R2*R3)) -- Total resistance (for induction RL circuit) self.R13 = R3+((R1^(-1) + R2^(-1))^(-1)) self.R24 = R3+((R1^(-1) + R2^(-1))^(-1)) -- Calculate everything else self.U13 = self.I13*R1 self.U24 = self.I24*R2 self.Utotal = (self.U13 + self.U24)/2 self.Itotal = Train.Electric.I13 + Train.Electric.I24 -- Energy consumption self.EnergyChange = -math.abs(((0.5*self.Itotal)^2)*self.R13) end --]=]