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:
@@ -128,7 +128,8 @@ function ENT:Initialize()
|
||||
Pos = Vector(-177, -66, -50), Radius = 20,
|
||||
},
|
||||
}
|
||||
|
||||
self.BattCurrent = 0
|
||||
self.eds_eq = 0
|
||||
|
||||
-- Cross connections in train wires
|
||||
self.TrainWireInverts = {
|
||||
@@ -226,6 +227,9 @@ end
|
||||
function ENT:TrainSpawnerUpdate()
|
||||
local typ = self:GetNW2Int("Type")
|
||||
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)
|
||||
local kvr=false
|
||||
local passtex = "Def_717SPBWhite"
|
||||
@@ -365,8 +369,8 @@ function ENT:Think()
|
||||
self:SetPackedRatio("TLPressure", Pneumatic.TrainLinePressure/16.0)
|
||||
self:SetPackedRatio("BCPressure", Pneumatic.BrakeCylinderPressure/6.0)
|
||||
|
||||
self:SetPackedRatio("BatteryVoltage",Panel["V1"]*self.Battery.Voltage/150.0)
|
||||
self:SetPackedRatio("BatteryCurrent",Panel["V1"]*math.Clamp((self.Battery.Voltage-75)*0.01,-0.01,1))
|
||||
self:SetPackedRatio("BatteryVoltage",(self.eds_eq)/150.0)
|
||||
self:SetPackedRatio("BatteryCurrent",self.BattCurrent/1000)
|
||||
self:SetPackedRatio("EnginesCurrent", 0.5 + 0.5*(self.Electric.I24/500.0))
|
||||
|
||||
self:SetPackedBool("Compressor",Pneumatic.Compressor > 0)
|
||||
|
||||
@@ -131,6 +131,8 @@ function ENT:Initialize()
|
||||
Pos = Vector(-177, -66, -50), Radius = 20,
|
||||
},
|
||||
}
|
||||
self.BattCurrent = 0
|
||||
self.eds_eq = 0
|
||||
|
||||
-- Cross connections in train wires
|
||||
self.TrainWireInverts = {
|
||||
@@ -228,6 +230,9 @@ end
|
||||
|
||||
function ENT:TrainSpawnerUpdate()
|
||||
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
|
||||
math.randomseed(num+817171)
|
||||
if self.CustomSettings then
|
||||
@@ -357,23 +362,9 @@ function ENT:Think()
|
||||
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)
|
||||
local pcloadratio = #self.WagonList/(hvcounter > 0 and 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 pcloadratio = #self.WagonList/(self.Battery.hvcounter > 0 and self.Battery.hvcounter or 0.5)
|
||||
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
|
||||
self.pcprotimer = self.pcprotimer or CurTime()
|
||||
--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:SetPackedRatio("BatteryVoltage",Panel["V1"]*PCV_o/150.0)
|
||||
self:SetPackedRatio("BatteryCurrent",Panel["V1"]*math.Clamp((self.Battery.Voltage-75)*0.01,-0.01,1))
|
||||
self:SetPackedRatio("BatteryVoltage",(self.eds_eq)/150.0)
|
||||
self:SetPackedRatio("BatteryCurrent",self.BattCurrent/1000)
|
||||
self:SetPackedRatio("EnginesCurrent", 0.5 + 0.5*(self.Electric.I24/500.0))
|
||||
|
||||
self:SetPackedBool("Compressor",Pneumatic.Compressor > 0)
|
||||
|
||||
@@ -243,6 +243,8 @@ function ENT:Initialize()
|
||||
self.PassengerDoor = false
|
||||
self.OtsekDoor1 = false
|
||||
self.OtsekDoor2 = false
|
||||
self.BattCurrent = 0
|
||||
self.eds_eq = 0
|
||||
|
||||
self.Lamps = {
|
||||
broken = {},
|
||||
@@ -334,6 +336,15 @@ function ENT:TrainSpawnerUpdate()
|
||||
local typ = self:GetNW2Int("Type")
|
||||
local num = self.WagonNumber
|
||||
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)
|
||||
local kvr=false
|
||||
local seats=false
|
||||
@@ -685,7 +696,7 @@ function ENT:Think()
|
||||
self:SetPackedRatio("EnginesVoltage", self.Electric.Aux750V/1000.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("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("Buzzer",Panel.Ring > 0)
|
||||
self:SetPackedBool("RK",self.RheostatController.Velocity ~= 0.0)
|
||||
|
||||
@@ -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
|
||||
if val==4 then ent.Pneumatic.BrakeLinePressure = 5.2 end
|
||||
end},
|
||||
{"BattCharge","Spawner.717.Chargeable","Boolean"}
|
||||
}
|
||||
|
||||
@@ -223,6 +223,8 @@ function ENT:Initialize()
|
||||
self.PassengerDoor = false
|
||||
self.OtsekDoor1 = false
|
||||
self.OtsekDoor2 = false
|
||||
self.BattCurrent = 0
|
||||
self.eds_eq = 0
|
||||
|
||||
self.Lamps = {
|
||||
broken = {},
|
||||
@@ -381,6 +383,15 @@ function ENT:TrainSpawnerUpdate()
|
||||
--
|
||||
local num = self.WagonNumber
|
||||
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)
|
||||
if self.CustomSettings then
|
||||
--{"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))
|
||||
|
||||
----------------------------------*****************************--------------------------------
|
||||
--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)
|
||||
local pcloadratio = #self.WagonList/(hvcounter > 0 and 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 pcloadratio = #self.WagonList/(self.Battery.hvcounter > 0 and self.Battery.hvcounter or 0.5)
|
||||
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
|
||||
self.pcprotimer = self.pcprotimer or CurTime()
|
||||
--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:SetPackedRatio("BatteryVoltage",Panel["V1"]*PCV_o/150.0)
|
||||
self:SetPackedRatio("BatteryVoltage",(self.eds_eq)/150.0)
|
||||
|
||||
self:SetPackedBool("Compressor",Pneumatic.Compressor > 0)
|
||||
self:SetPackedBool("Buzzer",Panel.Ring >= 1)
|
||||
|
||||
@@ -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.WorkingChamberPressure = val==3 and math.random()*1.0 or val==2 and 4.0+math.random()*1.0 or 5.2
|
||||
end},
|
||||
{"BattCharge","Spawner.717.Chargeable","Boolean"}
|
||||
}
|
||||
|
||||
@@ -58,8 +58,9 @@ 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 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*(1-Train.PA1.Value)
|
||||
local BO2 = B*Train.VB.Value*(1-Train.PA2.Value)
|
||||
local T = Train.SolverTemporaryVariables
|
||||
|
||||
local isMVM = self.Type == 1
|
||||
@@ -80,7 +81,7 @@ function TRAIN_SYSTEM:SolveAllInternalCircuits(Train,dT,firstIter)
|
||||
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["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["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)
|
||||
S["UO"] = T[10]*Train.A27.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(37,S["36N"]*Train.ConverterProtection.Value)
|
||||
|
||||
@@ -252,7 +253,7 @@ function TRAIN_SYSTEM:SolveAllInternalCircuits(Train,dT,firstIter)
|
||||
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
|
||||
S["D4"] = BO2*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"]
|
||||
@@ -340,13 +341,13 @@ 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 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*(1-Train.PA1.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["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)
|
||||
|
||||
@@ -56,8 +56,9 @@ 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 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*(1-Train.PA1.Value)
|
||||
local BO2 = B*Train.VB.Value*(1-Train.PA2.Value)
|
||||
local T = Train.SolverTemporaryVariables
|
||||
local elType = self.Type
|
||||
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["U2"] = S["10AK"]*KV["U2-10AK"] --10AK-KV-U2
|
||||
--print(Train.Battery.CutoffVoltage)
|
||||
|
||||
--Reverser
|
||||
S["7D"] = T[10]*Train.A48.Value
|
||||
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["14b"] = S["14a"]*Train.A17.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["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
|
||||
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.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(69,S["36N"]*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)
|
||||
Panel.KUP = S["B9a"]*Train.KUP.Value
|
||||
|
||||
S["D4"] = BO*Train.A13.Value
|
||||
S["D4"] = BO2*Train.A13.Value
|
||||
if isLVZ 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
|
||||
@@ -881,13 +883,13 @@ 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 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*(1-Train.PA1.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["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)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
--------------------------------------------------------------------------------
|
||||
-- Battery
|
||||
-- Battery (HKH-80 type NiCd battery)
|
||||
--------------------------------------------------------------------------------
|
||||
-- Copyright (C) 2013-2018 Metrostroi Team & FoxWorks Aerospace s.r.o.
|
||||
-- Contains proprietary code. See license.txt for additional information.
|
||||
--------------------------------------------------------------------------------
|
||||
Metrostroi.DefineSystem("Battery")
|
||||
TRAIN_SYSTEM.DontAccelerateSimulation = true
|
||||
|
||||
function TRAIN_SYSTEM:Initialize()
|
||||
-- Предохранители цепей (ПА1, ПА2)
|
||||
@@ -12,35 +13,98 @@ function TRAIN_SYSTEM:Initialize()
|
||||
self.Train:LoadSystem("PA2","Relay","PP-28", { trigger_level = 31.5 }) -- A
|
||||
|
||||
-- Battery parameters
|
||||
self.ElementCapacity = 80 -- A*hour
|
||||
self.ElementCount = 56 -- 52 on 81-717
|
||||
self.Capacity = self.ElementCapacity * self.ElementCount * 3600
|
||||
self.ElementCapacity = 80 -- A*hour
|
||||
self.Capacity = self.ElementCapacity * 3600
|
||||
self.Charge = self.Capacity
|
||||
self.Voltage = 65
|
||||
-- Current through battery in amperes
|
||||
self.Current = 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
|
||||
|
||||
function TRAIN_SYSTEM:Inputs()
|
||||
return { "Charge" }
|
||||
return { "Charge", "Dischargeable", "InitialVoltage", "CarType" }
|
||||
end
|
||||
function TRAIN_SYSTEM:Outputs()
|
||||
return { "Capacity", "Charge", "Voltage" }
|
||||
end
|
||||
function TRAIN_SYSTEM:TriggerInput(name,value)
|
||||
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
|
||||
function TRAIN_SYSTEM:Think(dT)
|
||||
-- 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)
|
||||
if self.CarType == 1 then
|
||||
self.SoC = 100 * (self.Voltage - self.SoC0v)/(75 - self.SoC0v)
|
||||
if self.SoC > 60 then
|
||||
self.IResistance = 1e-4 * self.SoC + 0.012
|
||||
elseif 20 <= self.SoC and self.SoC <= 60 then
|
||||
self.IResistance = 0.018
|
||||
elseif self.SoC < 20 then
|
||||
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
|
||||
|
||||
-- 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)
|
||||
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
|
||||
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
|
||||
--print(self.eds_eq)
|
||||
end
|
||||
@@ -5,6 +5,7 @@
|
||||
-- Contains proprietary code. See license.txt for additional information.
|
||||
--------------------------------------------------------------------------------
|
||||
Metrostroi.DefineSystem("BPSN")
|
||||
TRAIN_SYSTEM.DontAccelerateSimulation = true
|
||||
|
||||
function TRAIN_SYSTEM:Initialize()
|
||||
self.X2 = {
|
||||
@@ -19,6 +20,11 @@ function TRAIN_SYSTEM:Initialize()
|
||||
self.X6_2 = 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.Train:LoadSystem("ConverterProtection","Relay","Switch", {bass = true})
|
||||
end
|
||||
@@ -54,4 +60,6 @@ function TRAIN_SYSTEM:Think()
|
||||
self.Active = XT3_1>0 and 1 or 0
|
||||
self.X2_2 = Train.Electric.Aux750V*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
|
||||
@@ -75,7 +75,7 @@ function TRAIN_SYSTEM:Initialize(parameters,extra_parameters)
|
||||
-- Should relay be spring-returned to initial position
|
||||
parameters.returns = parameters.returns or (not parameters.latched)
|
||||
-- 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
|
||||
self[k] = v
|
||||
end
|
||||
|
||||
@@ -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.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.BattCharge.Name = @[Common.Spawner.Chargeable]
|
||||
|
||||
#Spawner:
|
||||
Entities.gmod_subway_81-717_lvz.Spawner.Texture.Name = @[Common.Spawner.Texture]
|
||||
|
||||
@@ -227,6 +227,7 @@ Common.Spawner.Old = Old
|
||||
Common.Spawner.New = New
|
||||
Common.Spawner.Type = Type
|
||||
Common.Spawner.SchemeInvert = Invert line schemes
|
||||
Common.Spawner.Chargeable = Train battery can lose it's charge
|
||||
|
||||
#Coupler common
|
||||
Common.Couple.Title = Coupler menu
|
||||
|
||||
@@ -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.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.BattCharge.Name = @[Common.Spawner.Chargeable]
|
||||
|
||||
#Spawner:
|
||||
Entities.gmod_subway_81-717_lvz.Spawner.Texture.Name = @[Common.Spawner.Texture]
|
||||
|
||||
@@ -227,6 +227,7 @@ Common.Spawner.Old = Старые
|
||||
Common.Spawner.New = Новые
|
||||
Common.Spawner.Type = Тип
|
||||
Common.Spawner.SchemeInvert = Инвертировать наддверные схемы
|
||||
Common.Spawner.Chargeable = Разряжаемые аккумуляторы
|
||||
|
||||
#Coupler common
|
||||
Common.Couple.Title = Меню сцепки
|
||||
|
||||
Reference in New Issue
Block a user