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

fixed KM 013 and 334 work logic; added retainer load choice to spawner for custom 717

This commit is contained in:
Moon Horse
2024-12-14 20:07:32 +03:00
parent 8700ab2d32
commit 633a65c806
17 changed files with 1148 additions and 183 deletions

View File

@@ -226,6 +226,16 @@ 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
local offs = math.random(1,3)
if self:GetNW2Int("RetainerLoad",1) == 5 then self:SetNW2Int("RetainerLoad",math.random(1,4)) end
self.Pneumatic:TriggerInput("KM013offset",5.0 + 0.1*(offs-1))
self.Pneumatic:TriggerInput("VZ1Offset",0.8)
self.Pneumatic:TriggerInput("VZ2Offset",2.4)
self.CompressorEfficiency = math.random()*0.05 + 0.02
self.AirConsumeRatio = math.random()*0.04 + 0.06
self.AirLeakRatio = math.random()*0.002 + 0.001
math.randomseed(num+817171) math.randomseed(num+817171)
local kvr=false local kvr=false
local passtex = "Def_717SPBWhite" local passtex = "Def_717SPBWhite"

View File

@@ -343,7 +343,7 @@ function ENT:InitializeSystems()
-- Панель управления 81-710 -- Панель управления 81-710
self:LoadSystem("Panel","81_714_Panel") self:LoadSystem("Panel","81_714_Panel")
-- Пневмосистема 81-710 -- Пневмосистема 81-710
self:LoadSystem("Pneumatic","81_717_Pneumatic",{br013_1 = true}) self:LoadSystem("Pneumatic","81_714_Pneumatic",{br013_1 = true})
-- Everything else -- Everything else
self:LoadSystem("Battery") self:LoadSystem("Battery")
self:LoadSystem("PowerSupply","BPSN") self:LoadSystem("PowerSupply","BPSN")

View File

@@ -230,6 +230,16 @@ function ENT:TrainSpawnerUpdate()
self:SetNW2Bool("Custom",self.CustomSettings) self:SetNW2Bool("Custom",self.CustomSettings)
local num = self.WagonNumber local num = self.WagonNumber
math.randomseed(num+817171) math.randomseed(num+817171)
local offs = math.random(1,3)
if self:GetNW2Int("RetainerLoad",1) == 5 then self:SetNW2Int("RetainerLoad",math.random(1,4)) end
self.Pneumatic:TriggerInput("KM013offset",5.0 + 0.1*(offs-1))
self.Pneumatic:TriggerInput("VZ1Offset",0.8)
self.Pneumatic:TriggerInput("VZ2Offset",2.4)
self.CompressorEfficiency = math.random()*0.05 + 0.02
self.AirConsumeRatio = math.random()*0.04 + 0.06
self.AirLeakRatio = math.random()*0.002 + 0.001
if self.CustomSettings then if self.CustomSettings then
local dot5 = self:GetNW2Int("Type")==2 local dot5 = self:GetNW2Int("Type")==2
local typ = self:GetNW2Int("BodyType") local typ = self:GetNW2Int("BodyType")

View File

@@ -360,7 +360,7 @@ function ENT:InitializeSystems()
-- Панель управления 81-710 -- Панель управления 81-710
self:LoadSystem("Panel","81_714_Panel") self:LoadSystem("Panel","81_714_Panel")
-- Пневмосистема 81-710 -- Пневмосистема 81-710
self:LoadSystem("Pneumatic","81_717_Pneumatic",{br013_1 = true}) self:LoadSystem("Pneumatic","81_714_Pneumatic",{br013_1 = true})
-- Everything else -- Everything else
self:LoadSystem("Battery") self:LoadSystem("Battery")
self:LoadSystem("PowerSupply","BPSN") self:LoadSystem("PowerSupply","BPSN")

View File

@@ -2417,6 +2417,21 @@ ENT.ButtonMap["AirDistributor"] = {
} }
} }
ENT.ButtonMap["AutostopValve"] = {
pos = Vector(365.8,-67.6,-56),
ang = Angle(0,0,90),
width = 130,
height = 40,
scale = 0.1,
hideseat=0.1,
hide=true,
screenHide = true,
buttons = {
{ID = "AutostopValveSet",x=0,y=0,w= 130,h = 40,tooltip="Сорвать срывной клапан"},
}
}
for i=0,4 do for i=0,4 do
ENT.ClientProps["TrainNumberL"..i] = { ENT.ClientProps["TrainNumberL"..i] = {
model = "models/metrostroi_train/common/bort_numbers.mdl", model = "models/metrostroi_train/common/bort_numbers.mdl",
@@ -3687,6 +3702,9 @@ function ENT:DrawPost()
self:DrawOnPanel("AirDistributor",function() self:DrawOnPanel("AirDistributor",function()
draw.DrawText(self:GetNW2Bool("AD") and "Air Distributor ON" or "Air Distributor OFF","Trebuchet24",0,0,Color(0,0,0,255)) draw.DrawText(self:GetNW2Bool("AD") and "Air Distributor ON" or "Air Distributor OFF","Trebuchet24",0,0,Color(0,0,0,255))
end) end)
self:DrawOnPanel("AutostopValve",function()
draw.DrawText("Autostop Valve", "Trebuchet24",0,6,Color(0,0,0,255))
end)
end end
function ENT:OnButtonPressed(button) function ENT:OnButtonPressed(button)

View File

@@ -224,6 +224,10 @@ function ENT:Initialize()
ID = "AirDistributorDisconnectToggle", ID = "AirDistributorDisconnectToggle",
Pos = Vector(-177, -66, -50), Radius = 20, Pos = Vector(-177, -66, -50), Radius = 20,
}, },
{
ID = "AutostopValveToggle",
Pos = Vector(377, -66, -50), Radius = 20,
},
} }
-- Cross connections in train wires -- Cross connections in train wires
@@ -342,6 +346,16 @@ function ENT:TrainSpawnerUpdate()
local cabtex = "Def_PUAV" local cabtex = "Def_PUAV"
local ring,puring = math.ceil(math.random()*4) local ring,puring = math.ceil(math.random()*4)
self:SetNW2Int("RingType",ring) self:SetNW2Int("RingType",ring)
local offs = math.random(1,3)
if self:GetNW2Int("RetainerLoad",1) == 5 then self:SetNW2Int("RetainerLoad",math.random(1,4)) end
self.Pneumatic:TriggerInput("KM013offset",5.0 + 0.1*(offs-1))
self.Pneumatic:TriggerInput("VZ1Offset",0.9)
self.Pneumatic:TriggerInput("VZ2Offset",2.5)
self.CompressorEfficiency = math.random()*0.05 + 0.02
self.AirConsumeRatio = math.random()*0.04 + 0.06
self.AirLeakRatio = math.random()*0.002 + 0.001
if typ == 1 then --PAKSDM if typ == 1 then --PAKSDM
self.Electric:TriggerInput("X2PS",0) self.Electric:TriggerInput("X2PS",0)
self.Electric:TriggerInput("Type",self.Electric.LVZ_4) self.Electric:TriggerInput("Type",self.Electric.LVZ_4)

View File

