1
0
mirror of https://github.com/metrostroi-repo/MetrostroiAddon.git synced 2026-05-04 00:52:33 +00:00
Files
MetrostroiAddon/lua/metrostroi/systems/sys_battery.lua

168 lines
9.3 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
--------------------------------------------------------------------------------
-- 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)
self.Train:LoadSystem("PA1","Relay","PP-28", { trigger_level = 31.5 }) -- A
self.Train:LoadSystem("PA2","Relay","PP-28", { trigger_level = 31.5 }) -- A
-- Battery parameters
self.ElementCapacity = 80 -- A*hour
self.Capacity = self.ElementCapacity * 3600
self.Charge = self.Capacity
-- 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 = 52--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.Consumers = {}
self.Ibatt_sigma = 0
self.CCcurrent_sigma = 0
self.Dischar = false
self.ComputerCar = false
for k,v in pairs(self.Train.Systems) do
if v.hasCoil and not self.Consumers[v] then
print("Registering relay",v.Name, "Train: ", self.Train)
self.Consumers[v] = {0,v.coil_res,0}
end
end
print "------------------\n"
end
-- TODO: - разобраться, почему при сборе схемы на ход пропадает контроль дверей
-- - расставить параметры для всех оставшихся реле
-- self.Consumers is a table of relays with the next structure:
-- [<relay>] = {<relay.Value>, <relay.coil_res>, <relay.current>}
function TRAIN_SYSTEM:Inputs()
return { "Charge", "Dischargeable", "InitialVoltage", "CarType", "Computer" }
end
function TRAIN_SYSTEM:Outputs()
return { "Capacity", "Charge", "Voltage", "eds_eq" }
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
local function GetBranchCondSum(consumers)
local br = 1e-12
for m,n in pairs(consumers) do
br = br + 1/(n[1] > 0 and n[2] or 1e12)
end
return br
end
function TRAIN_SYSTEM:Think(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 28 <= self.SoC and self.SoC <= 60 then --(20 — 60)
self.IResistance = 0.018
elseif self.SoC < 28 then --1.1
self.IResistance = math.min(0.32, 0.018 + 1.56^(12-1.48*self.SoC)) -- just made it up by myself >_>
end
self.IResistance = self.IResistance * self.ElementCount
for k,v in pairs(self.Consumers) do
v[1] = k.Value
v[3] = k.Current
end
if self.Train.ComputerCar then
local nodecurr_sum, branchcond_sum = 0, 0
local eds_eq = 0
local hvcounter = 0
self.Ibatt_sigma = 0
self.CCcurrent_sigma = 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 + GetBranchCondSum(v.Battery.Consumers) + v.A56.Value*(v.VB.Value/v.Battery.IResistance + v.PowerSupply.X2_1*v.A24.Value/v.PowerSupply.IResistance)
--[[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)
+ 1/(v.RC1 and v.RC1.Value > 0 and 32 or 1e12)
+ 1/(v.Panel.Headlights1 and v.Panel.Headlights1 > 0 and 38 or 1e12)
+ 1/(v.Panel.Headlights2 and v.Panel.Headlights2 > 0 and 38 or 1e12)
+ 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
--print(eds_eq, nodecurr_sum, branchcond_sum)
for k,v in ipairs(self.Train.WagonList) do
v.PowerSupply.car_control_load = eds_eq*GetBranchCondSum(v.Battery.Consumers)
--[[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.RC1 and v.RC1.Value > 0 and 32 or 1e12)
+ 1/(v.Panel.Headlights1 and v.Panel.Headlights1 > 0 and 38 or 1e12)
+ 1/(v.Panel.Headlights2 and v.Panel.Headlights2 > 0 and 38 or 1e12)
+ 1/(v.KK.Value > 0 and 24 or 1e12))]]
v.Battery.Ibatt = math.min(1,(2-self.Train.PA1.Value-self.Train.PA2.Value))
*(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))
self.Ibatt_sigma = self.Ibatt_sigma + v.Battery.Ibatt
self.CCcurrent_sigma = self.CCcurrent_sigma + v.PowerSupply.car_control_load
v.Battery.eds_eq = eds_eq
v.Battery.hvcounter = hvcounter
v.eds_eq = v.Battery.eds_eq
--print(v.eds_eq, branchcond_sum)
--print(v.PowerSupply.car_control_load,v.Battery.Ibatt,v.Battery.IResistance)
end
for k,v in ipairs(self.Train.WagonList) do
v.Battery.Ibatt_sigma = self.Ibatt_sigma
v.Battery.CCcurrent_sigma = self.CCcurrent_sigma
end
--print("БД = ", self.Train.BD.Value)
end
--print("Battery RD = ",self.Train.RD.Value)
-- Calculate discharge
if self.Dischar then
self.Train.BattCurrent = self.Ibatt*self.Train.A24.Value
self.Train.PA1:TriggerInput("Close",math.abs(self.Ibatt)/2) -- Это неправильно, но я уже заебалась
self.Train.PA2:TriggerInput("Close",math.abs(self.Ibatt)/2)
self.Charge = math.max(0,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
-- 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