mirror of
https://github.com/metrostroi-repo/MetrostroiAddon.git
synced 2026-05-02 00:42:29 +00:00
585 lines
26 KiB
Lua
585 lines
26 KiB
Lua
--------------------------------------------------------------------------------
|
||
-- 81-722 pneumatic
|
||
--------------------------------------------------------------------------------
|
||
-- Copyright (C) 2013-2018 Metrostroi Team & FoxWorks Aerospace s.r.o.
|
||
-- Contains proprietary code. See license.txt for additional information.
|
||
--------------------------------------------------------------------------------
|
||
Metrostroi.DefineSystem("81_722_Pneumatic")
|
||
TRAIN_SYSTEM.DontAccelerateSimulation = true
|
||
|
||
function TRAIN_SYSTEM:Initialize()
|
||
-- (013)
|
||
-- 1 Accelerated charge
|
||
-- 2 Normal charge (brake release)
|
||
-- 3 Closed
|
||
-- 4 Service application
|
||
-- 5 Emergency application
|
||
self.DriverValvePosition = 6
|
||
self.RealDriverValvePosition = self.DriverValvePosition
|
||
|
||
-- Pressure in parking brake
|
||
self.ParkingBrakePressure = 0
|
||
self.AirDistributorPressure = 0
|
||
self.PMPressure = 0
|
||
-- Pressure in reservoir
|
||
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
|
||
-- Pressure in the door line
|
||
self.DoorLinePressure = 0.0 -- atm
|
||
|
||
|
||
self.Train:LoadSystem("UAVA","Relay","Switch")
|
||
self.Train:LoadSystem("EmergencyBrakeValve","Relay","Switch")
|
||
|
||
self.Train:LoadSystem("K31","Relay","Switch", { normally_closed = true}) --KTO
|
||
self.Train:LoadSystem("K9","Relay","Switch", { normally_closed = true}) --РВТБ
|
||
self.Train:LoadSystem("K29","Relay","Switch") --КРМШ
|
||
self.Train:LoadSystem("S1","Relay","") --Двери
|
||
|
||
self.V4 = false --Включение РУ
|
||
|
||
self.K1 = false
|
||
self.K2 = false
|
||
self.SD2 = 0
|
||
self.SD3 = 0
|
||
self.SD4 = 0
|
||
-- 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 = false
|
||
|
||
-- Compressor simulation
|
||
self.Compressor = 0 --Simulate overheat with TRK FIXME
|
||
|
||
-- Disconnect valve status
|
||
self.DriverValveDisconnectPrevious = 0
|
||
self.EPKPrevious = 0
|
||
|
||
-- Doors state
|
||
--[[self.Train:LoadSystem("LeftDoor1","Relay",{ open_time = 0.5, close_time = 0.5 })
|
||
self.Train:LoadSystem("LeftDoor2","Relay",{ open_time = 0.5, close_time = 0.5 })
|
||
self.Train:LoadSystem("LeftDoor3","Relay",{ open_time = 0.5, close_time = 0.5 })
|
||
self.Train:LoadSystem("LeftDoor4","Relay",{ open_time = 0.5, close_time = 0.5 })
|
||
self.Train:LoadSystem("RightDoor1","Relay",{ open_time = 0.5, close_time = 0.5 })
|
||
self.Train:LoadSystem("RightDoor2","Relay",{ open_time = 0.5, close_time = 0.5 })
|
||
self.Train:LoadSystem("RightDoor3","Relay",{ open_time = 0.5, close_time = 0.5 })
|
||
self.Train:LoadSystem("RightDoor4","Relay",{ open_time = 0.5, close_time = 0.5 })]]--
|
||
self.DoorLeft = false
|
||
self.DoorRight = false
|
||
self.CloseDoors = false
|
||
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}
|
||
self.LeftDoorStuck = {false, false, false, false}
|
||
self.RightDoorStuck = {false, false, false, false}
|
||
self.DoorSpeedMain = math.Rand(1.9,2.1)
|
||
for i=1,#self.LeftDoorSpeed do
|
||
self.LeftDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.3,self.DoorSpeedMain+0.3)
|
||
self.RightDoorSpeed[i] = math.Rand(self.DoorSpeedMain-0.3,self.DoorSpeedMain+0.3)
|
||
end
|
||
end
|
||
self.PlayOpen = 1e9
|
||
self.PlayClosed = 1e9
|
||
self.TrainLineOpen = false
|
||
self.BrakeLineOpen = false
|
||
|
||
self.EmergencyValve = false
|
||
self.EmergencyValveEPK = false
|
||
self.OldValuePos = self.DriverValvePosition
|
||
|
||
self.WeightLoadRatio = 0
|
||
|
||
self.EPKLeaking = false
|
||
end
|
||
|
||
function TRAIN_SYSTEM:Inputs()
|
||
return { "BrakeUp", "BrakeDown", "BrakeSet", "Autostop" }
|
||
end
|
||
|
||
function TRAIN_SYSTEM:Outputs()
|
||
return { "BrakeLinePressure", "BrakeCylinderPressure", "DriverValvePosition",
|
||
"ReservoirPressure", "TrainLinePressure", "DoorLinePressure", "WeightLoadRatio", "SD2","SD3","SD4" }
|
||
end
|
||
|
||
function TRAIN_SYSTEM:TriggerInput(name,value)
|
||
if name == "BrakeSet" then
|
||
self.DriverValvePosition = math.floor(value)
|
||
if self.DriverValvePosition < 1 then self.DriverValvePosition = 1 end
|
||
if self.DriverValvePosition > 6 then self.DriverValvePosition = 6 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 == "Autostop" then
|
||
self.EmergencyValve = self.Train.UAVA.Value == 0
|
||
if self.EmergencyValve and value > 0 then RunConsoleCommand("say","Autostop braking",self.Train:GetDriverName()) end
|
||
end
|
||
end
|
||
|
||
|
||
-- 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,100,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)
|
||
|
||
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.BraieLineOpen=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
|
||
self.WeightLoadRatio = math.max(0,math.min(1,(Train:GetNW2Float("PassengerCount")/200)))
|
||
|
||
-- Apply specific rate to equalize pressure
|
||
|
||
local V4 = (Train.K29.Value == 1 or Train.Panel.V4>0)
|
||
----------------------------------------------------------------------------
|
||
-- Accumulate derivatives
|
||
self.TrainLinePressure_dPdT = 0.0
|
||
self.BrakeLinePressure_dPdT = 0.0
|
||
self.ReservoirPressure_dPdT = 0.0
|
||
self.BrakeCylinderPressure_dPdT = 0.0
|
||
self.AirDistributorPressure_dPdT = 0.0
|
||
self.ParkingBrakePressure_dPdT = 0.0
|
||
-- Reduce pressure for brake line
|
||
self.TrainToBrakeReducedPressure = math.min(5.1,self.TrainLinePressure) -- * 0.725)
|
||
-- Feed pressure to door line
|
||
self.DoorLinePressure = self.TrainToBrakeReducedPressure * 0.90
|
||
local trainLineConsumption_dPdT = 0.0
|
||
local wagc = Train:GetWagonCount()
|
||
local pr_speed = 1.25*wagc --2
|
||
if self.Leak or self.BraieLineOpen then pr_speed = pr_speed*0.7 end
|
||
-- 013: 1 Overcharge
|
||
if (self.RealDriverValvePosition == 1) and V4 then
|
||
self:equalizePressure(dT,"BrakeLinePressure", self.TrainLinePressure, pr_speed)
|
||
end
|
||
|
||
-- 013: 2 Normal pressure
|
||
if (self.RealDriverValvePosition == 2) and V4 then
|
||
self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(5.1,self.TrainToBrakeReducedPressure), pr_speed,nil, nil, 1.0)-- nil, 1.0)
|
||
end
|
||
|
||
-- 013: 3 4.3 Atm
|
||
if (self.RealDriverValvePosition == 3) and V4 then
|
||
self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(4.3,self.TrainToBrakeReducedPressure), pr_speed,nil, nil, 1.0)
|
||
end
|
||
|
||
-- 013: 4 4.0 Atm
|
||
if (self.RealDriverValvePosition == 4) and V4 then
|
||
self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(4.0,self.TrainToBrakeReducedPressure), pr_speed,nil, nil, 1.0)
|
||
end
|
||
|
||
-- 013: 5 3.7 Atm
|
||
if (self.RealDriverValvePosition == 5) and V4 then
|
||
self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(3.7,self.TrainToBrakeReducedPressure), pr_speed,nil, nil, 1.0)
|
||
end
|
||
|
||
-- 013: 6 3.0 Atm
|
||
if (self.RealDriverValvePosition == 6) and V4 then
|
||
self:equalizePressure(dT,"BrakeLinePressure", 1.01*math.min(3.0,self.TrainToBrakeReducedPressure), pr_speed,nil, nil, 1.0)
|
||
end
|
||
local pr_speed = 1.25*wagc
|
||
self.Leak = false
|
||
if Train.BARS then
|
||
local leak = 0
|
||
if self.EmergencyValve then
|
||
local leakst = 1.1*(Train:GetWagonCount())
|
||
leak = self:equalizePressure(dT,"BrakeLinePressure", 0.0,pr_speed,false,false,0.4)
|
||
if (leak >= -0.2*(Train:GetWagonCount()) or Train.UAVA.Value > 0) then
|
||
self.EmergencyValve = false
|
||
end
|
||
self.Leak = true
|
||
end
|
||
self.Train:SetPackedRatio("EmergencyValve_dPdT", -leak)
|
||
local leak = 0
|
||
if Train.K9.Value == 1 and V4 and Train.Electric.V6Power==0 then
|
||
leak = self:equalizePressure(dT,"BrakeLinePressure", 0.0,pr_speed,pr_speed)
|
||
self.Leak = true
|
||
end
|
||
self.EPKLeaking = self.Leak
|
||
self.Train:SetPackedRatio("EmergencyValveEPK_dPdT", -leak*2)
|
||
end
|
||
local leak = 0
|
||
if self.Train.EmergencyBrakeValve and self.Train.EmergencyBrakeValve.Value > 0.5 then
|
||
leak = self:equalizePressure(dT,"BrakeLinePressure", 0.0,pr_speed,false,false,0.4)
|
||
self.Leak = true
|
||
end
|
||
self.Train:SetPackedRatio("EmergencyBrakeValve_dPdT", -leak)
|
||
self.Train:SetPackedRatio("Crane_dPdT", self.BrakeLinePressure_dPdT )
|
||
trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeLinePressure_dPdT)
|
||
--[[
|
||
local leak = 0
|
||
if self.EmergencyValve then
|
||
leak = self:equalizePressure(dT,"BrakeLinePressure", 0.0,2 + 1.375*(Train:GetWagonCount() - 1),false,false,0.4)
|
||
end
|
||
self.Train:SetPackedRatio("EmergencyValve_dPdT", -leak)
|
||
local leak = 0
|
||
if self.EmergencyValveEPK then
|
||
leak = self:equalizePressure(dT,"BrakeLinePressure", 0.0,2 + 1.375*(Train:GetWagonCount() - 1),false,false,0.4)
|
||
end
|
||
self.Train:SetPackedRatio("EmergencyValveEPK_dPdT", -leak)
|
||
local leak = 0]]--[[
|
||
local count = 0
|
||
local command = 0
|
||
for i=1,#Train.WagonList do
|
||
local train = Train.WagonList[i]
|
||
if train.BUKP then
|
||
if train.BUKP.Loop == 0 then
|
||
count = -99
|
||
end
|
||
if train.BUKP.BTB then
|
||
count = count + 1
|
||
end
|
||
end
|
||
end
|
||
if Train.BUV.PN2 > 0 then
|
||
command = 2
|
||
elseif Train.BUV.PN1 > 0 then
|
||
command = 1
|
||
end--]]
|
||
|
||
local Power = Train.Electric.BUFT > 0
|
||
local targetPressure = 0--math.max(0,math.min(5.2,1.5*(math.min(5.1,self.TrainToBrakeReducedPressure) - self.BrakeLinePressure)))
|
||
--if self.BrakeLinePressure <= 3.3 then
|
||
local PMPressure = 0
|
||
local EPMPressure = 0
|
||
local from = self.TrainToBrakeReducedPressure
|
||
local targetPM = math.Clamp(((from-self.BrakeLinePressure)/(from-3.2)),0,1)*(2.7+self.WeightLoadRatio*0.7)
|
||
if self.PMPressure < targetPM then
|
||
self.PMPressure = math.min(targetPM,self.PMPressure+(0.5+math.max(0,(targetPM-self.PMPressure)-0.2)*0.6)*dT)
|
||
elseif self.PMPressure > targetPM then
|
||
self.PMPressure = math.max(targetPM,self.PMPressure-2*dT)
|
||
end
|
||
self:equalizePressure(dT,"AirDistributorPressure", targetPM, 2.50, 2.50, nil, 1.3)
|
||
--[[--]]
|
||
self.EmergencyBrakeActive = (1-Train:ReadTrainWire(26))+(1-Train:ReadTrainWire(25)) > 0
|
||
self.BTBReady = self.AirDistributorPressure >= (2.4+self.WeightLoadRatio*0.9)-0.1
|
||
if self.EmergencyBrakeActive then
|
||
PMPressure = self.AirDistributorPressure
|
||
if self.BrakeCylinderPressure < self.AirDistributorPressure and self.AirDistributorPressure-self.BrakeCylinderPressure > 0.1 then
|
||
self:equalizePressure(dT,"AirDistributorPressure",0, math.min(self.TrainLinePressure,self.AirDistributorPressure-self.BrakeCylinderPressure)*1, (self.AirDistributorPressure-self.BrakeCylinderPressure)*1, nil, 2)
|
||
end
|
||
end
|
||
if Power then
|
||
if Train:ReadTrainWire(27) > 0 then
|
||
if Train:ReadTrainWire(29) > 0 then
|
||
EPMPressure = 1.7+self.WeightLoadRatio*0.7 --2 уставка
|
||
elseif Train:ReadTrainWire(30) > 0 then
|
||
EPMPressure = 0.75+self.WeightLoadRatio*0.5 --1 уставка
|
||
end
|
||
else
|
||
if Train.BUKV.PN2 then
|
||
EPMPressure = 1.7+self.WeightLoadRatio*0.7 --2 уставка
|
||
elseif Train.BUKV.PN1 then
|
||
EPMPressure = 0.75+self.WeightLoadRatio*0.5 --1 уставка
|
||
end
|
||
end
|
||
end
|
||
if EPMPressure > PMPressure then --Работа П1
|
||
targetPressure = EPMPressure
|
||
else
|
||
targetPressure = PMPressure
|
||
end
|
||
self.DisableScheme = self.BrakeCylinderPressure > 0.6
|
||
--end
|
||
----------------------------------------------------------------------------
|
||
-- Fill brake cylinders
|
||
if Train.K31.Value == 1 then
|
||
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
|
||
local pneumaticValveConsumption_dPdT = 0
|
||
trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,pneumaticValveConsumption_dPdT)
|
||
if self.BrakeCylinderValve == 1 then
|
||
self:equalizePressure(dT,"BrakeCylinderPressure", math.min(3.3,self.TrainLinePressure,targetPressure), 2.50, 2.50, nil, self.BrakeCylinderPressure > targetPressure and 0.3+math.Clamp((self.BrakeCylinderPressure-0.4)/3.3,0,0.6) or 0.9)
|
||
--if self.DriversValve == 1 then
|
||
--self:equalizePressure(dT,"BrakeCylinderPressure", targetPressure, 2.00, 3.50, nil, 1.0) --0.75, 1.25)
|
||
--else
|
||
|
||
--self:equalizePressure(dT,"BrakeCylinderPressure", math.min(2.7,targetPressure+PN1+PN2), self.TrainToBrakeReducedPressure*0.2, 5.50, nil, 0.6+math.Clamp((self.BrakeCylinderPressure-0.75)/2.1,0,1.3)) --0.75, 1.25)
|
||
--print(self.TEMP-self.BrakeCylinderPressure)
|
||
--equalizePressure(dT, pressure, target,rate,fill_rate,no_limit,smooth)
|
||
--end
|
||
end
|
||
else
|
||
self:equalizePressure(dT,"BrakeCylinderPressure", 0.0, 2.00)
|
||
end
|
||
if Train.BUKV.ParkingBrake==0 then
|
||
self:equalizePressure(dT,"ParkingBrakePressure", self.TrainLinePressure, 0.4,1,nil,0.5)
|
||
else
|
||
self:equalizePressure(dT,"ParkingBrakePressure", 0, 0.4,1,nil,0.5)
|
||
end
|
||
Train:SetPackedRatio("ParkingBrakePressure_dPdT",self.ParkingBrakePressure_dPdT+0.02)
|
||
trainLineConsumption_dPdT = trainLineConsumption_dPdT + math.max(0,self.BrakeCylinderPressure_dPdT + self.ParkingBrakePressure_dPdT)
|
||
self.Train:SetPackedRatio("BrakeCylinderPressure_dPdT", self.BrakeCylinderPressure_dPdT)
|
||
|
||
-- Simulate cross-feed between different wagons
|
||
self:UpdatePressures(Train,dT)
|
||
----------------------------------------------------------------------------
|
||
-- Simulate compressor operation and train line depletion
|
||
self.Compressor = Train.Electric.MK and Train.Electric.MK>0--Train.KK.Value * ((not Train.Electric or Train.Electric.Power750V > 550) and 1 or 0)
|
||
self.CompressorOver = self.CompressorOver or 0
|
||
if self.Compressor then
|
||
self.CompressorOver = self.CompressorOver + math.random(0.0215,0.0235)*dT
|
||
if Train.SF54.Value > 0.5 and self.CompressorOver >= 1 then
|
||
self.CompressorOver = 0
|
||
Train:PlayOnce("compressor_pn","cabin",1,1)
|
||
end
|
||
end
|
||
local Ratio = 29/400
|
||
self.TrainLinePressure = self.TrainLinePressure - 0.07*trainLineConsumption_dPdT*dT -- 0.190 --0.170
|
||
if self.Compressor then self:equalizePressure(dT,"TrainLinePressure", 10.0, 0.039) end
|
||
--self:equalizePressure(dT,"TrainLinePressure", 8.0, 0.4) --TEMP
|
||
self:equalizePressure(dT,"TrainLinePressure", 0,0.001)
|
||
-- Overpressure
|
||
if self.TrainLinePressure > 9 then self.TrainLineOverpressureValve = true end
|
||
if self.TrainLineOverpressureValve then
|
||
self:equalizePressure(dT,"TrainLinePressure", 0.0, 0.2)
|
||
self.TrainLineOpen = true
|
||
if self.TrainLinePressure < 6 then self.TrainLineOverpressureValve = false end
|
||
end
|
||
|
||
if self.BrakeLinePressure <= 2.6 and self.SD2~=1 then self.SD2 = 1 end
|
||
if self.BrakeLinePressure >= 2.8 and self.SD2~=0 then self.SD2 = 0 end
|
||
if self.BrakeLinePressure <= 2.0 and self.SD3~=1 then self.SD3 = 1 end
|
||
if self.BrakeLinePressure >= 2.2 and self.SD3~=0 then self.SD3 = 0 end
|
||
self.SD4 = (IsValid(Train.FrontBogey) and Train.FrontBogey.BrakeCylinderPressure+(not Train.FrontBogey.DisableParking and Train.FrontBogey.ParkingBrakePressure or 0) or self.BrakeCylinderPressure)>0.1 and 1 or 0
|
||
----------------------------------------------------------------------------
|
||
-- 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.K31.Value == 0)
|
||
|
||
self.Timer = self.Timer or CurTime()
|
||
if ((CurTime() - self.Timer > 0.10) and (self.DriverValvePosition > self.RealDriverValvePosition)) then
|
||
self.Timer = CurTime()
|
||
self.Train:PlayOnce("br_013","cabin")
|
||
self.RealDriverValvePosition = self.RealDriverValvePosition + 1
|
||
end
|
||
if ((CurTime() - self.Timer > 0.10) and (self.DriverValvePosition < self.RealDriverValvePosition)) then
|
||
self.Timer = CurTime()
|
||
self.Train:PlayOnce("br_013","cabin")
|
||
self.RealDriverValvePosition = self.RealDriverValvePosition - 1
|
||
end
|
||
if self.V4Previous ~= V4 then
|
||
self.V4Previous = V4
|
||
if not V4 then
|
||
self.V4OffTimer = CurTime()
|
||
self.Train:PlayOnce("pneumo_disconnect_close","cabin")
|
||
else
|
||
self.V4OffTimer = nil
|
||
self.Train:PlayOnce("pneumo_disconnect_open","cabin")
|
||
end
|
||
end
|
||
if self.V4OffTimer then
|
||
if CurTime()-self.V4OffTimer < 0.45 then
|
||
local pr_speed = 2.2*(Train:GetWagonCount()) --2
|
||
self:equalizePressure(dT,"BrakeLinePressure", 0,pr_speed)
|
||
else
|
||
self.V4OffTimer = nil
|
||
end
|
||
end
|
||
|
||
--[[
|
||
if Train.BUV.OpenLeft then
|
||
self.DoorLeft = true
|
||
end
|
||
if Train.BUV.OpenRight then
|
||
self.DoorRight = true
|
||
end
|
||
if Train.BUV.CloseDoors then
|
||
self.DoorLeft = false
|
||
self.DoorRight = false
|
||
end--]]
|
||
local commandLeft = (Train:ReadTrainWire(34) > 0 or Train.BUKV.OpenLeft) and (Train:ReadTrainWire(38) > 0 or Train:ReadTrainWire(39) > 0) and Train.SF41.Value > 0
|
||
local commandRight = (Train.BUKV.OpenRightBack or (Train:ReadTrainWire(34) > 0 or Train.BUKV.OpenRight) and (Train:ReadTrainWire(37) > 0 or Train:ReadTrainWire(39) > 0)) and Train.SF42.Value > 0
|
||
local commandClose = Train.BUKV.CloseDoors and Train.SF43.Value > 0
|
||
if commandClose or commandLeft and commandRight then
|
||
self.DoorLeft = false
|
||
self.DoorRight = false
|
||
elseif commandLeft then self.DoorLeft = true
|
||
elseif commandRight then self.DoorRight = true 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
|
||
|
||
Train.LeftDoorsOpen = false
|
||
Train.RightDoorsOpen = false
|
||
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] + (1/self.LeftDoorSpeed[i]*dT*self.LeftDoorDir[i]),self.LeftDoorStuck[i] and 0.3 or 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] + (1/self.RightDoorSpeed[i]*dT*self.RightDoorDir[i]),self.RightDoorStuck[i] and 0.3 or 0,1)
|
||
if self.RightDoorState[i] == 0 or self.RightDoorState[i] == 1 then self.RightDoorDir[i] = 0 end
|
||
---[[
|
||
if self.LeftDoorState[i] > 0 then
|
||
Train.LeftDoorsOpen = true
|
||
end
|
||
if self.RightDoorState[i] > 0 then
|
||
Train.RightDoorsOpen = true
|
||
end
|
||
--Train.BUV.DoorsOpened = Train.LeftDoorsOpen or Train.RightDoorsOpen--]]
|
||
Train:SetPackedRatio("DoorL"..i,self.LeftDoorState[i])
|
||
Train:SetPackedRatio("DoorR"..i,self.RightDoorState[i])
|
||
Train.S1:TriggerInput("Set",not Train.RightDoorsOpen and not Train.LeftDoorsOpen)
|
||
end
|
||
Train:SetPackedBool("DoorL",self.DoorLeft)
|
||
Train:SetPackedBool("DoorR",self.DoorRight)
|
||
--[[
|
||
self.DoorLeft = false
|
||
self.DoorRight = false
|
||
self.CloseDoors = false
|
||
self.LeftDoorState = { 0,0,0,0 }
|
||
self.RightDoorState = { 0,0,0,0 }
|
||
self.LeftDoorSpeed = {0,0,0,0}
|
||
self.RightDoorSpeed = {0,0,0,0}
|
||
for i=1,#self.LeftDoorSpeed do
|
||
self.LeftDoorSpeed = math.random(2.8,3.2)
|
||
self.RightDoorSpeed = math.random(2.8,3.2)
|
||
end]]
|
||
end
|