@@ -970,6 +970,16 @@ ENT.Spawner = {
train.NumberRangesID = typ train.NumberRangesID = typ
end end
end, end,
postfunc = function(cartable,wagnum)
for k,v in ipairs(cartable) do
local val = v._Settings.SpawnMode
v.CarCount = wagnum
v.InitIsoCountNeeded = true
v.Pneumatic.TrainLinePressure = val==3 and math.random()*4 or val==2 and 4.5+math.random()*3 or 7.6+math.random()*0.6
v.Pneumatic.WorkingChamberPressure = val==3 and math.random()*1.0 or val==2 and 4.0+math.random()*1.0 or 5.2
v.Pneumatic.BrakeLinePressure = val==4 and 5.2 or 2.3
end
end,
wagfunc = function(ent,i,num) wagfunc = function(ent,i,num)
end, end,
--Metrostroi.Skins.GetTable("Texture","Spawner.Texture",false,"train"), --Metrostroi.Skins.GetTable("Texture","Spawner.Texture",false,"train"),

View File

@@ -46,6 +46,16 @@ ENT.Spawner = {
train.NumberRangesID = typ train.NumberRangesID = typ
end end
end, end,
postfunc = function(cartable,wagnum)
for k,v in ipairs(cartable) do
local val = v._Settings.SpawnMode
v.CarCount = wagnum
v.InitIsoCountNeeded = true
v.Pneumatic.TrainLinePressure = val==3 and math.random()*4 or val==2 and 4.5+math.random()*3 or 7.6+math.random()*0.6
v.Pneumatic.WorkingChamberPressure = val==3 and math.random()*1.0 or val==2 and 4.0+math.random()*1.0 or 5.2
v.Pneumatic.BrakeLinePressure = val==4 and 5.2 or 2.3
end
end,
{"Type","Spawner.717.Type","List",{"Spawner.717.Type.Line2","Spawner.717.Type.Line4","Spawner.717.Type.Line5"}}, {"Type","Spawner.717.Type","List",{"Spawner.717.Type.Line2","Spawner.717.Type.Line4","Spawner.717.Type.Line5"}},
{"Scheme","Spawner.717.Schemes","List",function() {"Scheme","Spawner.717.Schemes","List",function()
local Schemes = {} local Schemes = {}
@@ -59,6 +69,7 @@ ENT.Spawner = {
{}, {},
{"SeatType","Spawner.717.SeatType","List",{"Spawner.717.Common.Random","Spawner.717.Common.Old","Spawner.717.Common.New","Spawner.717.Common.NewBlue"}}, {"SeatType","Spawner.717.SeatType","List",{"Spawner.717.Common.Random","Spawner.717.Common.Old","Spawner.717.Common.New","Spawner.717.Common.NewBlue"}},
{}, {},
{"RetainerLoad","Spawner.717.RetainerLoad","List",{"Spawner.717.RetainerLoad.1","Spawner.717.RetainerLoad.2","Spawner.717.RetainerLoad.3","Spawner.717.RetainerLoad.4","Spawner.717.Common.Random"}},
{"SpawnMode","Spawner.717.SpawnMode","List",{"Spawner.717.SpawnMode.Full","Spawner.717.SpawnMode.Deadlock","Spawner.717.SpawnMode.NightDeadlock","Spawner.717.SpawnMode.Depot"}, nil,function(ent,val,rot,i,wagnum,rclk) {"SpawnMode","Spawner.717.SpawnMode","List",{"Spawner.717.SpawnMode.Full","Spawner.717.SpawnMode.Deadlock","Spawner.717.SpawnMode.NightDeadlock","Spawner.717.SpawnMode.Depot"}, nil,function(ent,val,rot,i,wagnum,rclk)
if rclk then return end if rclk then return end
if ent._SpawnerStarted~=val then if ent._SpawnerStarted~=val then

View File

@@ -379,6 +379,15 @@ function ENT:TrainSpawnerUpdate()
end--]] end--]]
--self:SetNW2String("PassTexture","Def_717MSKBlue") --self:SetNW2String("PassTexture","Def_717MSKBlue")
-- --
local offs = math.random(1,3)
if self:GetNW2Int("RetainerLoad",1) == 5 then self:SetNW2Int("RetainerLoad",math.random(1,4)) end
self.Pneumatic:TriggerInput("KM013offset",5.0 + 0.1*(offs-1))
self.Pneumatic:TriggerInput("VZ1Offset",0.9)
self.Pneumatic:TriggerInput("VZ2Offset",2.5)
self.CompressorEfficiency = math.random()*0.05 + 0.02
self.AirConsumeRatio = math.random()*0.04 + 0.06
self.AirLeakRatio = math.random()*0.002 + 0.001
local num = self.WagonNumber local num = self.WagonNumber
self:SetNW2Bool("Custom",self.CustomSettings) self:SetNW2Bool("Custom",self.CustomSettings)
math.randomseed(num+817171) math.randomseed(num+817171)

View File

@@ -948,6 +948,16 @@ ENT.Spawner = {
--Metrostroi.Skins.GetTable("Texture","Spawner.Texture",false,"train"), --Metrostroi.Skins.GetTable("Texture","Spawner.Texture",false,"train"),
--Metrostroi.Skins.GetTable("PassTexture","Spawner.PassTexture",false,"pass"), --Metrostroi.Skins.GetTable("PassTexture","Spawner.PassTexture",false,"pass"),
--Metrostroi.Skins.GetTable("CabTexture","Spawner.CabTexture",false,"cab"), --Metrostroi.Skins.GetTable("CabTexture","Spawner.CabTexture",false,"cab"),
postfunc = function(cartable,wagnum)
for k,v in ipairs(cartable) do
local val = v._Settings.SpawnMode
v.CarCount = wagnum
v.InitIsoCountNeeded = true
v.Pneumatic.TrainLinePressure = val==3 and math.random()*4 or val==2 and 4.5+math.random()*3 or 7.6+math.random()*0.6
v.Pneumatic.WorkingChamberPressure = val==3 and math.random()*1.0 or val==2 and 4.0+math.random()*1.0 or 5.2
v.Pneumatic.BrakeLinePressure = val==4 and 5.2 or 2.3
end
end,
{"Announcer","Spawner.717.Announcer","List",function() {"Announcer","Spawner.717.Announcer","List",function()
local Announcer = {} local Announcer = {}
for k,v in pairs(Metrostroi.AnnouncementsASNP or {}) do if not v.riu then Announcer[k] = v.name or k end end for k,v in pairs(Metrostroi.AnnouncementsASNP or {}) do if not v.riu then Announcer[k] = v.name or k end end

View File

@@ -47,6 +47,16 @@ ENT.Spawner = {
train.NumberRangesID = body>1 and (math.random()>0.5 and 6 or 7) or (math.random()>0.5 and 4 or 5) train.NumberRangesID = body>1 and (math.random()>0.5 and 6 or 7) or (math.random()>0.5 and 4 or 5)
end end
end, end,
postfunc = function(cartable,wagnum)
for k,v in ipairs(cartable) do
local val = v._Settings.SpawnMode
v.CarCount = wagnum
v.InitIsoCountNeeded = true
v.Pneumatic.TrainLinePressure = val==3 and math.random()*4 or val==2 and 4.5+math.random()*3 or 7.6+math.random()*0.6
v.Pneumatic.WorkingChamberPressure = val==3 and math.random()*1.0 or val==2 and 4.0+math.random()*1.0 or 5.2
v.Pneumatic.BrakeLinePressure = val==4 and 5.2 or 2.3
end
end,
{"Type","Spawner.717.Type","List",{"81-717","81-717.5"}}, {"Type","Spawner.717.Type","List",{"81-717","81-717.5"}},
{"BodyType","Spawner.717.BodyType","List",{"Spawner.717.Type.MVM","Spawner.717.Type.LVZ"}}, {"BodyType","Spawner.717.BodyType","List",{"Spawner.717.Type.MVM","Spawner.717.Type.LVZ"}},
{"Scheme","Spawner.717.Schemes","List",function() {"Scheme","Spawner.717.Schemes","List",function()
@@ -72,6 +82,7 @@ ENT.Spawner = {
{"RingType","Spawner.717.RingType","List",{"Spawner.717.Common.Random","Spawner.717.RingType.1","Spawner.717.RingType.2","Spawner.717.RingType.3","Spawner.717.RingType.4","Spawner.717.RingType.5","Spawner.717.RingType.6","Spawner.717.RingType.7","Spawner.717.RingType.8"}}, {"RingType","Spawner.717.RingType","List",{"Spawner.717.Common.Random","Spawner.717.RingType.1","Spawner.717.RingType.2","Spawner.717.RingType.3","Spawner.717.RingType.4","Spawner.717.RingType.5","Spawner.717.RingType.6","Spawner.717.RingType.7","Spawner.717.RingType.8"}},
{"BPSNType","Spawner.717.BPSNType","List",{"Spawner.717.Common.Random","Spawner.717.BPSNType.1","Spawner.717.BPSNType.2","Spawner.717.BPSNType.3","Spawner.717.BPSNType.4","Spawner.717.BPSNType.5","Spawner.717.BPSNType.6","Spawner.717.BPSNType.7","Spawner.717.BPSNType.8","Spawner.717.BPSNType.9","Spawner.717.BPSNType.10","Spawner.717.BPSNType.11","Spawner.717.BPSNType.12","Spawner.717.BPSNType.13"}}, {"BPSNType","Spawner.717.BPSNType","List",{"Spawner.717.Common.Random","Spawner.717.BPSNType.1","Spawner.717.BPSNType.2","Spawner.717.BPSNType.3","Spawner.717.BPSNType.4","Spawner.717.BPSNType.5","Spawner.717.BPSNType.6","Spawner.717.BPSNType.7","Spawner.717.BPSNType.8","Spawner.717.BPSNType.9","Spawner.717.BPSNType.10","Spawner.717.BPSNType.11","Spawner.717.BPSNType.12","Spawner.717.BPSNType.13"}},
{}, {},
{"RetainerLoad","Spawner.717.RetainerLoad","List",{"Spawner.717.RetainerLoad.1","Spawner.717.RetainerLoad.2","Spawner.717.RetainerLoad.3","Spawner.717.RetainerLoad.4","Spawner.717.Common.Random"}},
{"SpawnMode","Spawner.717.SpawnMode","List",{"Spawner.717.SpawnMode.Full","Spawner.717.SpawnMode.Deadlock","Spawner.717.SpawnMode.NightDeadlock","Spawner.717.SpawnMode.Depot"}, nil,function(ent,val,rot,i,wagnum,rclk) {"SpawnMode","Spawner.717.SpawnMode","List",{"Spawner.717.SpawnMode.Full","Spawner.717.SpawnMode.Deadlock","Spawner.717.SpawnMode.NightDeadlock","Spawner.717.SpawnMode.Depot"}, nil,function(ent,val,rot,i,wagnum,rclk)
if rclk then return end if rclk then return end
if ent._SpawnerStarted~=val then if ent._SpawnerStarted~=val then

View File

@@ -276,6 +276,10 @@ function ENT:Initialize()
self.PrevRightDoorsOpening = false self.PrevRightDoorsOpening = false
self.RightDoorsOpening = false self.RightDoorsOpening = false
self.BrakeLineConnectedCarsCounter = 1
self.TrainLineConnectedCarsCounter = 1
self.CarCount = false
-- Get default train mass -- Get default train mass
if IsValid(self:GetPhysicsObject()) then if IsValid(self:GetPhysicsObject()) then
self.NormalMass = self:GetPhysicsObject():GetMass() self.NormalMass = self:GetPhysicsObject():GetMass()
@@ -551,6 +555,48 @@ function ENT:GetWagonCount()
return #self.WagonList return #self.WagonList
end end
function ENT:UpdateIsolation(wagnum)
if not self.IsoCountTimer and (self.InitIsoCountNeeded or self.RepeatIsoUpdate) then
self.IsoCountTimer = CurTime()
end
if (self.InitIsoCountNeeded or self.RepeatIsoUpdate) and (CurTime() - self.IsoCountTimer > 2) then
self:UpdateIsolationConnectedCarCounter("Brake")
self:UpdateIsolationConnectedCarCounter("Train")
if self:GetBLConnectedWagonCount() == wagnum and self:GetTLConnectedWagonCount() == wagnum or self.RepeatIsoUpdate then
self.InitIsoCountNeeded = false
self.RepeatIsoUpdate = nil
end
self.IsoCountTimer = nil
end
end
function ENT:UpdateIsolationConnectedCarCounter(line)
self[line.."LineConnectedCarsCounter"] = 1
local checked = {}
local function count(this)
checked[this] = true
if this.FrontTrain and not checked[this.FrontTrain] and this["Front"..line.."LineIsolation"].Value == 0 then
if this.FrontTrain.FrontTrain == this and this.FrontTrain["Front"..line.."LineIsolation"].Value == 0 or this.FrontTrain.RearTrain == this and this.FrontTrain["Rear"..line.."LineIsolation"].Value == 0 then count(this.FrontTrain) end
end
if this.RearTrain and not checked[this.RearTrain] and this["Rear"..line.."LineIsolation"].Value == 0 then
if this.RearTrain.FrontTrain == this and this.RearTrain["Front"..line.."LineIsolation"].Value == 0 or this.RearTrain.RearTrain == this and this.RearTrain["Rear"..line.."LineIsolation"].Value == 0 then count(this.RearTrain) end
end
end
count(self)
local b = 0
for k,v in pairs(checked) do b = b + 1 end
for k,v in pairs(checked) do k[line.."LineConnectedCarsCounter"] = b end
--PrintMessage(HUD_PRINTTALK, Format("Вагон %u; line: %s; cars: %u",self:GetWagonNumber(), line, self[line.."LineConnectedCarsCounter"]))
end
function ENT:GetBLConnectedWagonCount()
return self.BrakeLineConnectedCarsCounter
end
function ENT:GetTLConnectedWagonCount()
return self.TrainLineConnectedCarsCounter
end
function ENT:ReadCell(Address) function ENT:ReadCell(Address)
if Address < 0 then return nil end if Address < 0 then return nil end
if Address == 0 then if Address == 0 then
@@ -1991,6 +2037,8 @@ function ENT:Think()
self:SetNW2Float("Accel",math.Round((self.OldSpeed or 0) - (self.Speed or 0)*(self.SpeedSign or 0),2)) self:SetNW2Float("Accel",math.Round((self.OldSpeed or 0) - (self.Speed or 0)*(self.SpeedSign or 0),2))
self:SetNW2Float("TrainSpeed",self.Speed) self:SetNW2Float("TrainSpeed",self.Speed)
self.OldSpeed = (self.Speed or 0)*(self.SpeedSign or 0) self.OldSpeed = (self.Speed or 0)*(self.SpeedSign or 0)
if self.InitIsoCountNeeded or self.RepeatIsoUpdate then self:UpdateIsolation(self.CarCount) end
for k,v in pairs(self.CustomThinks) do if k ~= "BaseClass" then v(self) end end for k,v in pairs(self.CustomThinks) do if k ~= "BaseClass" then v(self) end end
self:NextThink(CurTime()+0.05) self:NextThink(CurTime()+0.05)
@@ -2162,6 +2210,7 @@ function ENT:ButtonEvent(button,state,ply)
if ShouldFireEvents(self.ButtonBuffer[button],state) then if ShouldFireEvents(self.ButtonBuffer[button],state) then
if state == false and not self:OnButtonRelease(button,ply) then if state == false and not self:OnButtonRelease(button,ply) then
self:TriggerInput(button,0.0) self:TriggerInput(button,0.0)
if button:match("LineIsolationToggle") then self:UpdateIsolationConnectedCarCounter(button:sub(-24,-20)) end
elseif state ~= false and not self:OnButtonPress(button,ply) then elseif state ~= false and not self:OnButtonPress(button,ply) then
self:TriggerInput(button,1.0) self:TriggerInput(button,1.0)
if self.Plombs and button:sub(-2,-1) == "Pl" and self.Plombs[button:sub(1,-3)] then if self.Plombs and button:sub(-2,-1) == "Pl" and self.Plombs[button:sub(1,-3)] then

View File

@@ -209,6 +209,8 @@ net.Receive("metrostroi-coupler-menu",function(_,ply)
ftrain.FrontBrakeLineIsolation:TriggerInput("Set",state and 0 or 1) ftrain.FrontBrakeLineIsolation:TriggerInput("Set",state and 0 or 1)
ftrain.FrontTrainLineIsolation:TriggerInput("Set",state and 0 or 1) ftrain.FrontTrainLineIsolation:TriggerInput("Set",state and 0 or 1)
end end
train.RepeatIsoUpdate = true
ftrain.RepeatIsoUpdate = true
end end
elseif not isfront and train.RearBrakeLineIsolation and train.RearTrainLineIsolation then elseif not isfront and train.RearBrakeLineIsolation and train.RearTrainLineIsolation then
local state = train.RearBrakeLineIsolation.Value>0 or train.RearTrainLineIsolation.Value>0 local state = train.RearBrakeLineIsolation.Value>0 or train.RearTrainLineIsolation.Value>0
@@ -223,6 +225,8 @@ net.Receive("metrostroi-coupler-menu",function(_,ply)
rtrain.FrontBrakeLineIsolation:TriggerInput("Set",state and 0 or 1) rtrain.FrontBrakeLineIsolation:TriggerInput("Set",state and 0 or 1)
rtrain.FrontTrainLineIsolation:TriggerInput("Set",state and 0 or 1) rtrain.FrontTrainLineIsolation:TriggerInput("Set",state and 0 or 1)
end end
train.RepeatIsoUpdate = true
rtrain.RepeatIsoUpdate = true
end end
end end
end end

View File

@@ -0,0 +1,707 @@
--------------------------------------------------------------------------------
-- 81-714 pneumatic system
--------------------------------------------------------------------------------
-- Copyright (C) 2013-2018 Metrostroi Team & FoxWorks Aerospace s.r.o.
-- Contains proprietary code. See license.txt for additional information.
--------------------------------------------------------------------------------
Metrostroi.DefineSystem("81_714_Pneumatic")
TRAIN_SYSTEM.DontAccelerateSimulation = true
function TRAIN_SYSTEM:Initialize(parameters)
self.ValveType = 1
-- Position of the train drivers valve
-- Type 1 (334)
-- 1 Accelerated charge
-- 2 Normal charge (brake release)
-- 3 Closed
-- 4 Service application
-- 5 Emergency application
--
-- Type 2 (013)
-- 1 Accelerated charge
-- 2 Normal charge (brake release)
-- 3 Closed
-- 4 Service application
-- 5 Emergency application
self.DriverValvePosition = 2
self.RealDriverValvePosition = self.DriverValvePosition
-- Pressure in reservoir
self.ParkingBrakePressure = 0
self.ReservoirPressure = 0.0 -- atm
-- Pressure in trains feed line
self.TrainLinePressure = 8.0 -- atm
-- Pressure in trains brake line
self.BrakeLinePressure = 0.0 -- atm
-- Pressure in brake cylinder
self.BrakeCylinderPressure = 0.0 -- atm
self.OldBrakeLinePressure = 0.0
-- Pressure in the door line
self.DoorLinePressure = 0.0 -- atm
self.OldBrakeLinePressure = 0.0
self.BCPressure = 0
-- Air distrubutor part
self.WorkingChamberPressure = 0.0
-- Disconnected KM 334 vessels (trainline and brakeline parts between disconnect valve and KM itself) emulation
self.TLDisconnectPressure = 0.0
self.BLDisconnectPressure = 0.0
self.WCChargeValve = true
self.PN1 = 0
self.PN2 = 0
self.cranPres = 0
self.KM013offset = 5.2
--DKPT
self.Train:LoadSystem("DKPT","Relay","R-52B") --
-- Valve #1
self.Train:LoadSystem("PneumaticNo1","Relay")
-- Valve #2
self.Train:LoadSystem("PneumaticNo2","Relay")
-- Автоматический выключатель торможения (АВТ)
self.Train:LoadSystem("AVT","Relay","AVT-325")
-- Регулятор давления (АК)
self.Train:LoadSystem("AK","Relay","AK-11B")
-- Блокировка тормозов
self.Train:LoadSystem("BPT","Relay","")
-- Блокировка дверей
self.Train:LoadSystem("BD","Relay","")
-- Вентили дверного воздухораспределителя (ВДОЛ, ВДОП, ВДЗ)
self.Train:LoadSystem("VDOL","Relay","", {bass = true})
self.Train:LoadSystem("VDOP","Relay","", {bass = true})
self.Train:LoadSystem("VDZ","Relay","", {bass = true})
-- Краны двойной тяги
self.Train:LoadSystem("DriverValveTLDisconnect","Relay","Switch", {bass = true})
self.Train:LoadSystem("DriverValveBLDisconnect","Relay","Switch", {bass = true})
self.Train:LoadSystem("EmergencyBrakeValve","Relay","Switch")
-- Воздухораспределитель
self.Train:LoadSystem("AirDistributorDisconnect","Relay","Switch")
--Стояночный тормоз
self.Train:LoadSystem("ParkingBrake","Relay","Switch",{bass = true})
-- Isolation valves
self.Train:LoadSystem("FrontBrakeLineIsolation","Relay","Switch", { normally_closed = true, bass = true})
self.Train:LoadSystem("RearBrakeLineIsolation","Relay","Switch", { normally_closed = true, bass = true})
self.Train:LoadSystem("FrontTrainLineIsolation","Relay","Switch", { normally_closed = true, bass = true})
self.Train:LoadSystem("RearTrainLineIsolation","Relay","Switch", { normally_closed = true, bass = true})
-- Brake cylinder atmospheric valve open
self.BrakeCylinderValve = 0
-- Overpressure protection valve open
self.TrainLineOverpressureValve = 0
-- Compressor simulation
self.Compressor = 0 --Simulate overheat with TRK FIXME
-- Doors state
if not TURBOSTROI then
self.LeftDoorState = { 0,0,0,0 }
self.RightDoorState = { 0,0,0,0 }
self.LeftDoorDir = { 0,0,0,0 }
self.RightDoorDir = { 0,0,0,0 }
self.LeftDoorSpeed = {0,0,0,0}
self.RightDoorSpeed = {0,0,0,0}
local start = math.Rand(0.6,0.8)
-- 0.6-1
self.DoorSpeedMain = -math.Rand(start,math.Rand(start+0.1,start+0.2))
for i=1,#self.LeftDoorSpeed do
if math.random() > 0.7 then
self.LeftDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain+0.2)
self.RightDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain+0.2)
else
self.LeftDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain+0.1)
self.RightDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.1,self.DoorSpeedMain+0.1)
end
end
end
self.TrainLineOpen = false
self.BrakeLineOpen = false
self.BLDisconnect = true
self.TLDisconnect = true
self.OldValuePos = self.DriverValvePosition
self.WeightLoadRatio = 0
self.PassengerDoor = 0
end
function TRAIN_SYSTEM:Inputs()
return { "BrakeUp", "BrakeDown", "BrakeSet", "ValveType", "Autostop", "KM013offset" }
end
function TRAIN_SYSTEM:Outputs()
return { "BrakeLinePressure", "BrakeCylinderPressure", "DriverValvePosition", "WorkingChamberPressure",
"ReservoirPressure", "TrainLinePressure", "DoorLinePressure", "WeightLoadRatio" }
end
function TRAIN_SYSTEM:TriggerInput(name,value)
if name == "BrakeSet" then
self.DriverValvePosition = math.floor(value)
if self.ValveType == 1 then
if self.DriverValvePosition < 1 then self.DriverValvePosition = 1 end
if self.DriverValvePosition > 5 then self.DriverValvePosition = 5 end
else
if self.DriverValvePosition < 1 then self.DriverValvePosition = 1 end
if self.DriverValvePosition > 7 then self.DriverValvePosition = 7 end
end
elseif (name == "BrakeUp") and (value > 0.5) then
self:TriggerInput("BrakeSet",self.DriverValvePosition+1)
elseif (name == "BrakeDown") and (value > 0.5) then
self:TriggerInput("BrakeSet",self.DriverValvePosition-1)
elseif name == "ValveType" then
self.ValveType = math.floor(value)
elseif name == "KM013offset" then
self.KM013offset = value
elseif name:match("VZ%dOffset") then
local idx = name:match("VZ(%d)Offset")
self["GN"..idx.."Offset"] = math.random(2,10)*0.02 + value
self["GN"..idx.."Start"] = value
--PrintMessage(HUD_PRINTTALK, Format("Вагон %u; ВЗ-1: %.1f; ВЗ-2: %.1f",self.Train:GetWagonNumber(),self.GN1Offset or 0,self.GN2Offset or 0))
end
end
-- TODO: почистить это говно, сделать раздельные звуки пневмы
-- Calculate derivatives
function TRAIN_SYSTEM:equalizeCouplePressure(dT,pressure,train,valve_status,rate,close_rate)
if not valve_status then return 0 end
local other
if IsValid(train) then other = train.Pneumatic end
-- Get second pressure
local P2 = 0
if other then P2 = other[pressure] end
if (not other) and (valve_status) then
self.TrainLineOpen = (pressure == "TrainLinePressure")
rate = close_rate or rate
--self.TrainLinePressure_dPdT = 0.0
end
-- Calculate rate
local dPdT = rate * (P2 - self[pressure])
-- Calculate delta
local dP = dPdT*dT
if other and other.ReadOnly then
dP = dP/250
end
-- Equalized pressure
local P0 = (P2 + self[pressure]) / 2
-- Update pressures
if dP > 0 then
self[pressure] = math.min(P0,self[pressure] + dP)
if other and not other.ReadOnly then
other[pressure] = math.max(P0,other[pressure] - dP)
end
else
self[pressure] = math.max(P0,self[pressure] + dP)
if other and not other.ReadOnly then
other[pressure] = math.min(P0,other[pressure] - dP)
end
end
-- Update delta if losing air
if self.TrainLineOpen and (pressure == "TrainLinePressure") then
self[pressure.."_dPdT"] = (self[pressure.."_dPdT"] or 0) + dPdT
end
return dP
end
-------------------------------------------------------------------------------
function TRAIN_SYSTEM:UpdatePressures(Train,dT)
local frontBrakeOpen = Train.FrontBrakeLineIsolation.Value == 0
local rearBrakeOpen = Train.RearBrakeLineIsolation.Value == 0
local frontTrainOpen = Train.FrontTrainLineIsolation.Value == 0
local rearTrainOpen = Train.RearTrainLineIsolation.Value == 0
local Ft = IsValid(Train.FrontTrain) and Train.FrontTrain
local Rt = IsValid(Train.RearTrain) and Train.RearTrain
local Fc, Rc = Train.FrontCouple or Train.FrontBogey, Train.RearCouple or Train.RearBogey
local Fb,Rb
if IsValid(Fc) and Fc.DepotPneumo then Fb = Fc.DepotPneumo end
if IsValid(Rc) and Rc.DepotPneumo then Rb = Rc.DepotPneumo end
local frontBrakeLeak = false
local rearBrakeLeak = false
local frontTrainLeak = false
local rearTrainLeak = false
-- Check if both valve on this train and connected train are open
if Ft and Ft.FrontBrakeLineIsolation then
if Ft.FrontTrain == Train then -- Nose to nose
frontBrakeLeak = frontBrakeOpen and Ft.FrontBrakeLineIsolation.Value==1 and 0.08
frontTrainLeak = frontTrainOpen and Ft.FrontTrainLineIsolation.Value==1 and 0.08
else -- Rear to nose
frontBrakeLeak = frontBrakeOpen and Ft.RearBrakeLineIsolation.Value==1 and 0.08
frontTrainLeak = frontTrainOpen and Ft.RearTrainLineIsolation.Value==1 and 0.08
end
else
frontBrakeLeak = frontBrakeOpen and 0.7
frontTrainLeak = frontTrainOpen and not Fb and 0.3
end
if Rt and Rt.FrontBrakeLineIsolation then
if Rt.FrontTrain == Train then -- Nose to nose
rearBrakeLeak = rearBrakeOpen and Rt.FrontBrakeLineIsolation.Value==1 and 0.08
rearTrainLeak = rearTrainOpen and Rt.FrontTrainLineIsolation.Value==1 and 0.08
else -- Rear to nose
rearBrakeLeak = rearBrakeOpen and Rt.RearBrakeLineIsolation.Value==1 and 0.08
rearTrainLeak = rearTrainOpen and Rt.RearTrainLineIsolation.Value==1 and 0.08
end
else
rearBrakeLeak = rearBrakeOpen and 0.7
rearTrainLeak = rearTrainOpen and not Rb and 0.3
end
-- Equalize pressure
local Fl=math.min(0,self:equalizeCouplePressure(dT,"BrakeLinePressure",frontBrakeLeak==false and Ft,frontBrakeOpen,50,frontBrakeLeak or 0.08)*3)*(frontBrakeLeak and 1 or 0)
local Rl=math.min(0,self:equalizeCouplePressure(dT,"BrakeLinePressure",rearBrakeLeak==false and Rt,rearBrakeOpen,50,rearBrakeLeak or 0.08)*3)*(rearBrakeLeak and 1 or 0)
Fl=Fl+math.min(0,self:equalizeCouplePressure(dT,"TrainLinePressure",frontTrainLeak==false and Ft or Fb,frontTrainOpen,100,frontTrainLeak or 0.08)*10)*(frontTrainLeak and 1 or 0)
Rl=Rl+math.min(0,self:equalizeCouplePressure(dT,"TrainLinePressure",rearTrainLeak==false and Rt or Rb,rearTrainOpen,100,rearTrainLeak or 0.08)*10)*(rearTrainLeak and 1 or 0)
self.TrainLineOpen=frontTrainLeak or rearTrainLeak
self.BrakeLineOpen=frontBrakeLeak or rearBrakeLeak
Train:SetPackedRatio("FrontLeak",Fl)
Train:SetPackedRatio("RearLeak",Rl)
end
function TRAIN_SYSTEM:equalizePressure(dT,pressure,target,rate,fill_rate,no_limit,smooth)
if fill_rate and (target > self[pressure]) then rate = fill_rate end
-- Calculate derivative
local dPdT = rate
if target < self[pressure] then dPdT = -dPdT end
local dPdTramp = math.min(1.0,math.abs(target - self[pressure])*(smooth or 0.5))
dPdT = dPdT*dPdTramp
-- Update pressure
self[pressure] = self[pressure] + dT * dPdT
self[pressure] = math.max(0.0,math.min(16.0,self[pressure]))
self[pressure.."_dPdT"] = (self[pressure.."_dPdT"] or 0) + dPdT
if no_limit ~= true then
if self[pressure] == 0.0 then self[pressure.."_dPdT"] = 0 end
if self[pressure] == 16.0 then self[pressure.."_dPdT"] = 0 end
end
return dPdT
end
-------------------------------------------------------------------------------
function TRAIN_SYSTEM:Think(dT)
local Train = self.Train
local retainer = Train:GetNW2Int("RetainerLoad", 4)
self.WeightLoadRatio = retainer == 4 and math.max(0,math.min(1,(Train:GetNW2Float("PassengerCount")/200))) or (retainer-1)*0.5
----------------------------------------------------------------------------
-- Accumulate derivatives
self.TrainLinePressure_dPdT = 0.0
self.BrakeLinePressure_dPdT = 0.0
self.ReservoirPressure_dPdT = 0.0
self.BrakeCylinderPressure_dPdT = 0.0
self.ParkingBrakePressure_dPdT = 0.0
self.WorkingChamberPressure_dPdT = 0.0
-- Reduce pressure for brake line
self.TrainToBrakeReducedPressure = math.min(self.KM013offset,self.TrainLinePressure) -- * 0.725)
-- Feed pressure to door line
self.DoorLinePressure = self.TrainToBrakeReducedPressure * 0.90
local trainLineConsumption_dPdT = 0.0
local wagc = Train:GetBLConnectedWagonCount()
local HaveEPK = not Train.SubwayTrain or not Train.SubwayTrain.ARS or not Train.SubwayTrain.ARS.NoEPK
local pr_speed = 1
if self.ValveType == 1 then
self.BLDisconnect = Train.DriverValveBLDisconnect.Value > 0
self.TLDisconnect = Train.DriverValveTLDisconnect.Value > 0 and self.RealDriverValvePosition ~= 3
pr_speed = 1*wagc--*((self.BrakeLinePressure-self.ReservoirPressure)/0.6) --2
if self.TLDisconnect then self.TLDisconnectPressure = self.TrainLinePressure end
if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.3 end
-- 334: 1 Fill reservoir from train line, fill brake line from train line
if (self.RealDriverValvePosition == 1) then
if self.TLDisconnect or self.ReservoirPressure ~= self.TLDisconnectPressure then
if self.BLDisconnect then
self.ReservoirPressure = self.BrakeLinePressure
self:equalizePressure(dT,"BrakeLinePressure", self.TLDisconnectPressure, pr_speed*(pr_speed < wagc and 1 or 1.35),nil,nil,2)--0.7
else
self:equalizePressure(dT,"ReservoirPressure", self.TLDisconnectPressure, 3.55,nil,nil,2)
end
end
end
-- 334: 2 Brake line, reservoir replenished from brake line reductor
if (self.RealDriverValvePosition == 2) then
if self.TLDisconnect then
local a = 1
if --[[self.EmergencyValve or ]]Train.EmergencyBrakeValve.Value > 0.5 then a = 1.85 end
if self.BLDisconnect then
self.ReservoirPressure = self.BrakeLinePressure
self:equalizePressure(dT,"BrakeLinePressure", self.TrainToBrakeReducedPressure, pr_speed*0, pr_speed*0.6*a, nil, 1.6)
self.ReservoirPressure_dPdT = self.BrakeLinePressure_dPdT*0.8
else
self:equalizePressure(dT,"ReservoirPressure", self.TrainToBrakeReducedPressure,0,1.55,nil,2)
end
end
end
-- 334: 3 Close all valves
if (self.RealDriverValvePosition == 3) then
-- Typical leak
self:equalizePressure(dT,"ReservoirPressure", 0.00, 0.001)
end
local res_dischrg_rate4 = self.BLDisconnect and 0.55 or 8
local res_dischrg_rate5 = self.BLDisconnect and 1.12 or 8
-- 334: 4 Reservoir open to atmosphere, brake line equalizes with reservoir
if (self.RealDriverValvePosition == 4) then
self:equalizePressure(dT,"ReservoirPressure", 0.0, res_dischrg_rate4, nil,nil,6)--0.35)-0.55
end
-- 334: 5 Reservoir and brake line open to atmosphere
if (self.RealDriverValvePosition == 5) then
self:equalizePressure(dT,"ReservoirPressure", 0.0, res_dischrg_rate5)--,nil,nil,2)--1.70
local pr_speed = 1.25*wagc
if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.3 end
if self.BLDisconnect then
if self.Leak then pr_speed = pr_speed*6.2 end
self:equalizePressure(dT,"BrakeLinePressure", 0.0, pr_speed,nil,nil,2)
end
end
-- утечка через неплотность уравнительного поршня
if self.BLDisconnect then self:equalizePressure(dT, "ReservoirPressure", self.BrakeLinePressure, 0.06, 0) end
if (self.RealDriverValvePosition > 2) and (self.RealDriverValvePosition < 5) then
local pr_speed = 1.25*wagc
if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.3 end
local _a = 0
for _i = 1, #Train.WagonList do
if Train.WagonList[_i].Pneumatic.TLDisconnect and Train.WagonList[_i].Pneumatic.BLDisconnect and (Train.WagonList[_i].Pneumatic.RealDriverValvePosition == 2 or Train.WagonList[_i].Pneumatic.RealDriverValvePosition == 1) then
_a = _a + 1
end
if _a > 0 then break end
end
if _a > 0 then pr_speed = pr_speed*0.1 end
if self.BLDisconnect and self.BrakeLinePressure - self.ReservoirPressure > (self.RealDriverValvePosition == 3 and 0 or self.RealDriverValvePosition == 4 and 0.2 or 100) then --0.2 bar is a piston sensitivity
self:equalizePressure(dT, "BrakeLinePressure", 0, pr_speed*math.abs(self.BrakeLinePressure - self.ReservoirPressure), nil, nil, 6)
end
end
if not self.TLDisconnect then
self.TLDisconnectPressure = math.max(0,self.TLDisconnectPressure - math.abs(self.ReservoirPressure_dPdT)*dT)
end
self.ReservoirPressure_dPdT = self.ReservoirPressure_dPdT + self.BrakeLinePressure_dPdT*0.2
Train:SetPackedRatio("ReservoirPressure_dPdT",self.ReservoirPressure_dPdT/wagc*2)
--[[
---------------debug---------------------
self.dlreadtimer = self.dlreadtimer or CurTime()
if CurTime() - self.dlreadtimer > 1.0 then
self.dlreadtimer = CurTime()
if Train:GetDriver() then
PrintMessage(HUD_PRINTTALK, Format("Вагон %u; P ТМ: %.3f; P УР =%.3f; Утечка ТМ %.3f; TLDis = %.3f; pr_speed = %.3f",Train:GetWagonNumber(),self.BrakeLinePressure,self.ReservoirPressure,self.BrakeLinePressure_dPdT, self.TLDisconnectPressure, pr_speed))
end
end
---------------debug---------------------]]
trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeLinePressure_dPdT)
trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.ReservoirPressure_dPdT)*0.05
else
pr_speed = 2.8--1.25*wagc --2
local pz_speed
-- wagc | pr_speed
------------------
-- 1 | 8.455
-- 2 | 7.865
-- 3 | 7.376
-- 4 | 6.969
-- 5 | 6.627
-- 6 | 6.341
-- 7 | 6.100
-- 8 | 5.900
--pr_speed = (0.4*math.exp(0.1*wagc-1)+1)*160/(2*wagc+20) --2
--local frc = 0.6--0.35
if self.Leak or self.BrakeLineOpen then pz_speed = pr_speed*0.25 else pz_speed = pr_speed*1.3 end--*frc end
self.BLDisconnect = Train.DriverValveBLDisconnect.Value > 0
self.TLDisconnect = Train.DriverValveTLDisconnect.Value > 0
if self.RealDriverValvePosition > 4 and not self.km13_error2 then self.km13_error2 = 0.7 end
-- 013: 1 Overcharge
if (self.RealDriverValvePosition == 1) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > self.TrainLinePressure) then
self:equalizePressure(dT,"BrakeLinePressure", math.min(6.4,self.TrainLinePressure), pr_speed, pz_speed, nil, 1.0)
end
-- 013: 2 Normal pressure
if (self.RealDriverValvePosition == 2) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > 1.01*math.min(self.KM013offset,self.TrainToBrakeReducedPressure)) then--was pr_speed*2
self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(self.KM013offset+(self.km13_error2 or 0),self.TrainLinePressure), pr_speed, pz_speed, nil, 2.5)-- nil, 1.0)
if self.km13_error2 and self.BrakeLinePressure >= self.KM013offset+self.km13_error2-0.1 then
self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(self.KM013offset,self.TrainToBrakeReducedPressure), 35, pz_speed, nil, 1)
self.km13_error2 = nil
end
end
-- 013: 3 4.3 Atm
if (self.RealDriverValvePosition == 3) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > 1.01*math.min(4.3,self.TrainToBrakeReducedPressure)) then
self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(4.3,self.TrainToBrakeReducedPressure), pr_speed,pz_speed, nil, 2.5)
end
-- 013: 4 4.0 Atm
if (self.RealDriverValvePosition == 4) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > 1.01*math.min(4.0,self.TrainToBrakeReducedPressure)) then
self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(4.0,self.TrainToBrakeReducedPressure), pr_speed,pz_speed, nil, 2.5)
end
-- 013: 5 3.7 Atm
if (self.RealDriverValvePosition == 5) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > 1.01*math.min(3.7,self.TrainToBrakeReducedPressure)) then
self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(3.7,self.TrainToBrakeReducedPressure), pr_speed,pz_speed, nil, 2.5)
end
-- 013: 6 3.0 Atm
if (self.RealDriverValvePosition == 6) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > 1.01*math.min(3.0,self.TrainToBrakeReducedPressure)) then
self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(3.0,self.TrainToBrakeReducedPressure), pr_speed,pz_speed, nil, 2.5)
end
-- 013: 7 0.0 Atm
if (self.RealDriverValvePosition == 7) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > 0.0) then
self:equalizePressure(dT,"BrakeLinePressure", 0.0, (0.6 + pr_speed*math.exp(math.min(0,self.BrakeLinePressure - 2.3)*1.0))*(0.15*wagc+1),pz_speed, nil, 2.5)
end
trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeLinePressure_dPdT)
end
self.Leak = false
if wagc ~= Train.OldWagIsoCount or not Train.pr_spd_init then
pr_speed = (0.4*math.exp(0.1*wagc-1)+1)*160/(2*wagc+20) --2
Train.OldWagIsoCount = wagc
Train.pr_spd_init = true
end
if self.ValveType == 1 then
Train:SetPackedRatio("Crane_dPdT", self.ReservoirPressure_dPdT )
else
Train:SetPackedRatio("Crane_dPdT", self.BrakeLinePressure_dPdT/wagc*3 )
end
local leak = 0
if Train.EmergencyBrakeValve and Train.EmergencyBrakeValve.Value > 0.5 then
local leakst = math.max(0.5,math.exp(0.5*self.BrakeLinePressure))
leak = self:equalizePressure(dT,"BrakeLinePressure", 0.0,leakst)--,false,false,10) --was leakst*wagc/5
self.Leak = true
end
Train:SetPackedRatio("EmergencyBrakeValve_dPdT", -leak/wagc)
----------------------------------------------------------------------------
-- Fill brake cylinders
if self.WCChargeValve == true then
self:equalizePressure(dT,"WorkingChamberPressure",self.BrakeLinePressure,0.094,nil,nil,1.0) --simulate 0.8mm hole btw BL and working chambers
end
local aird_ready = self.WorkingChamberPressure >= 2.2
self.WCChargeValve = not ((self.WorkingChamberPressure - self.BrakeLinePressure) > 0.2 and (self.WorkingChamberPressure - self.BrakeLinePressure) < 2.5)
local KLSZ = self.WorkingChamberPressure > 5.2 and not self.WCChargeValve
if KLSZ then
self:equalizePressure(dT,"WorkingChamberPressure",0.0,0.12) -- КЛСЗ
end
trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.WorkingChamberPressure_dPdT*0.2)
self.GN2Offset = self.GN2Offset or math.random(20,100)*0.002 + (self.GN2Start or 2.4)
self.GN1Offset = self.GN1Offset or math.random(20,100)*0.002 + (self.GN1Start or 0.8)
self.BcBl = (self.GN2Offset + self.WeightLoadRatio*(self.GN2Offset - 1.4))/1.82--1.92
if Train.AirDistributorDisconnect.Value == 0 and aird_ready then
-- Valve #1
if (Train.PneumaticNo1.Value == 1.0) and (Train.PneumaticNo2.Value == 0.0) then
if self.PN1 < self.GN1Offset then
self.PN1 = math.min(self.TrainLinePressure,self.GN1Offset)
end
elseif Train.PneumaticNo1.Value == 0 and self.PN1 > 0.0 then
self.PN1 = self.BrakeCylinderPressure > 0.2 and 0.05 or self.PN1 - 0.5*dT
end
-- Valve #2
if Train.PneumaticNo2.Value == 1.0 then
self.PN2 = math.min(self.TrainLinePressure,(self.GN2Offset + self.WeightLoadRatio*1.3))
if self.BePN2 == false and self.BrakeCylinderPressure > 1.6 then
Train:PlayOnce("PN2end","stop")
end
self.BePN2 = true
elseif self.PN2 > 0.0 then
self.PN2 = self.BrakeCylinderPressure > 0.4 and 0.2 or self.PN2 - 0.5*dT
end
--[[
---------------debug---------------------
self.brreadtimer = self.brreadtimer or CurTime()
if CurTime() - self.brreadtimer > 1.0 then
self.brreadtimer = CurTime()
if Train:GetDriver() then
--PrintMessage(HUD_PRINTTALK, Format("br_threshold = %.3f; WcBl = %s",br_threshold, tostring(WcBl)))
--PrintMessage(HUD_PRINTTALK, Format("Это %s", isLVZ and "ЛВЗ" or "не ЛВЗ"))
--PrintMessage(HUD_PRINTTALK, Format("Вагон %u; Авторежим: %.3f",Train:GetWagonNumber(),self.WeightLoadRatio))
--PrintMessage(HUD_PRINTTALK, Format("wagc = %u; wagd = %u",wagc,wagd))
end
end
---------------debug---------------------]]
self.BchExh = self.WorkingChamberPressure < 4.8 and self.BrakeLinePressure < 3.4 and 0 or 1
self.cranPres = math.max(0,self.BcBl*(self.WorkingChamberPressure - self.BrakeLinePressure*self.BchExh)*(self.BrakeLinePressure > self.KM013offset and (0.6 + self.PN1*0.43) or 1))
local targetPressure = math.max(0,math.min(self.GN2Offset + self.WeightLoadRatio*1.3, (self.cranPres < (self.PN1 + self.WeightLoadRatio*0.7) and (Train.PneumaticNo1.Value == 1.0) and (self.PN1 + self.WeightLoadRatio*0.7) or self.PN1) + self.PN2 + self.cranPres))
if math.abs(self.BrakeCylinderPressure - targetPressure) > 0.150 then
self.BrakeCylinderValve = 1
end
if math.abs(self.BrakeCylinderPressure - targetPressure) < 0.025 then
self.BrakeCylinderValve = 0
end
if self.BrakeCylinderValve == 1 then
self:equalizePressure(dT,"BrakeCylinderPressure", math.min(self.GN2Offset + self.WeightLoadRatio*(self.GN2Offset - 1.4),targetPressure), 0.8, (Train.PneumaticNo1.Value > 0 or Train.PneumaticNo2.Value > 0) and 2.8 or 1.5, nil, 1.2)
end
trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeCylinderPressure_dPdT*0.5)
elseif Train.AirDistributorDisconnect.Value ~= 0 then
self:equalizePressure(dT,"BrakeCylinderPressure", 0.0, 2.00)
end
if (self.BrakeCylinderPressure > 0.2 and self.BrakeCylinderPressure_dPdT > 0.1 or self.BrakeCylinderPressure_dPdT > 1) and not self.BrakeEngaged then
self.BrakeEngaged = true
Train:PlayOnce("brake","bass",1,math.Clamp(self.BrakeCylinderPressure_dPdT,0.7,1.2))
end
if self.BrakeCylinderPressure < 1 and self.BrakeCylinderPressure_dPdT < -0.1 and self.BrakeEngaged then
self.BrakeEngaged = false
end
Train:SetPackedRatio("BrakeCylinderPressure_dPdT", self.BrakeCylinderPressure_dPdT)
self.TrainLinePressure = self.TrainLinePressure-math.max(0,self.BrakeCylinderPressure_dPdT*0.002)
if Train.PneumaticNo2.Value == 0 then
if self.BePN2 == true then
self.BePN2 = CurTime()
elseif self.BePN2 and self.BrakeCylinderPressure_dPdT > -0.2 then
Train:PlayOnce("PN2end","bass",math.Clamp(math.min(1,(CurTime()-self.BePN2)/1.3)*((3.2-self.BrakeCylinderPressure)/1.2),0,1))
self.BePN2 = false
end
end
if self.BePN2 == false and (self.BrakeCylinderPressure_dPdT >= 0.2) then
self.BePN2 = nil
Train:PlayOnce("PN2end","stop")
end
--Parking brake simulation
local PBPressure = math.Clamp(self.TrainLinePressure/5,0,1)*2.7
if Train.ParkingBrake.Value == 0 then
self:equalizePressure(dT,"ParkingBrakePressure", PBPressure, 10,10,nil,0.5)
else
self:equalizePressure(dT,"ParkingBrakePressure", 0, 3,10,nil,0.5)
end
Train:SetPackedRatio("ParkingBrakePressure_dPdT",self.ParkingBrakePressure_dPdT)
trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.ParkingBrakePressure_dPdT*0.5)
-- Simulate cross-feed between different wagons
self:UpdatePressures(Train,dT)
----------------------------------------------------------------------------
-- Simulate compressor operation and train line depletion
self.Compressor = Train.KK.Value * (Train.Electric.Aux750V > 550 and 1 or 0)
self.TrainLinePressure = self.TrainLinePressure - Train.AirConsumeRatio*trainLineConsumption_dPdT*dT -- 0.190 --0.170 --0.07
if self.Compressor == 1 then self:equalizePressure(dT,"TrainLinePressure", 10.0, Train.CompressorEfficiency) end -- 0.04
self:equalizePressure(dT,"TrainLinePressure", 0,Train.AirLeakRatio)
-- Overpressure
if self.TrainLinePressure > math.max(7.2, (9.2 - self.TrainLineOverpressureValve*0.2)) and self.TrainLineOverpressureValve%2 == 0 then self.TrainLineOverpressureValve = self.TrainLineOverpressureValve + 1 end
if self.TrainLineOverpressureValve%2 == 1 then
self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.2)
self.TrainLineOpen = true
if self.TrainLinePressure < 5.2 and self.TrainLineOverpressureValve < 20 then self.TrainLineOverpressureValve = self.TrainLineOverpressureValve + 1 end
end
----------------------------------------------------------------------------
-- Pressure triggered relays
Train.AVT:TriggerInput("Open", self.BrakeCylinderPressure > 1.9) -- 1.8 - 2.0
Train.AVT:TriggerInput("Close",self.BrakeCylinderPressure < 0.9) -- 0.9 - 1.5
Train.AK:TriggerInput( "Open", self.TrainLinePressure > 8.2)
Train.AK:TriggerInput( "Close",self.TrainLinePressure < 6.3)
Train.BPT:TriggerInput("Set", (IsValid(Train.FrontBogey) and Train.FrontBogey.BrakeCylinderPressure+(not Train.FrontBogey.DisableParking and Train.FrontBogey.ParkingBrakePressure or 0) or self.BrakeCylinderPressure)>0.3)
Train.DKPT:TriggerInput("Set", self.BrakeCylinderPressure > 0.3) -- 1.8 - 2.0
----------------------------------------------------------------------------
-- Simulate doors opening, closing
if self.DoorLinePressure > 3.5 then
if (Train.VDOL.Value == 1.0) and (Train.VDOP.Value == 0.0) and not self.DoorLeft then
self.DoorLeft = true
if self.VDOLLoud then Train:PlayOnce("vdol_loud","cabin",0.8+math.random()*0.2,self.VDOLLoud) end
end
if (Train.VDOL.Value == 0.0) and (Train.VDOP.Value == 1.0) and not self.DoorRight then
self.DoorRight = true
if self.VDORLoud then Train:PlayOnce("vdop_loud","cabin",0.8+math.random()*0.2,self.VDORLoud) end
end
if (Train.VDZ.Value == 1.0 or Train.VDOL.Value == 1.0 and Train.VDOP.Value == 1.0 or self.RZDTimer) and (self.DoorLeft or self.DoorRight) then
if not self.OpenWaitL or CurTime()-self.OpenWaitL < 0.2 then
self.DoorLeft = false
end
if not self.OpenWaitR or CurTime()-self.OpenWaitR < 0.2 then
self.DoorRight = false
end
else
self.CloseValue = nil
end
if Train.VDOL.Value == 1.0 and Train.VDOP.Value == 1.0 then
self.RZDTimer = CurTime()
elseif self.RZDTimer and CurTime()-self.RZDTimer > 0.1 then
self.RZDTimer = nil
end
end
if self.VDOL ~= Train.VDOL.Value then
self.VDOL = Train.VDOL.Value
self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.05)
end
if self.VDOP ~= Train.VDOP.Value then
self.VDOP = Train.VDOP.Value
self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.05)
end
if self.VDZ ~= Train.VDZ.Value then
self.VDZ = Train.VDZ.Value
self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.05)
end
Train.LeftDoorsOpen = false
Train.RightDoorsOpen = false
local openL = true
local openR = true
for i=1,4 do
self.LeftDoorDir[i] = math.Clamp(self.LeftDoorDir[i]+dT/(self.DoorLeft and self.LeftDoorSpeed[i] or -self.LeftDoorSpeed[i]),-1,1)
self.RightDoorDir[i] = math.Clamp(self.RightDoorDir[i]+dT/(self.DoorRight and self.RightDoorSpeed[i] or -self.RightDoorSpeed[i]),-1,1)
self.LeftDoorState[i] = math.Clamp(self.LeftDoorState[i] + ((self.LeftDoorDir[i]/self.LeftDoorSpeed[i])*dT),0,1)
if self.LeftDoorState[i] == 0 or self.LeftDoorState[i] == 1 then self.LeftDoorDir[i] = 0 end
self.RightDoorState[i] = math.Clamp(self.RightDoorState[i] + ((self.RightDoorDir[i]/self.RightDoorSpeed[i])*dT),0,1)
if self.RightDoorState[i] == 0 or self.RightDoorState[i] == 1 then self.RightDoorDir[i] = 0 end
if not Train.LeftDoorsOpen and self.LeftDoorState[i] > 0 then
Train.LeftDoorsOpen = true
end
if self.LeftDoorState[i] > self.LeftDoorSpeed[i]/20 then self.OpenWaitL = false end
if self.RightDoorState[i] > self.LeftDoorSpeed[i]/20 then self.OpenWaitR = false end
if self.LeftDoorState[i] > 0 then openL = false end
if self.RightDoorState[i] > 0 then openR = false end
if not Train.RightDoorsOpen and self.RightDoorState[i] > 0 then
Train.RightDoorsOpen = true
end
Train:SetPackedRatio("DoorL"..i,self.LeftDoorState[i])
Train:SetPackedRatio("DoorR"..i,self.RightDoorState[i])
end
if openL and not self.OpenWaitL then self.OpenWaitL = CurTime() end
if openR and not self.OpenWaitR then self.OpenWaitR = CurTime() end
Train:SetPackedBool("DoorL",self.DoorLeft)
Train:SetPackedBool("DoorR",self.DoorRight)
Train.BD:TriggerInput("Set",not Train.RightDoorsOpen and not Train.LeftDoorsOpen)
----------------------------------------------------------------------------
-- FIXME
Train:SetNW2Bool("FbI",Train.FrontBrakeLineIsolation.Value ~= 0)
Train:SetNW2Bool("RbI",Train.RearBrakeLineIsolation.Value ~= 0)
Train:SetNW2Bool("FtI",Train.FrontTrainLineIsolation.Value ~= 0)
Train:SetNW2Bool("RtI",Train.RearTrainLineIsolation.Value ~= 0)
Train:SetNW2Bool("AD",Train.AirDistributorDisconnect.Value == 0)
local ValveType = self.ValveType > 1
self.Timer = self.Timer or CurTime()
if ((CurTime() - self.Timer > 0.10) and (self.DriverValvePosition > self.RealDriverValvePosition)) then
self.Timer = CurTime()
if not ValveType then
if self.RealDriverValvePosition ~= 3 then
Train:PlayOnce("br_334",self.RealDriverValvePosition.."-"..(self.RealDriverValvePosition+1))
end
else
Train:PlayOnce("br_013","cabin")
end
self.RealDriverValvePosition = self.RealDriverValvePosition + 1
end
if ((CurTime() - self.Timer > 0.10) and (self.DriverValvePosition < self.RealDriverValvePosition)) then
self.Timer = CurTime()
if not ValveType then
if self.RealDriverValvePosition ~= 5 then
Train:PlayOnce("br_334",self.RealDriverValvePosition.."-"..(self.RealDriverValvePosition-1))
end
else
Train:PlayOnce("br_013","cabin")
end
self.RealDriverValvePosition = self.RealDriverValvePosition - 1
end
end

