1
0
mirror of https://github.com/metrostroi-repo/MetrostroiAddon.git synced 2026-05-02 00:42:29 +00:00

Implemented rechargeable battery and imitation of control circuit's current. Randomized initial battery voltage and relays trigger level

This commit is contained in:
Moon Horse
2023-05-02 02:22:30 +03:00
parent d17cb74904
commit 0027160c2d
15 changed files with 156 additions and 73 deletions

View File

@@ -128,7 +128,8 @@ function ENT:Initialize()
Pos = Vector(-177, -66, -50), Radius = 20, Pos = Vector(-177, -66, -50), Radius = 20,
}, },
} }
self.BattCurrent = 0
self.eds_eq = 0
-- Cross connections in train wires -- Cross connections in train wires
self.TrainWireInverts = { self.TrainWireInverts = {
@@ -226,6 +227,9 @@ end
function ENT:TrainSpawnerUpdate() function ENT:TrainSpawnerUpdate()
local typ = self:GetNW2Int("Type") local typ = self:GetNW2Int("Type")
local num = self.WagonNumber local num = self.WagonNumber
self.Battery:TriggerInput("CarType",1)
self.Battery:TriggerInput("InitialVoltage",math.random(62,75))
self.Battery:TriggerInput("Dischargeable",self:GetNW2Bool("BattCharge"))
math.randomseed(num+817171) math.randomseed(num+817171)
local kvr=false local kvr=false
local passtex = "Def_717SPBWhite" local passtex = "Def_717SPBWhite"
@@ -365,8 +369,8 @@ function ENT:Think()
self:SetPackedRatio("TLPressure", Pneumatic.TrainLinePressure/16.0) self:SetPackedRatio("TLPressure", Pneumatic.TrainLinePressure/16.0)
self:SetPackedRatio("BCPressure", Pneumatic.BrakeCylinderPressure/6.0) self:SetPackedRatio("BCPressure", Pneumatic.BrakeCylinderPressure/6.0)
self:SetPackedRatio("BatteryVoltage",Panel["V1"]*self.Battery.Voltage/150.0) self:SetPackedRatio("BatteryVoltage",(self.eds_eq)/150.0)
self:SetPackedRatio("BatteryCurrent",Panel["V1"]*math.Clamp((self.Battery.Voltage-75)*0.01,-0.01,1)) self:SetPackedRatio("BatteryCurrent",self.BattCurrent/1000)
self:SetPackedRatio("EnginesCurrent", 0.5 + 0.5*(self.Electric.I24/500.0)) self:SetPackedRatio("EnginesCurrent", 0.5 + 0.5*(self.Electric.I24/500.0))
self:SetPackedBool("Compressor",Pneumatic.Compressor > 0) self:SetPackedBool("Compressor",Pneumatic.Compressor > 0)

View File

@@ -131,6 +131,8 @@ function ENT:Initialize()
Pos = Vector(-177, -66, -50), Radius = 20, Pos = Vector(-177, -66, -50), Radius = 20,
}, },
} }
self.BattCurrent = 0
self.eds_eq = 0
-- Cross connections in train wires -- Cross connections in train wires
self.TrainWireInverts = { self.TrainWireInverts = {
@@ -228,6 +230,9 @@ end
function ENT:TrainSpawnerUpdate() function ENT:TrainSpawnerUpdate()
self:SetNW2Bool("Custom",self.CustomSettings) self:SetNW2Bool("Custom",self.CustomSettings)
self.Battery:TriggerInput("CarType",1)
self.Battery:TriggerInput("InitialVoltage",math.random(62,75))
self.Battery:TriggerInput("Dischargeable",self:GetNW2Bool("BattCharge"))
local num = self.WagonNumber local num = self.WagonNumber
math.randomseed(num+817171) math.randomseed(num+817171)
if self.CustomSettings then if self.CustomSettings then
@@ -357,23 +362,9 @@ function ENT:Think()
self:SetPackedRatio("BCPressure", Pneumatic.BrakeCylinderPressure/6.0) self:SetPackedRatio("BCPressure", Pneumatic.BrakeCylinderPressure/6.0)
----------------------------------*****************************-------------------------------- ----------------------------------*****************************--------------------------------
--10th wire voltage readout imitation depending on the BPSNs and EKK state, not on the wagon battery switch state
local hvcounter = 0
local hvcar = nil
local vdrop = 1.125*(#self.WagonList)
for k,v in ipairs(self.WagonList) do
if v.PowerSupply.X2_2 > 0 and v.A24.Value > 0 then
hvcounter = hvcounter + 1
hvcar = hvcar or v
vdrop = vdrop - 1.125
else
vdrop = vdrop - ((v.A56.Value == 0 and 0.4 or (v.VB.Value == 0 and 0.4 or 0)) + (v.LK4.Value == 0 and 0.725 or 0))
end
end
local PCV_o = hvcounter > 0 and math.Clamp(76+(hvcar.Electric.Aux750V - 600)*8/375, 76, 84) - vdrop or self.WagonList[1].Battery.Voltage
--imitating converter overload protection only when control circuits are energized and at least one PC on the train is off; pretty useless btw (but fun) --imitating converter overload protection only when control circuits are energized and at least one PC on the train is off; pretty useless btw (but fun)
local pcloadratio = #self.WagonList/(hvcounter > 0 and hvcounter or 0.5) local pcloadratio = #self.WagonList/(self.Battery.hvcounter > 0 and self.Battery.hvcounter or 0.5)
local _A = 25*(6 - 6/(5.01)) --assuming one PC on 6 cars can work for 25 secs while the cars' CCs are energized local _A = 90*(6 - 6/(5.01)) --assuming one PC on 6 cars can work for 90 secs while the cars' CCs are energized
if pcloadratio > 1 and pcloadratio <= #self.WagonList and self.LK4.Value > 0 and self.PowerSupply.X2_2 > 0 and not self.pcrlxtimer then if pcloadratio > 1 and pcloadratio <= #self.WagonList and self.LK4.Value > 0 and self.PowerSupply.X2_2 > 0 and not self.pcrlxtimer then
self.pcprotimer = self.pcprotimer or CurTime() self.pcprotimer = self.pcprotimer or CurTime()
--hyperbolic function of PC operating time depending on load coeff --hyperbolic function of PC operating time depending on load coeff
@@ -394,8 +385,8 @@ function ENT:Think()
self.PowerSupply:TriggerInput("3x2",self.pcrlxtimer and 1 or 0) --BPSN overheat protection in case of RZP button is being pressed constantly self.PowerSupply:TriggerInput("3x2",self.pcrlxtimer and 1 or 0) --BPSN overheat protection in case of RZP button is being pressed constantly
----------------------------------*****************************-------------------------------- ----------------------------------*****************************--------------------------------
self:SetPackedRatio("BatteryVoltage",Panel["V1"]*PCV_o/150.0) self:SetPackedRatio("BatteryVoltage",(self.eds_eq)/150.0)
self:SetPackedRatio("BatteryCurrent",Panel["V1"]*math.Clamp((self.Battery.Voltage-75)*0.01,-0.01,1)) self:SetPackedRatio("BatteryCurrent",self.BattCurrent/1000)
self:SetPackedRatio("EnginesCurrent", 0.5 + 0.5*(self.Electric.I24/500.0)) self:SetPackedRatio("EnginesCurrent", 0.5 + 0.5*(self.Electric.I24/500.0))
self:SetPackedBool("Compressor",Pneumatic.Compressor > 0) self:SetPackedBool("Compressor",Pneumatic.Compressor > 0)

View File

@@ -243,6 +243,8 @@ function ENT:Initialize()
self.PassengerDoor = false self.PassengerDoor = false
self.OtsekDoor1 = false self.OtsekDoor1 = false
self.OtsekDoor2 = false self.OtsekDoor2 = false
self.BattCurrent = 0
self.eds_eq = 0
self.Lamps = { self.Lamps = {
broken = {}, broken = {},
@@ -334,6 +336,15 @@ function ENT:TrainSpawnerUpdate()
local typ = self:GetNW2Int("Type") local typ = self:GetNW2Int("Type")
local num = self.WagonNumber local num = self.WagonNumber
self:SetNW2Bool("Custom",self.CustomSettings) self:SetNW2Bool("Custom",self.CustomSettings)
self.Battery:TriggerInput("CarType",1)
self.Battery:TriggerInput("InitialVoltage",math.random(62,75))
self.Battery:TriggerInput("Dischargeable",self:GetNW2Bool("BattCharge"))
local ccc = 0
self.ComputerCar = false
for k,v in ipairs(self.WagonList) do
if v.AR63 and v.ComputerCar then ccc = ccc + 1; break end
end
if ccc == 0 then self.ComputerCar = true end
math.randomseed(num+817171) math.randomseed(num+817171)
local kvr=false local kvr=false
local seats=false local seats=false
@@ -685,7 +696,7 @@ function ENT:Think()
self:SetPackedRatio("EnginesVoltage", self.Electric.Aux750V/1000.0) self:SetPackedRatio("EnginesVoltage", self.Electric.Aux750V/1000.0)
self:SetPackedRatio("EnginesCurrent2", 0.5 + 0.5*(self.Electric.I13/500.0)) self:SetPackedRatio("EnginesCurrent2", 0.5 + 0.5*(self.Electric.I13/500.0))
self:SetPackedRatio("EnginesCurrent", 0.5 + 0.5*(self.Electric.I24/500.0)) self:SetPackedRatio("EnginesCurrent", 0.5 + 0.5*(self.Electric.I24/500.0))
self:SetPackedRatio("BatteryVoltage",Panel["V1"]*self.Battery.Voltage/150.0) self:SetPackedRatio("BatteryVoltage",(self.eds_eq)/150.0)
self:SetPackedBool("Compressor",self.Pneumatic.Compressor > 0) self:SetPackedBool("Compressor",self.Pneumatic.Compressor > 0)
self:SetPackedBool("Buzzer",Panel.Ring > 0) self:SetPackedBool("Buzzer",Panel.Ring > 0)
self:SetPackedBool("RK",self.RheostatController.Velocity ~= 0.0) self:SetPackedBool("RK",self.RheostatController.Velocity ~= 0.0)

View File

@@ -110,4 +110,5 @@ ENT.Spawner = {
ent.Pneumatic.TrainLinePressure = val==3 and math.random()*4 or val==2 and 4.5+math.random()*3 or 7.6+math.random()*0.6 ent.Pneumatic.TrainLinePressure = val==3 and math.random()*4 or val==2 and 4.5+math.random()*3 or 7.6+math.random()*0.6
if val==4 then ent.Pneumatic.BrakeLinePressure = 5.2 end if val==4 then ent.Pneumatic.BrakeLinePressure = 5.2 end
end}, end},
{"BattCharge","Spawner.717.Chargeable","Boolean"}
} }

View File

@@ -223,6 +223,8 @@ function ENT:Initialize()
self.PassengerDoor = false self.PassengerDoor = false
self.OtsekDoor1 = false self.OtsekDoor1 = false
self.OtsekDoor2 = false self.OtsekDoor2 = false
self.BattCurrent = 0
self.eds_eq = 0
self.Lamps = { self.Lamps = {
broken = {}, broken = {},
@@ -381,6 +383,15 @@ function ENT:TrainSpawnerUpdate()
-- --
local num = self.WagonNumber local num = self.WagonNumber
self:SetNW2Bool("Custom",self.CustomSettings) self:SetNW2Bool("Custom",self.CustomSettings)
self.Battery:TriggerInput("CarType",1)
self.Battery:TriggerInput("InitialVoltage",math.random(62,75))
self.Battery:TriggerInput("Dischargeable",self:GetNW2Bool("BattCharge"))
local ccc = 0
self.ComputerCar = false
for k,v in ipairs(self.WagonList) do
if v.AR63 and v.ComputerCar then ccc = ccc + 1; break end
end
if ccc == 0 then self.ComputerCar = true end
math.randomseed(num+817171) math.randomseed(num+817171)
if self.CustomSettings then if self.CustomSettings then
--{"Type","Spawner.717.Type","List",{"Spawner.717.Type.717","Spawner.717.Type.7175"}}, --{"Type","Spawner.717.Type","List",{"Spawner.717.Type.717","Spawner.717.Type.7175"}},
@@ -677,24 +688,9 @@ function ENT:Think()
self:SetPackedRatio("EnginesCurrent", 0.5 + 0.5*(self.Electric.I24/500.0)) self:SetPackedRatio("EnginesCurrent", 0.5 + 0.5*(self.Electric.I24/500.0))
----------------------------------*****************************-------------------------------- ----------------------------------*****************************--------------------------------
--10th wire voltage readout imitation depending on the BPSNs and EKK state, not on the wagon battery switch state
-- PC — power converter; CC — control circuits
local hvcounter = 0
local hvcar = nil
local vdrop = 1.125*(#self.WagonList)
for k,v in ipairs(self.WagonList) do
if v.PowerSupply.X2_2 > 0 and v.A24.Value > 0 then
hvcounter = hvcounter + 1
hvcar = hvcar or v
vdrop = vdrop - 1.125
else
vdrop = vdrop - ((v.A56.Value == 0 and 0.4 or (v.VB.Value == 0 and 0.4 or 0)) + (v.LK4.Value == 0 and 0.725 or 0))
end
end
local PCV_o = hvcounter > 0 and math.Clamp(76+(hvcar.Electric.Aux750V - 600)*8/375, 76, 84) - vdrop or self.WagonList[1].Battery.Voltage
--imitating converter overload protection only when control circuits are energized and at least one PC on the train is off; pretty useless btw (but fun) --imitating converter overload protection only when control circuits are energized and at least one PC on the train is off; pretty useless btw (but fun)
local pcloadratio = #self.WagonList/(hvcounter > 0 and hvcounter or 0.5) local pcloadratio = #self.WagonList/(self.Battery.hvcounter > 0 and self.Battery.hvcounter or 0.5)
local _A = 25*(6 - 6/(5.01)) --assuming one PC on 6 cars can work for 25 secs while the cars' CCs are energized local _A = 90*(6 - 6/(5.01)) --assuming one PC on 6 cars can work for 90 secs while the cars' CCs are energized
if pcloadratio > 1 and pcloadratio <= #self.WagonList and self.LK4.Value > 0 and self.PowerSupply.X2_2 > 0 and not self.pcrlxtimer then if pcloadratio > 1 and pcloadratio <= #self.WagonList and self.LK4.Value > 0 and self.PowerSupply.X2_2 > 0 and not self.pcrlxtimer then
self.pcprotimer = self.pcprotimer or CurTime() self.pcprotimer = self.pcprotimer or CurTime()
--hyperbolic function of PC operating time depending on load coeff --hyperbolic function of PC operating time depending on load coeff
@@ -715,7 +711,7 @@ function ENT:Think()
self.PowerSupply:TriggerInput("3x2",self.pcrlxtimer and 1 or 0) --BPSN overheat protection in case of RZP button is being pressed constantly self.PowerSupply:TriggerInput("3x2",self.pcrlxtimer and 1 or 0) --BPSN overheat protection in case of RZP button is being pressed constantly
----------------------------------*****************************-------------------------------- ----------------------------------*****************************--------------------------------
self:SetPackedRatio("BatteryVoltage",Panel["V1"]*PCV_o/150.0) self:SetPackedRatio("BatteryVoltage",(self.eds_eq)/150.0)
self:SetPackedBool("Compressor",Pneumatic.Compressor > 0) self:SetPackedBool("Compressor",Pneumatic.Compressor > 0)
self:SetPackedBool("Buzzer",Panel.Ring >= 1) self:SetPackedBool("Buzzer",Panel.Ring >= 1)

View File

@@ -114,4 +114,5 @@ ENT.Spawner = {
ent.Pneumatic.BrakeLinePressure = val == 4 and 5.2 or val == 1 and 2.3 or math.min(ent.Pneumatic.TrainLinePressure+0.25,math.random()*4) ent.Pneumatic.BrakeLinePressure = val == 4 and 5.2 or val == 1 and 2.3 or math.min(ent.Pneumatic.TrainLinePressure+0.25,math.random()*4)
ent.Pneumatic.WorkingChamberPressure = val==3 and math.random()*1.0 or val==2 and 4.0+math.random()*1.0 or 5.2 ent.Pneumatic.WorkingChamberPressure = val==3 and math.random()*1.0 or val==2 and 4.0+math.random()*1.0 or 5.2
end}, end},
{"BattCharge","Spawner.717.Chargeable","Boolean"}
} }

View File

@@ -58,8 +58,9 @@ function TRAIN_SYSTEM:SolveAllInternalCircuits(Train,dT,firstIter)
local P = Train.PositionSwitch local P = Train.PositionSwitch
local RheostatController = Train.RheostatController local RheostatController = Train.RheostatController
local RK = RheostatController.SelectedPosition local RK = RheostatController.SelectedPosition
local B = (Train.Battery.Voltage > 55) and 1 or 0 local B = (Train.Battery.Voltage >= 60) and 1 or (Train.Battery.Voltage >= Train.Battery.CutoffVoltage) and 0.5 or 0
local BO = B*Train.VB.Value local BO = B*Train.VB.Value*(1-Train.PA1.Value)
local BO2 = B*Train.VB.Value*(1-Train.PA2.Value)
local T = Train.SolverTemporaryVariables local T = Train.SolverTemporaryVariables
local isMVM = self.Type == 1 local isMVM = self.Type == 1
@@ -80,7 +81,7 @@ function TRAIN_SYSTEM:SolveAllInternalCircuits(Train,dT,firstIter)
end end
--Вагонная часть --Вагонная часть
S["10A"] = BO*Train.A30.Value 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["ZR"] = (1-Train.RRP.Value)+(B*(1-Train.PA2.Value)*Train.A39.Value*(1-Train.RPvozvrat.Value)*Train.RRP.Value)*-1
S["1A"] = T[1]*Train.A1.Value*Train.IGLA_PCBK.KVC S["1A"] = T[1]*Train.A1.Value*Train.IGLA_PCBK.KVC
S["6A"] = T[6]*Train.A6.Value S["6A"] = T[6]*Train.A6.Value
@@ -229,7 +230,7 @@ function TRAIN_SYSTEM:SolveAllInternalCircuits(Train,dT,firstIter)
Train:WriteTrainWire(22,T[10]*Train.A10.Value*Train.AK.Value) Train:WriteTrainWire(22,T[10]*Train.A10.Value*Train.AK.Value)
S["UO"] = T[10]*Train.A27.Value S["UO"] = T[10]*Train.A27.Value
Train:WriteTrainWire(27,S["UO"]*Train.L_1.Value) Train:WriteTrainWire(27,S["UO"]*Train.L_1.Value)
S["36N"] = BO*Train.A45.Value S["36N"] = BO2*Train.A45.Value
Train:WriteTrainWire(36,S["36N"]*Train.BPSNon.Value) Train:WriteTrainWire(36,S["36N"]*Train.BPSNon.Value)
Train:WriteTrainWire(37,S["36N"]*Train.ConverterProtection.Value) Train:WriteTrainWire(37,S["36N"]*Train.ConverterProtection.Value)
@@ -252,7 +253,7 @@ function TRAIN_SYSTEM:SolveAllInternalCircuits(Train,dT,firstIter)
S["B9a"] = S["B9"]*Train.VB.Value S["B9a"] = S["B9"]*Train.VB.Value
Train.KVC:TriggerInput("Set",S["B9a"]) Train.KVC:TriggerInput("Set",S["B9a"])
--Train.KUP:TriggerInput("Set",S["B9a"]*Train.A75.Value) --Train.KUP:TriggerInput("Set",S["B9a"]*Train.A75.Value)
S["D4"] = BO*Train.A13.Value S["D4"] = BO2*Train.A13.Value
Panel.RZP = T[36]*T[61] Panel.RZP = T[36]*T[61]
--[[S["14b"] = S["14a"]*Train.A17.Value --[[S["14b"] = S["14a"]*Train.A17.Value
S["D1"] = ["10"]*Train.A21.Value*KV["D-D1"]+S["14b"]*KRU["11/3-D1/1"] S["D1"] = ["10"]*Train.A21.Value*KV["D-D1"]+S["14b"]*KRU["11/3-D1/1"]
@@ -340,13 +341,13 @@ function TRAIN_SYSTEM:SolveRKInternalCircuits(Train,dT,firstIter)
local P = Train.PositionSwitch local P = Train.PositionSwitch
local RheostatController = Train.RheostatController local RheostatController = Train.RheostatController
local RK = RheostatController.SelectedPosition local RK = RheostatController.SelectedPosition
local B = (Train.Battery.Voltage > 55) and 1 or 0 local B = (Train.Battery.Voltage >= 60) and 1 or (Train.Battery.Voltage >= Train.Battery.CutoffVoltage) and 0.5 or 0
local BO = B*Train.VB.Value local BO = B*Train.VB.Value*(1-Train.PA1.Value)
local T = Train.SolverTemporaryVariables local T = Train.SolverTemporaryVariables
--Вагонная часть --Вагонная часть
S["10A"] = BO*Train.A30.Value 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["ZR"] = (1-Train.RRP.Value)+(B*(1-Train.PA2.Value)*Train.A39.Value*(1-Train.RPvozvrat.Value)*Train.RRP.Value)*-1
S["1N"] = C(11<=RK and RK<=18)*(1-Train.LK4.Value) S["1N"] = C(11<=RK and RK<=18)*(1-Train.LK4.Value)

View File

@@ -56,8 +56,9 @@ function TRAIN_SYSTEM:SolveAllInternalCircuits(Train,dT,firstIter)
local P = Train.PositionSwitch local P = Train.PositionSwitch
local RheostatController = Train.RheostatController local RheostatController = Train.RheostatController
local RK = RheostatController.SelectedPosition local RK = RheostatController.SelectedPosition
local B = (Train.Battery.Voltage > 55) and 1 or 0 local B = (Train.Battery.Voltage >= 60) and 1 or (Train.Battery.Voltage >= Train.Battery.CutoffVoltage) and 0.5 or 0
local BO = B*Train.VB.Value local BO = B*Train.VB.Value*(1-Train.PA1.Value)
local BO2 = B*Train.VB.Value*(1-Train.PA2.Value)
local T = Train.SolverTemporaryVariables local T = Train.SolverTemporaryVariables
local elType = self.Type local elType = self.Type
local isMVM = elType == 1 local isMVM = elType == 1
@@ -77,11 +78,12 @@ function TRAIN_SYSTEM:SolveAllInternalCircuits(Train,dT,firstIter)
S["10AK"] = T[10]*Train.A54.Value*Train.A84.Value S["10AK"] = T[10]*Train.A54.Value*Train.A84.Value
S["U2"] = S["10AK"]*KV["U2-10AK"] --10AK-KV-U2 S["U2"] = S["10AK"]*KV["U2-10AK"] --10AK-KV-U2
--print(Train.Battery.CutoffVoltage)
--Reverser --Reverser
S["7D"] = T[10]*Train.A48.Value S["7D"] = T[10]*Train.A48.Value
S["7G"] = S["7D"]*KV["10-7G"] --10-A48-RV-7G --FIXME 34w ARS S["7G"] = S["7D"]*KV["10-7G"] --10-A48-RV-7G --FIXME 34w ARS
S["B3"] = B*Train.A44.Value S["B3"] = B*(1-Train.PA2.Value)*Train.A44.Value
S["14a"] = S["B3"]*KRU["14/1-B3"] S["14a"] = S["B3"]*KRU["14/1-B3"]
S["14b"] = S["14a"]*Train.A17.Value S["14b"] = S["14a"]*Train.A17.Value
S["F"] = T[10]*Train.A29.Value S["F"] = T[10]*Train.A29.Value
@@ -475,7 +477,7 @@ function TRAIN_SYSTEM:SolveAllInternalCircuits(Train,dT,firstIter)
--Вагонная часть --Вагонная часть
S["10A"] = BO*Train.A30.Value 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["ZR"] = (1-Train.RRP.Value)+(B*(1-Train.PA2.Value)*Train.A39.Value*(1-Train.RPvozvrat.Value)*Train.RRP.Value)*-1
if isMVM then if isMVM then
S["1A"] = T[1]*Train.A1.Value*Train.IGLA_PCBK.KVC S["1A"] = T[1]*Train.A1.Value*Train.IGLA_PCBK.KVC
@@ -703,7 +705,7 @@ function TRAIN_SYSTEM:SolveAllInternalCircuits(Train,dT,firstIter)
Panel.TW18 = S["18A"] Panel.TW18 = S["18A"]
Panel.GreenRP = S["10AN"]*S["UO"] Panel.GreenRP = S["10AN"]*S["UO"]
S["36N"] = BO*Train.A45.Value S["36N"] = BO2*Train.A45.Value
Train:WriteTrainWire(37,Train.ConverterProtection.Value) Train:WriteTrainWire(37,Train.ConverterProtection.Value)
Train:WriteTrainWire(69,S["36N"]*Train.BPSNon.Value) Train:WriteTrainWire(69,S["36N"]*Train.BPSNon.Value)
Train:WriteTrainWire(36,T[69]*(1-Train.BPSNon.Value)) Train:WriteTrainWire(36,T[69]*(1-Train.BPSNon.Value))
@@ -715,7 +717,7 @@ function TRAIN_SYSTEM:SolveAllInternalCircuits(Train,dT,firstIter)
Train.KUP:TriggerInput("Set",S["B9a"]*Train.A75.Value) Train.KUP:TriggerInput("Set",S["B9a"]*Train.A75.Value)
Panel.KUP = S["B9a"]*Train.KUP.Value Panel.KUP = S["B9a"]*Train.KUP.Value
S["D4"] = BO*Train.A13.Value S["D4"] = BO2*Train.A13.Value
if isLVZ then if isLVZ then
if isKSD then if isKSD then
S["D1"] = T[10]*Train.A21.Value*KV["D-D1"]+S["14b"]*KRU["11/3-D1/1"]+T[16]*Train.VUD1.Value S["D1"] = T[10]*Train.A21.Value*KV["D-D1"]+S["14b"]*KRU["11/3-D1/1"]+T[16]*Train.VUD1.Value
@@ -881,13 +883,13 @@ function TRAIN_SYSTEM:SolveRKInternalCircuits(Train,dT,firstIter)
local P = Train.PositionSwitch local P = Train.PositionSwitch
local RheostatController = Train.RheostatController local RheostatController = Train.RheostatController
local RK = RheostatController.SelectedPosition local RK = RheostatController.SelectedPosition
local B = (Train.Battery.Voltage > 55) and 1 or 0 local B = (Train.Battery.Voltage >= 60) and 1 or (Train.Battery.Voltage >= Train.Battery.CutoffVoltage) and 0.5 or 0
local BO = B*Train.VB.Value local BO = B*Train.VB.Value*(1-Train.PA1.Value)
local T = Train.SolverTemporaryVariables local T = Train.SolverTemporaryVariables
--Вагонная часть --Вагонная часть
S["10A"] = BO*Train.A30.Value 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["ZR"] = (1-Train.RRP.Value)+(B*(1-Train.PA2.Value)*Train.A39.Value*(1-Train.RPvozvrat.Value)*Train.RRP.Value)*-1
S["1N"] = C(11<=RK and RK<=18)*(1-Train.LK4.Value) S["1N"] = C(11<=RK and RK<=18)*(1-Train.LK4.Value)

View File

@@ -1,10 +1,11 @@
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Battery -- Battery (HKH-80 type NiCd battery)
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
-- Copyright (C) 2013-2018 Metrostroi Team & FoxWorks Aerospace s.r.o. -- Copyright (C) 2013-2018 Metrostroi Team & FoxWorks Aerospace s.r.o.
-- Contains proprietary code. See license.txt for additional information. -- Contains proprietary code. See license.txt for additional information.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
Metrostroi.DefineSystem("Battery") Metrostroi.DefineSystem("Battery")
TRAIN_SYSTEM.DontAccelerateSimulation = true
function TRAIN_SYSTEM:Initialize() function TRAIN_SYSTEM:Initialize()
-- Предохранители цепей (ПА1, ПА2) -- Предохранители цепей (ПА1, ПА2)
@@ -12,35 +13,98 @@ function TRAIN_SYSTEM:Initialize()
self.Train:LoadSystem("PA2","Relay","PP-28", { trigger_level = 31.5 }) -- A self.Train:LoadSystem("PA2","Relay","PP-28", { trigger_level = 31.5 }) -- A
-- Battery parameters -- Battery parameters
self.ElementCapacity = 80 -- A*hour self.ElementCapacity = 80 -- A*hour
self.ElementCount = 56 -- 52 on 81-717 self.Capacity = self.ElementCapacity * 3600
self.Capacity = self.ElementCapacity * self.ElementCount * 3600
self.Charge = self.Capacity self.Charge = self.Capacity
self.Voltage = 65
-- Current through battery in amperes -- Current through battery in amperes
self.Current = 0 self.Current = 0
self.Charging = 0 self.Charging = 0
self.ElementCount = 52
self.StartVoltage = 75 -- 1.44 volt per fully charged new NiCd-cell
self.Voltage = self.StartVoltage
self.IResistance = 0.018*52 -- 0.018 Ohm is a standard internal resistance of a fully-charged and rested new 80 Ah NiCd-cell
self.SoC0v = 52 -- 52 volts at 0% state of charge assuming 1.0 volt per fully discharged cell
self.SoC = 100 -- fully charged
self.CutoffVoltage = 54.7 -- 52 Volts actually, but due to lack of CC's current simulation train devices won't ever be shut down with this value
self.Ibatt = 0
self.eds_eq = 0
self.hvcounter = 0
self.Dischar = false
self.ComputerCar = false
end end
function TRAIN_SYSTEM:Inputs() function TRAIN_SYSTEM:Inputs()
return { "Charge" } return { "Charge", "Dischargeable", "InitialVoltage", "CarType" }
end end
function TRAIN_SYSTEM:Outputs() function TRAIN_SYSTEM:Outputs()
return { "Capacity", "Charge", "Voltage" } return { "Capacity", "Charge", "Voltage" }
end end
function TRAIN_SYSTEM:TriggerInput(name,value) function TRAIN_SYSTEM:TriggerInput(name,value)
if name == "Charge" then self.Charging = value end if name == "Charge" then self.Charging = value end
if name == "Dischargeable" then self.Dischar = value end
if name == "InitialVoltage" then self.StartVoltage = value end
if name == "CarType" then self.CarType = value end
end end
function TRAIN_SYSTEM:Think(dT) function TRAIN_SYSTEM:Think(dT)
-- Calculate discharge if self.CarType == 1 then
self.Current = 0--self.Train.KVC.Value*90*(self.Train.PowerSupply.XT3_1 > 0 and 3 or -1 + 4*self.Train:ReadTrainWire(27))*50*self.Train.Panel["V1"] self.SoC = 100 * (self.Voltage - self.SoC0v)/(75 - self.SoC0v)
--print(self.Train.Panel["V1"]) if self.SoC > 60 then
self.Charge = math.min(self.Capacity,self.Charge + self.Current * dT) self.IResistance = 1e-4 * self.SoC + 0.012
elseif 20 <= self.SoC and self.SoC <= 60 then
-- Calculate battery voltage self.IResistance = 0.018
if self.Train.PowerSupply then elseif self.SoC < 20 then
self.Voltage = 65*(self.Charge/self.Capacity) + ((self.Train.PowerSupply.XT3_1 or self.Charging) > 0 and 17 or 0) self.IResistance = math.min(1.1, 0.018 + 1.56^(12-1.48*self.SoC)) -- just made it up by myself >_>
end
self.IResistance = self.IResistance * self.ElementCount
if self.Train.ComputerCar then
local nodecurr_sum, branchcond_sum = 0, 0
local eds_eq = 0
local hvcounter = 0
for k,v in ipairs(self.Train.WagonList) do
if v.PowerSupply.X2_2 > 0 and v.A24.Value > 0 then
hvcounter = hvcounter + 1
end
end
--a "two-node method" of 10's wire voltage computing
for k,v in ipairs(self.Train.WagonList) do
nodecurr_sum = nodecurr_sum + v.A56.Value*(v.VB.Value*v.Battery.Voltage/v.Battery.IResistance + v.PowerSupply.X2_1*v.A24.Value*v.PowerSupply.VoltageOut/v.PowerSupply.IResistance)
--+ 1/((1 - v.VB.Value*v.A49.Value)*1e12 + 1e3)
branchcond_sum = branchcond_sum + 1/(v.LK4.Value > 0 and 20 or 1e12) + 1/(v.RV1.Value > 0 and 10 or 1e12) + 1/(v.KK.Value > 0 and 24 or 1e12) + 1/(1e3) + v.A56.Value*(v.VB.Value/v.Battery.IResistance + v.PowerSupply.X2_1*v.A24.Value/v.PowerSupply.IResistance)
end
eds_eq = nodecurr_sum/branchcond_sum
for k,v in ipairs(self.Train.WagonList) do
v.PowerSupply.car_control_load = eds_eq*(1/(v.LK4.Value > 0 and 20 or 1e12) + 1/(v.RV1.Value > 0 and 10 or 1e12) + 1/(v.KK.Value > 0 and 24 or 1e12))
v.Battery.Ibatt = math.min(60,(math.min(1,(v.VB.Value*v.A56.Value+v.A24.Value))*v.VB.Value*((v.A56.Value*(eds_eq - v.Battery.Voltage) + v.PowerSupply.X2_1*(1-v.A56.Value)*(v.PowerSupply.VoltageOut*v.A24.Value - v.Battery.Voltage))))/v.Battery.IResistance) -- math.max(0,(2.4*(v.Battery.Voltage/v.Battery.StartVoltage)-2.39))
v.Battery.eds_eq = eds_eq
v.Battery.hvcounter = hvcounter
v.eds_eq = v.Battery.eds_eq
--print(v.PowerSupply.car_control_load,v.Battery.Ibatt,v.Battery.IResistance)
end
end
-- Calculate discharge
if self.Dischar then
self.Train.BattCurrent = self.Ibatt*self.Train.A24.Value
self.Train.PA1:TriggerInput("Close",self.Ibatt)
self.Train.PA2:TriggerInput("Close",self.Ibatt)
self.Charge = math.min(self.Capacity,self.Charge + self.Ibatt * (self.Ibatt < 0 and 1000/self.SoC0v or 500/self.SoC0v)* dT)--1.33*Capacity
end
-- Calculate battery voltage
local batt_calc_voltage = math.max(self.StartVoltage,self.eds_eq*self.Train.VB.Value*self.Train.A56.Value,self.Train.PowerSupply.VoltageOut*self.Train.VB.Value*self.Train.A24.Value*self.Train.PowerSupply.X2_1)
self.Voltage = batt_calc_voltage*(self.Charge/self.Capacity)
--self.Voltage = self.StartVoltage*(self.Charge/self.Capacity)
else else
self.Voltage = 65*(self.Charge/self.Capacity) + (self.Charging > 0 and 17 or 0) -- Calculate discharge
self.Current = 0--self.Train.KVC.Value*90*(self.Train.PowerSupply.XT3_1 > 0 and 3 or -1 + 4*self.Train:ReadTrainWire(27))*50*self.Train.Panel["V1"]
--print(self.Train.Panel["V1"])
self.Charge = math.min(self.Capacity,self.Charge + self.Current * dT)
-- Calculate battery voltage
if self.Train.PowerSupply then
self.Voltage = 65*(self.Charge/self.Capacity) + ((self.Train.PowerSupply.XT3_1 or self.Charging) > 0 and 17 or 0)
else
self.Voltage = 65*(self.Charge/self.Capacity) + (self.Charging > 0 and 17 or 0)
end
end end
--print(self.eds_eq)
end end

View File

@@ -5,6 +5,7 @@
-- Contains proprietary code. See license.txt for additional information. -- Contains proprietary code. See license.txt for additional information.
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
Metrostroi.DefineSystem("BPSN") Metrostroi.DefineSystem("BPSN")
TRAIN_SYSTEM.DontAccelerateSimulation = true
function TRAIN_SYSTEM:Initialize() function TRAIN_SYSTEM:Initialize()
self.X2 = { self.X2 = {
@@ -19,6 +20,11 @@ function TRAIN_SYSTEM:Initialize()
self.X6_2 = 0 self.X6_2 = 0
self.X2_1 = 0 self.X2_1 = 0
self.OutputVoltage = math.random(78,82) -- volts
self.IResistance = 0.05--1.33 --Ohm
self.car_control_load= 0 --Amp
self.VoltageOut = 0
self.Active = 0 self.Active = 0
self.Train:LoadSystem("ConverterProtection","Relay","Switch", {bass = true}) self.Train:LoadSystem("ConverterProtection","Relay","Switch", {bass = true})
end end
@@ -54,4 +60,6 @@ function TRAIN_SYSTEM:Think()
self.Active = XT3_1>0 and 1 or 0 self.Active = XT3_1>0 and 1 or 0
self.X2_2 = Train.Electric.Aux750V*self.Active self.X2_2 = Train.Electric.Aux750V*self.Active
self.X6_2 = self.Active self.X6_2 = self.Active
self.VoltageOut = self.X2_1*((self.OutputVoltage - self.car_control_load*self.IResistance) + (Train.Electric.Aux750V - 600)*2/375)
end end

View File

@@ -75,7 +75,7 @@ function TRAIN_SYSTEM:Initialize(parameters,extra_parameters)
-- Should relay be spring-returned to initial position -- Should relay be spring-returned to initial position
parameters.returns = parameters.returns or (not parameters.latched) parameters.returns = parameters.returns or (not parameters.latched)
-- Trigger level for the relay -- Trigger level for the relay
parameters.trigger_level = parameters.trigger_level or 0.5 parameters.trigger_level = parameters.trigger_level or 0.2*math.random() + 0.4
for k,v in pairs(parameters) do for k,v in pairs(parameters) do
self[k] = v self[k] = v
end end

View File

@@ -1207,6 +1207,7 @@ Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.1 = @[Common.Spawn
Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.2 = @[Common.Spawner.SpawnMode.Deadlock] Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.2 = @[Common.Spawner.SpawnMode.Deadlock]
Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.3 = @[Common.Spawner.SpawnMode.NightDeadlock] Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.3 = @[Common.Spawner.SpawnMode.NightDeadlock]
Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.4 = @[Common.Spawner.SpawnMode.Depot] Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.4 = @[Common.Spawner.SpawnMode.Depot]
Entities.gmod_subway_81-717_mvm_custom.Spawner.BattCharge.Name = @[Common.Spawner.Chargeable]
#Spawner: #Spawner:
Entities.gmod_subway_81-717_lvz.Spawner.Texture.Name = @[Common.Spawner.Texture] Entities.gmod_subway_81-717_lvz.Spawner.Texture.Name = @[Common.Spawner.Texture]

View File

@@ -227,6 +227,7 @@ Common.Spawner.Old = Old
Common.Spawner.New = New Common.Spawner.New = New
Common.Spawner.Type = Type Common.Spawner.Type = Type
Common.Spawner.SchemeInvert = Invert line schemes Common.Spawner.SchemeInvert = Invert line schemes
Common.Spawner.Chargeable = Train battery can lose it's charge
#Coupler common #Coupler common
Common.Couple.Title = Coupler menu Common.Couple.Title = Coupler menu

View File

@@ -1207,6 +1207,7 @@ Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.1 = @[Common.Spawn
Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.2 = @[Common.Spawner.SpawnMode.Deadlock] Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.2 = @[Common.Spawner.SpawnMode.Deadlock]
Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.3 = @[Common.Spawner.SpawnMode.NightDeadlock] Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.3 = @[Common.Spawner.SpawnMode.NightDeadlock]
Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.4 = @[Common.Spawner.SpawnMode.Depot] Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.4 = @[Common.Spawner.SpawnMode.Depot]
Entities.gmod_subway_81-717_mvm_custom.Spawner.BattCharge.Name = @[Common.Spawner.Chargeable]
#Spawner: #Spawner:
Entities.gmod_subway_81-717_lvz.Spawner.Texture.Name = @[Common.Spawner.Texture] Entities.gmod_subway_81-717_lvz.Spawner.Texture.Name = @[Common.Spawner.Texture]

View File

@@ -227,6 +227,7 @@ Common.Spawner.Old = Старые
Common.Spawner.New = Новые Common.Spawner.New = Новые
Common.Spawner.Type = Тип Common.Spawner.Type = Тип
Common.Spawner.SchemeInvert = Инвертировать наддверные схемы Common.Spawner.SchemeInvert = Инвертировать наддверные схемы
Common.Spawner.Chargeable = Разряжаемые аккумуляторы
#Coupler common #Coupler common
Common.Couple.Title = Меню сцепки Common.Couple.Title = Меню сцепки