JachyHm

Diesel RW

Sep 19th, 2020
1,108
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. DIESEL = {
  2.     IDLE_RPM = 480, --IDLE ENGINE RPM
  3.     MAX_RPM = 1100, --MAX ENGINE RPM
  4.     RPM_AIM = 1.6, --MAX RPM CHANGE PER SECOND
  5.     HEATING_RPM_S = 600, --ENGINE RPM WHEN HEATING ON AND REGIME SUMMER
  6.     HEATING_RPM_W = 800, --ENGINE RPM WHEN HEATING ON AND REGIME WINTER
  7.     MIN_OIL_PRESSURE = 0.15, --MIN PERMISSIBLE OIL PRESSURE FOR ENGINE TO WORK - should not be lower than 0.15 of gauge
  8.     MAX_OIL_PRESSURE = 0.65, --MAX OIL PRESSURE
  9.     MAX_ENGINE_POWER = 1460, --MAX ENGINE POWER
  10.     MAX_GENERATOR_POWER = 1200, --MAX GENERATOR POWER
  11.     ENGINE_TO_BIG_CIRCUIT_KOEF = 80, --kfs
  12.     ENGINE_TO_AMBIENT_KOEF = 1, --kfe
  13.     ENGINE_TO_OIL_KOEF = 25, --kfo
  14.     OIL_TO_SMALL_CIRCUIT_WATER_KOEF = 24, --kfo2
  15.     SMALL_CIRCUIT_TO_AMBIENT_KOEF = 0.011, --kw
  16.     SMALL_CIRCUIT_TO_AMBIENT_MOVING_KOEF = 0.07, --kv
  17.     BIG_CIRCUIT_TO_AMBIENT_KOEF = 0.011, --kw
  18.     BIG_CIRCUIT_TO_AMBIENT_MOVING_KOEF = 0.07, --kv
  19.     SMALL_CIRCUIT_SHUTTERS_OPEN = 61,
  20.     SMALL_CIRCUIT_SHUTTERS_CLOSE = 55,
  21.     BIG_CIRCUIT_SHUTTERS_OPEN = 81,
  22.     BIG_CIRCUIT_SHUTTERS_CLOSE = 75,
  23.     V_HYP = 7.2,
  24.     V_ADD = 5.5,
  25.     PWR_CR = 1,
  26.     FMAX = 215000,
  27.     NUM_POWERED_AXLES = 4,
  28.     WHEEL_RADIUS = 0.523095,
  29.     TRANSMITION_RATIO = 77/16,
  30.     RPM_BASED_CURRENT_MULTIPLIER = 4,
  31.     RPM_BASED_CURRENT_ADDITION = -2570,
  32.     GENERATOR_CONSTANT = 1,
  33.     GEN_EXCIT_FIELD_DELTA = 1,
  34.     GENERATOR_RESISTANCE = 1.2,
  35.     engineRPM = 0,
  36.     targetRPM = 0,
  37.     rpmToFullRatio = 0,
  38.     engineStop = false,
  39.     engineStart = false,
  40.     isOn = false,
  41.     spinup = false,
  42.     fuelPump = true,
  43.     waterPump = false,
  44.     oilPump = false,
  45.     oilTargetPressure = 0,
  46.     oilPressure = 0,
  47.     powerControl = 0,
  48.     trainHeatingMode = 0, --0 - off; 1 - summer; 2 - winter
  49.     trainHeatingPower = 0,
  50.     mainFanTargetRPM = 0,
  51.     bigCircuitFanRPM = 0,
  52.     auxiliaryFanTargetRPM = 0,
  53.     smallCircuitFanRPM = 0,
  54.     ambientTemp = 31,
  55.     engineTemp = 50,
  56.     oilTemp = 50,
  57.     bigCircuitCoolerTemp = 50,
  58.     bigCircuitWaterTemp = 50,
  59.     smallCircuitCoolerTemp = 50,
  60.     smallCircuitWaterTemp = 50,
  61.     bigCircuitMeasuredTemp = 50,
  62.     smallCircuitMeasuredTemp = 50,
  63.     realPower = 0,
  64.     apparentPower = 0,
  65.     smallCircuitShuttersRequest = false,
  66.     smallCircuitShutters = false,
  67.     bigCircuitShuttersRequest = false,
  68.     bigCircuitShutters = false,
  69.     generatorExcitationField = 0,
  70.     generatorExcitationCurrent = 0,
  71.     generatorVoltage = 0,
  72.     generatorCurrent = 0,
  73.     tractionEngineVoltage = 0,
  74.     tractionEngineInductedVoltage = 0,
  75.     tractionEngineExcitationCurrent = 0,
  76.     tractionEngineExcitationField = 0,
  77.     tractionEngineArmatureCurrent = 0,
  78.     emitterColor = 0,
  79.     emitterVelocity = 0,
  80.     emitterRate = 0,
  81.     Limit = function(self, v, min, max)
  82.         if v < min then v = min elseif v > max then v = max end
  83.         return v
  84.     end,
  85.     InitTemps = function(coldStart, temperature)
  86.         self.ambientTemp = temperature
  87.         if coldStart then
  88.             self.engineTemp = temperature
  89.             self.oilTemp = temperature
  90.             self.bigCircuitCoolerTemp = temperature
  91.             self.bigCircuitWaterTemp = temperature
  92.             self.smallCircuitCoolerTemp = temperature
  93.             self.smallCircuitWaterTemp = temperature
  94.             self.bigCircuitMeasuredTemp = temperature
  95.             self.smallCircuitMeasuredTemp = temperature
  96.         end
  97.     end,
  98.     toInt = function(self, val)
  99.         if val then
  100.             return(1)
  101.         end
  102.         return(0)
  103.     end,
  104.     Update = function (self, dGameTime, dRealTime)
  105.         --OIL PRESSURE
  106.             if self.engineRPM > 0.1 then
  107.                 self.oilTargetPressure = self.MIN_OIL_PRESSURE + (self.rpmToFullRatio)*(self.MAX_OIL_PRESSURE-self.MIN_OIL_PRESSURE)
  108.             elseif self.oilPump then
  109.                 self.oilTargetPressure = math.min(self.MIN_OIL_PRESSURE+0.1, self.MAX_OIL_PRESSURE)
  110.             else
  111.                 self.oilTargetPressure = 0
  112.             end
  113.             koef = 0.035
  114.             if self.engineRPM > 300 then
  115.                 koef = 0.05
  116.             end
  117.             if self.oilPressure < self.oilTargetPressure then
  118.                 self.oilPressure = math.min(self.oilTargetPressure, self.oilPressure + koef*dRealTime)
  119.             elseif self.oilPressure > self.oilTargetPressure then
  120.                 self.oilPressure = math.max(self.oilTargetPressure, self.oilPressure - koef/2*dRealTime)
  121.             end
  122.             self.oilPressure = self:Limit(self.oilPressure, 0, 1.5)
  123.        
  124.         --ENGINE UPDATE
  125.             if self.engineStart and not self.isOn  then
  126.                 --self.spinup = true
  127.                 self.isOn = true
  128.                 --self.engineRPM = math.max(self.engineRPM, 0.35*(IDLE_RPM))
  129.             end
  130.             --self.spinup = (self.spinup and not self.engineStop and self.engineRPM < self.IDLE_RPM)
  131.             self.isOn = (self.isOn and not self.engineStop and self.oilPressure > self.MIN_OIL_PRESSURE)
  132.  
  133.         --OUTPUT FORCE CALCULATION
  134.             availablePower = math.max(self.MAX_GENERATOR_POWER - self.trainHeatingPower, 0)
  135.             targetPower = self.MAX_GENERATOR_POWER*self.powerControl
  136.             generatedPower = 0
  137.             if self.targetRPM > 0 then
  138.                 generatedPower = targetPower * (self.engineRPM/self.targetRPM)
  139.             end
  140.             genPowerToFullRatio = generatedPower/(targetPower)
  141.             generatedPower = math.min(generatedPower,availablePower)
  142.  
  143.             if self.generatorExcitationCurrent > self.generatorExcitationField+0.1 then
  144.                 self.generatorExcitationField = self.generatorExcitationField + math.sqrt(self.generatorExcitationCurrent-self.generatorExcitationField)*dRealTime*self.GEN_EXCIT_FIELD_DELTA
  145.             elseif self.generatorExcitationField > self.generatorExcitationCurrent+0.1 then
  146.                 self.generatorExcitationField = self.generatorExcitationField + math.sqrt(self.generatorExcitationField-self.generatorExcitationCurrent)*dRealTime*self.GEN_EXCIT_FIELD_DELTA
  147.             else
  148.                 self.generatorExcitationField = self.generatorExcitationCurrent
  149.             end
  150.             generatedVoltage = self.GENERATOR_CONSTANT * self.generatorExcitationField * (math.pi*self.engineRPM/30)
  151.             self.generatorVoltage = generatedVoltage - self.generatorCurrent * self.GENERATOR_RESISTANCE
  152.             tractiveForce = generatedPower/Call("GetSpeed")
  153.  
  154.             -- if self.isOn and self.powerControl > 0 then
  155.             --     if Call("GetSpeed") < self.V_HYP * (self.availablePower/targetPower) then
  156.             --         tractiveForce = (self.FMAX-((self.FMAX - 1000*targetPower/(self.V_HYP+self.V_ADD))*(Call("GetSpeed")/self.V_HYP))/self.PWR_CR)*genPowerToFullRatio
  157.             --     else
  158.             --         tractiveForce = 1000*generatedPower/(Call("GetSpeed")+self.V_ADD)/self.PWR_CR
  159.             --     end
  160.             -- end
  161.  
  162.             -- wheelForce = tractiveForce / self.NUM_POWERED_AXLES
  163.             -- wheelMoment = wheelForce * self.WHEEL_RADIUS
  164.             -- engineMoment = wheelMoment / self.TRANSMITION_RATIO
  165.  
  166.             self.apparentPower = self.realPower + 0.15 * self.rpmToFullRatio * self.MAX_ENGINE_POWER
  167.  
  168.         --REVOLUTIONS CALCULATION
  169.             self.targetRPM = 0
  170.             if self.isOn and self.fuelPump then
  171.                 self.targetRPM = self.IDLE_RPM + self.powerControl*(self.MAX_RPM-self.IDLE_RPM)
  172.                 if self.trainHeatingMode == 2 then
  173.                     self.targetRPM = math.max(self.targetRPM, math.min(self.MAX_RPM, self.HEATING_RPM_W))
  174.                 elseif self.trainHeatingMode == 1 then
  175.                     self.targetRPM = math.max(self.targetRPM, math.min(self.MAX_RPM, self.HEATING_RPM_S))
  176.                 end
  177.                 self.emitterColor = 1-self:Limit(0.07 + 0.00583*(self.targetRPM-self.engineRPM), 0, 1)*0.9
  178.             else
  179.                 self.targetRPM = 0
  180.                 self.emitterColor = 0
  181.             end
  182.  
  183.             if self.targetRPM ~= self.engineRPM then
  184.                 startupKoef = self.Limit(self.engineRPM/self.IDLE_RPM,0.2,1)
  185.                 if self.targetRPM > self.engineRPM then
  186.                     self.engineRPM = math.min(self.engineRPM + 60*dRealTime/self.RPM_AIM*startupKoef, self.targetRPM)
  187.                 elseif self.targetRPM < self.engineRPM then
  188.                     self.engineRPM = math.max(self.engineRPM - 120*dRealTime/self.RPM_AIM, self.targetRPM)
  189.                 end
  190.                 if math.abs(self.engineRPM - self.targetRPM) < 0.1 then
  191.                     self.engineRPM = self.targetRPM
  192.                 end
  193.             end
  194.             self.rpmToFullRatio = self.engineRPM/self.MAX_RPM
  195.  
  196.             if self.isOn then
  197.                 self.bigCircuitFanRPM = self.bigCircuitFanRPM + self:Limit(self.mainFanTargetRPM - self.bigCircuitFanRPM, -100, 50)*dRealTime
  198.                 self.smallCircuitFanRPM = self.smallCircuitFanRPM + self:Limit(self.auxiliaryFanTargetRPM - self.smallCircuitFanRPM, -100, 50)*dRealTime
  199.             else
  200.                 self.bigCircuitFanRPM = self.bigCircuitFanRPM * math.max(0, 1-self.bigCircuitFanRPM*dRealTime)
  201.                 self.smallCircuitFanRPM = self.smallCircuitFanRPM * math.max(0, 1-self.smallCircuitFanRPM*dRealTime)
  202.             end
  203.  
  204.         --ENGINE HEAT
  205.             qs = 44700
  206.             engineHeatCapacity = 11000
  207.             waterHeatCapacity = 4.189
  208.             oilHeatCapacity = 1.885
  209.             minHeatLoss = 400
  210.             maxHeatLoss = 4000
  211.  
  212.             heatLossFactor = minHeatLoss+(self.rpmToFullRatio*(maxHeatLoss-minHeatLoss))
  213.  
  214.             waterFlowFactor = self:toInt(self.isOn)*heatLossFactor+self:toInt(self.waterPump)*1000+self:toInt(not self.isOn)*200
  215.  
  216.             dieselPower = self.rpmToFullRatio * self.MAX_ENGINE_POWER
  217.  
  218.             generatedEnergy = (0.21*dieselPower+12)/3600
  219.             usedEnergy = (dieselPower/950)+self.trainHeatingPower+70
  220.             generatedHeat = self:toInt(self.isOn)*(qs*generatedEnergy-usedEnergy)
  221.             Call("SetControlValue", "generovaneTeploMotoru", 0, generatedHeat)
  222.             remainedHeat = generatedHeat - (self.ENGINE_TO_BIG_CIRCUIT_KOEF * (self.engineTemp - self.bigCircuitCoolerTemp)) - (self.ENGINE_TO_AMBIENT_KOEF * (self.engineTemp - self.ambientTemp))
  223.             Call("SetControlValue", "zbyleTeploMotoru", 0, remainedHeat)
  224.  
  225.             dEngineTemperature = remainedHeat/engineHeatCapacity
  226.             Call("SetControlValue", "dTeplotaMotoru", 0, dEngineTemperature)
  227.             self.engineTemp = self.engineTemp + dEngineTemperature*dRealTime
  228.  
  229.             dOilTemperature = ((self.ENGINE_TO_OIL_KOEF * (self.engineTemp - self.oilTemp)) - (self.OIL_TO_SMALL_CIRCUIT_WATER_KOEF * (self.oilTemp - self.smallCircuitCoolerTemp)))/(heatLossFactor*oilHeatCapacity)
  230.             self.oilTemp = self.oilTemp + dOilTemperature*dRealTime
  231.  
  232.             self.smallCircuitShuttersRequest = self.smallCircuitMeasuredTemp > self.SMALL_CIRCUIT_SHUTTERS_OPEN or (self.smallCircuitMeasuredTemp > self.SMALL_CIRCUIT_SHUTTERS_CLOSE and self.smallCircuitShuttersRequest)
  233.             self.auxiliaryFanTargetRPM = self:toInt(self.smallCircuitShuttersRequest)*1200
  234.             smallCircuitSpecificDissipatedHeat = self.SMALL_CIRCUIT_TO_AMBIENT_KOEF * (0.3+0.7*self:toInt(self.smallCircuitShutters)) * self.smallCircuitFanRPM + self.SMALL_CIRCUIT_TO_AMBIENT_MOVING_KOEF * (0.3+0.7*self:toInt(self.smallCircuitShutters)) * Call("GetSpeed") + 2
  235.             Call("SetControlValue", "MVOmerneTeplo", 0, smallCircuitSpecificDissipatedHeat)
  236.             dOilExchangedEnergy = (self.OIL_TO_SMALL_CIRCUIT_WATER_KOEF * (self.oilTemp - self.smallCircuitCoolerTemp))/(waterFlowFactor*waterHeatCapacity)
  237.             Call("SetControlValue", "MVOodOleje", 0, dOilExchangedEnergy)
  238.             smallCircuitDissipatedHeat = -smallCircuitSpecificDissipatedHeat * (self.smallCircuitCoolerTemp - self.ambientTemp)
  239.             Call("SetControlValue", "MVOvyzareneTeplo", 0, smallCircuitDissipatedHeat)
  240.             dSmallCircuitDissipatedEnergy = smallCircuitDissipatedHeat/(waterFlowFactor*waterHeatCapacity)
  241.             Call("SetControlValue", "MVOvyzarenaEnergie", 0, dSmallCircuitDissipatedEnergy)
  242.             smallCircuitWatterLostTemp = self.smallCircuitWaterTemp + dSmallCircuitDissipatedEnergy*dRealTime
  243.             self.smallCircuitWaterTemp = smallCircuitWatterLostTemp + dOilExchangedEnergy*dRealTime
  244.             self.smallCircuitCoolerTemp = 0.5 * (self.smallCircuitWaterTemp + smallCircuitWatterLostTemp)
  245.             self.smallCircuitMeasuredTemp = self.smallCircuitWaterTemp
  246.  
  247.             self.bigCircuitShuttersRequest = self.bigCircuitMeasuredTemp > self.BIG_CIRCUIT_SHUTTERS_OPEN or (self.bigCircuitMeasuredTemp > self.BIG_CIRCUIT_SHUTTERS_CLOSE and self.bigCircuitShuttersRequest)
  248.             self.mainFanTargetRPM = self:toInt(self.bigCircuitShuttersRequest)*1200
  249.             bigCircuitSpecificDissipatedHeat = self.BIG_CIRCUIT_TO_AMBIENT_KOEF * (0.3+0.7*self:toInt(self.bigCircuitShutters)) * self.bigCircuitFanRPM + self.BIG_CIRCUIT_TO_AMBIENT_MOVING_KOEF * (0.3+0.7*self:toInt(self.bigCircuitShutters)) * Call("GetSpeed") + 5
  250.             Call("SetControlValue", "VVOmerneTeplo", 0, bigCircuitSpecificDissipatedHeat)
  251.             dEngineExchangedEnergy = (self.ENGINE_TO_BIG_CIRCUIT_KOEF * (self.engineTemp - self.bigCircuitCoolerTemp))/(waterFlowFactor*waterHeatCapacity)
  252.             Call("SetControlValue", "VVOodMotoru", 0, dEngineExchangedEnergy)
  253.             bigCircuitDissipatedHeat = -bigCircuitSpecificDissipatedHeat * (self.bigCircuitCoolerTemp - self.ambientTemp)
  254.             Call("SetControlValue", "VVOvyzareneTeplo", 0, bigCircuitDissipatedHeat)
  255.             dBigCircuitDissipatedEnergy = bigCircuitDissipatedHeat/(waterFlowFactor*waterHeatCapacity)
  256.             Call("SetControlValue", "VVOvyzarenaEnergie", 0, dBigCircuitDissipatedEnergy)
  257.             bigCircuitWatterLostTemp = self.bigCircuitWaterTemp + dBigCircuitDissipatedEnergy*dRealTime
  258.             self.bigCircuitWaterTemp = bigCircuitWatterLostTemp + dEngineExchangedEnergy*dRealTime
  259.             self.bigCircuitCoolerTemp = 0.5 * (self.bigCircuitWaterTemp + bigCircuitWatterLostTemp)
  260.             self.bigCircuitMeasuredTemp = self.bigCircuitWaterTemp
  261.  
  262.         --SMOKE GENERATION
  263.             if self.targetRPM > 0 then
  264.                 if self.engineRPM < self.IDLE_RPM then
  265.                     self.emitterVelocity = math.max(((100-math.min(self.engineRPM,100))/30)^2,3)
  266.                 else
  267.                     self.emitterVelocity = 3*self.engineRPM/self.targetRPM
  268.                 end
  269.             else
  270.                 self.emitterVelocity = 0
  271.             end
  272.  
  273.             if self.engineRPM^2/(50+0.2*self.engineRPM) > self.IDLE_RPM then
  274.                 self.emitterRate = self:Limit(DIESEL.engineRPM/DIESEL.targetRPM/10-0.02,0.02,0.1)
  275.             else
  276.                 self.emitterRate = math.max(5/DIESEL.engineRPM,0.02)
  277.             end
  278.     end
  279. }
RAW Paste Data