View File

@@ -38,19 +38,21 @@ function TRAIN_SYSTEM:Initialize(parameters)
self.EPKPressure = 0.0 -- atm self.EPKPressure = 0.0 -- atm
-- Pressure in brake cylinder -- Pressure in brake cylinder
self.BrakeCylinderPressure = 0.0 -- atm self.BrakeCylinderPressure = 0.0 -- atm
self.OldBrakeLinePressure = 0.0
-- Pressure in the door line -- Pressure in the door line
self.DoorLinePressure = 0.0 -- atm self.DoorLinePressure = 0.0 -- atm
self.OldBrakeLinePressure = 0.0 self.OldBrakeLinePressure = 0.0
self.BCPressure = 0 self.BCPressure = 0
-- Air distrubutor part -- Air distrubutor part
self.WorkingChamberPressure = 0.0 self.WorkingChamberPressure = 0.0
--self.AirDistributorReady = false --заменено на локальные -- Disconnected KM 334 vessels (trainline and brakeline parts between disconnect valve and KM itself) emulation
--self.OverchargeReleaseValve = false --переменные self.TLDisconnectPressure = 0.0
self.BLDisconnectPressure = 0.0
self.WCChargeValve = true self.WCChargeValve = true
self.PN1 = 0 self.PN1 = 0
self.PN2 = 0 self.PN2 = 0
self.cranPres = 0 self.cranPres = 0
self.KM013offset = 5.2
--DKPT --DKPT
self.Train:LoadSystem("DKPT","Relay","R-52B") -- self.Train:LoadSystem("DKPT","Relay","R-52B") --
@@ -82,12 +84,12 @@ function TRAIN_SYSTEM:Initialize(parameters)
self.Train:LoadSystem("EmergencyBrakeValve","Relay","Switch") self.Train:LoadSystem("EmergencyBrakeValve","Relay","Switch")
-- Воздухораспределитель -- Воздухораспределитель
self.Train:LoadSystem("AirDistributorDisconnect","Relay","Switch") self.Train:LoadSystem("AirDistributorDisconnect","Relay","Switch")
--Срывной клапан
self.Train:LoadSystem("AutostopValve","Relay","Switch")
--УАВА --УАВА
self.Train:LoadSystem("UAVA","Relay","Switch",{ bass = true}) self.Train:LoadSystem("UAVA","Relay","Switch",{ bass = true})
--self.Train:LoadSystem("UAVAContact","Relay","Switch") self.Train:LoadSystem("UAVAContact","Relay","Switch")
self.Train:LoadSystem("UAVAC","Relay","",{normally_closed=true,bass=true}) self.Train:LoadSystem("UAVAC","Relay","",{normally_closed=true,bass=true})
--Срывной клапан
self.Train:LoadSystem("AutostopValve","Relay","Switch")
--Стояночный тормоз --Стояночный тормоз
self.Train:LoadSystem("ParkingBrake","Relay","Switch",{bass = true}) self.Train:LoadSystem("ParkingBrake","Relay","Switch",{bass = true})
--ЭПК --ЭПК
@@ -114,8 +116,6 @@ function TRAIN_SYSTEM:Initialize(parameters)
self.DriverValveDisconnectPrevious = 0 self.DriverValveDisconnectPrevious = 0
-- Doors state -- Doors state
self.DoorLeft = false
self.DoorRight = false
if not TURBOSTROI then if not TURBOSTROI then
self.LeftDoorState = { 0,0,0,0 } self.LeftDoorState = { 0,0,0,0 }
self.RightDoorState = { 0,0,0,0 } self.RightDoorState = { 0,0,0,0 }
@@ -123,8 +123,6 @@ function TRAIN_SYSTEM:Initialize(parameters)
self.RightDoorDir = { 0,0,0,0 } self.RightDoorDir = { 0,0,0,0 }
self.LeftDoorSpeed = {0,0,0,0} self.LeftDoorSpeed = {0,0,0,0}
self.RightDoorSpeed = {0,0,0,0} self.RightDoorSpeed = {0,0,0,0}
self.LeftDoorStuck = {false, false, false, false}
self.RightDoorStuck = {false, false, false, false}
local start = math.Rand(0.6,0.8) local start = math.Rand(0.6,0.8)
-- 0.6-1 -- 0.6-1
self.DoorSpeedMain = -math.Rand(start,math.Rand(start+0.1,start+0.2)) self.DoorSpeedMain = -math.Rand(start,math.Rand(start+0.1,start+0.2))
@@ -141,6 +139,9 @@ function TRAIN_SYSTEM:Initialize(parameters)
self.TrainLineOpen = false self.TrainLineOpen = false
self.BrakeLineOpen = false self.BrakeLineOpen = false
self.BLDisconnect = true
self.TLDisconnect = true
self.EmergencyValve = false self.EmergencyValve = false
self.EmergencyValveEPK = false self.EmergencyValveEPK = false
self.OldValuePos = self.DriverValvePosition self.OldValuePos = self.DriverValvePosition
@@ -150,12 +151,12 @@ function TRAIN_SYSTEM:Initialize(parameters)
end end
function TRAIN_SYSTEM:Inputs() function TRAIN_SYSTEM:Inputs()
return { "BrakeUp", "BrakeDown", "BrakeSet", "ValveType", "Autostop" } return { "BrakeUp", "BrakeDown", "BrakeSet", "ValveType", "Autostop", "KM013offset" }
end end
function TRAIN_SYSTEM:Outputs() function TRAIN_SYSTEM:Outputs()
return { "BrakeLinePressure", "BrakeCylinderPressure", "DriverValvePosition", return { "BrakeLinePressure", "BrakeCylinderPressure", "DriverValvePosition", "WorkingChamberPressure",
"ReservoirPressure", "TrainLinePressure", "DoorLinePressure", "WeightLoadRatio", "WorkingChamberPressure" } "ReservoirPressure", "TrainLinePressure", "DoorLinePressure", "WeightLoadRatio" }
end end
function TRAIN_SYSTEM:TriggerInput(name,value) function TRAIN_SYSTEM:TriggerInput(name,value)
@@ -174,17 +175,24 @@ function TRAIN_SYSTEM:TriggerInput(name,value)
self:TriggerInput("BrakeSet",self.DriverValvePosition-1) self:TriggerInput("BrakeSet",self.DriverValvePosition-1)
elseif name == "ValveType" then elseif name == "ValveType" then
self.ValveType = math.floor(value) self.ValveType = math.floor(value)
elseif name:match("VZ%dOffset") then
local idx = name:match("VZ(%d)Offset")
self["GN"..idx.."Offset"] = math.random(2,10)*0.02 + value
self["GN"..idx.."Start"] = value
--PrintMessage(HUD_PRINTTALK, Format("Вагон %u; ВЗ-1: %.1f; ВЗ-2: %.1f",self.Train:GetWagonNumber(),self.GN1Offset or 0,self.GN2Offset or 0))
elseif name == "KM013offset" then
self.KM013offset = value
elseif name == "Autostop" then elseif name == "Autostop" then
local HaveUAVA = not self.Train.SubwayTrain or not self.Train.SubwayTrain.ARS or not self.Train.SubwayTrain.ARS.NoUAVA local HaveUAVA = not self.Train.SubwayTrain or not self.Train.SubwayTrain.ARS or not self.Train.SubwayTrain.ARS.NoUAVA
if HaveUAVA and self.Train.UAVA.Value == 0 then if HaveUAVA and self.Train.UAVA.Value == 0 then
self.EmergencyValve = true self.EmergencyValve = true
if value ~= 2 then if value ~= 2 then
self.Train.UAVAC:TriggerInput("Set",0) self.Train.UAVAC:TriggerInput("Set",0)
if not self.Train.AutoStopNotify then if not self.Train.AutoStopNotify then
self.Train.AutoStopNotify = true self.Train.AutoStopNotify = true
RunConsoleCommand("say","Autostop braking",self.Train:GetDriverName()) RunConsoleCommand("say","Autostop braking",self.Train:GetDriverName())
end end
end end
end end
end end
end end
@@ -279,14 +287,14 @@ function TRAIN_SYSTEM:UpdatePressures(Train,dT)
end end
-- Equalize pressure -- Equalize pressure
local Fl=math.min(0,self:equalizeCouplePressure(dT,"BrakeLinePressure",frontBrakeLeak==false and Ft,frontBrakeOpen,100,frontBrakeLeak or 0.08)*3)*(frontBrakeLeak and 1 or 0) local Fl=math.min(0,self:equalizeCouplePressure(dT,"BrakeLinePressure",frontBrakeLeak==false and Ft,frontBrakeOpen,50,frontBrakeLeak or 0.08)*3)*(frontBrakeLeak and 1 or 0)
local Rl=math.min(0,self:equalizeCouplePressure(dT,"BrakeLinePressure",rearBrakeLeak==false and Rt,rearBrakeOpen,100,rearBrakeLeak or 0.08)*3)*(rearBrakeLeak and 1 or 0) local Rl=math.min(0,self:equalizeCouplePressure(dT,"BrakeLinePressure",rearBrakeLeak==false and Rt,rearBrakeOpen,50,rearBrakeLeak or 0.08)*3)*(rearBrakeLeak and 1 or 0)
Fl=Fl+math.min(0,self:equalizeCouplePressure(dT,"TrainLinePressure",frontTrainLeak==false and Ft or Fb,frontTrainOpen,100,frontTrainLeak or 0.08)*10)*(frontTrainLeak and 1 or 0) Fl=Fl+math.min(0,self:equalizeCouplePressure(dT,"TrainLinePressure",frontTrainLeak==false and Ft or Fb,frontTrainOpen,100,frontTrainLeak or 0.08)*10)*(frontTrainLeak and 1 or 0)
Rl=Rl+math.min(0,self:equalizeCouplePressure(dT,"TrainLinePressure",rearTrainLeak==false and Rt or Rb,rearTrainOpen,100,rearTrainLeak or 0.08)*10)*(rearTrainLeak and 1 or 0) Rl=Rl+math.min(0,self:equalizeCouplePressure(dT,"TrainLinePressure",rearTrainLeak==false and Rt or Rb,rearTrainOpen,100,rearTrainLeak or 0.08)*10)*(rearTrainLeak and 1 or 0)
self.TrainLineOpen=frontTrainLeak or rearTrainLeak self.TrainLineOpen=frontTrainLeak or rearTrainLeak
self.BraieLineOpen=frontBrakeLeak or rearBrakeLeak self.BrakeLineOpen=frontBrakeLeak or rearBrakeLeak
Train:SetPackedRatio("FrontLeak",Fl) Train:SetPackedRatio("FrontLeak",Fl)
Train:SetPackedRatio("RearLeak",Rl) Train:SetPackedRatio("RearLeak",Rl)
end end
@@ -313,8 +321,10 @@ end
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
function TRAIN_SYSTEM:Think(dT) function TRAIN_SYSTEM:Think(dT)
local Train = self.Train local Train = self.Train
self.WeightLoadRatio = math.max(0,math.min(1,(Train:GetNW2Float("PassengerCount")/200))) local retainer = Train:GetNW2Int("RetainerLoad", 4)
--self.WeightLoadRatio = (Train.R_ZS and Train.R_ZS.Value > 0 and 0.5 or 0) + (Train.R_G and Train.R_G.Value > 0 and 0.5 or 0) self.WeightLoadRatio = retainer == 4 and math.max(0,math.min(1,(Train:GetNW2Float("PassengerCount")/200))) or (retainer-1)*0.5
Train.Panel.UAVACOpened = (1-Train.UAVAC.Value)*((CurTime()-CurTime()%0.5)%1)
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
-- Accumulate derivatives -- Accumulate derivatives
self.TrainLinePressure_dPdT = 0.0 self.TrainLinePressure_dPdT = 0.0
@@ -325,43 +335,50 @@ function TRAIN_SYSTEM:Think(dT)
self.ParkingBrakePressure_dPdT = 0.0 self.ParkingBrakePressure_dPdT = 0.0
self.WorkingChamberPressure_dPdT = 0.0 self.WorkingChamberPressure_dPdT = 0.0
local rnd = math.random(1,10)
local offs = 0.1
self.KM013offset = self.KM013offset or math.Clamp(5.1 + (rnd >= 3 and rnd <= 7 and offs or -offs),5.0,5.2)
-- Reduce pressure for brake line -- Reduce pressure for brake line
self.TrainToBrakeReducedPressure = math.min(self.KM013offset,self.TrainLinePressure) -- * 0.725) self.TrainToBrakeReducedPressure = math.min(self.KM013offset,self.TrainLinePressure) -- * 0.725)
-- Feed pressure to door line -- Feed pressure to door line
self.DoorLinePressure = self.TrainToBrakeReducedPressure * 0.90 self.DoorLinePressure = self.TrainToBrakeReducedPressure * 0.90
local trainLineConsumption_dPdT = 0.0 local trainLineConsumption_dPdT = 0.0
local wagc = Train:GetWagonCount() local wagc = Train:GetBLConnectedWagonCount()
local HaveEPK = not Train.SubwayTrain or not Train.SubwayTrain.ARS or not Train.SubwayTrain.ARS.NoEPK local HaveEPK = not Train.SubwayTrain or not Train.SubwayTrain.ARS or not Train.SubwayTrain.ARS.NoEPK
local BLDisconnect,pr_speed = true,1 local pr_speed = 1
-- работа срывного клапана -- работа срывного клапана
if Train.AutostopValve.Value > 0 then if Train.AutostopValve.Value > 0 then
self:TriggerInput("Autostop",self.BrakeLinePressure > 1.86 and 1 or 2) --value == 2 — просто открыть срывной клапан без размыкания контактов УАВА self:TriggerInput("Autostop",self.BrakeLinePressure > 1.86 and 1 or 2) --value == 2 — просто открыть срывной клапан без размыкания контактов УАВА
end end
if self.ValveType == 1 then if self.ValveType == 1 then
BLDisconnect = Train.DriverValveBLDisconnect.Value > 0 self.BLDisconnect = Train.DriverValveBLDisconnect.Value > 0
local TLDisconnect = Train.DriverValveTLDisconnect.Value > 0 self.TLDisconnect = Train.DriverValveTLDisconnect.Value > 0 and self.RealDriverValvePosition ~= 3
pr_speed = 1*wagc--*((self.BrakeLinePressure-self.ReservoirPressure)/0.6) --2 pr_speed = 1*wagc--*((self.BrakeLinePressure-self.ReservoirPressure)/0.6)
if self.Leak or self.BraieLineOpen then pr_speed = pr_speed*0.3 end if self.TLDisconnect then self.TLDisconnectPressure = self.TrainLinePressure end
if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.3 end
-- 334: 1 Fill reservoir from train line, fill brake line from train line -- 334: 1 Fill reservoir from train line, fill brake line from train line
if (self.RealDriverValvePosition == 1) then if (self.RealDriverValvePosition == 1) then
if TLDisconnect or self.ReservoirPressure > self.TrainLinePressure then if self.TLDisconnect or self.ReservoirPressure ~= self.TLDisconnectPressure then
self:equalizePressure(dT,"ReservoirPressure", self.TrainLinePressure, 1,nil,nil,2) if self.BLDisconnect then
if BLDisconnect then self.ReservoirPressure = self.BrakeLinePressure
self:equalizePressure(dT,"BrakeLinePressure", self.TrainLinePressure, pr_speed,nil,nil,2) self:equalizePressure(dT,"BrakeLinePressure", self.TLDisconnectPressure, pr_speed*(pr_speed < wagc and 1 or 1.35),nil,nil,2)--0.7
else
self:equalizePressure(dT,"ReservoirPressure", self.TLDisconnectPressure, 3.55,nil,nil,2)
end end
end end
end end
-- 334: 2 Brake line, reservoir replenished from brake line reductor -- 334: 2 Brake line, reservoir replenished from brake line reductor
if (self.RealDriverValvePosition == 2) then if (self.RealDriverValvePosition == 2) then
if TLDisconnect or self.ReservoirPressure > self.TrainToBrakeReducedPressure*1.05 then if self.TLDisconnect then
self:equalizePressure(dT,"ReservoirPressure", self.TrainToBrakeReducedPressure*1.05, 0.55,nil,nil,2) local a = 1
if self.EmergencyValve or Train.EmergencyBrakeValve.Value > 0.5 then a = 1.85 end
if self.BLDisconnect then
self.ReservoirPressure = self.BrakeLinePressure
self:equalizePressure(dT,"BrakeLinePressure", self.TrainToBrakeReducedPressure, pr_speed*0, pr_speed*0.6*a, nil, 1.6)
self.ReservoirPressure_dPdT = self.BrakeLinePressure_dPdT*0.8
else
self:equalizePressure(dT,"ReservoirPressure", self.TrainToBrakeReducedPressure,0,1.55,nil,2)
end
end end
end end
@@ -371,155 +388,213 @@ function TRAIN_SYSTEM:Think(dT)
self:equalizePressure(dT,"ReservoirPressure", 0.00, 0.001) self:equalizePressure(dT,"ReservoirPressure", 0.00, 0.001)
end end
local res_dischrg_rate4 = self.BLDisconnect and 0.55 or 8
local res_dischrg_rate5 = self.BLDisconnect and 1.12 or 8
-- 334: 4 Reservoir open to atmosphere, brake line equalizes with reservoir -- 334: 4 Reservoir open to atmosphere, brake line equalizes with reservoir
if (self.RealDriverValvePosition == 4) then if (self.RealDriverValvePosition == 4) then
self:equalizePressure(dT,"ReservoirPressure", 0.0,0.55,nil,nil,2)--0.35)-0.55 self:equalizePressure(dT,"ReservoirPressure", 0.0, res_dischrg_rate4, nil,nil,6)--0.35)-0.55
end end
-- 334: 5 Reservoir and brake line open to atmosphere -- 334: 5 Reservoir and brake line open to atmosphere
if (self.RealDriverValvePosition == 5) then if (self.RealDriverValvePosition == 5) then
self:equalizePressure(dT,"ReservoirPressure", 0.0, 1.00)--,nil,nil,2)--1.70 self:equalizePressure(dT,"ReservoirPressure", 0.0, res_dischrg_rate5)--,nil,nil,2)--1.70
if BLDisconnect then local pr_speed = 1.25*wagc
if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.3 end
if self.BLDisconnect then
if self.Leak then pr_speed = pr_speed*6.2 end
self:equalizePressure(dT,"BrakeLinePressure", 0.0, pr_speed,nil,nil,2) self:equalizePressure(dT,"BrakeLinePressure", 0.0, pr_speed,nil,nil,2)
end end
end end
if BLDisconnect and (TLDisconnect or self.ReservoirPressure < self.BrakeLinePressure) then -- утечка через неплотность уравнительного поршня
--local pr_speed = wagc*(1.375) --2 if self.BLDisconnect then self:equalizePressure(dT, "ReservoirPressure", self.BrakeLinePressure, 0.06, 0) end
if (self.RealDriverValvePosition > 2) and (self.RealDriverValvePosition < 5) then
local pr_speed = 1.25*wagc local pr_speed = 1.25*wagc
if self.Leak or self.BraieLineOpen then pr_speed = pr_speed*0.3 end if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.3 end
Train:SetPackedRatio("ReservoirPressure_dPdT",self:equalizePressure(dT,"BrakeLinePressure", self.ReservoirPressure,pr_speed,pr_speed*3,nil)/wagc*2) local _a = 0
else for _i = 1, #Train.WagonList do
Train:SetPackedRatio("ReservoirPressure_dPdT",0) if Train.WagonList[_i].Pneumatic.TLDisconnect and Train.WagonList[_i].Pneumatic.BLDisconnect and (Train.WagonList[_i].Pneumatic.RealDriverValvePosition == 2 or Train.WagonList[_i].Pneumatic.RealDriverValvePosition == 1) then
_a = _a + 1
end
if _a > 0 then break end
end
if _a > 0 then pr_speed = pr_speed*0.1 end
if self.BLDisconnect and self.BrakeLinePressure - self.ReservoirPressure > (self.RealDriverValvePosition == 3 and 0 or self.RealDriverValvePosition == 4 and 0.2 or 100) then --0.2 bar is a piston sensitivity
self:equalizePressure(dT, "BrakeLinePressure", 0, pr_speed*math.abs(self.BrakeLinePressure - self.ReservoirPressure), nil, nil, 6)
end
end end
if not self.TLDisconnect then
self.TLDisconnectPressure = math.max(0,self.TLDisconnectPressure - math.abs(self.ReservoirPressure_dPdT)*dT)
end
self.ReservoirPressure_dPdT = self.ReservoirPressure_dPdT + self.BrakeLinePressure_dPdT*0.2
Train:SetPackedRatio("ReservoirPressure_dPdT",self.ReservoirPressure_dPdT/wagc*2)
--[[
---------------debug---------------------
self.dlreadtimer = self.dlreadtimer or CurTime()
if CurTime() - self.dlreadtimer > 1.0 then
self.dlreadtimer = CurTime()
if Train:GetDriver() then
PrintMessage(HUD_PRINTTALK, Format("Вагон %u; P ТМ: %.3f; P УР =%.3f; Утечка ТМ %.3f; TLDis = %.3f; pr_speed = %.3f",Train:GetWagonNumber(),self.BrakeLinePressure,self.ReservoirPressure,self.BrakeLinePressure_dPdT, self.TLDisconnectPressure, pr_speed))
end
end
---------------debug---------------------]]
trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeLinePressure_dPdT) trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeLinePressure_dPdT)
trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.ReservoirPressure_dPdT)*0.05 trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.ReservoirPressure_dPdT)*0.05
else else
pr_speed = 1.25*wagc --2 pr_speed = 2.8--1.25*wagc --2
if self.Leak or self.BrakeLineOpen then pr_speed = pr_speed*0.7 end local pz_speed
BLDisconnect = self.DisconnectType and Train.DriverValveBLDisconnect.Value > 0 or Train.DriverValveDisconnect.Value > 0 -- wagc | pr_speed
local TLDisconnect = self.DisconnectType and Train.DriverValveTLDisconnect.Value > 0 or Train.DriverValveDisconnect.Value > 0 ------------------
-- 1 | 8.455
-- 2 | 7.865
-- 3 | 7.376
-- 4 | 6.969
-- 5 | 6.627
-- 6 | 6.341
-- 7 | 6.100
-- 8 | 5.900
--pr_speed = (0.4*math.exp(0.1*wagc-1)+1)*160/(2*wagc+20) --2
--[[
---------------debug---------------------
self.brreadtimer = self.brreadtimer or CurTime()
if CurTime() - self.brreadtimer > 1.0 then
self.brreadtimer = CurTime()
if Train:GetDriver() and Train.R_Radio.Value > 0 then
--PrintMessage(HUD_PRINTTALK, Format("br_threshold = %.3f; WcBl = %s",br_threshold, tostring(WcBl)))
--PrintMessage(HUD_PRINTTALK, Format("Это %s", isLVZ and "ЛВЗ" or "не ЛВЗ"))
--PrintMessage(HUD_PRINTTALK, Format("Вагон %u; Авторежим: %.3f",Train:GetWagonNumber(),self.WeightLoadRatio))
--PrintMessage(HUD_PRINTTALK, Format("wagc = %u",wagc))
end
end
---------------debug---------------------]]
--local frc = 0.4--0.35
--if Train.EPK.Value > 0 or self.EmergencyValve or self.BrakeLineOpen then pz_speed = pr_speed*0.75 else pz_speed = pr_speed*1.3 end
if self.Leak or self.BrakeLineOpen then pz_speed = pr_speed*0.75 else pz_speed = pr_speed*1.3 end
self.BLDisconnect = self.DisconnectType and Train.DriverValveBLDisconnect.Value > 0 or Train.DriverValveDisconnect.Value > 0
self.TLDisconnect = self.DisconnectType and Train.DriverValveTLDisconnect.Value > 0 or Train.DriverValveDisconnect.Value > 0
if self.RealDriverValvePosition > 4 and not self.km13_error2 then self.km13_error2 = 0.7 end
-- 013: 1 Overcharge -- 013: 1 Overcharge
if (self.RealDriverValvePosition == 1) and BLDisconnect and (TLDisconnect or self.BrakeLinePressure > self.TrainLinePressure) then if (self.RealDriverValvePosition == 1) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > self.TrainLinePressure) then
self:equalizePressure(dT,"BrakeLinePressure", math.min(6.4,self.TrainLinePressure), pr_speed,Train.EPKC and Train.EPKC.Value==0 and Train.EPK.Value > 0 and pr_speed*2.2 or pr_speed*0.35, nil, 1.0) self:equalizePressure(dT,"BrakeLinePressure", math.min(6.4,self.TrainLinePressure), pr_speed, pz_speed, nil, 1.0)
end end
-- 013: 2 Normal pressure -- 013: 2 Normal pressure
if (self.RealDriverValvePosition == 2) and BLDisconnect and (TLDisconnect or self.BrakeLinePressure > 1.01*math.min(self.KM013offset,self.TrainToBrakeReducedPressure)) then if (self.RealDriverValvePosition == 2) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > 1.01*math.min(self.KM013offset,self.TrainToBrakeReducedPressure)) then--was pr_speed*2
self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(self.KM013offset,self.TrainToBrakeReducedPressure), pr_speed,Train.EPKC and Train.EPKC.Value==0 and Train.EPK.Value > 0 and pr_speed*2 or pr_speed*0.35, nil, 1.0)-- nil, 1.0) self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(self.KM013offset+(self.km13_error2 or 0),self.TrainLinePressure), pr_speed, pz_speed, nil, 2.5)-- nil, 1.0)
if self.km13_error2 and self.BrakeLinePressure >= self.KM013offset+self.km13_error2-0.1 then
self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(self.KM013offset,self.TrainToBrakeReducedPressure), 35, pz_speed, nil, 1)
self.km13_error2 = nil
end
end end
-- 013: 3 4.3 Atm -- 013: 3 4.3 Atm
if (self.RealDriverValvePosition == 3) and BLDisconnect and (TLDisconnect or self.BrakeLinePressure > 1.01*math.min(4.3,self.TrainToBrakeReducedPressure)) then if (self.RealDriverValvePosition == 3) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > 1.01*math.min(4.3,self.TrainToBrakeReducedPressure)) then
self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(4.3,self.TrainToBrakeReducedPressure), pr_speed,pr_speed*0.35, nil, 1.0) self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(4.3,self.TrainToBrakeReducedPressure), pr_speed,pz_speed, nil, 2.5)
end end
-- 013: 4 4.0 Atm -- 013: 4 4.0 Atm
if (self.RealDriverValvePosition == 4) and BLDisconnect and (TLDisconnect or self.BrakeLinePressure > 1.01*math.min(4.0,self.TrainToBrakeReducedPressure)) then if (self.RealDriverValvePosition == 4) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > 1.01*math.min(4.0,self.TrainToBrakeReducedPressure)) then
self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(4.0,self.TrainToBrakeReducedPressure), pr_speed,pr_speed*0.35, nil, 1.0) self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(4.0,self.TrainToBrakeReducedPressure), pr_speed,pz_speed, nil, 2.5)
end end
-- 013: 5 3.7 Atm -- 013: 5 3.7 Atm
if (self.RealDriverValvePosition == 5) and BLDisconnect and (TLDisconnect or self.BrakeLinePressure > 1.01*math.min(3.7,self.TrainToBrakeReducedPressure)) then if (self.RealDriverValvePosition == 5) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > 1.01*math.min(3.7,self.TrainToBrakeReducedPressure)) then
self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(3.7,self.TrainToBrakeReducedPressure), pr_speed,pr_speed*0.35, nil, 1.0) self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(3.7,self.TrainToBrakeReducedPressure), pr_speed,pz_speed, nil, 2.5)
end end
-- 013: 6 3.0 Atm -- 013: 6 3.0 Atm
if (self.RealDriverValvePosition == 6) and BLDisconnect and (TLDisconnect or self.BrakeLinePressure > 1.01*math.min(3.0,self.TrainToBrakeReducedPressure)) then if (self.RealDriverValvePosition == 6) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > 1.01*math.min(3.0,self.TrainToBrakeReducedPressure)) then
self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(3.0,self.TrainToBrakeReducedPressure), pr_speed,pr_speed*0.35, nil, 1.0) self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(3.0,self.TrainToBrakeReducedPressure), pr_speed,pz_speed, nil, 2.5)
end end
-- 013: 7 0.0 Atm -- 013: 7 0.0 Atm
if (self.RealDriverValvePosition == 7) and BLDisconnect and (TLDisconnect or self.BrakeLinePressure > 0.0) then if (self.RealDriverValvePosition == 7) and self.BLDisconnect and (self.TLDisconnect or self.BrakeLinePressure > 0.0) then
self:equalizePressure(dT,"BrakeLinePressure", 0.0, 0.6 + pr_speed*math.exp(math.min(0,self.BrakeLinePressure - 2.8)*1.0),pr_speed*0.35, nil, 1.0) self:equalizePressure(dT,"BrakeLinePressure", 0.0, (0.6 + pr_speed*math.exp(math.min(0,self.BrakeLinePressure - 2.3)*1.0))*(0.15*wagc+1),pz_speed, nil, 2.5)
end end
trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeLinePressure_dPdT) trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeLinePressure_dPdT)
end end
local leak local leak
self.Leak = false self.Leak = false
local pr_speed = 1.25*wagc if wagc ~= Train.OldWagIsoCount or not Train.pr_spd_init then
pr_speed = (0.4*math.exp(0.1*wagc-1)+1)*160/(2*wagc+20) --2
Train.OldWagIsoCount = wagc
Train.pr_spd_init = true
end
if HaveEPK and Train.EPKC then if HaveEPK and Train.EPKC then
local leak = 0 local leak = 0
local epkDiff = math.abs(self.EPKPressure-self.BrakeLinePressure) local epkDiff = math.abs(self.EPKPressure-self.BrakeLinePressure)
if BLDisconnect and Train.EPK.Value>0 then if self.BLDisconnect and Train.EPK.Value>0 then
if Train.EPKC.Value>0 then if Train.EPKC.Value>0 then
self:equalizePressure(dT,"EPKPressure", self.BrakeLinePressure,math.min(1,epkDiff)*6--[[ pr_speed*math.min(1,epkDiff)*2--]] ,math.min(1,epkDiff)*26,false,4*epkDiff*2) self:equalizePressure(dT,"EPKPressure", self.BrakeLinePressure,math.min(1,epkDiff)*6, math.min(1,epkDiff)*16,false,4*epkDiff*2)
end end
if self.EPKPressure<self.BrakeLinePressure and math.abs(self.EPKPressure-self.BrakeLinePressure)>0.3 then if self.EPKPressure<self.BrakeLinePressure and math.abs(self.EPKPressure-self.BrakeLinePressure)>0.3 then
leak = self:equalizePressure(dT,"BrakeLinePressure", self.EPKPressure,pr_speed*epkDiff/1.28,pr_speed*epkDiff/1.28) leak = self:equalizePressure(dT,"BrakeLinePressure", self.EPKPressure,pr_speed*epkDiff/3.8,pr_speed*epkDiff/3.28)
--[[ if self.ValveType==1 then
leak = self:equalizePressure(dT,"ReservoirPressure", self.EPKPressure,epkDiff/2,epkDiff/2)
end--]]
end end
self.Leak = self.Leak or leak<-0.1 self.Leak = self.Leak or leak<-0.1
end end
if Train.EPK.Value == 0 or Train.EPKC.Value == 0 then if Train.EPK.Value == 0 or Train.EPKC.Value == 0 then
leak = leak+self:equalizePressure(dT,"EPKPressure", 0,16,false,false,5) leak = leak+self:equalizePressure(dT,"EPKPressure", 0,16,false,false,5)
end end
if self.ValveType==2 and not BLDisconnect then if self.ValveType==2 and not self.BLDisconnect then
self:equalizePressure(dT,"EPKPressure", 0,16,false,false,5) self:equalizePressure(dT,"EPKPressure", 0,16,false,false,5)
end end
Train:SetPackedRatio("EmergencyValveEPK_dPdT", -leak/wagc) Train:SetPackedRatio("EmergencyValveEPK_dPdT", -leak/wagc*8)
end end
if self.ValveType == 1 then if self.ValveType == 1 then
Train:SetPackedRatio("Crane_dPdT", self.ReservoirPressure_dPdT ) Train:SetPackedRatio("Crane_dPdT", self.ReservoirPressure_dPdT )
else else
Train:SetPackedRatio("Crane_dPdT", self.BrakeLinePressure_dPdT/wagc*3 ) Train:SetPackedRatio("Crane_dPdT", self.BrakeLinePressure_dPdT/wagc*3 )
end end
if self.EmergencyValveDisable then--and (self.BrakeLinePressure-self.OldBrakeLinePressure)>0.01 then if self.EmergencyValveDisable then
self.EmergencyValveDisable=false self.EmergencyValveDisable=false
self.EmergencyValve=false self.EmergencyValve=false
Train.AutoStopNotify=false Train.AutoStopNotify=false
end end
self.OldBrakeLinePressure = self.BrakeLinePressure
local leak = 0 local leak = 0
if self.EmergencyValve then if self.EmergencyValve then
local leakst = BLDisconnect and math.max(0.3,math.log(self.BrakeLinePressure,1.2) - 2.5) or math.max(1.6,math.log(0.63*self.BrakeLinePressure,1.15)) local leakst = self.BLDisconnect and math.max(0.3,math.log(self.BrakeLinePressure,1.2) - 2.0) or math.max(1.6,math.log(0.63*self.BrakeLinePressure,1.15))
leak = self:equalizePressure(dT,"BrakeLinePressure", 0.0,leakst*wagc/6)--,false,false,10) leak = self:equalizePressure(dT,"BrakeLinePressure", 0.0,leakst*wagc/6)--,false,false,10)
if Train.UAVA.Value > 0 or (self.BrakeLinePressure < 1.8 and Train.AutostopValve.Value == 0) then --пока держим ЛКМ нажатой, срывной клапан открыт if Train.UAVA.Value > 0 or (self.BrakeLinePressure < 1.8 and Train.AutostopValve.Value == 0) then --пока держим ЛКМ нажатой, срывной клапан открыт
self.EmergencyValveDisable = true self.EmergencyValveDisable = true
end end
self.Leak = true self.Leak = true
end end
local UAVABlocked = (self.BrakeLinePressure>1.8 and Train.UAVA.Value==0) local UAVABlocked = (self.BrakeLinePressure>1.8 and Train.UAVA.Value==0)
if (Train.UAVA.Blocked>0) ~= UAVABlocked then if (Train.UAVA.Blocked>0) ~= UAVABlocked then
Train.UAVA:TriggerInput("Block",UAVABlocked and 1 or 0) Train.UAVA:TriggerInput("Block",UAVABlocked and 1 or 0)
end end
local UAVACBlocked = self.EmergencyValve and not self.EmergencyValveDisable local UAVACBlocked = self.EmergencyValve and not self.EmergencyValveDisable
if (Train.UAVAC.Blocked>0) ~= UAVACBlocked then if (Train.UAVAC.Blocked>0) ~= UAVACBlocked then
Train.UAVAC:TriggerInput("Block",UAVACBlocked and 1 or 0) Train.UAVAC:TriggerInput("Block",UAVACBlocked and 1 or 0)
end end
Train:SetPackedRatio("EmergencyValve_dPdT", -1.8*leak/wagc) --Регулировка свиста срывного клапана Train:SetPackedRatio("EmergencyValve_dPdT", -0.6*leak/wagc) --Регулировка свиста срывного клапана was -1.8
local leak = 0 local leak = 0
if Train.EmergencyBrakeValve and Train.EmergencyBrakeValve.Value > 0.5 then if Train.EmergencyBrakeValve and Train.EmergencyBrakeValve.Value > 0.5 then
--local leakst = (1.6*(Train:GetWagonCount())*(self.BrakeLinePressure-math.min(2.5,self.TrainToBrakeReducedPressure))*0.9) local leakst = math.max(0.5,math.exp(0.5*self.BrakeLinePressure))
leak = self:equalizePressure(dT,"BrakeLinePressure", 0.0,(1.1*wagc)*2,false,false,1) leak = self:equalizePressure(dT,"BrakeLinePressure", 0.0,leakst)--,false,false,10) --was leakst*wagc/5
self.Leak = true self.Leak = true
end end
Train:SetPackedRatio("EmergencyBrakeValve_dPdT", -leak/wagc) Train:SetPackedRatio("EmergencyBrakeValve_dPdT", -leak/wagc)
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
-- Fill brake cylinders -- Fill brake cylinders
if self.WCChargeValve == true then if self.WCChargeValve == true then
self:equalizePressure(dT,"WorkingChamberPressure",self.BrakeLinePressure,0.107,nil,nil,1.0) --simulate 0.8mm hole btw BL and working chambers self:equalizePressure(dT,"WorkingChamberPressure",self.BrakeLinePressure,0.094,nil,nil,1.0) --simulate 0.8mm hole btw BL and working chambers
end end
--self.AirDistributorReady = self.WorkingChamberPressure >= 2.2
local aird_ready = self.WorkingChamberPressure >= 2.2 local aird_ready = self.WorkingChamberPressure >= 2.2
self.WCChargeValve = not ((self.WorkingChamberPressure - self.BrakeLinePressure) > 0.2 and (self.WorkingChamberPressure - self.BrakeLinePressure) < 2.5) self.WCChargeValve = not ((self.WorkingChamberPressure - self.BrakeLinePressure) > 0.2 and (self.WorkingChamberPressure - self.BrakeLinePressure) < 2.5)
--self.OverchargeReleaseValve = self.WorkingChamberPressure > 5.2 and not self.WCChargeValve
local KLSZ = self.WorkingChamberPressure > 5.2 and not self.WCChargeValve local KLSZ = self.WorkingChamberPressure > 5.2 and not self.WCChargeValve
if KLSZ then if KLSZ then
self:equalizePressure(dT,"WorkingChamberPressure",0.0,0.22) -- КЛСЗ self:equalizePressure(dT,"WorkingChamberPressure",0.0,0.12) -- КЛСЗ
end end
--trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.WorkingChamberPressure_dPdT*0.2) trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.WorkingChamberPressure_dPdT*0.2)
local _offset2 = self.Train.AR63 and 2.5 or 2.4 self.GN2Offset = self.GN2Offset or math.random(20,100)*0.002 + (self.GN2Start or 2.5)
self.GN2Offset = self.GN2Offset or math.random(20,100)*0.002 + _offset2 self.GN1Offset = self.GN1Offset or math.random(20,100)*0.002 + (self.GN1Start or 0.9)
local _offset1 = self.Train.AR63 and 0.9 or 0.8 self.BcBl = (self.GN2Offset + self.WeightLoadRatio*(self.GN2Offset - 1.4))/1.82--1.92
self.GN1Offset = self.GN1Offset or math.random(20,100)*0.002 + _offset1
self.BcBl = (self.GN2Offset + self.WeightLoadRatio*1.3)/1.93
if Train.AirDistributorDisconnect.Value == 0 and aird_ready then if Train.AirDistributorDisconnect.Value == 0 and aird_ready then
-- Valve #1 -- Valve #1
if (Train.PneumaticNo1.Value == 1.0) and (Train.PneumaticNo2.Value == 0.0) then if (Train.PneumaticNo1.Value == 1.0) and (Train.PneumaticNo2.Value == 0.0) then
@@ -527,22 +602,22 @@ function TRAIN_SYSTEM:Think(dT)
self.PN1 = math.min(self.TrainLinePressure,self.GN1Offset) self.PN1 = math.min(self.TrainLinePressure,self.GN1Offset)
end end
elseif Train.PneumaticNo1.Value == 0 and self.PN1 > 0.0 then elseif Train.PneumaticNo1.Value == 0 and self.PN1 > 0.0 then
self.PN1 = math.max(0,self.PN1-math.exp(3.6*(self.BrakeCylinderPressure - self.GN1Offset))*1.7*dT) self.PN1 = self.BrakeCylinderPressure > 0.2 and 0.05 or self.PN1 - 0.5*dT
end end
-- Valve #2 -- Valve #2
if Train.PneumaticNo2.Value == 1.0 then if Train.PneumaticNo2.Value == 1.0 then
self.PN2 = math.min(self.TrainLinePressure,(self.GN2Offset + self.WeightLoadRatio*1.3)) self.PN2 = math.min(self.TrainLinePressure,(self.GN2Offset + self.WeightLoadRatio*1.3))
if self.BePN2 == false and self.BrakeCylinderPressure > 1.6 then if self.BePN2 == false and self.BrakeCylinderPressure > 1.6 then
Train:PlayOnce("PN2end","stop") Train:PlayOnce("PN2end","stop")
end end
self.BePN2 = true self.BePN2 = true
elseif self.PN2 > 0.0 then elseif self.PN2 > 0.0 then
self.PN2 = self.BrakeCylinderPressure > 0.4 and 0.2 or self.PN2 - 0.5*dT self.PN2 = self.BrakeCylinderPressure > 0.4 and 0.2 or self.PN2 - 0.5*dT
end end
local WcBl = (self.BrakeLinePressure < 3.55 and 0.45*(self.WorkingChamberPressure - 2.2) or self.BrakeLinePressure > 3.65 and self.BrakeLinePressure*(self.BrakeLinePressure > 4.5 and self.BrakeLinePressure_dPdT > 0.02 and 1.06 or 1))
--self.cranPres = WcBl and math.max(0,math.min(self.GN2Offset + self.WeightLoadRatio*1.3,self.BcBl*(self.WorkingChamberPressure - WcBl)*(self.BrakeLinePressure > self.KM013offset and 0.6 or 1))) or self.cranPres self.BchExh = self.WorkingChamberPressure < 4.8 and self.BrakeLinePressure < 3.4 and 0 or 1
self.cranPres = WcBl and math.max(0,self.BcBl*(self.WorkingChamberPressure - WcBl)*(self.BrakeLinePressure > self.KM013offset and (0.56 + self.PN1*0.43) or 1)) or self.cranPres self.cranPres = math.max(0,self.BcBl*(self.WorkingChamberPressure - self.BrakeLinePressure*self.BchExh)*(self.BrakeLinePressure > self.KM013offset and (0.6 + self.PN1*0.43) or 1))
local targetPressure = math.max(0,math.min(self.GN2Offset + self.WeightLoadRatio*1.3, (self.cranPres < (self.PN1 + self.WeightLoadRatio*0.7) and (Train.PneumaticNo1.Value == 1.0) and (self.PN1 + self.WeightLoadRatio*0.7) or self.PN1) + self.PN2 + self.cranPres)) local targetPressure = math.max(0,math.min(self.GN2Offset + self.WeightLoadRatio*1.3, (self.cranPres < (self.PN1 + self.WeightLoadRatio*0.7) and (Train.PneumaticNo1.Value == 1.0) and (self.PN1 + self.WeightLoadRatio*0.7) or self.PN1) + self.PN2 + self.cranPres))
if math.abs(self.BrakeCylinderPressure - targetPressure) > 0.150 then if math.abs(self.BrakeCylinderPressure - targetPressure) > 0.150 then
self.BrakeCylinderValve = 1 self.BrakeCylinderValve = 1
end end
@@ -550,13 +625,11 @@ function TRAIN_SYSTEM:Think(dT)
self.BrakeCylinderValve = 0 self.BrakeCylinderValve = 0
end end
if self.BrakeCylinderValve == 1 then if self.BrakeCylinderValve == 1 then
--self:equalizePressure(dT,"BrakeCylinderPressure", math.min(self.GN2Offset + self.WeightLoadRatio*1.3,targetPressure), 1, 3.5, nil, (self.BrakeLinePressure_dPdT > 0.02) and (0.9+math.Clamp((1 - self.BrakeCylinderPressure)*0.9,0,1.8)) or 1) self:equalizePressure(dT,"BrakeCylinderPressure", math.min(self.GN2Offset + self.WeightLoadRatio*(self.GN2Offset - 1.4),targetPressure), 0.8, (Train.PneumaticNo1.Value > 0 or Train.PneumaticNo2.Value > 0) and 2.8 or 1.5, nil, 1.2)
self:equalizePressure(dT,"BrakeCylinderPressure", math.min(self.GN2Offset + self.WeightLoadRatio*1.3,targetPressure), 1, 3.5, nil, 1)
end end
trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeCylinderPressure_dPdT*0.5) trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeCylinderPressure_dPdT*0.5)
elseif Train.AirDistributorDisconnect.Value ~= 0 then elseif Train.AirDistributorDisconnect.Value ~= 0 then
self:equalizePressure(dT,"BrakeCylinderPressure", 0.0, 2.00) self:equalizePressure(dT,"BrakeCylinderPressure", 0.0, 2.00)
self:equalizePressure(dT,"WorkingChamberPressure", 0.0, 2.00) --имитируем потягивание за тросик отпускного клапана
end end
if (self.BrakeCylinderPressure > 0.2 and self.BrakeCylinderPressure_dPdT > 0.1 or self.BrakeCylinderPressure_dPdT > 1) and not self.BrakeEngaged then if (self.BrakeCylinderPressure > 0.2 and self.BrakeCylinderPressure_dPdT > 0.1 or self.BrakeCylinderPressure_dPdT > 1) and not self.BrakeEngaged then
self.BrakeEngaged = true self.BrakeEngaged = true
@@ -580,6 +653,11 @@ function TRAIN_SYSTEM:Think(dT)
Train:PlayOnce("PN2end","stop") Train:PlayOnce("PN2end","stop")
end end
if Train.UAVAContact.Value > 0.5 and Train.UAVAC.Value < 0.5 then
Train.UAVAC:TriggerInput("Set",1)
Train:PlayOnce("uava_reset","bass",1)
end
--Parking brake simulation --Parking brake simulation
local PBPressure = math.Clamp(self.TrainLinePressure/5,0,1)*2.7 local PBPressure = math.Clamp(self.TrainLinePressure/5,0,1)*2.7
if Train.ParkingBrake.Value == 0 then if Train.ParkingBrake.Value == 0 then
@@ -596,15 +674,15 @@ function TRAIN_SYSTEM:Think(dT)
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
-- Simulate compressor operation and train line depletion -- Simulate compressor operation and train line depletion
self.Compressor = Train.KK.Value * (Train.Electric.Aux750V > 550 and 1 or 0) self.Compressor = Train.KK.Value * (Train.Electric.Aux750V > 550 and 1 or 0)
self.TrainLinePressure = self.TrainLinePressure - 0.07*trainLineConsumption_dPdT*dT -- 0.190 --0.170 self.TrainLinePressure = self.TrainLinePressure - Train.AirConsumeRatio*trainLineConsumption_dPdT*dT -- 0.190 --0.170 --0.07
if self.Compressor == 1 then self:equalizePressure(dT,"TrainLinePressure", 10.0, 0.04) end if self.Compressor == 1 then self:equalizePressure(dT,"TrainLinePressure", 10.0, Train.CompressorEfficiency) end -- 0.04
self:equalizePressure(dT,"TrainLinePressure", 0,0.001) self:equalizePressure(dT,"TrainLinePressure", 0,Train.AirLeakRatio)
-- Overpressure -- Overpressure
if self.TrainLinePressure > 9.2 then self.TrainLineOverpressureValve = 1 end if self.TrainLinePressure > math.max(7.2, (9.2 - self.TrainLineOverpressureValve*0.2)) and self.TrainLineOverpressureValve%2 == 0 then self.TrainLineOverpressureValve = self.TrainLineOverpressureValve + 1 end
if self.TrainLineOverpressureValve == 1 then if self.TrainLineOverpressureValve%2 == 1 then
self:equalizePressure(dT,"TrainLinePressure", 0.0, (self.TrainLinePressure-(self.Compressor == 1 and 6.5 or 4))*0.6) --was 0.2 self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.2)
self.TrainLineOpen = true self.TrainLineOpen = true
if self.TrainLinePressure < 5.2 then self.TrainLineOverpressureValve = 0 end if self.TrainLinePressure < 5.2 and self.TrainLineOverpressureValve < 20 then self.TrainLineOverpressureValve = self.TrainLineOverpressureValve + 1 end
end end
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
@@ -626,9 +704,11 @@ function TRAIN_SYSTEM:Think(dT)
if self.DoorLinePressure > 3.5 then if self.DoorLinePressure > 3.5 then
if (Train.VDOL.Value == 1.0) and (Train.VDOP.Value == 0.0) and not self.DoorLeft then if (Train.VDOL.Value == 1.0) and (Train.VDOP.Value == 0.0) and not self.DoorLeft then
self.DoorLeft = true self.DoorLeft = true
if self.VDOLLoud then Train:PlayOnce("vdol_loud","cabin",0.8+math.random()*0.2,self.VDOLLoud) end
end end
if (Train.VDOL.Value == 0.0) and (Train.VDOP.Value == 1.0) and not self.DoorRight then if (Train.VDOL.Value == 0.0) and (Train.VDOP.Value == 1.0) and not self.DoorRight then
self.DoorRight = true self.DoorRight = true
if self.VDORLoud then Train:PlayOnce("vdop_loud","cabin",0.8+math.random()*0.2,self.VDORLoud) end
end end
if (Train.VDZ.Value == 1.0 or Train.VDOL.Value == 1.0 and Train.VDOP.Value == 1.0 or self.RZDTimer) and (self.DoorLeft or self.DoorRight) then if (Train.VDZ.Value == 1.0 or Train.VDOL.Value == 1.0 and Train.VDOP.Value == 1.0 or self.RZDTimer) and (self.DoorLeft or self.DoorRight) then
if not self.OpenWaitL or CurTime()-self.OpenWaitL < 0.2 then if not self.OpenWaitL or CurTime()-self.OpenWaitL < 0.2 then
@@ -648,32 +728,18 @@ function TRAIN_SYSTEM:Think(dT)
end end
if self.VDOL ~= Train.VDOL.Value then if self.VDOL ~= Train.VDOL.Value then
self.VDOL = Train.VDOL.Value self.VDOL = Train.VDOL.Value
self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.3) self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.05)
if self.VDLoud and self.VDOL > 0 and not Train.LeftDoorsOpen then Train:PlayOnce("vdol_loud"..self.VDLoudID,"bass",self.VDLoud) end
end end
if self.VDOP ~= Train.VDOP.Value then if self.VDOP ~= Train.VDOP.Value then
self.VDOP = Train.VDOP.Value self.VDOP = Train.VDOP.Value
self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.3) self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.05)
if self.VDLoud and self.VDOP > 0 and not Train.RightDoorsOpen then Train:PlayOnce("vdop_loud"..self.VDLoudID,"bass",self.VDLoud) end
end end
if self.VDZ ~= Train.VDZ.Value then if self.VDZ ~= Train.VDZ.Value then
self.VDZ = Train.VDZ.Value self.VDZ = Train.VDZ.Value
self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.3) self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.05)
if self.VDLoud and self.VDZ > 0 and (Train.RightDoorsOpen or Train.LeftDoorsOpen) then Train:PlayOnce("vzd_loud"..self.VDLoudID,"bass",self.VDLoud) end
end
if Train.CanStuckPassengerLeft then
for i in ipairs(self.LeftDoorStuck) do
self.LeftDoorStuck[i] = math.random() < (0.6+math.min(2,2-self.LeftDoorSpeed[i])*0.2)*Train.CanStuckPassengerLeft*0.6 and (math.random() > 0.7 and CurTime()+math.random()*15)
end
Train.CanStuckPassengerLeft = false
end
if Train.CanStuckPassengerRight then
for i in ipairs(self.RightDoorStuck) do
self.RightDoorStuck[i] = math.random() < (0.6+math.min(2,2-self.LeftDoorSpeed[i])*0.2)*Train.CanStuckPassengerRight*0.6 and (math.random() > 0.7 and CurTime()+math.random()*15)
end
Train.CanStuckPassengerRight = false
end end
Train.LeftDoorsOpen = false Train.LeftDoorsOpen = false
Train.RightDoorsOpen = false Train.RightDoorsOpen = false
local openL = true local openL = true
@@ -681,9 +747,9 @@ function TRAIN_SYSTEM:Think(dT)
for i=1,4 do for i=1,4 do
self.LeftDoorDir[i] = math.Clamp(self.LeftDoorDir[i]+dT/(self.DoorLeft and self.LeftDoorSpeed[i] or -self.LeftDoorSpeed[i]),-1,1) self.LeftDoorDir[i] = math.Clamp(self.LeftDoorDir[i]+dT/(self.DoorLeft and self.LeftDoorSpeed[i] or -self.LeftDoorSpeed[i]),-1,1)
self.RightDoorDir[i] = math.Clamp(self.RightDoorDir[i]+dT/(self.DoorRight and self.RightDoorSpeed[i] or -self.RightDoorSpeed[i]),-1,1) self.RightDoorDir[i] = math.Clamp(self.RightDoorDir[i]+dT/(self.DoorRight and self.RightDoorSpeed[i] or -self.RightDoorSpeed[i]),-1,1)
self.LeftDoorState[i] = math.Clamp(self.LeftDoorState[i] + ((self.LeftDoorDir[i]/self.LeftDoorSpeed[i])*dT),self.LeftDoorStuck[i] and 0.3 or 0,1) self.LeftDoorState[i] = math.Clamp(self.LeftDoorState[i] + ((self.LeftDoorDir[i]/self.LeftDoorSpeed[i])*dT),0,1)
if self.LeftDoorState[i] == 0 or self.LeftDoorState[i] == 1 then self.LeftDoorDir[i] = 0 end if self.LeftDoorState[i] == 0 or self.LeftDoorState[i] == 1 then self.LeftDoorDir[i] = 0 end
self.RightDoorState[i] = math.Clamp(self.RightDoorState[i] + ((self.RightDoorDir[i]/self.RightDoorSpeed[i])*dT),self.RightDoorStuck[i] and 0.3 or 0,1) self.RightDoorState[i] = math.Clamp(self.RightDoorState[i] + ((self.RightDoorDir[i]/self.RightDoorSpeed[i])*dT),0,1)
if self.RightDoorState[i] == 0 or self.RightDoorState[i] == 1 then self.RightDoorDir[i] = 0 end if self.RightDoorState[i] == 0 or self.RightDoorState[i] == 1 then self.RightDoorDir[i] = 0 end
if not Train.LeftDoorsOpen and self.LeftDoorState[i] > 0 then if not Train.LeftDoorsOpen and self.LeftDoorState[i] > 0 then
Train.LeftDoorsOpen = true Train.LeftDoorsOpen = true
@@ -697,39 +763,34 @@ function TRAIN_SYSTEM:Think(dT)
end end
Train:SetPackedRatio("DoorL"..i,self.LeftDoorState[i]) Train:SetPackedRatio("DoorL"..i,self.LeftDoorState[i])
Train:SetPackedRatio("DoorR"..i,self.RightDoorState[i]) Train:SetPackedRatio("DoorR"..i,self.RightDoorState[i])
if self.LeftDoorStuck[i] and (self.DoorLeft or type(self.LeftDoorStuck[i]) == "number" and CurTime()-self.LeftDoorStuck[i] > 0) then
self.LeftDoorStuck[i] = false
end
if self.RightDoorStuck[i] and (self.DoorRight or type(self.RightDoorStuck[i]) == "number" and CurTime()-self.RightDoorStuck[i] > 0) then
self.RightDoorStuck[i] = false
end
Train:SetPackedBool("DoorLS"..i,self.LeftDoorStuck[i])
Train:SetPackedBool("DoorRS"..i,self.RightDoorStuck[i])
end end
if openL and not self.OpenWaitL then self.OpenWaitL = CurTime() end if openL and not self.OpenWaitL then self.OpenWaitL = CurTime() end
if openR and not self.OpenWaitR then self.OpenWaitR = CurTime() end if openR and not self.OpenWaitR then self.OpenWaitR = CurTime() end
Train:SetPackedBool("DoorL",self.DoorLeft) Train:SetPackedBool("DoorL",self.DoorLeft)
Train:SetPackedBool("DoorR",self.DoorRight) Train:SetPackedBool("DoorR",self.DoorRight)
Train.BD:TriggerInput("Set",not Train.RightDoorsOpen and not Train.LeftDoorsOpen) Train.BD:TriggerInput("Set",not Train.RightDoorsOpen and not Train.LeftDoorsOpen)
Train.LeftDoorsOpening = self.DoorLeft
Train.RightDoorsOpening = self.DoorRight
---------------------------------------------------------------------------- ----------------------------------------------------------------------------
if self.DriverValveDisconnectPrevious ~= Train.DriverValveDisconnect.Value then if self.DriverValveDisconnectPrevious ~= Train.DriverValveDisconnect.Value then
self.DriverValveDisconnectPrevious = Train.DriverValveDisconnect.Value self.DriverValveDisconnectPrevious = Train.DriverValveDisconnect.Value
if self.DriverValveDisconnectPrevious == 0 and self.TrainLinePressure>1 then if self.DriverValveDisconnectPrevious == 0 then
self.DVDOffTimer = CurTime() self.DVDOffTimer = CurTime()
Train:PlayOnce("pneumo_disconnect2","cabin",0.9) Train:PlayOnce("pneumo_disconnect2","cabin",0.9)
elseif self.TrainLinePressure>1 then else
self.DVDOffTimer = nil self.DVDOffTimer = nil
Train:PlayOnce("pneumo_disconnect1","cabin",0.9) Train:PlayOnce("pneumo_disconnect1","cabin",0.9)
end end
end end
--Написано в описании КМ013, что при закрытии разобщительного он снижает давление в ТМ на 0.7, значит так и сделаем!
--(и обработку случая, когда в обеих кабинах разобщительный открыт не забудем)
local km013_setpoint = {6.4, self.KM013offset, 4.3, 4.0, 3.7, 3.0, 0}
if self.DVDOffTimer then if self.DVDOffTimer then
if CurTime()-self.DVDOffTimer < 0.45 then if self.BrakeLinePressure - (km013_setpoint[self.RealDriverValvePosition]-0.7) > 0.02 and CurTime()-self.DVDOffTimer < wagc*5/8 then
local pr_speed = 1.3*(Train:GetWagonCount()) --2 --print "Снижение давления в ТМ..."
self:equalizePressure(dT,"BrakeLinePressure", 0,pr_speed) local pr_speed = 22--1.4*wagc --2
self:equalizePressure(dT,"BrakeLinePressure", math.max(0,km013_setpoint[self.RealDriverValvePosition]-0.7), pr_speed)
else else
--print("Снижение давления в ТМ завершено за "..(CurTime()-self.DVDOffTimer).." секунд")
self.DVDOffTimer = nil self.DVDOffTimer = nil
end end
end end
@@ -741,8 +802,7 @@ function TRAIN_SYSTEM:Think(dT)
Train:SetNW2Bool("FtI",Train.FrontTrainLineIsolation.Value ~= 0) Train:SetNW2Bool("FtI",Train.FrontTrainLineIsolation.Value ~= 0)
Train:SetNW2Bool("RtI",Train.RearTrainLineIsolation.Value ~= 0) Train:SetNW2Bool("RtI",Train.RearTrainLineIsolation.Value ~= 0)
Train:SetNW2Bool("AD",Train.AirDistributorDisconnect.Value == 0) Train:SetNW2Bool("AD",Train.AirDistributorDisconnect.Value == 0)
Train:SetNW2Bool("UAVAContacts",Train.UAVAC.Value ~= 0)
local ValveType = self.ValveType > 1 local ValveType = self.ValveType > 1
self.Timer = self.Timer or CurTime() self.Timer = self.Timer or CurTime()

View File

@@ -19,19 +19,20 @@ Spawner.717.Line2 = Train from MPL
Spawner.717.Line4 = Train from PBL Spawner.717.Line4 = Train from PBL
Spawner.717.Line5 = Train from FPL Spawner.717.Line5 = Train from FPL
Spawner.717.Type = Train type Spawner.717.Type = Train type
Spawner.717.BodyType = Body type Spawner.717.BodyType = Body type
Spawner.717.MVM = MVM Spawner.717.MVM = MVM
Spawner.717.LVZ = LVZ Spawner.717.LVZ = LVZ
Spawner.717.MaskType = Mask type Spawner.717.MaskType = Mask type
Spawner.717.CranType = Driver's valve type Spawner.717.CranType = Driver's valve type
Spawner.717.LampType = Lamps type Spawner.717.LampType = Lamps type
Spawner.717.Lamp1 = LPV-02 Spawner.717.Lamp1 = LPV-02
Spawner.717.Lamp2 = LLV-01 Spawner.717.Lamp2 = LLV-01
Spawner.717.SeatType = Seats type Spawner.717.SeatType = Seats type
Spawner.717.ARS = ARS panel type Spawner.717.ARS = ARS panel type
Spawner.717.RingType = ARS beeper type Spawner.717.RingType = ARS beeper type
Spawner.717.BPSNType = BPSN type Spawner.717.BPSNType = BPSN type
Spawner.717.RetainerLoad = Retainer load
#######Buttons########### #######Buttons###########
Train.Buttons.RZP = BPSN converter protection engaged #NEW Train.Buttons.RZP = BPSN converter protection engaged #NEW
@@ -198,6 +199,11 @@ Common.PA.Enter = Enter
Common.714.Start = Start traction-motors #FIXME Common.714.Start = Start traction-motors #FIXME
Common.714.RV = Direction switch #FIXME Common.714.RV = Direction switch #FIXME
Common.717.RetEmpty = Empty car
Common.717.RetMedium = Medium load
Common.717.RetFull = Full load
Common.717.RetPassengers = Passengers load
#gmod_subway_81-717 #gmod_subway_81-717
Entities.gmod_subway_81-717_mvm.Buttons.Battery_C.1:UOSToggle = @[Common.ALL.UOS] Entities.gmod_subway_81-717_mvm.Buttons.Battery_C.1:UOSToggle = @[Common.ALL.UOS]
Entities.gmod_subway_81-717_mvm.Buttons.Battery_R.2:UOSToggle = @[Common.ALL.UOS] Entities.gmod_subway_81-717_mvm.Buttons.Battery_R.2:UOSToggle = @[Common.ALL.UOS]
@@ -1202,6 +1208,14 @@ Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.11 = @[Common.Spawn
Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.12 = @[Common.Spawner.Type] 11 Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.12 = @[Common.Spawner.Type] 11
Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.13 = @[Common.Spawner.Type] 12 Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.13 = @[Common.Spawner.Type] 12
Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.14 = @[Common.Spawner.Type] 13 Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.14 = @[Common.Spawner.Type] 13
Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.Name = @[Spawner.717.RetainerLoad]
Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.1 = @[Common.717.RetEmpty]
Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.2 = @[Common.717.RetMedium]
Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.3 = @[Common.717.RetFull]
Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.4 = @[Common.717.RetPassengers]
Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.5 = @[Common.Spawner.Random]
Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.Name = @[Common.Spawner.SpawnMode] Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.Name = @[Common.Spawner.SpawnMode]
Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.1 = @[Common.Spawner.SpawnMode.Full] Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.1 = @[Common.Spawner.SpawnMode.Full]
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]
@@ -1209,6 +1223,13 @@ Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.3 = @[Common.Spawn
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]
#Spawner: #Spawner:
Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.Name = @[Spawner.717.RetainerLoad]
Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.1 = @[Common.717.RetEmpty]
Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.2 = @[Common.717.RetMedium]
Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.3 = @[Common.717.RetFull]
Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.4 = @[Common.717.RetPassengers]
Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.5 = @[Common.Spawner.Random]
Entities.gmod_subway_81-717_lvz.Spawner.Texture.Name = @[Common.Spawner.Texture] Entities.gmod_subway_81-717_lvz.Spawner.Texture.Name = @[Common.Spawner.Texture]
Entities.gmod_subway_81-717_lvz.Spawner.PassTexture.Name = @[Common.Spawner.PassTexture] Entities.gmod_subway_81-717_lvz.Spawner.PassTexture.Name = @[Common.Spawner.PassTexture]
Entities.gmod_subway_81-717_lvz.Spawner.CabTexture.Name = @[Common.Spawner.CabTexture] Entities.gmod_subway_81-717_lvz.Spawner.CabTexture.Name = @[Common.Spawner.CabTexture]

View File

@@ -19,19 +19,20 @@ Spawner.717.Line2 = Состав с МПЛ
Spawner.717.Line4 = Состав с ПБЛ Spawner.717.Line4 = Состав с ПБЛ
Spawner.717.Line5 = Состав с ФПЛ Spawner.717.Line5 = Состав с ФПЛ
Spawner.717.Type = Тип состава Spawner.717.Type = Тип состава
Spawner.717.BodyType = Тип кузова Spawner.717.BodyType = Тип кузова
Spawner.717.MVM = МВМ Spawner.717.MVM = МВМ
Spawner.717.LVZ = ЛВЗ Spawner.717.LVZ = ЛВЗ
Spawner.717.MaskType = Тип маски Spawner.717.MaskType = Тип маски
Spawner.717.CranType = Тип крана машиниста Spawner.717.CranType = Тип крана машиниста
Spawner.717.LampType = Тип ламп Spawner.717.LampType = Тип ламп
Spawner.717.Lamp1 = ЛПВ-02 Spawner.717.Lamp1 = ЛПВ-02
Spawner.717.Lamp2 = ЛЛВ-01 Spawner.717.Lamp2 = ЛЛВ-01
Spawner.717.SeatType = Тип сидений Spawner.717.SeatType = Тип сидений
Spawner.717.ARS = Тип панели АРС Spawner.717.ARS = Тип панели АРС
Spawner.717.RingType = Тип звонка Spawner.717.RingType = Тип звонка
Spawner.717.BPSNType = Тип БПСН Spawner.717.BPSNType = Тип БПСН
Spawner.717.RetainerLoad = Авторежим
#######Buttons########### #######Buttons###########
Train.Buttons.RZP = Сработала защита БПСН Train.Buttons.RZP = Сработала защита БПСН
@@ -198,6 +199,11 @@ Common.PA.Enter = Ввод
Common.714.Start = Пуск тяговых двигателей Common.714.Start = Пуск тяговых двигателей
Common.714.RV = Переключатель направления Common.714.RV = Переключатель направления
Common.717.RetEmpty = Порожний
Common.717.RetMedium = Средняя загрузка
Common.717.RetFull = Груженый
Common.717.RetPassengers = Пассажиры
#gmod_subway_81-717 #gmod_subway_81-717
Entities.gmod_subway_81-717_mvm.Buttons.Battery_C.1:UOSToggle = @[Common.ALL.UOS] Entities.gmod_subway_81-717_mvm.Buttons.Battery_C.1:UOSToggle = @[Common.ALL.UOS]
Entities.gmod_subway_81-717_mvm.Buttons.Battery_R.2:UOSToggle = @[Common.ALL.UOS] Entities.gmod_subway_81-717_mvm.Buttons.Battery_R.2:UOSToggle = @[Common.ALL.UOS]
@@ -1202,6 +1208,14 @@ Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.11 = @[Common.Spawn
Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.12 = @[Common.Spawner.Type] 11 Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.12 = @[Common.Spawner.Type] 11
Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.13 = @[Common.Spawner.Type] 12 Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.13 = @[Common.Spawner.Type] 12
Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.14 = @[Common.Spawner.Type] 13 Entities.gmod_subway_81-717_mvm_custom.Spawner.BPSNType.14 = @[Common.Spawner.Type] 13
Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.Name = @[Spawner.717.RetainerLoad]
Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.1 = @[Common.717.RetEmpty]
Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.2 = @[Common.717.RetMedium]
Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.3 = @[Common.717.RetFull]
Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.4 = @[Common.717.RetPassengers]
Entities.gmod_subway_81-717_mvm_custom.Spawner.RetainerLoad.5 = @[Common.Spawner.Random]
Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.Name = @[Common.Spawner.SpawnMode] Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.Name = @[Common.Spawner.SpawnMode]
Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.1 = @[Common.Spawner.SpawnMode.Full] Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.1 = @[Common.Spawner.SpawnMode.Full]
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]
@@ -1209,6 +1223,13 @@ Entities.gmod_subway_81-717_mvm_custom.Spawner.SpawnMode.3 = @[Common.Spawn
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]
#Spawner: #Spawner:
Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.Name = @[Spawner.717.RetainerLoad]
Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.1 = @[Common.717.RetEmpty]
Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.2 = @[Common.717.RetMedium]
Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.3 = @[Common.717.RetFull]
Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.4 = @[Common.717.RetPassengers]
Entities.gmod_subway_81-717_lvz_custom.Spawner.RetainerLoad.5 = @[Common.Spawner.Random]
Entities.gmod_subway_81-717_lvz.Spawner.Texture.Name = @[Common.Spawner.Texture] Entities.gmod_subway_81-717_lvz.Spawner.Texture.Name = @[Common.Spawner.Texture]
Entities.gmod_subway_81-717_lvz.Spawner.PassTexture.Name = @[Common.Spawner.PassTexture] Entities.gmod_subway_81-717_lvz.Spawner.PassTexture.Name = @[Common.Spawner.PassTexture]
Entities.gmod_subway_81-717_lvz.Spawner.CabTexture.Name = @[Common.Spawner.CabTexture] Entities.gmod_subway_81-717_lvz.Spawner.CabTexture.Name = @[Common.Spawner.CabTexture]