From 86b0c1e817a366d71d56f7cbc757fe723501cd3f Mon Sep 17 00:00:00 2001 From: peternewell Date: Fri, 19 May 2023 17:27:19 +1000 Subject: [PATCH 01/27] Adjust Brake Force to use Brake Shoe Force --- .../Simulation/RollingStocks/MSTSWagon.cs | 11 ++++++++++- .../Simulation/RollingStocks/TrainCar.cs | 14 ++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs index feabfecd99..5200e83168 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs @@ -597,7 +597,14 @@ public virtual void LoadFromWagFile(string wagFilePath) // Initialise key wagon parameters MassKG = InitialMassKG; MaxHandbrakeForceN = InitialMaxHandbrakeForceN; - MaxBrakeForceN = InitialMaxBrakeForceN; + if (MaxBrakeShoeForceN != 0) + { + MaxBrakeForceN = MaxBrakeShoeForceN; + } + else + { + MaxBrakeForceN = InitialMaxBrakeForceN; + } CentreOfGravityM = InitialCentreOfGravityM; if (FreightAnimations != null) @@ -1129,6 +1136,7 @@ public virtual void Parse(string lowercasetoken, STFReader stf) case "wagon(ortsbrakeshoefriction": BrakeShoeFrictionFactor = new Interpolator(stf); break; case "wagon(maxhandbrakeforce": InitialMaxHandbrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break; case "wagon(maxbrakeforce": InitialMaxBrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break; + case "wagon(maxbrakeshoebrakeforce": MaxBrakeShoeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break; case "wagon(ortswheelbrakeslideprotection": // stf.MustMatch("("); var brakeslideprotection = stf.ReadFloatBlock(STFReader.UNITS.None, null); @@ -1504,6 +1512,7 @@ public virtual void Copy(MSTSWagon copy) InitialMaxBrakeForceN = copy.InitialMaxBrakeForceN; InitialMaxHandbrakeForceN = copy.InitialMaxHandbrakeForceN; MaxBrakeForceN = copy.MaxBrakeForceN; + MaxBrakeShoeForceN = copy.MaxBrakeShoeForceN; MaxHandbrakeForceN = copy.MaxHandbrakeForceN; WindowDeratingFactor = copy.WindowDeratingFactor; DesiredCompartmentTempSetpointC = copy.DesiredCompartmentTempSetpointC; diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs index ec545107ea..4674a1f9f5 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs @@ -210,8 +210,9 @@ public static Interpolator SteamHeatBoilerFuelUsageGalukpH() public float MaxHandbrakeForceN; public float MaxBrakeForceN = 89e3f; + public float MaxBrakeShoeForceN; public float InitialMaxHandbrakeForceN; // Initial force when agon initialised - public float InitialMaxBrakeForceN = 89e3f; // Initial force when agon initialised + public float InitialMaxBrakeForceN = 89e3f; // Initial force when wagon initialised // Coupler Animation public AnimatedCoupler FrontCoupler = new AnimatedCoupler(); @@ -959,12 +960,21 @@ public virtual void UpdateBrakeSlideCalculation() float UserFriction = GetUserBrakeShoeFrictionFactor(); float ZeroUserFriction = GetZeroUserBrakeShoeFrictionFactor(); float AdhesionMultiplier = Simulator.Settings.AdhesionFactor / 100.0f; // User set adjustment factor - convert to a factor where 100% = no change to adhesion + BrakeShoeCoefficientFrictionAdjFactor = 1.0f; + BrakeShoeRetardCoefficientFrictionAdjFactor = 1.0f; + BrakeShoeCoefficientFriction = 1.0f; // This section calculates an adjustment factor for the brake force dependent upon the "base" (zero speed) friction value. //For a user defined case the base value is the zero speed value from the curve entered by the user. // For a "default" case where no user data has been added to the WAG file, the base friction value has been assumed to be 0.2, thus maximum value of 20% applied. - if (UserFriction != 0) // User defined friction has been applied in WAG file - Assume MaxBrakeForce is correctly set in the WAG, so no adjustment required + if (UserFriction != 0 && MaxBrakeShoeForceN != 0) // Assume user has set up brakeshoe force and brakeshoe CoF + { + BrakeShoeCoefficientFrictionAdjFactor = UserFriction * AdhesionMultiplier; + BrakeShoeRetardCoefficientFrictionAdjFactor = BrakeShoeCoefficientFrictionAdjFactor; + BrakeShoeCoefficientFriction = UserFriction * AdhesionMultiplier; // For display purposes on HUD + } + else if (UserFriction != 0) // User defined friction has been applied in WAG file - Assume MaxBrakeForce is correctly set in the WAG, so no adjustment required { BrakeShoeCoefficientFrictionAdjFactor = UserFriction / ZeroUserFriction * AdhesionMultiplier; // Factor calculated by normalising zero speed value on friction curve applied in WAG file BrakeShoeRetardCoefficientFrictionAdjFactor = UserFriction / ZeroUserFriction * AdhesionMultiplier; From 366c96e4d9d99f859abf82feec3594695a6df459 Mon Sep 17 00:00:00 2001 From: peternewell Date: Fri, 19 May 2023 17:38:01 +1000 Subject: [PATCH 02/27] Correct typing error --- Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs index 5200e83168..4b12053c8f 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs @@ -1136,7 +1136,7 @@ public virtual void Parse(string lowercasetoken, STFReader stf) case "wagon(ortsbrakeshoefriction": BrakeShoeFrictionFactor = new Interpolator(stf); break; case "wagon(maxhandbrakeforce": InitialMaxHandbrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break; case "wagon(maxbrakeforce": InitialMaxBrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break; - case "wagon(maxbrakeshoebrakeforce": MaxBrakeShoeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break; + case "wagon(ortsmaxbrakeshoeforce": MaxBrakeShoeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break; case "wagon(ortswheelbrakeslideprotection": // stf.MustMatch("("); var brakeslideprotection = stf.ReadFloatBlock(STFReader.UNITS.None, null); From 270252005ac5725e10af1762fc99f887a4011a32 Mon Sep 17 00:00:00 2001 From: peternewell Date: Sun, 21 May 2023 16:14:53 +1000 Subject: [PATCH 03/27] Allow for Brake shoe force in dynamic load operation. --- .../Simulation/RollingStocks/MSTSWagon.cs | 20 ++++++++++++++----- .../SubSystems/FreightAnimations.cs | 9 +++++++++ .../Simulation/RollingStocks/TrainCar.cs | 4 ++-- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs index 4b12053c8f..7d455896ea 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs @@ -676,7 +676,11 @@ public virtual void LoadFromWagFile(string wagFilePath) LoadEmptyWagonFrontalAreaM2 = WagonFrontalAreaM2; } - if (FreightAnimations.EmptyMaxBrakeForceN > 0) + if (FreightAnimations.EmptyMaxBrakeShoeForceN > 0) + { + LoadEmptyMaxBrakeForceN = FreightAnimations.EmptyMaxBrakeShoeForceN; + } + else if (FreightAnimations.EmptyMaxBrakeForceN > 0) { LoadEmptyMaxBrakeForceN = FreightAnimations.EmptyMaxBrakeForceN; } @@ -752,8 +756,11 @@ public virtual void LoadFromWagFile(string wagFilePath) LoadFullWagonFrontalAreaM2 = WagonFrontalAreaM2; } - - if (FreightAnimations.FullPhysicsStaticOne.FullStaticMaxBrakeForceN > 0) + if (FreightAnimations.FullPhysicsStaticOne.FullStaticMaxBrakeShoeForceN > 0) + { + LoadFullMaxBrakeForceN = FreightAnimations.FullPhysicsStaticOne.FullStaticMaxBrakeShoeForceN; + } + else if (FreightAnimations.FullPhysicsStaticOne.FullStaticMaxBrakeForceN > 0) { LoadFullMaxBrakeForceN = FreightAnimations.FullPhysicsStaticOne.FullStaticMaxBrakeForceN; } @@ -839,8 +846,11 @@ public virtual void LoadFromWagFile(string wagFilePath) LoadFullWagonFrontalAreaM2 = WagonFrontalAreaM2; } - - if (FreightAnimations.FullPhysicsContinuousOne.FullMaxBrakeForceN > 0) + if (FreightAnimations.FullPhysicsContinuousOne.FullMaxBrakeShoeForceN > 0) + { + LoadFullMaxBrakeForceN = FreightAnimations.FullPhysicsContinuousOne.FullMaxBrakeShoeForceN; + } + else if (FreightAnimations.FullPhysicsContinuousOne.FullMaxBrakeForceN > 0) { LoadFullMaxBrakeForceN = FreightAnimations.FullPhysicsContinuousOne.FullMaxBrakeForceN; } diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/FreightAnimations.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/FreightAnimations.cs index 1da8bb1d97..ff5a3a8176 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/FreightAnimations.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/FreightAnimations.cs @@ -67,6 +67,7 @@ public class FreightAnimations public float EmptyORTSWagonFrontalAreaM2 = -9999; public float EmptyORTSDavisDragConstant = -9999; public float EmptyMaxBrakeForceN = -9999; + public float EmptyMaxBrakeShoeForceN = -9999; public float EmptyMaxHandbrakeForceN = -9999; public float EmptyCentreOfGravityM_Y = -9999; // get centre of gravity after adjusted for freight animation public bool ContinuousFreightAnimationsPresent = false; // Flag to indicate that a continuous freight animation is present @@ -104,6 +105,7 @@ public FreightAnimations(STFReader stf, MSTSWagon wagon) new STFReader.TokenProcessor("emptyortswagonfrontalarea", ()=>{ EmptyORTSWagonFrontalAreaM2 = stf.ReadFloatBlock(STFReader.UNITS.AreaDefaultFT2, -1); }), new STFReader.TokenProcessor("emptyortsdavisdragconstant", ()=>{ EmptyORTSDavisDragConstant = stf.ReadFloatBlock(STFReader.UNITS.Any, -1); }), new STFReader.TokenProcessor("emptymaxbrakeforce", ()=>{ EmptyMaxBrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, -1); }), + new STFReader.TokenProcessor("emptymaxbrakeshoeforce", ()=>{ EmptyMaxBrakeShoeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, -1); }), new STFReader.TokenProcessor("emptymaxhandbrakeforce", ()=>{ EmptyMaxHandbrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, -1); }), new STFReader.TokenProcessor("emptycentreofgravity_y", ()=>{ EmptyCentreOfGravityM_Y = stf.ReadFloatBlock(STFReader.UNITS.Distance, -1); }), new STFReader.TokenProcessor("freightanimcontinuous", ()=> @@ -285,6 +287,7 @@ public FreightAnimations(FreightAnimations copyFACollection, MSTSWagon wagon) EmptyORTSWagonFrontalAreaM2 = copyFACollection.EmptyORTSWagonFrontalAreaM2; EmptyORTSDavisDragConstant = copyFACollection.EmptyORTSDavisDragConstant; EmptyMaxBrakeForceN = copyFACollection.EmptyMaxBrakeForceN; + EmptyMaxBrakeShoeForceN = copyFACollection.EmptyMaxBrakeShoeForceN; EmptyMaxHandbrakeForceN = copyFACollection.EmptyMaxHandbrakeForceN; EmptyCentreOfGravityM_Y = copyFACollection.EmptyCentreOfGravityM_Y; ContinuousFreightAnimationsPresent = copyFACollection.ContinuousFreightAnimationsPresent; @@ -982,6 +985,7 @@ public class FreightAnimationContinuous : FreightAnimation public float FullORTSWagonFrontalAreaM2 = -9999; public float FullORTSDavisDragConstant = -9999; public float FullMaxBrakeForceN = -9999; + public float FullMaxBrakeShoeForceN = -9999; public float FullMaxHandbrakeForceN = -9999; public float FullCentreOfGravityM_Y = -9999; // get centre of gravity after adjusted for freight animation @@ -1008,6 +1012,7 @@ public FreightAnimationContinuous(STFReader stf, MSTSWagon wagon) new STFReader.TokenProcessor("fullortswagonfrontalarea", ()=>{ FullORTSWagonFrontalAreaM2 = stf.ReadFloatBlock(STFReader.UNITS.AreaDefaultFT2, -1); }), new STFReader.TokenProcessor("fullortsdavisdragconstant", ()=>{ FullORTSDavisDragConstant = stf.ReadFloatBlock(STFReader.UNITS.Any, -1); }), new STFReader.TokenProcessor("fullmaxbrakeforce", ()=>{ FullMaxBrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, -1); }), + new STFReader.TokenProcessor("fullmaxbrakeshoeforce", ()=>{ FullMaxBrakeShoeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, -1); }), new STFReader.TokenProcessor("fullmaxhandbrakeforce", ()=>{ FullMaxHandbrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, -1); }), new STFReader.TokenProcessor("fullcentreofgravity_y", ()=>{ FullCentreOfGravityM_Y = stf.ReadFloatBlock(STFReader.UNITS.Distance, -1); }) }); @@ -1036,6 +1041,7 @@ public FreightAnimationContinuous(FreightAnimationContinuous freightAnimContin, FullORTSWagonFrontalAreaM2 = freightAnimContin.FullORTSWagonFrontalAreaM2; FullORTSDavisDragConstant = freightAnimContin.FullORTSDavisDragConstant; FullMaxBrakeForceN = freightAnimContin.FullMaxBrakeForceN; + FullMaxBrakeShoeForceN = freightAnimContin.FullMaxBrakeShoeForceN; FullMaxHandbrakeForceN = freightAnimContin.FullMaxHandbrakeForceN; FullCentreOfGravityM_Y = freightAnimContin.FullCentreOfGravityM_Y; } @@ -1070,6 +1076,7 @@ public enum VisibleFrom public float FullStaticORTSWagonFrontalAreaM2 = -9999; public float FullStaticORTSDavisDragConstant = -9999; public float FullStaticMaxBrakeForceN = -9999; + public float FullStaticMaxBrakeShoeForceN = -9999; public float FullStaticMaxHandbrakeForceN = -9999; public float FullStaticCentreOfGravityM_Y = -9999; // get centre of gravity after adjusted for freight animation @@ -1125,6 +1132,7 @@ public FreightAnimationStatic(STFReader stf) new STFReader.TokenProcessor("fullortswagonfrontalarea", ()=>{ FullStaticORTSWagonFrontalAreaM2 = stf.ReadFloatBlock(STFReader.UNITS.AreaDefaultFT2, -1); }), new STFReader.TokenProcessor("fullortsdavisdragconstant", ()=>{ FullStaticORTSDavisDragConstant = stf.ReadFloatBlock(STFReader.UNITS.Any, -1); }), new STFReader.TokenProcessor("fullmaxbrakeforce", ()=>{ FullStaticMaxBrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, -1); }), + new STFReader.TokenProcessor("fullmaxbrakeshoeforce", ()=>{ FullStaticMaxBrakeShoeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, -1); }), new STFReader.TokenProcessor("fullmaxhandbrakeforce", ()=>{ FullStaticMaxHandbrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, -1); }), new STFReader.TokenProcessor("fullcentreofgravity_y", ()=>{ FullStaticCentreOfGravityM_Y = stf.ReadFloatBlock(STFReader.UNITS.Distance, -1); }) }); @@ -1150,6 +1158,7 @@ public FreightAnimationStatic(FreightAnimationStatic freightAnimStatic) FullStaticORTSWagonFrontalAreaM2 = freightAnimStatic.FullStaticORTSWagonFrontalAreaM2; FullStaticORTSDavisDragConstant = freightAnimStatic.FullStaticORTSDavisDragConstant; FullStaticMaxBrakeForceN = freightAnimStatic.FullStaticMaxBrakeForceN; + FullStaticMaxBrakeShoeForceN = freightAnimStatic.FullStaticMaxBrakeShoeForceN; FullStaticMaxHandbrakeForceN = freightAnimStatic.FullStaticMaxHandbrakeForceN; FullStaticCentreOfGravityM_Y = freightAnimStatic.FullStaticCentreOfGravityM_Y; } diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs index 4674a1f9f5..d251bbba5c 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs @@ -210,9 +210,9 @@ public static Interpolator SteamHeatBoilerFuelUsageGalukpH() public float MaxHandbrakeForceN; public float MaxBrakeForceN = 89e3f; - public float MaxBrakeShoeForceN; + public float MaxBrakeShoeForceN; // This is the force applied to the brake shoe, hence it will be decreased by CoF to give force applied to the wheel public float InitialMaxHandbrakeForceN; // Initial force when agon initialised - public float InitialMaxBrakeForceN = 89e3f; // Initial force when wagon initialised + public float InitialMaxBrakeForceN = 89e3f; // Initial force when wagon initialised, this is the force on the wheel, ie after the brake shoe. // Coupler Animation public AnimatedCoupler FrontCoupler = new AnimatedCoupler(); From 8b4e134fd45c9f11ca94c2304a26fda05b96cf56 Mon Sep 17 00:00:00 2001 From: peternewell Date: Sun, 21 May 2023 19:32:01 +1000 Subject: [PATCH 04/27] Correct issue reading brake shoe force --- .../Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs | 6 +++--- Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs index 7d455896ea..2e8baef452 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs @@ -85,8 +85,7 @@ public class MSTSWagon : TrainCar public bool GenericItem1; public bool GenericItem2; - - Interpolator BrakeShoeFrictionFactor; // Factor of friction for wagon brake shoes + const float WaterLBpUKG = 10.0f; // lbs of water in 1 gal (uk) float TempMassDiffRatio; @@ -596,8 +595,9 @@ public virtual void LoadFromWagFile(string wagFilePath) // Initialise key wagon parameters MassKG = InitialMassKG; + MaxHandbrakeForceN = InitialMaxHandbrakeForceN; - if (MaxBrakeShoeForceN != 0) + if (MaxBrakeShoeForceN != 0 && BrakeShoeFrictionFactor != null) { MaxBrakeForceN = MaxBrakeShoeForceN; } diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs index d251bbba5c..5d1bf3a992 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs @@ -139,6 +139,8 @@ public abstract class TrainCar 0.0f, 31.0f }; + public Interpolator BrakeShoeFrictionFactor; // Factor of friction for wagon brake shoes + public static Interpolator SteamHeatBoilerWaterUsageGalukpH() { return new Interpolator(SteamUsageLbpH, WaterUsageGalukpH); @@ -968,7 +970,7 @@ public virtual void UpdateBrakeSlideCalculation() //For a user defined case the base value is the zero speed value from the curve entered by the user. // For a "default" case where no user data has been added to the WAG file, the base friction value has been assumed to be 0.2, thus maximum value of 20% applied. - if (UserFriction != 0 && MaxBrakeShoeForceN != 0) // Assume user has set up brakeshoe force and brakeshoe CoF + if (BrakeShoeFrictionFactor != null && MaxBrakeShoeForceN != 0) // Assume user has set up brakeshoe force and brakeshoe CoF { BrakeShoeCoefficientFrictionAdjFactor = UserFriction * AdhesionMultiplier; BrakeShoeRetardCoefficientFrictionAdjFactor = BrakeShoeCoefficientFrictionAdjFactor; From 7d81e0a537b9a25fef7e59bfbcfdf22ec97c42a1 Mon Sep 17 00:00:00 2001 From: peternewell Date: Tue, 30 May 2023 14:53:09 +1000 Subject: [PATCH 05/27] Install default CoF curves for Cast Iron and Composte CoF --- .../Simulation/RollingStocks/MSTSWagon.cs | 54 ++---- .../SubSystems/Brakes/MSTS/AirSinglePipe.cs | 20 +- .../SubSystems/Brakes/MSTS/ManualBraking.cs | 20 +- .../Brakes/MSTS/SingleTransferPipe.cs | 7 +- .../Brakes/MSTS/StraightVacuumSinglePipe.cs | 21 +- .../Brakes/MSTS/VacuumSinglePipe.cs | 20 +- .../Simulation/RollingStocks/TrainCar.cs | 179 ++++++++++++------ .../RunActivity/Viewer3D/Popups/HUDWindow.cs | 2 +- 8 files changed, 189 insertions(+), 134 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs index 2e8baef452..34840cb08f 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs @@ -1147,6 +1147,19 @@ public virtual void Parse(string lowercasetoken, STFReader stf) case "wagon(maxhandbrakeforce": InitialMaxHandbrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break; case "wagon(maxbrakeforce": InitialMaxBrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break; case "wagon(ortsmaxbrakeshoeforce": MaxBrakeShoeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break; + case "wagon(ortsbrakeshoetype": + stf.MustMatch("("); + var brakeShoeType = stf.ReadString(); + try + { + BrakeShoeType = (BrakeShoeTypes)Enum.Parse(typeof(BrakeShoeTypes), brakeShoeType); + } + catch + { + STFException.TraceWarning(stf, "Assumed unknown brake shoe type " + brakeShoeType); + } + break; + case "wagon(ortswheelbrakeslideprotection": // stf.MustMatch("("); var brakeslideprotection = stf.ReadFloatBlock(STFReader.UNITS.None, null); @@ -1480,6 +1493,7 @@ public virtual void Copy(MSTSWagon copy) HasPassengerCapacity = copy.HasPassengerCapacity; WagonType = copy.WagonType; WagonSpecialType = copy.WagonSpecialType; + BrakeShoeType = copy.BrakeShoeType; FreightShapeFileName = copy.FreightShapeFileName; FreightAnimMaxLevelM = copy.FreightAnimMaxLevelM; FreightAnimMinLevelM = copy.FreightAnimMinLevelM; @@ -3969,46 +3983,6 @@ public override float GetFilledFraction(uint pickupType) if (FreightAnimations.LoadedOne != null) fraction = FreightAnimations.LoadedOne.LoadPerCent / 100; return fraction; } - - /// - /// Returns the Brake shoe coefficient. - /// - - public override float GetUserBrakeShoeFrictionFactor() - { - var frictionfraction = 0.0f; - if ( BrakeShoeFrictionFactor == null) - { - frictionfraction = 0.0f; - } - else - { - frictionfraction = BrakeShoeFrictionFactor[MpS.ToKpH(AbsSpeedMpS)]; - } - - return frictionfraction; - } - - /// - /// Returns the Brake shoe coefficient at zero speed. - /// - - public override float GetZeroUserBrakeShoeFrictionFactor() - { - var frictionfraction = 0.0f; - if (BrakeShoeFrictionFactor == null) - { - frictionfraction = 0.0f; - } - else - { - frictionfraction = BrakeShoeFrictionFactor[0.0f]; - } - - return frictionfraction; - } - - /// /// Starts a continuous increase in controlled value. diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/AirSinglePipe.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/AirSinglePipe.cs index 8df6254049..97a9bfacfe 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/AirSinglePipe.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/AirSinglePipe.cs @@ -711,23 +711,25 @@ public override void Update(float elapsedClockSeconds) { Car.Train.HUDWagonBrakeCylinderPSI = CylPressurePSI; } - - float f; + if (!Car.BrakesStuck) { - f = Car.MaxBrakeForceN * Math.Min(CylPressurePSI / MaxCylPressurePSI, 1); - if (f < Car.MaxHandbrakeForceN * HandbrakePercent / 100) - f = Car.MaxHandbrakeForceN * HandbrakePercent / 100; + Car.BrakeShoeForceN = Car.MaxBrakeForceN * Math.Min(CylPressurePSI / MaxCylPressurePSI, 1); + if (Car.BrakeShoeForceN < Car.MaxHandbrakeForceN * HandbrakePercent / 100) + Car.BrakeShoeForceN = Car.MaxHandbrakeForceN * HandbrakePercent / 100; } - else f = Math.Max(Car.MaxBrakeForceN, Car.MaxHandbrakeForceN / 2); - Car.BrakeRetardForceN = f * Car.BrakeShoeRetardCoefficientFrictionAdjFactor; // calculates value of force applied to wheel, independent of wheel skid + else Car.BrakeShoeForceN = Math.Max(Car.MaxBrakeForceN, Car.MaxHandbrakeForceN / 2); + + float brakeShoeFriction = Car.GetBrakeShoeFrictionFactor(); + + Car.BrakeRetardForceN = Car.BrakeShoeForceN * brakeShoeFriction; // calculates value of force applied to wheel, independent of wheel skid if (Car.BrakeSkid) // Test to see if wheels are skiding to excessive brake force { - Car.BrakeForceN = f * Car.SkidFriction; // if excessive brakeforce, wheel skids, and loses adhesion + Car.BrakeForceN = Car.BrakeShoeForceN * Car.SkidFriction; // if excessive brakeforce, wheel skids, and loses adhesion } else { - Car.BrakeForceN = f * Car.BrakeShoeCoefficientFrictionAdjFactor; // In advanced adhesion model brake shoe coefficient varies with speed, in simple model constant force applied as per value in WAG file, will vary with wheel skid. + Car.BrakeForceN = Car.BrakeShoeForceN * brakeShoeFriction; // In advanced adhesion model brake shoe coefficient varies with speed, in simple model constant force applied as per value in WAG file, will vary with wheel skid. } // sound trigger checking runs every half second, to avoid the problems caused by the jumping BrakeLine1PressurePSI value, and also saves cpu time :) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/ManualBraking.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/ManualBraking.cs index f3be7f601a..0afe7fbc83 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/ManualBraking.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/ManualBraking.cs @@ -206,22 +206,24 @@ public override void Update(float elapsedClockSeconds) } } - float f; if (!Car.BrakesStuck) { - f = Car.MaxBrakeForceN * Math.Min(BrakeForceFraction, 1); - if (f < Car.MaxHandbrakeForceN * HandbrakePercent / 100) - f = Car.MaxHandbrakeForceN * HandbrakePercent / 100; + Car.BrakeShoeForceN = Car.MaxBrakeForceN * Math.Min(BrakeForceFraction, 1); + if (Car.BrakeShoeForceN < Car.MaxHandbrakeForceN * HandbrakePercent / 100) + Car.BrakeShoeForceN = Car.MaxHandbrakeForceN * HandbrakePercent / 100; } - else f = Math.Max(Car.MaxBrakeForceN, Car.MaxHandbrakeForceN / 2); - Car.BrakeRetardForceN = f * Car.BrakeShoeRetardCoefficientFrictionAdjFactor; // calculates value of force applied to wheel, independent of wheel skid + else Car.BrakeShoeForceN = Math.Max(Car.MaxBrakeForceN, Car.MaxHandbrakeForceN / 2); + + float brakeShoeFriction = Car.GetBrakeShoeFrictionFactor(); + + Car.BrakeRetardForceN = Car.BrakeShoeForceN * brakeShoeFriction; // calculates value of force applied to wheel, independent of wheel skid if (Car.BrakeSkid) // Test to see if wheels are skiding to excessive brake force { - Car.BrakeForceN = f * Car.SkidFriction; // if excessive brakeforce, wheel skids, and loses adhesion + Car.BrakeForceN = Car.BrakeShoeForceN * Car.SkidFriction; // if excessive brakeforce, wheel skids, and loses adhesion } else { - Car.BrakeForceN = f * Car.BrakeShoeCoefficientFrictionAdjFactor; // In advanced adhesion model brake shoe coefficient varies with speed, in simple model constant force applied as per value in WAG file, will vary with wheel skid. + Car.BrakeForceN = Car.BrakeShoeForceN * brakeShoeFriction; // In advanced adhesion model brake shoe coefficient varies with speed, in simple model constant force applied as per value in WAG file, will vary with wheel skid. } } @@ -395,4 +397,4 @@ public override void PropagateBrakePressure(float elapsedClockSeconds) } -} \ No newline at end of file +} diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/SingleTransferPipe.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/SingleTransferPipe.cs index 83bbab588d..647e060a1b 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/SingleTransferPipe.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/SingleTransferPipe.cs @@ -158,14 +158,17 @@ public override float GetVacResPressurePSI() public override void Update(float elapsedClockSeconds) { BleedOffValveOpen = false; - Car.BrakeRetardForceN = ( Car.MaxHandbrakeForceN * HandbrakePercent / 100) * Car.BrakeShoeRetardCoefficientFrictionAdjFactor; // calculates value of force applied to wheel, independent of wheel skid + + float brakeShoeFriction = Car.GetBrakeShoeFrictionFactor(); + + Car.BrakeRetardForceN = ( Car.MaxHandbrakeForceN * HandbrakePercent / 100) * brakeShoeFriction; // calculates value of force applied to wheel, independent of wheel skid if (Car.BrakeSkid) // Test to see if wheels are skiding to excessive brake force { Car.BrakeForceN = (Car.MaxHandbrakeForceN * HandbrakePercent / 100) * Car.SkidFriction; // if excessive brakeforce, wheel skids, and loses adhesion } else { - Car.BrakeForceN = (Car.MaxHandbrakeForceN * HandbrakePercent / 100) * Car.BrakeShoeCoefficientFrictionAdjFactor; // In advanced adhesion model brake shoe coefficient varies with speed, in simple model constant force applied as per value in WAG file, will vary with wheel skid. + Car.BrakeForceN = (Car.MaxHandbrakeForceN * HandbrakePercent / 100) * brakeShoeFriction; // In advanced adhesion model brake shoe coefficient varies with speed, in simple model constant force applied as per value in WAG file, will vary with wheel skid. } } diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/StraightVacuumSinglePipe.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/StraightVacuumSinglePipe.cs index 2a1c365324..72671edfe1 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/StraightVacuumSinglePipe.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/StraightVacuumSinglePipe.cs @@ -128,30 +128,33 @@ public override void Update(float elapsedClockSeconds) } // Adjust braking force as brake cylinder pressure varies. - float f; + if (!Car.BrakesStuck) { float brakecylinderfraction = ((OneAtmospherePSI - CylPressurePSIA) / MaxForcePressurePSI); brakecylinderfraction = MathHelper.Clamp(brakecylinderfraction, 0, 1); - f = Car.MaxBrakeForceN * brakecylinderfraction; + Car.BrakeShoeForceN = Car.MaxBrakeForceN * brakecylinderfraction; - if (f < Car.MaxHandbrakeForceN * HandbrakePercent / 100) - f = Car.MaxHandbrakeForceN * HandbrakePercent / 100; + if (Car.BrakeShoeForceN < Car.MaxHandbrakeForceN * HandbrakePercent / 100) + Car.BrakeShoeForceN = Car.MaxHandbrakeForceN * HandbrakePercent / 100; } else { - f = Math.Max(Car.MaxBrakeForceN, Car.MaxHandbrakeForceN / 2); + Car.BrakeShoeForceN = Math.Max(Car.MaxBrakeForceN, Car.MaxHandbrakeForceN / 2); } - Car.BrakeRetardForceN = f * Car.BrakeShoeRetardCoefficientFrictionAdjFactor; // calculates value of force applied to wheel, independent of wheel skid + + float brakeShoeFriction = Car.GetBrakeShoeFrictionFactor(); + + Car.BrakeRetardForceN = Car.BrakeShoeForceN * brakeShoeFriction; // calculates value of force applied to wheel, independent of wheel skid if (Car.BrakeSkid) // Test to see if wheels are skiding due to excessive brake force { - Car.BrakeForceN = f * Car.SkidFriction; // if excessive brakeforce, wheel skids, and loses adhesion + Car.BrakeForceN = Car.BrakeShoeForceN * Car.SkidFriction; // if excessive brakeforce, wheel skids, and loses adhesion } else { - Car.BrakeForceN = f * Car.BrakeShoeCoefficientFrictionAdjFactor; // In advanced adhesion model brake shoe coefficient varies with speed, in simple odel constant force applied as per value in WAG file, will vary with wheel skid. + Car.BrakeForceN = Car.BrakeShoeForceN * brakeShoeFriction; // In advanced adhesion model brake shoe coefficient varies with speed, in simple odel constant force applied as per value in WAG file, will vary with wheel skid. } // If wagons are not attached to the locomotive, then set wagon BC pressure to same as locomotive in the Train brake line @@ -413,4 +416,4 @@ public override string[] GetDebugStatus(Dictionary + /// Returns the coefficient of friction (CoF) for the brake shoe. For legacy operation, it will be a "representation" of the CoF that will adjust + /// the brake retard force with speed. + /// + + public virtual float GetBrakeShoeFrictionFactor() { - return 0f; + + var frictionfraction = 0.0f; + float AdhesionMultiplier = Simulator.Settings.AdhesionFactor / 100.0f; // User set adjustment factor - convert to a factor where 100% = no change to adhesion + + if (Simulator.UseAdvancedAdhesion && !Simulator.Settings.SimpleControlPhysics && IsPlayerTrain) + { + // Formula 9 and 10 from the paper "Study of the influence of the brake shoe temperature and wheel tread on braking effectiveness" by P Ivanov1, A Khudonogov1, + // E Dulskiy1, N Manuilov1, A Khamnaeva1, A Korsun1, S Treskin is used for the Cast Iron and Hi Friction Composite brake shoe friction curves. + // https://iopscience.iop.org/article/10.1088/1742-6596/1614/1/012086/pdf + + float NewtonsTokNewtons = 0.001f; + float brakeShoeForcekN = NewtonsTokNewtons * BrakeShoeForceN; + + if (BrakeShoeType == BrakeShoeTypes.CastIron) + { + frictionfraction = 0.6f * ((1.6f * brakeShoeForcekN + 100.0f) / (8.0f * brakeShoeForcekN + 100.0f)) * ((AbsSpeedMpS + 100.0f) / (5.0f * AbsSpeedMpS + 100.0f)); + } + else if (BrakeShoeType == BrakeShoeTypes.HiFrictionCompost) + { + frictionfraction = 0.44f * ((0.1f * brakeShoeForcekN + 20.0f) / (0.4f * brakeShoeForcekN + 20.0f)) * ((AbsSpeedMpS + 150.0f) / (2.0f * AbsSpeedMpS + 150.0f)); + } + else if (BrakeShoeType == BrakeShoeTypes.UserDefined) + { + frictionfraction = BrakeShoeFrictionFactor[MpS.ToKpH(AbsSpeedMpS)]; + } + else // default curve - assume that this is legacy stock + { + if (BrakeShoeFrictionFactor != null) // User defined friction has been applied in WAG file, but brake shoe has not be described, hence a legacy condition - Assume MaxBrakeForce is correctly set in the WAG, so no adjustment required + { + + float userFriction = BrakeShoeFrictionFactor[MpS.ToKpH(AbsSpeedMpS)]; + float zeroUserFriction = BrakeShoeFrictionFactor[MpS.ToKpH(0)]; + + frictionfraction = userFriction / zeroUserFriction * AdhesionMultiplier; // Factor calculated by normalising zero speed value on friction curve applied in WAG file + } + else + { + // Base Curtius - Kniffler equation - u = 0.50, all other values are scaled off this formula + float defaultBrakeShoeCoefficientFriction = (7.6f / (MpS.ToKpH(AbsSpeedMpS) + 17.5f) + 0.07f) * AdhesionMultiplier; + + // Assuming that current MaxBrakeForce has been set with an existing Friction CoF of 0.2f, an adjustment factor needs to be developed to reduce + // the MAxBrakeForce by a relative amount. Note force will be higher then ENG file value at low speed and reduce to actual value at higher speeds. + frictionfraction = defaultBrakeShoeCoefficientFriction / 0.2f * AdhesionMultiplier; // Assuming that current MaxBrakeForce has been set with an existing Friction CoF of 0.2f, an adjustment factor needs to be developed to reduce the MAxBrakeForce by a relative amount + } + } + + return frictionfraction; + + } + else + { + frictionfraction = (7.6f / (MpS.ToKpH(AbsSpeedMpS) + 17.5f) + 0.07f); // Base Curtius - Kniffler equation - u = 0.50, all other values are scaled off this formula; // For simple friction use "default" curve + return frictionfraction; + } + } - public virtual float GetZeroUserBrakeShoeFrictionFactor() + /// + /// Returns the coefficient of friction (CoF) of the brake shoe for display on the HuD. + /// For legacy operation, it will be different to the "representation" of the CoF calculated above, and be the actual CoF. + /// + public virtual float GetBrakeShoeFrictionCoefficientHuD() { - return 0f; + var frictionfraction = 0.0f; + float AdhesionMultiplier = Simulator.Settings.AdhesionFactor / 100.0f; // User set adjustment factor - convert to a factor where 100% = no change to adhesion + + if (Simulator.UseAdvancedAdhesion && !Simulator.Settings.SimpleControlPhysics && IsPlayerTrain) + { + // Formula 9 and 10 from the paper "Study of the influence of the brake shoe temperature and wheel tread on braking effectiveness" by P Ivanov1, A Khudonogov1, + // E Dulskiy1, N Manuilov1, A Khamnaeva1, A Korsun1, S Treskin is used for the Cast Iron and Hi Friction Composite brake shoe friction curves. + // https://iopscience.iop.org/article/10.1088/1742-6596/1614/1/012086/pdf + + float NewtonsTokNewtons = 0.001f; + float brakeShoeForcekN = NewtonsTokNewtons * BrakeShoeForceN; + + if (BrakeShoeType == BrakeShoeTypes.CastIron) + { + frictionfraction = 0.6f * ((1.6f * brakeShoeForcekN + 100.0f) / (8.0f * brakeShoeForcekN + 100.0f)) * ((AbsSpeedMpS + 100.0f) / (5.0f * AbsSpeedMpS + 100.0f)); + } + else if (BrakeShoeType == BrakeShoeTypes.HiFrictionCompost) + { + frictionfraction = 0.44f * ((0.1f * brakeShoeForcekN + 20.0f) / (0.4f * brakeShoeForcekN + 20.0f)) * ((AbsSpeedMpS + 150.0f) / (2.0f * AbsSpeedMpS + 150.0f)); + } + else if (BrakeShoeType == BrakeShoeTypes.UserDefined) + { + frictionfraction = BrakeShoeFrictionFactor[MpS.ToKpH(AbsSpeedMpS)]; + } + else // default curve - assume that this is legacy stock + { + if (BrakeShoeFrictionFactor != null) // User defined friction has been applied in WAG file, but brake shoe has not be described, hence a legacy condition - Assume MaxBrakeForce is correctly set in the WAG, so no adjustment required + { + frictionfraction = BrakeShoeFrictionFactor[MpS.ToKpH(AbsSpeedMpS)]; + } + else + { + frictionfraction = (7.6f / (MpS.ToKpH(AbsSpeedMpS) + 17.5f) + 0.07f) * AdhesionMultiplier; // Base Curtius - Kniffler equation - u = 0.50, all other values are scaled off this formula + } + } + + return frictionfraction; + + } + else + { + frictionfraction = (7.6f / (MpS.ToKpH(AbsSpeedMpS) + 17.5f) + 0.07f); // Base Curtius - Kniffler equation - u = 0.50, all other values are scaled off this formula; // For simple friction use "default" curve + return frictionfraction; + } } public virtual void InitializeCarHeatingVariables() diff --git a/Source/RunActivity/Viewer3D/Popups/HUDWindow.cs b/Source/RunActivity/Viewer3D/Popups/HUDWindow.cs index 82ab0736dd..196c88ed83 100644 --- a/Source/RunActivity/Viewer3D/Popups/HUDWindow.cs +++ b/Source/RunActivity/Viewer3D/Popups/HUDWindow.cs @@ -1160,7 +1160,7 @@ void TextPageForceInfo(TableData table) TableSetCell(table, 12, "{0}", FormatStrings.FormatLargeMass(car.MassKG, car.IsMetric, car.IsUK)); TableSetCell(table, 13, "{0:F2}%", -car.CurrentElevationPercent); TableSetCell(table, 14, "{0}", FormatStrings.FormatDistance(car.CurrentCurveRadius, car.IsMetric)); - TableSetCell(table, 15, "{0:F0}%", car.BrakeShoeCoefficientFriction * 100.0f); + TableSetCell(table, 15, "{0:F0}%", car.GetBrakeShoeFrictionCoefficientHuD() * 100.0f); TableSetCell(table, 16, car.HUDBrakeSkid ? Viewer.Catalog.GetString("Yes") : Viewer.Catalog.GetString("No")); TableSetCell(table, 17, "{0} {1}", FormatStrings.FormatTemperature(car.WheelBearingTemperatureDegC, car.IsMetric, false), car.DisplayWheelBearingTemperatureStatus); TableSetCell(table, 18, car.Flipped ? Viewer.Catalog.GetString("Flipped") : ""); From 4e475c28c77838903db5dcb754738ba935af249d Mon Sep 17 00:00:00 2001 From: peternewell Date: Wed, 31 May 2023 14:38:46 +1000 Subject: [PATCH 06/27] Adjust input of MaxBrakeShoeForce --- .../Simulation/RollingStocks/MSTSWagon.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs index 34840cb08f..832a9d1524 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs @@ -597,13 +597,24 @@ public virtual void LoadFromWagFile(string wagFilePath) MassKG = InitialMassKG; MaxHandbrakeForceN = InitialMaxHandbrakeForceN; - if (MaxBrakeShoeForceN != 0 && BrakeShoeFrictionFactor != null) + if (MaxBrakeShoeForceN != 0 && BrakeShoeType != BrakeShoeTypes.Unknown) { MaxBrakeForceN = MaxBrakeShoeForceN; + + if (Simulator.Settings.VerboseConfigurationMessages) + { + Trace.TraceInformation("BrakeShoeType set to {0}, with a MaxBrakeShoeForce of {1}", BrakeShoeType, FormatStrings.FormatForce(MaxBrakeForceN, IsMetric)); + } + } else { MaxBrakeForceN = InitialMaxBrakeForceN; + + if (Simulator.Settings.VerboseConfigurationMessages) + { + Trace.TraceInformation("BrakeShoeType set to {0}, with a MaxBrakeForce of {1}", BrakeShoeType, FormatStrings.FormatForce(MaxBrakeForceN, IsMetric)); + } } CentreOfGravityM = InitialCentreOfGravityM; From d1ddb9873a242ac761e48dfe098d99327dcf46ff Mon Sep 17 00:00:00 2001 From: peternewell Date: Thu, 1 Jun 2023 15:07:31 +1000 Subject: [PATCH 07/27] Correct calculation issue with brake shoe CoF --- .../SubSystems/Brakes/MSTS/AirSinglePipe.cs | 1 + .../SubSystems/Brakes/MSTS/ManualBraking.cs | 1 + .../SubSystems/Brakes/MSTS/SingleTransferPipe.cs | 1 + .../SubSystems/Brakes/MSTS/StraightVacuumSinglePipe.cs | 1 + .../SubSystems/Brakes/MSTS/VacuumSinglePipe.cs | 1 + .../Orts.Simulation/Simulation/RollingStocks/TrainCar.cs | 9 +++++---- Source/RunActivity/Viewer3D/Popups/HUDWindow.cs | 2 +- 7 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/AirSinglePipe.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/AirSinglePipe.cs index 97a9bfacfe..f227e9bf6a 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/AirSinglePipe.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/AirSinglePipe.cs @@ -721,6 +721,7 @@ public override void Update(float elapsedClockSeconds) else Car.BrakeShoeForceN = Math.Max(Car.MaxBrakeForceN, Car.MaxHandbrakeForceN / 2); float brakeShoeFriction = Car.GetBrakeShoeFrictionFactor(); + Car.HuDBrakeShoeFriction = Car.GetBrakeShoeFrictionCoefficientHuD(); Car.BrakeRetardForceN = Car.BrakeShoeForceN * brakeShoeFriction; // calculates value of force applied to wheel, independent of wheel skid if (Car.BrakeSkid) // Test to see if wheels are skiding to excessive brake force diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/ManualBraking.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/ManualBraking.cs index 0afe7fbc83..70e3712508 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/ManualBraking.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/ManualBraking.cs @@ -215,6 +215,7 @@ public override void Update(float elapsedClockSeconds) else Car.BrakeShoeForceN = Math.Max(Car.MaxBrakeForceN, Car.MaxHandbrakeForceN / 2); float brakeShoeFriction = Car.GetBrakeShoeFrictionFactor(); + Car.HuDBrakeShoeFriction = Car.GetBrakeShoeFrictionCoefficientHuD(); Car.BrakeRetardForceN = Car.BrakeShoeForceN * brakeShoeFriction; // calculates value of force applied to wheel, independent of wheel skid if (Car.BrakeSkid) // Test to see if wheels are skiding to excessive brake force diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/SingleTransferPipe.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/SingleTransferPipe.cs index 647e060a1b..56f1485160 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/SingleTransferPipe.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/SingleTransferPipe.cs @@ -160,6 +160,7 @@ public override void Update(float elapsedClockSeconds) BleedOffValveOpen = false; float brakeShoeFriction = Car.GetBrakeShoeFrictionFactor(); + Car.HuDBrakeShoeFriction = Car.GetBrakeShoeFrictionCoefficientHuD(); Car.BrakeRetardForceN = ( Car.MaxHandbrakeForceN * HandbrakePercent / 100) * brakeShoeFriction; // calculates value of force applied to wheel, independent of wheel skid if (Car.BrakeSkid) // Test to see if wheels are skiding to excessive brake force diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/StraightVacuumSinglePipe.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/StraightVacuumSinglePipe.cs index 72671edfe1..d831d08be3 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/StraightVacuumSinglePipe.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/StraightVacuumSinglePipe.cs @@ -146,6 +146,7 @@ public override void Update(float elapsedClockSeconds) } float brakeShoeFriction = Car.GetBrakeShoeFrictionFactor(); + Car.HuDBrakeShoeFriction = Car.GetBrakeShoeFrictionCoefficientHuD(); Car.BrakeRetardForceN = Car.BrakeShoeForceN * brakeShoeFriction; // calculates value of force applied to wheel, independent of wheel skid if (Car.BrakeSkid) // Test to see if wheels are skiding due to excessive brake force diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/VacuumSinglePipe.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/VacuumSinglePipe.cs index cbc9592f6a..eccac81e6e 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/VacuumSinglePipe.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/VacuumSinglePipe.cs @@ -581,6 +581,7 @@ public override void Update(float elapsedClockSeconds) else Car.BrakeShoeForceN = Math.Max(Car.MaxBrakeForceN, Car.MaxHandbrakeForceN / 2); float brakeShoeFriction = Car.GetBrakeShoeFrictionFactor(); + Car.HuDBrakeShoeFriction = Car.GetBrakeShoeFrictionCoefficientHuD(); Car.BrakeRetardForceN = Car.BrakeShoeForceN * brakeShoeFriction; // calculates value of force applied to wheel, independent of wheel skid if (Car.BrakeSkid) // Test to see if wheels are skiding due to excessive brake force diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs index 63d5422489..ae0b0dfccc 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs @@ -275,6 +275,7 @@ public float ConvectionFactor float BrakeWheelTreadForceN; // The retarding force apparent on the tread of the wheel float WagonBrakeAdhesiveForceN; // The adhesive force existing on the wheels of the wagon public float SkidFriction = 0.08f; // Friction if wheel starts skidding - based upon wheel dynamic friction of approx 0.08 + public float HuDBrakeShoeFriction; public float AuxTenderWaterMassKG; // Water mass in auxiliary tender public string AuxWagonType; // Store wagon type for use with auxilary tender calculations @@ -3242,11 +3243,11 @@ public virtual float GetBrakeShoeFrictionFactor() if (BrakeShoeType == BrakeShoeTypes.CastIron) { - frictionfraction = 0.6f * ((1.6f * brakeShoeForcekN + 100.0f) / (8.0f * brakeShoeForcekN + 100.0f)) * ((AbsSpeedMpS + 100.0f) / (5.0f * AbsSpeedMpS + 100.0f)); + frictionfraction = 0.6f * ((1.6f * brakeShoeForcekN + 100.0f) / (8.0f * brakeShoeForcekN + 100.0f)) * ((MpS.ToKpH(AbsSpeedMpS) + 100.0f) / (5.0f * MpS.ToKpH(AbsSpeedMpS) + 100.0f)); } else if (BrakeShoeType == BrakeShoeTypes.HiFrictionCompost) { - frictionfraction = 0.44f * ((0.1f * brakeShoeForcekN + 20.0f) / (0.4f * brakeShoeForcekN + 20.0f)) * ((AbsSpeedMpS + 150.0f) / (2.0f * AbsSpeedMpS + 150.0f)); + frictionfraction = 0.44f * ((0.1f * brakeShoeForcekN + 20.0f) / (0.4f * brakeShoeForcekN + 20.0f)) * ((MpS.ToKpH(AbsSpeedMpS) + 150.0f) / (2.0f * MpS.ToKpH(AbsSpeedMpS) + 150.0f)); } else if (BrakeShoeType == BrakeShoeTypes.UserDefined) { @@ -3304,11 +3305,11 @@ public virtual float GetBrakeShoeFrictionCoefficientHuD() if (BrakeShoeType == BrakeShoeTypes.CastIron) { - frictionfraction = 0.6f * ((1.6f * brakeShoeForcekN + 100.0f) / (8.0f * brakeShoeForcekN + 100.0f)) * ((AbsSpeedMpS + 100.0f) / (5.0f * AbsSpeedMpS + 100.0f)); + frictionfraction = 0.6f * ((1.6f * brakeShoeForcekN + 100.0f) / (8.0f * brakeShoeForcekN + 100.0f)) * ((MpS.ToKpH(AbsSpeedMpS) + 100.0f) / (5.0f * MpS.ToKpH(AbsSpeedMpS) + 100.0f)); } else if (BrakeShoeType == BrakeShoeTypes.HiFrictionCompost) { - frictionfraction = 0.44f * ((0.1f * brakeShoeForcekN + 20.0f) / (0.4f * brakeShoeForcekN + 20.0f)) * ((AbsSpeedMpS + 150.0f) / (2.0f * AbsSpeedMpS + 150.0f)); + frictionfraction = 0.44f * ((0.1f * brakeShoeForcekN + 20.0f) / (0.4f * brakeShoeForcekN + 20.0f)) * ((MpS.ToKpH(AbsSpeedMpS) + 150.0f) / (2.0f * MpS.ToKpH(AbsSpeedMpS) + 150.0f)); } else if (BrakeShoeType == BrakeShoeTypes.UserDefined) { diff --git a/Source/RunActivity/Viewer3D/Popups/HUDWindow.cs b/Source/RunActivity/Viewer3D/Popups/HUDWindow.cs index 196c88ed83..4622d478df 100644 --- a/Source/RunActivity/Viewer3D/Popups/HUDWindow.cs +++ b/Source/RunActivity/Viewer3D/Popups/HUDWindow.cs @@ -1160,7 +1160,7 @@ void TextPageForceInfo(TableData table) TableSetCell(table, 12, "{0}", FormatStrings.FormatLargeMass(car.MassKG, car.IsMetric, car.IsUK)); TableSetCell(table, 13, "{0:F2}%", -car.CurrentElevationPercent); TableSetCell(table, 14, "{0}", FormatStrings.FormatDistance(car.CurrentCurveRadius, car.IsMetric)); - TableSetCell(table, 15, "{0:F0}%", car.GetBrakeShoeFrictionCoefficientHuD() * 100.0f); + TableSetCell(table, 15, "{0:F0}%", car.HuDBrakeShoeFriction * 100.0f); TableSetCell(table, 16, car.HUDBrakeSkid ? Viewer.Catalog.GetString("Yes") : Viewer.Catalog.GetString("No")); TableSetCell(table, 17, "{0} {1}", FormatStrings.FormatTemperature(car.WheelBearingTemperatureDegC, car.IsMetric, false), car.DisplayWheelBearingTemperatureStatus); TableSetCell(table, 18, car.Flipped ? Viewer.Catalog.GetString("Flipped") : ""); From ea7a67f5ebe4ed708552ecac60ec839a4c8fe4f7 Mon Sep 17 00:00:00 2001 From: peternewell Date: Thu, 1 Jun 2023 15:46:25 +1000 Subject: [PATCH 08/27] Correct code factor issues. --- .../Simulation/RollingStocks/MSTSWagon.cs | 1 - .../SubSystems/Brakes/MSTS/ManualBraking.cs | 7 ++++++- .../Orts.Simulation/Simulation/RollingStocks/TrainCar.cs | 9 +-------- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs index 832a9d1524..6b4dadc53f 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs @@ -981,7 +981,6 @@ public virtual void LoadFromWagFile(string wagFilePath) Trace.TraceInformation("Empty Values = Brake {0} Handbrake {1} DavisA {2} DavisB {3} DavisC {4} CoGY {5}", LoadEmptyMaxBrakeForceN, LoadEmptyMaxHandbrakeForceN, LoadEmptyORTSDavis_A, LoadEmptyORTSDavis_B, LoadEmptyORTSDavis_C, LoadEmptyCentreOfGravityM_Y); Trace.TraceInformation("Full Values = Brake {0} Handbrake {1} DavisA {2} DavisB {3} DavisC {4} CoGY {5}", LoadFullMaxBrakeForceN, LoadFullMaxHandbrakeForceN, LoadFullORTSDavis_A, LoadFullORTSDavis_B, LoadFullORTSDavis_C, LoadFullCentreOfGravityM_Y); #endif - } // Determine whether or not to use the Davis friction model. Must come after freight animations are initialized. diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/ManualBraking.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/ManualBraking.cs index 70e3712508..1f534f75c0 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/ManualBraking.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/ManualBraking.cs @@ -210,9 +210,14 @@ public override void Update(float elapsedClockSeconds) { Car.BrakeShoeForceN = Car.MaxBrakeForceN * Math.Min(BrakeForceFraction, 1); if (Car.BrakeShoeForceN < Car.MaxHandbrakeForceN * HandbrakePercent / 100) + { Car.BrakeShoeForceN = Car.MaxHandbrakeForceN * HandbrakePercent / 100; + } + } + else + { + Car.BrakeShoeForceN = Math.Max(Car.MaxBrakeForceN, Car.MaxHandbrakeForceN / 2); } - else Car.BrakeShoeForceN = Math.Max(Car.MaxBrakeForceN, Car.MaxHandbrakeForceN / 2); float brakeShoeFriction = Car.GetBrakeShoeFrictionFactor(); Car.HuDBrakeShoeFriction = Car.GetBrakeShoeFrictionCoefficientHuD(); diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs index ae0b0dfccc..3b9eacf3d9 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs @@ -3220,15 +3220,12 @@ public virtual float GetFilledFraction(uint pickupType) return 0f; } - /// /// Returns the coefficient of friction (CoF) for the brake shoe. For legacy operation, it will be a "representation" of the CoF that will adjust /// the brake retard force with speed. /// - public virtual float GetBrakeShoeFrictionFactor() - { - + { var frictionfraction = 0.0f; float AdhesionMultiplier = Simulator.Settings.AdhesionFactor / 100.0f; // User set adjustment factor - convert to a factor where 100% = no change to adhesion @@ -3257,7 +3254,6 @@ public virtual float GetBrakeShoeFrictionFactor() { if (BrakeShoeFrictionFactor != null) // User defined friction has been applied in WAG file, but brake shoe has not be described, hence a legacy condition - Assume MaxBrakeForce is correctly set in the WAG, so no adjustment required { - float userFriction = BrakeShoeFrictionFactor[MpS.ToKpH(AbsSpeedMpS)]; float zeroUserFriction = BrakeShoeFrictionFactor[MpS.ToKpH(0)]; @@ -3275,14 +3271,12 @@ public virtual float GetBrakeShoeFrictionFactor() } return frictionfraction; - } else { frictionfraction = (7.6f / (MpS.ToKpH(AbsSpeedMpS) + 17.5f) + 0.07f); // Base Curtius - Kniffler equation - u = 0.50, all other values are scaled off this formula; // For simple friction use "default" curve return frictionfraction; } - } /// @@ -3328,7 +3322,6 @@ public virtual float GetBrakeShoeFrictionCoefficientHuD() } return frictionfraction; - } else { From 96e3353ee2084c8e96fb98c4887719328fd58413 Mon Sep 17 00:00:00 2001 From: peternewell Date: Thu, 1 Jun 2023 18:54:52 +1000 Subject: [PATCH 09/27] Add parameter to specify number of brake shoes --- .../Simulation/RollingStocks/MSTSWagon.cs | 13 +++++++++++++ .../Simulation/RollingStocks/TrainCar.cs | 3 ++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs index 6b4dadc53f..7c5b0f851d 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs @@ -616,6 +616,17 @@ public virtual void LoadFromWagFile(string wagFilePath) Trace.TraceInformation("BrakeShoeType set to {0}, with a MaxBrakeForce of {1}", BrakeShoeType, FormatStrings.FormatForce(MaxBrakeForceN, IsMetric)); } } + + // Initialise number of brake shoes per wagon + if (NumberCarBrakeShoes == 0 && WagonType == WagonTypes.Engine) + { + NumberCarBrakeShoes = LocoNumDrvAxles * 4.0f; // Assume 4 brake shoes per axle + } + else if (NumberCarBrakeShoes == 0) + { + NumberCarBrakeShoes = WagonNumAxles * 4.0f; // Assume 4 brake shoes per axle + } + CentreOfGravityM = InitialCentreOfGravityM; if (FreightAnimations != null) @@ -1157,6 +1168,7 @@ public virtual void Parse(string lowercasetoken, STFReader stf) case "wagon(maxhandbrakeforce": InitialMaxHandbrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break; case "wagon(maxbrakeforce": InitialMaxBrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break; case "wagon(ortsmaxbrakeshoeforce": MaxBrakeShoeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break; + case "engine(ortsnumberwagonbrakeshoes": NumberCarBrakeShoes = stf.ReadIntBlock(null); break; case "wagon(ortsbrakeshoetype": stf.MustMatch("("); var brakeShoeType = stf.ReadString(); @@ -1547,6 +1559,7 @@ public virtual void Copy(MSTSWagon copy) InitialMaxHandbrakeForceN = copy.InitialMaxHandbrakeForceN; MaxBrakeForceN = copy.MaxBrakeForceN; MaxBrakeShoeForceN = copy.MaxBrakeShoeForceN; + NumberCarBrakeShoes = copy.NumberCarBrakeShoes; MaxHandbrakeForceN = copy.MaxHandbrakeForceN; WindowDeratingFactor = copy.WindowDeratingFactor; DesiredCompartmentTempSetpointC = copy.DesiredCompartmentTempSetpointC; diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs index 3b9eacf3d9..41349e4d92 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs @@ -213,6 +213,7 @@ public static Interpolator SteamHeatBoilerFuelUsageGalukpH() public float MaxHandbrakeForceN; public float MaxBrakeForceN = 89e3f; public float MaxBrakeShoeForceN; // This is the force applied to the brake shoe, hence it will be decreased by CoF to give force applied to the wheel + public float NumberCarBrakeShoes; public float InitialMaxHandbrakeForceN; // Initial force when agon initialised public float InitialMaxBrakeForceN = 89e3f; // Initial force when wagon initialised, this is the force on the wheel, ie after the brake shoe. @@ -3236,7 +3237,7 @@ public virtual float GetBrakeShoeFrictionFactor() // https://iopscience.iop.org/article/10.1088/1742-6596/1614/1/012086/pdf float NewtonsTokNewtons = 0.001f; - float brakeShoeForcekN = NewtonsTokNewtons * BrakeShoeForceN; + float brakeShoeForcekN = (NewtonsTokNewtons * BrakeShoeForceN) / NumberCarBrakeShoes; if (BrakeShoeType == BrakeShoeTypes.CastIron) { From 44cb5a528f4eb9d17ad9a4fec71f3900fb6c78eb Mon Sep 17 00:00:00 2001 From: peternewell Date: Thu, 1 Jun 2023 18:58:25 +1000 Subject: [PATCH 10/27] Minor correction --- Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs index 7c5b0f851d..d0ab86d084 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs @@ -1168,7 +1168,7 @@ public virtual void Parse(string lowercasetoken, STFReader stf) case "wagon(maxhandbrakeforce": InitialMaxHandbrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break; case "wagon(maxbrakeforce": InitialMaxBrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break; case "wagon(ortsmaxbrakeshoeforce": MaxBrakeShoeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break; - case "engine(ortsnumberwagonbrakeshoes": NumberCarBrakeShoes = stf.ReadIntBlock(null); break; + case "engine(ortsnumbercarbrakeshoes": NumberCarBrakeShoes = stf.ReadIntBlock(null); break; case "wagon(ortsbrakeshoetype": stf.MustMatch("("); var brakeShoeType = stf.ReadString(); From f36598411c407a642d7200125df1d481a01a8f5c Mon Sep 17 00:00:00 2001 From: peternewell Date: Fri, 2 Jun 2023 16:04:58 +1000 Subject: [PATCH 11/27] Correction to brake CoF --- .../RollingStocks/MSTSLocomotive.cs | 1 + .../Simulation/RollingStocks/MSTSWagon.cs | 23 +++++++++++-------- .../Simulation/RollingStocks/TrainCar.cs | 2 +- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs index 780aba86cc..c6b5d8a747 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs @@ -1492,6 +1492,7 @@ public override void Initialize() Trace.TraceInformation("Number of Locomotive Drive Axles set to default value of {0}", LocoNumDrvAxles); } } + if (TractionMotorType == TractionMotorTypes.AC) { InductionMotor motor = new InductionMotor(LocomotiveAxle, this); diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs index d0ab86d084..20866d908b 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs @@ -597,15 +597,10 @@ public virtual void LoadFromWagFile(string wagFilePath) MassKG = InitialMassKG; MaxHandbrakeForceN = InitialMaxHandbrakeForceN; + if (MaxBrakeShoeForceN != 0 && BrakeShoeType != BrakeShoeTypes.Unknown) { - MaxBrakeForceN = MaxBrakeShoeForceN; - - if (Simulator.Settings.VerboseConfigurationMessages) - { - Trace.TraceInformation("BrakeShoeType set to {0}, with a MaxBrakeShoeForce of {1}", BrakeShoeType, FormatStrings.FormatForce(MaxBrakeForceN, IsMetric)); - } - + MaxBrakeForceN = MaxBrakeShoeForceN; } else { @@ -613,7 +608,7 @@ public virtual void LoadFromWagFile(string wagFilePath) if (Simulator.Settings.VerboseConfigurationMessages) { - Trace.TraceInformation("BrakeShoeType set to {0}, with a MaxBrakeForce of {1}", BrakeShoeType, FormatStrings.FormatForce(MaxBrakeForceN, IsMetric)); + Trace.TraceInformation("Unknown BrakeShoeType set to OR default (Cast Iron) with a MaxBrakeForce of {0}", FormatStrings.FormatForce(MaxBrakeForceN, IsMetric)); } } @@ -621,10 +616,20 @@ public virtual void LoadFromWagFile(string wagFilePath) if (NumberCarBrakeShoes == 0 && WagonType == WagonTypes.Engine) { NumberCarBrakeShoes = LocoNumDrvAxles * 4.0f; // Assume 4 brake shoes per axle + + if (Simulator.Settings.VerboseConfigurationMessages && (BrakeShoeType == BrakeShoeTypes.CastIron || BrakeShoeType == BrakeShoeTypes.HiFrictionCompost)) + { + Trace.TraceInformation("Number of Locomotive Brakeshoes set to default value of {0}", NumberCarBrakeShoes); + } } - else if (NumberCarBrakeShoes == 0) + else if (NumberCarBrakeShoes == 0 ) { NumberCarBrakeShoes = WagonNumAxles * 4.0f; // Assume 4 brake shoes per axle + + if (Simulator.Settings.VerboseConfigurationMessages && (BrakeShoeType == BrakeShoeTypes.CastIron || BrakeShoeType == BrakeShoeTypes.HiFrictionCompost)) + { + Trace.TraceInformation("Number of Wagon Brakeshoes set to default value of {0}", NumberCarBrakeShoes); + } } CentreOfGravityM = InitialCentreOfGravityM; diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs index 41349e4d92..c14ac92d1d 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs @@ -3296,7 +3296,7 @@ public virtual float GetBrakeShoeFrictionCoefficientHuD() // https://iopscience.iop.org/article/10.1088/1742-6596/1614/1/012086/pdf float NewtonsTokNewtons = 0.001f; - float brakeShoeForcekN = NewtonsTokNewtons * BrakeShoeForceN; + float brakeShoeForcekN = NewtonsTokNewtons * BrakeShoeForceN / NumberCarBrakeShoes; if (BrakeShoeType == BrakeShoeTypes.CastIron) { From e9c98d70fc441a6f88f5e76e528b2d249af530ab Mon Sep 17 00:00:00 2001 From: peternewell Date: Fri, 2 Jun 2023 19:31:49 +1000 Subject: [PATCH 12/27] Fix display error with HuD --- .../Simulation/RollingStocks/MSTSSteamLocomotive.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSSteamLocomotive.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSSteamLocomotive.cs index 8deb30c186..fffa64c92b 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSSteamLocomotive.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSSteamLocomotive.cs @@ -6307,6 +6307,10 @@ public override string GetStatus() public override string GetDebugStatus() { + // calculate values for display, so that display value doesn't go negative + var superheatTempDisplayC = C.FromF(CurrentSuperheatTempF); + superheatTempDisplayC = MathHelper.Clamp(superheatTempDisplayC, 0.0f, C.FromF(MaxSuperheatRefTempF)); + var status = new StringBuilder(base.GetDebugStatus()); status.AppendFormat("\n\n\t\t === {0} === \t\t\n", Simulator.Catalog.GetString("Key Inputs")); @@ -6378,7 +6382,8 @@ public override string GetDebugStatus() Simulator.Catalog.GetString("MaxSupH"), FormatStrings.FormatTemperature(C.FromF(MaxSuperheatRefTempF), IsMetric, false), Simulator.Catalog.GetString("CurSupH"), - FormatStrings.FormatTemperature(C.FromF(CurrentSuperheatTempF), IsMetric, false)); + FormatStrings.FormatTemperature(superheatTempDisplayC, IsMetric, false) + ); status.AppendFormat("\n\t\t === {0} === \t\t{1}/{2}\n", Simulator.Catalog.GetString("Steam Usage"), From 4495dfe4fa980c230177ed9349c1c24331422c22 Mon Sep 17 00:00:00 2001 From: peternewell Date: Fri, 2 Jun 2023 20:03:06 +1000 Subject: [PATCH 13/27] Revert "Fix display error with HuD" This reverts commit e9c98d70fc441a6f88f5e76e528b2d249af530ab. --- .../Simulation/RollingStocks/MSTSSteamLocomotive.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSSteamLocomotive.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSSteamLocomotive.cs index fffa64c92b..8deb30c186 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSSteamLocomotive.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSSteamLocomotive.cs @@ -6307,10 +6307,6 @@ public override string GetStatus() public override string GetDebugStatus() { - // calculate values for display, so that display value doesn't go negative - var superheatTempDisplayC = C.FromF(CurrentSuperheatTempF); - superheatTempDisplayC = MathHelper.Clamp(superheatTempDisplayC, 0.0f, C.FromF(MaxSuperheatRefTempF)); - var status = new StringBuilder(base.GetDebugStatus()); status.AppendFormat("\n\n\t\t === {0} === \t\t\n", Simulator.Catalog.GetString("Key Inputs")); @@ -6382,8 +6378,7 @@ public override string GetDebugStatus() Simulator.Catalog.GetString("MaxSupH"), FormatStrings.FormatTemperature(C.FromF(MaxSuperheatRefTempF), IsMetric, false), Simulator.Catalog.GetString("CurSupH"), - FormatStrings.FormatTemperature(superheatTempDisplayC, IsMetric, false) - ); + FormatStrings.FormatTemperature(C.FromF(CurrentSuperheatTempF), IsMetric, false)); status.AppendFormat("\n\t\t === {0} === \t\t{1}/{2}\n", Simulator.Catalog.GetString("Steam Usage"), From 70a32d81852aea80708cd360c36554efe85944b2 Mon Sep 17 00:00:00 2001 From: peternewell Date: Fri, 2 Jun 2023 21:24:54 +1000 Subject: [PATCH 14/27] Revert "Correction to brake CoF" This reverts commit f36598411c407a642d7200125df1d481a01a8f5c. --- .../RollingStocks/MSTSLocomotive.cs | 1 - .../Simulation/RollingStocks/MSTSWagon.cs | 23 ++++++++----------- .../Simulation/RollingStocks/TrainCar.cs | 2 +- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs index c6b5d8a747..780aba86cc 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs @@ -1492,7 +1492,6 @@ public override void Initialize() Trace.TraceInformation("Number of Locomotive Drive Axles set to default value of {0}", LocoNumDrvAxles); } } - if (TractionMotorType == TractionMotorTypes.AC) { InductionMotor motor = new InductionMotor(LocomotiveAxle, this); diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs index 20866d908b..d0ab86d084 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs @@ -597,10 +597,15 @@ public virtual void LoadFromWagFile(string wagFilePath) MassKG = InitialMassKG; MaxHandbrakeForceN = InitialMaxHandbrakeForceN; - if (MaxBrakeShoeForceN != 0 && BrakeShoeType != BrakeShoeTypes.Unknown) { - MaxBrakeForceN = MaxBrakeShoeForceN; + MaxBrakeForceN = MaxBrakeShoeForceN; + + if (Simulator.Settings.VerboseConfigurationMessages) + { + Trace.TraceInformation("BrakeShoeType set to {0}, with a MaxBrakeShoeForce of {1}", BrakeShoeType, FormatStrings.FormatForce(MaxBrakeForceN, IsMetric)); + } + } else { @@ -608,7 +613,7 @@ public virtual void LoadFromWagFile(string wagFilePath) if (Simulator.Settings.VerboseConfigurationMessages) { - Trace.TraceInformation("Unknown BrakeShoeType set to OR default (Cast Iron) with a MaxBrakeForce of {0}", FormatStrings.FormatForce(MaxBrakeForceN, IsMetric)); + Trace.TraceInformation("BrakeShoeType set to {0}, with a MaxBrakeForce of {1}", BrakeShoeType, FormatStrings.FormatForce(MaxBrakeForceN, IsMetric)); } } @@ -616,20 +621,10 @@ public virtual void LoadFromWagFile(string wagFilePath) if (NumberCarBrakeShoes == 0 && WagonType == WagonTypes.Engine) { NumberCarBrakeShoes = LocoNumDrvAxles * 4.0f; // Assume 4 brake shoes per axle - - if (Simulator.Settings.VerboseConfigurationMessages && (BrakeShoeType == BrakeShoeTypes.CastIron || BrakeShoeType == BrakeShoeTypes.HiFrictionCompost)) - { - Trace.TraceInformation("Number of Locomotive Brakeshoes set to default value of {0}", NumberCarBrakeShoes); - } } - else if (NumberCarBrakeShoes == 0 ) + else if (NumberCarBrakeShoes == 0) { NumberCarBrakeShoes = WagonNumAxles * 4.0f; // Assume 4 brake shoes per axle - - if (Simulator.Settings.VerboseConfigurationMessages && (BrakeShoeType == BrakeShoeTypes.CastIron || BrakeShoeType == BrakeShoeTypes.HiFrictionCompost)) - { - Trace.TraceInformation("Number of Wagon Brakeshoes set to default value of {0}", NumberCarBrakeShoes); - } } CentreOfGravityM = InitialCentreOfGravityM; diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs index c14ac92d1d..41349e4d92 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs @@ -3296,7 +3296,7 @@ public virtual float GetBrakeShoeFrictionCoefficientHuD() // https://iopscience.iop.org/article/10.1088/1742-6596/1614/1/012086/pdf float NewtonsTokNewtons = 0.001f; - float brakeShoeForcekN = NewtonsTokNewtons * BrakeShoeForceN / NumberCarBrakeShoes; + float brakeShoeForcekN = NewtonsTokNewtons * BrakeShoeForceN; if (BrakeShoeType == BrakeShoeTypes.CastIron) { From a479616b3a1b0a0cc78e22c285f4adde1a2213a7 Mon Sep 17 00:00:00 2001 From: peternewell Date: Fri, 2 Jun 2023 21:43:04 +1000 Subject: [PATCH 15/27] Correction to CoF --- .../Simulation/RollingStocks/MSTSWagon.cs | 21 ++++++++++++------- .../Simulation/RollingStocks/TrainCar.cs | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs index d0ab86d084..5113d9f193 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs @@ -597,15 +597,10 @@ public virtual void LoadFromWagFile(string wagFilePath) MassKG = InitialMassKG; MaxHandbrakeForceN = InitialMaxHandbrakeForceN; + if (MaxBrakeShoeForceN != 0 && BrakeShoeType != BrakeShoeTypes.Unknown) { - MaxBrakeForceN = MaxBrakeShoeForceN; - - if (Simulator.Settings.VerboseConfigurationMessages) - { - Trace.TraceInformation("BrakeShoeType set to {0}, with a MaxBrakeShoeForce of {1}", BrakeShoeType, FormatStrings.FormatForce(MaxBrakeForceN, IsMetric)); - } - + MaxBrakeForceN = MaxBrakeShoeForceN; } else { @@ -613,7 +608,7 @@ public virtual void LoadFromWagFile(string wagFilePath) if (Simulator.Settings.VerboseConfigurationMessages) { - Trace.TraceInformation("BrakeShoeType set to {0}, with a MaxBrakeForce of {1}", BrakeShoeType, FormatStrings.FormatForce(MaxBrakeForceN, IsMetric)); + Trace.TraceInformation("Unknown BrakeShoeType set to OR default (Cast Iron) with a MaxBrakeForce of {0}", FormatStrings.FormatForce(MaxBrakeForceN, IsMetric)); } } @@ -621,10 +616,20 @@ public virtual void LoadFromWagFile(string wagFilePath) if (NumberCarBrakeShoes == 0 && WagonType == WagonTypes.Engine) { NumberCarBrakeShoes = LocoNumDrvAxles * 4.0f; // Assume 4 brake shoes per axle + + if (Simulator.Settings.VerboseConfigurationMessages && (BrakeShoeType == BrakeShoeTypes.CastIron || BrakeShoeType == BrakeShoeTypes.HiFrictionCompost)) + { + Trace.TraceInformation("Number of Locomotive Brakeshoes set to default value of {0}", NumberCarBrakeShoes); + } } else if (NumberCarBrakeShoes == 0) { NumberCarBrakeShoes = WagonNumAxles * 4.0f; // Assume 4 brake shoes per axle + + if (Simulator.Settings.VerboseConfigurationMessages && (BrakeShoeType == BrakeShoeTypes.CastIron || BrakeShoeType == BrakeShoeTypes.HiFrictionCompost)) + { + Trace.TraceInformation("Number of Wagon Brakeshoes set to default value of {0}", NumberCarBrakeShoes); + } } CentreOfGravityM = InitialCentreOfGravityM; diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs index 41349e4d92..c14ac92d1d 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs @@ -3296,7 +3296,7 @@ public virtual float GetBrakeShoeFrictionCoefficientHuD() // https://iopscience.iop.org/article/10.1088/1742-6596/1614/1/012086/pdf float NewtonsTokNewtons = 0.001f; - float brakeShoeForcekN = NewtonsTokNewtons * BrakeShoeForceN; + float brakeShoeForcekN = NewtonsTokNewtons * BrakeShoeForceN / NumberCarBrakeShoes; if (BrakeShoeType == BrakeShoeTypes.CastIron) { From 32bb9110ffcdf55c9bf505bc8692cf8c82b5a5a9 Mon Sep 17 00:00:00 2001 From: peternewell Date: Sat, 3 Jun 2023 10:26:10 +1000 Subject: [PATCH 16/27] Correct reading of input parameters --- .../Simulation/RollingStocks/MSTSWagon.cs | 15 ++++++++++++--- .../Simulation/RollingStocks/TrainCar.cs | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs index 5113d9f193..d77e8427ad 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs @@ -615,7 +615,16 @@ public virtual void LoadFromWagFile(string wagFilePath) // Initialise number of brake shoes per wagon if (NumberCarBrakeShoes == 0 && WagonType == WagonTypes.Engine) { - NumberCarBrakeShoes = LocoNumDrvAxles * 4.0f; // Assume 4 brake shoes per axle + var LocoTest = Simulator.PlayerLocomotive as MSTSLocomotive; + + if (LocoTest != null && !LocoTest.DriveWheelOnlyBrakes) + { + NumberCarBrakeShoes = LocoNumDrvAxles * 4 + WagonNumAxles * 4; // Assume 4 brake shoes per axle on all wheels + } + else + { + NumberCarBrakeShoes = LocoNumDrvAxles * 4; // Assume 4 brake shoes per axle on drive wheels only + } if (Simulator.Settings.VerboseConfigurationMessages && (BrakeShoeType == BrakeShoeTypes.CastIron || BrakeShoeType == BrakeShoeTypes.HiFrictionCompost)) { @@ -624,7 +633,7 @@ public virtual void LoadFromWagFile(string wagFilePath) } else if (NumberCarBrakeShoes == 0) { - NumberCarBrakeShoes = WagonNumAxles * 4.0f; // Assume 4 brake shoes per axle + NumberCarBrakeShoes = WagonNumAxles * 4; // Assume 4 brake shoes per axle if (Simulator.Settings.VerboseConfigurationMessages && (BrakeShoeType == BrakeShoeTypes.CastIron || BrakeShoeType == BrakeShoeTypes.HiFrictionCompost)) { @@ -1173,7 +1182,7 @@ public virtual void Parse(string lowercasetoken, STFReader stf) case "wagon(maxhandbrakeforce": InitialMaxHandbrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break; case "wagon(maxbrakeforce": InitialMaxBrakeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break; case "wagon(ortsmaxbrakeshoeforce": MaxBrakeShoeForceN = stf.ReadFloatBlock(STFReader.UNITS.Force, null); break; - case "engine(ortsnumbercarbrakeshoes": NumberCarBrakeShoes = stf.ReadIntBlock(null); break; + case "wagon(ortsnumbercarbrakeshoes": NumberCarBrakeShoes = stf.ReadIntBlock(null); break; case "wagon(ortsbrakeshoetype": stf.MustMatch("("); var brakeShoeType = stf.ReadString(); diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs index c14ac92d1d..284c899a06 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs @@ -213,7 +213,7 @@ public static Interpolator SteamHeatBoilerFuelUsageGalukpH() public float MaxHandbrakeForceN; public float MaxBrakeForceN = 89e3f; public float MaxBrakeShoeForceN; // This is the force applied to the brake shoe, hence it will be decreased by CoF to give force applied to the wheel - public float NumberCarBrakeShoes; + public int NumberCarBrakeShoes; public float InitialMaxHandbrakeForceN; // Initial force when agon initialised public float InitialMaxBrakeForceN = 89e3f; // Initial force when wagon initialised, this is the force on the wheel, ie after the brake shoe. From 57dfe6390f38d2f1df9ea9db3e2eb5bd9d4d2a54 Mon Sep 17 00:00:00 2001 From: peternewell Date: Sat, 3 Jun 2023 17:16:23 +1000 Subject: [PATCH 17/27] Fix superheat display --- .../Simulation/RollingStocks/MSTSSteamLocomotive.cs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSSteamLocomotive.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSSteamLocomotive.cs index 8deb30c186..6aec7a48db 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSSteamLocomotive.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSSteamLocomotive.cs @@ -6369,6 +6369,10 @@ public override string GetDebugStatus() FormatStrings.FormatEnergy(W.FromBTUpS(BoilerHeatBTU), IsMetric) ); + // calculate values for display, so that display value doesn't go negative + var superheatTempDisplayC = C.FromF(CurrentSuperheatTempF); + superheatTempDisplayC = MathHelper.Clamp(superheatTempDisplayC, 0.0f, C.FromF(MaxSuperheatRefTempF)); + status.AppendFormat("{0}\t{1}\t{2}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8}\n", Simulator.Catalog.GetString("Temp:"), Simulator.Catalog.GetString("Flue"), @@ -6378,7 +6382,8 @@ public override string GetDebugStatus() Simulator.Catalog.GetString("MaxSupH"), FormatStrings.FormatTemperature(C.FromF(MaxSuperheatRefTempF), IsMetric, false), Simulator.Catalog.GetString("CurSupH"), - FormatStrings.FormatTemperature(C.FromF(CurrentSuperheatTempF), IsMetric, false)); + FormatStrings.FormatTemperature(superheatTempDisplayC, IsMetric, false) + ); status.AppendFormat("\n\t\t === {0} === \t\t{1}/{2}\n", Simulator.Catalog.GetString("Steam Usage"), @@ -6819,8 +6824,8 @@ public override string GetDebugStatus() ); } - if (Simulator.UseAdvancedAdhesion && !Simulator.Settings.SimpleControlPhysics && SteamEngineType != SteamEngineTypes.Geared) - // Only display slip monitor if advanced adhesion is set and simplecontrols/physics not set + if (Simulator.UseAdvancedAdhesion && !Simulator.Settings.SimpleControlPhysics && SteamEngineType != SteamEngineTypes.Geared) + // Only display slip monitor if advanced adhesion is set and simplecontrols/physics not set { status.AppendFormat("\n\t\t === {0} === \n", Simulator.Catalog.GetString("Slip Monitor")); status.AppendFormat("{0}\t{1}\t{2:N0}\t{3}\t{4}\t{5}\t{6}\t{7}\t{8:N2}\t{9}\t{10}\t{11:N2}\t{12}\t{13}\t{14:N1}\n", From 4447c8d4221c4e3901765048be5d8c6160b48318 Mon Sep 17 00:00:00 2001 From: peternewell Date: Sun, 4 Jun 2023 09:46:21 +1000 Subject: [PATCH 18/27] Change default settings for drive wheel braking --- .../Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs | 6 +++--- Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs index d77e8427ad..5c043f563e 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs @@ -617,13 +617,13 @@ public virtual void LoadFromWagFile(string wagFilePath) { var LocoTest = Simulator.PlayerLocomotive as MSTSLocomotive; - if (LocoTest != null && !LocoTest.DriveWheelOnlyBrakes) + if (LocoTest != null && LocoTest.DriveWheelOnlyBrakes) { - NumberCarBrakeShoes = LocoNumDrvAxles * 4 + WagonNumAxles * 4; // Assume 4 brake shoes per axle on all wheels + NumberCarBrakeShoes = LocoNumDrvAxles * 4; // Assume 4 brake shoes per axle on drive wheels only } else { - NumberCarBrakeShoes = LocoNumDrvAxles * 4; // Assume 4 brake shoes per axle on drive wheels only + NumberCarBrakeShoes = (LocoNumDrvAxles * 4) + (WagonNumAxles * 4); // Assume 4 brake shoes per axle on all wheels } if (Simulator.Settings.VerboseConfigurationMessages && (BrakeShoeType == BrakeShoeTypes.CastIron || BrakeShoeType == BrakeShoeTypes.HiFrictionCompost)) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs index 284c899a06..c5905dd3fe 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs @@ -3318,7 +3318,7 @@ public virtual float GetBrakeShoeFrictionCoefficientHuD() } else { - frictionfraction = (7.6f / (MpS.ToKpH(AbsSpeedMpS) + 17.5f) + 0.07f) * AdhesionMultiplier; // Base Curtius - Kniffler equation - u = 0.50, all other values are scaled off this formula + frictionfraction = 7.6f / ((MpS.ToKpH(AbsSpeedMpS) + 17.5f) + 0.07f) * AdhesionMultiplier; // Base Curtius - Kniffler equation - u = 0.50, all other values are scaled off this formula } } @@ -3326,7 +3326,7 @@ public virtual float GetBrakeShoeFrictionCoefficientHuD() } else { - frictionfraction = (7.6f / (MpS.ToKpH(AbsSpeedMpS) + 17.5f) + 0.07f); // Base Curtius - Kniffler equation - u = 0.50, all other values are scaled off this formula; // For simple friction use "default" curve + frictionfraction = 7.6f / ((MpS.ToKpH(AbsSpeedMpS) + 17.5f) + 0.07f); // Base Curtius - Kniffler equation - u = 0.50, all other values are scaled off this formula; // For simple friction use "default" curve return frictionfraction; } } From 1168d6192108640e31a07863dde0e6239ae26509 Mon Sep 17 00:00:00 2001 From: peternewell Date: Tue, 6 Jun 2023 14:55:45 +1000 Subject: [PATCH 19/27] Restore original brake calculations --- Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs index c5905dd3fe..09fa9a81c0 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs @@ -3259,6 +3259,9 @@ public virtual float GetBrakeShoeFrictionFactor() float zeroUserFriction = BrakeShoeFrictionFactor[MpS.ToKpH(0)]; frictionfraction = userFriction / zeroUserFriction * AdhesionMultiplier; // Factor calculated by normalising zero speed value on friction curve applied in WAG file + + // Clamp adjustment factor to a value of 1.0 - i.e. the brakeforce can never exceed the Brake Force value defined in the WAG file + frictionfraction = MathHelper.Clamp(frictionfraction, 0.01f, 1.0f); } else { @@ -3268,6 +3271,9 @@ public virtual float GetBrakeShoeFrictionFactor() // Assuming that current MaxBrakeForce has been set with an existing Friction CoF of 0.2f, an adjustment factor needs to be developed to reduce // the MAxBrakeForce by a relative amount. Note force will be higher then ENG file value at low speed and reduce to actual value at higher speeds. frictionfraction = defaultBrakeShoeCoefficientFriction / 0.2f * AdhesionMultiplier; // Assuming that current MaxBrakeForce has been set with an existing Friction CoF of 0.2f, an adjustment factor needs to be developed to reduce the MAxBrakeForce by a relative amount + + // Clamp adjustment factor to a value of 1.0 - i.e. the brakeforce can never exceed the Brake Force value defined in the WAG file + frictionfraction = MathHelper.Clamp(frictionfraction, 0.01f, 1.0f); } } From c3d05c4fbaeb53f5b291901d42c350e81a5f095a Mon Sep 17 00:00:00 2001 From: peternewell Date: Wed, 7 Jun 2023 06:43:46 +1000 Subject: [PATCH 20/27] Restore brakeshoe CoF to legacy operation --- Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs index 09fa9a81c0..e70b834e52 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs @@ -3281,7 +3281,9 @@ public virtual float GetBrakeShoeFrictionFactor() } else { - frictionfraction = (7.6f / (MpS.ToKpH(AbsSpeedMpS) + 17.5f) + 0.07f); // Base Curtius - Kniffler equation - u = 0.50, all other values are scaled off this formula; // For simple friction use "default" curve + // set default values if simple adhesion model, or if diesel or electric locomotive is used, which doesn't check for brake skid. + + frictionfraction = 1.0f; // Default value set to leave existing brakeforce constant regardless of changing speed return frictionfraction; } } @@ -3332,7 +3334,7 @@ public virtual float GetBrakeShoeFrictionCoefficientHuD() } else { - frictionfraction = 7.6f / ((MpS.ToKpH(AbsSpeedMpS) + 17.5f) + 0.07f); // Base Curtius - Kniffler equation - u = 0.50, all other values are scaled off this formula; // For simple friction use "default" curve + frictionfraction = 1.0f; // Default value set to leave existing brakeforce constant regardless of changing speed return frictionfraction; } } From 756716bf92c4ed1f63205a726ec6391f3d066ad7 Mon Sep 17 00:00:00 2001 From: peternewell Date: Thu, 8 Jun 2023 15:39:06 +1000 Subject: [PATCH 21/27] improve readability --- Source/Orts.Simulation/Simulation/Physics/Train.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/Physics/Train.cs b/Source/Orts.Simulation/Simulation/Physics/Train.cs index 2800a4a4f2..fcfdfa93fc 100644 --- a/Source/Orts.Simulation/Simulation/Physics/Train.cs +++ b/Source/Orts.Simulation/Simulation/Physics/Train.cs @@ -5460,7 +5460,7 @@ public void UpdateCarSpeeds(float elapsedTime) if (car is MSTSLocomotive) locoBehind = false; if (car.SpeedMpS > 0) { - car.SpeedMpS += car.TotalForceN / car.MassKG * elapsedTime; + car.SpeedMpS += (car.TotalForceN / car.MassKG) * elapsedTime; if (car.SpeedMpS < 0) car.SpeedMpS = 0; // If car is manual braked, air_piped car or vacuum_piped, and preceeding car is at stop, then set speed to zero. @@ -5473,7 +5473,7 @@ public void UpdateCarSpeeds(float elapsedTime) } else if (car.SpeedMpS < 0) { - car.SpeedMpS += car.TotalForceN / car.MassKG * elapsedTime; + car.SpeedMpS += (car.TotalForceN / car.MassKG) * elapsedTime; if (car.SpeedMpS > 0) car.SpeedMpS = 0; // If car is manual braked, air_piped car or vacuum_piped, and preceeding car is at stop, then set speed to zero. From 1b6ca35a24ed3f61002d669e894c41cb266e00fe Mon Sep 17 00:00:00 2001 From: peternewell Date: Thu, 8 Jun 2023 16:42:40 +1000 Subject: [PATCH 22/27] Add documentation --- Source/Documentation/Manual/physics.rst | 28 +++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/Source/Documentation/Manual/physics.rst b/Source/Documentation/Manual/physics.rst index 44daf2f406..a74746d9bc 100644 --- a/Source/Documentation/Manual/physics.rst +++ b/Source/Documentation/Manual/physics.rst @@ -2739,6 +2739,34 @@ These changes introduce an extra challenge to train braking, but provide a more For example, in a lot of normal Westinghouse brake systems, a minimum pressure reduction was applied by moving the brake controller to the LAP position. Typically Westinghouse recommended values of between 7 and 10 psi. +Brake Shoe Force +---------------- + +As indicated above the ``MaxBrakeForce`` parameter in the WAG file is the actual force applied to the wheel after reduction by the friction coefficient, often railway companies will provide an Net Braking Ratio (NBR) value to +specify the amount of force to be applied to the brake shoe. This force is then reduced by the brake shoe CoF to determine the actual force applied to the wheel. + +To facilitate the direct usage of the NBR value in the WAG file, the following parameters can be used. NB: When using these parameters the ``MaxBrakeForce`` parameter is not required. + +Brake Shoe Force - This is the current change being implemented. The following changes and parameter are included. + +``ORTSMaxBrakeShoeForce`` - the force applied to the brake shoe is the main braking force. + +``ORTSBrakeShoeType`` - this defines a number of different brake shoe types and curves. To provide a more realistic representation of the braking force the default CoF curves are 2D, ie +they are impacted by both the speed and Brake Shoe Force. Typically ``ORTSBrakeShoeType`` will have one of the following keywords included - +``CastIron`` - cast iron brake shoe, 2D as above, ``HiFrictionCompost`` - high friction composite shoe, 2D as above, ``UserDefined`` - is a user defined curve +using the ORTSBrakeShoeFriction parameter, 1D (ie, speed only, see above section for the parameter format). + +``ORTSNumberCarBrakeShoes`` - to facilitate the operation of the default 2D curves above it is necessary to configure the number of brake shoes for each car. + +Whilst OR will attempt to set some defaults if parameters are left out, the most realistic operation will be achieved by using all the relevant parameters. + +The following two legacy arrangements can be used as an alternative to the above method, + +- Legacy #1 - legacy arrangements using MaxBrakeForce on its own will remain unchanged. This in effect is an old MSTS file. + +- Legacy #2 - where MaxBrakeForce and ORTSBrakeShoeFriction have been set, legacy operation will remain unchanged. + + Train Brake Pipe Losses ----------------------- From fa510b016a13546a1c764abb07a06d5072b097a4 Mon Sep 17 00:00:00 2001 From: peternewell Date: Sun, 11 Jun 2023 09:23:38 +1000 Subject: [PATCH 23/27] Correct Codacy issue --- .../SubSystems/Brakes/MSTS/StraightVacuumSinglePipe.cs | 2 ++ .../RollingStocks/SubSystems/Brakes/MSTS/VacuumSinglePipe.cs | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/StraightVacuumSinglePipe.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/StraightVacuumSinglePipe.cs index d831d08be3..80215fd08f 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/StraightVacuumSinglePipe.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/StraightVacuumSinglePipe.cs @@ -138,7 +138,9 @@ public override void Update(float elapsedClockSeconds) Car.BrakeShoeForceN = Car.MaxBrakeForceN * brakecylinderfraction; if (Car.BrakeShoeForceN < Car.MaxHandbrakeForceN * HandbrakePercent / 100) + { Car.BrakeShoeForceN = Car.MaxHandbrakeForceN * HandbrakePercent / 100; + } } else { diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/VacuumSinglePipe.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/VacuumSinglePipe.cs index eccac81e6e..c7e0b70a18 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/VacuumSinglePipe.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/VacuumSinglePipe.cs @@ -562,7 +562,7 @@ public override void Update(float elapsedClockSeconds) } float vrp = VacResPressureAdjPSIA(); - + if (!Car.BrakesStuck) { // depending upon whether steam brake fitted or not, calculate brake force to be applied @@ -575,8 +575,11 @@ public override void Update(float elapsedClockSeconds) { Car.BrakeShoeForceN = CylPressurePSIA <= vrp ? 0 : Car.MaxBrakeForceN * Math.Min((CylPressurePSIA - vrp) / MaxForcePressurePSI, 1); } + if (Car.BrakeShoeForceN < Car.MaxHandbrakeForceN * HandbrakePercent / 100) + { Car.BrakeShoeForceN = Car.MaxHandbrakeForceN * HandbrakePercent / 100; + } } else Car.BrakeShoeForceN = Math.Max(Car.MaxBrakeForceN, Car.MaxHandbrakeForceN / 2); From 037dbdf97f70a8bf51f3d9c81970fc91752c38c6 Mon Sep 17 00:00:00 2001 From: peternewell Date: Sun, 11 Jun 2023 09:38:04 +1000 Subject: [PATCH 24/27] Correct codacy error --- .../RollingStocks/SubSystems/Brakes/MSTS/VacuumSinglePipe.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/VacuumSinglePipe.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/VacuumSinglePipe.cs index c7e0b70a18..3547f30180 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/VacuumSinglePipe.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/VacuumSinglePipe.cs @@ -581,7 +581,10 @@ public override void Update(float elapsedClockSeconds) Car.BrakeShoeForceN = Car.MaxHandbrakeForceN * HandbrakePercent / 100; } } - else Car.BrakeShoeForceN = Math.Max(Car.MaxBrakeForceN, Car.MaxHandbrakeForceN / 2); + else + { + Car.BrakeShoeForceN = Math.Max(Car.MaxBrakeForceN, Car.MaxHandbrakeForceN / 2); + } float brakeShoeFriction = Car.GetBrakeShoeFrictionFactor(); Car.HuDBrakeShoeFriction = Car.GetBrakeShoeFrictionCoefficientHuD(); From 1df98a39ca3181daeb41817d9e3fdaa0ac850b15 Mon Sep 17 00:00:00 2001 From: peternewell Date: Sun, 11 Jun 2023 15:58:36 +1000 Subject: [PATCH 25/27] Adjust user inputs --- .../Simulation/RollingStocks/MSTSWagon.cs | 4 ++-- .../Simulation/RollingStocks/TrainCar.cs | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs index 5c043f563e..09cfe38225 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs @@ -626,7 +626,7 @@ public virtual void LoadFromWagFile(string wagFilePath) NumberCarBrakeShoes = (LocoNumDrvAxles * 4) + (WagonNumAxles * 4); // Assume 4 brake shoes per axle on all wheels } - if (Simulator.Settings.VerboseConfigurationMessages && (BrakeShoeType == BrakeShoeTypes.CastIron || BrakeShoeType == BrakeShoeTypes.HiFrictionCompost)) + if (Simulator.Settings.VerboseConfigurationMessages && (BrakeShoeType == BrakeShoeTypes.Cast_Iron || BrakeShoeType == BrakeShoeTypes.Hi_Friction_Compost)) { Trace.TraceInformation("Number of Locomotive Brakeshoes set to default value of {0}", NumberCarBrakeShoes); } @@ -635,7 +635,7 @@ public virtual void LoadFromWagFile(string wagFilePath) { NumberCarBrakeShoes = WagonNumAxles * 4; // Assume 4 brake shoes per axle - if (Simulator.Settings.VerboseConfigurationMessages && (BrakeShoeType == BrakeShoeTypes.CastIron || BrakeShoeType == BrakeShoeTypes.HiFrictionCompost)) + if (Simulator.Settings.VerboseConfigurationMessages && (BrakeShoeType == BrakeShoeTypes.Cast_Iron || BrakeShoeType == BrakeShoeTypes.Hi_Friction_Compost)) { Trace.TraceInformation("Number of Wagon Brakeshoes set to default value of {0}", NumberCarBrakeShoes); } diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs index e70b834e52..04a6ecf9bc 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs @@ -683,9 +683,9 @@ public enum WagonSpecialTypes public enum BrakeShoeTypes { Unknown, - CastIron, - HiFrictionCompost, - UserDefined, + Cast_Iron, + Hi_Friction_Compost, + User_Defined, } public BrakeShoeTypes BrakeShoeType; @@ -3239,15 +3239,15 @@ public virtual float GetBrakeShoeFrictionFactor() float NewtonsTokNewtons = 0.001f; float brakeShoeForcekN = (NewtonsTokNewtons * BrakeShoeForceN) / NumberCarBrakeShoes; - if (BrakeShoeType == BrakeShoeTypes.CastIron) + if (BrakeShoeType == BrakeShoeTypes.Cast_Iron) { frictionfraction = 0.6f * ((1.6f * brakeShoeForcekN + 100.0f) / (8.0f * brakeShoeForcekN + 100.0f)) * ((MpS.ToKpH(AbsSpeedMpS) + 100.0f) / (5.0f * MpS.ToKpH(AbsSpeedMpS) + 100.0f)); } - else if (BrakeShoeType == BrakeShoeTypes.HiFrictionCompost) + else if (BrakeShoeType == BrakeShoeTypes.Hi_Friction_Compost) { frictionfraction = 0.44f * ((0.1f * brakeShoeForcekN + 20.0f) / (0.4f * brakeShoeForcekN + 20.0f)) * ((MpS.ToKpH(AbsSpeedMpS) + 150.0f) / (2.0f * MpS.ToKpH(AbsSpeedMpS) + 150.0f)); } - else if (BrakeShoeType == BrakeShoeTypes.UserDefined) + else if (BrakeShoeType == BrakeShoeTypes.User_Defined) { frictionfraction = BrakeShoeFrictionFactor[MpS.ToKpH(AbsSpeedMpS)]; } @@ -3306,15 +3306,15 @@ public virtual float GetBrakeShoeFrictionCoefficientHuD() float NewtonsTokNewtons = 0.001f; float brakeShoeForcekN = NewtonsTokNewtons * BrakeShoeForceN / NumberCarBrakeShoes; - if (BrakeShoeType == BrakeShoeTypes.CastIron) + if (BrakeShoeType == BrakeShoeTypes.Cast_Iron) { frictionfraction = 0.6f * ((1.6f * brakeShoeForcekN + 100.0f) / (8.0f * brakeShoeForcekN + 100.0f)) * ((MpS.ToKpH(AbsSpeedMpS) + 100.0f) / (5.0f * MpS.ToKpH(AbsSpeedMpS) + 100.0f)); } - else if (BrakeShoeType == BrakeShoeTypes.HiFrictionCompost) + else if (BrakeShoeType == BrakeShoeTypes.Hi_Friction_Compost) { frictionfraction = 0.44f * ((0.1f * brakeShoeForcekN + 20.0f) / (0.4f * brakeShoeForcekN + 20.0f)) * ((MpS.ToKpH(AbsSpeedMpS) + 150.0f) / (2.0f * MpS.ToKpH(AbsSpeedMpS) + 150.0f)); } - else if (BrakeShoeType == BrakeShoeTypes.UserDefined) + else if (BrakeShoeType == BrakeShoeTypes.User_Defined) { frictionfraction = BrakeShoeFrictionFactor[MpS.ToKpH(AbsSpeedMpS)]; } From 4c9375eddc85d0c3293cee6b6e129331b489a603 Mon Sep 17 00:00:00 2001 From: peternewell Date: Sun, 11 Jun 2023 16:05:25 +1000 Subject: [PATCH 26/27] Update Documentation --- Source/Documentation/Manual/physics.rst | 2 +- .../Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs | 4 ++-- Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/Documentation/Manual/physics.rst b/Source/Documentation/Manual/physics.rst index a74746d9bc..ac5dde7b62 100644 --- a/Source/Documentation/Manual/physics.rst +++ b/Source/Documentation/Manual/physics.rst @@ -2753,7 +2753,7 @@ Brake Shoe Force - This is the current change being implemented. The following c ``ORTSBrakeShoeType`` - this defines a number of different brake shoe types and curves. To provide a more realistic representation of the braking force the default CoF curves are 2D, ie they are impacted by both the speed and Brake Shoe Force. Typically ``ORTSBrakeShoeType`` will have one of the following keywords included - -``CastIron`` - cast iron brake shoe, 2D as above, ``HiFrictionCompost`` - high friction composite shoe, 2D as above, ``UserDefined`` - is a user defined curve +``Cast_Iron`` - cast iron brake shoe, 2D as above, ``Hi_Friction_Composite`` - high friction composite shoe, 2D as above, ``User_Defined`` - is a user defined curve using the ORTSBrakeShoeFriction parameter, 1D (ie, speed only, see above section for the parameter format). ``ORTSNumberCarBrakeShoes`` - to facilitate the operation of the default 2D curves above it is necessary to configure the number of brake shoes for each car. diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs index 09cfe38225..343592cc63 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs @@ -626,7 +626,7 @@ public virtual void LoadFromWagFile(string wagFilePath) NumberCarBrakeShoes = (LocoNumDrvAxles * 4) + (WagonNumAxles * 4); // Assume 4 brake shoes per axle on all wheels } - if (Simulator.Settings.VerboseConfigurationMessages && (BrakeShoeType == BrakeShoeTypes.Cast_Iron || BrakeShoeType == BrakeShoeTypes.Hi_Friction_Compost)) + if (Simulator.Settings.VerboseConfigurationMessages && (BrakeShoeType == BrakeShoeTypes.Cast_Iron || BrakeShoeType == BrakeShoeTypes.High_Friction_Composite)) { Trace.TraceInformation("Number of Locomotive Brakeshoes set to default value of {0}", NumberCarBrakeShoes); } @@ -635,7 +635,7 @@ public virtual void LoadFromWagFile(string wagFilePath) { NumberCarBrakeShoes = WagonNumAxles * 4; // Assume 4 brake shoes per axle - if (Simulator.Settings.VerboseConfigurationMessages && (BrakeShoeType == BrakeShoeTypes.Cast_Iron || BrakeShoeType == BrakeShoeTypes.Hi_Friction_Compost)) + if (Simulator.Settings.VerboseConfigurationMessages && (BrakeShoeType == BrakeShoeTypes.Cast_Iron || BrakeShoeType == BrakeShoeTypes.High_Friction_Composite)) { Trace.TraceInformation("Number of Wagon Brakeshoes set to default value of {0}", NumberCarBrakeShoes); } diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs index 04a6ecf9bc..44a03f3e42 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs @@ -684,7 +684,7 @@ public enum BrakeShoeTypes { Unknown, Cast_Iron, - Hi_Friction_Compost, + High_Friction_Composite, User_Defined, } public BrakeShoeTypes BrakeShoeType; @@ -3243,7 +3243,7 @@ public virtual float GetBrakeShoeFrictionFactor() { frictionfraction = 0.6f * ((1.6f * brakeShoeForcekN + 100.0f) / (8.0f * brakeShoeForcekN + 100.0f)) * ((MpS.ToKpH(AbsSpeedMpS) + 100.0f) / (5.0f * MpS.ToKpH(AbsSpeedMpS) + 100.0f)); } - else if (BrakeShoeType == BrakeShoeTypes.Hi_Friction_Compost) + else if (BrakeShoeType == BrakeShoeTypes.High_Friction_Composite) { frictionfraction = 0.44f * ((0.1f * brakeShoeForcekN + 20.0f) / (0.4f * brakeShoeForcekN + 20.0f)) * ((MpS.ToKpH(AbsSpeedMpS) + 150.0f) / (2.0f * MpS.ToKpH(AbsSpeedMpS) + 150.0f)); } @@ -3310,7 +3310,7 @@ public virtual float GetBrakeShoeFrictionCoefficientHuD() { frictionfraction = 0.6f * ((1.6f * brakeShoeForcekN + 100.0f) / (8.0f * brakeShoeForcekN + 100.0f)) * ((MpS.ToKpH(AbsSpeedMpS) + 100.0f) / (5.0f * MpS.ToKpH(AbsSpeedMpS) + 100.0f)); } - else if (BrakeShoeType == BrakeShoeTypes.Hi_Friction_Compost) + else if (BrakeShoeType == BrakeShoeTypes.High_Friction_Composite) { frictionfraction = 0.44f * ((0.1f * brakeShoeForcekN + 20.0f) / (0.4f * brakeShoeForcekN + 20.0f)) * ((MpS.ToKpH(AbsSpeedMpS) + 150.0f) / (2.0f * MpS.ToKpH(AbsSpeedMpS) + 150.0f)); } From e632edbc3d7ea63b510cda4025198f69a830edb6 Mon Sep 17 00:00:00 2001 From: peternewell Date: Wed, 14 Jun 2023 15:23:28 +1000 Subject: [PATCH 27/27] Fix bug introduced to dynamic brake blending --- .../Simulation/RollingStocks/MSTSLocomotive.cs | 2 +- .../Simulation/RollingStocks/MSTSWagon.cs | 2 ++ .../SubSystems/Brakes/MSTS/AirSinglePipe.cs | 10 +++++----- .../Simulation/RollingStocks/TrainCar.cs | 3 ++- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs index 780aba86cc..dc979261b7 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSLocomotive.cs @@ -1834,7 +1834,7 @@ public void DynamicBrakeBlending(float elapsedClockSeconds) { if (DynamicBrakeBlendingForceMatch) { - float diff = target * MaxBrakeForceN - DynamicBrakeForceN; + float diff = target * FrictionBrakeBlendingMaxForceN - DynamicBrakeForceN; float threshold = 100; if (diff > threshold && DynamicBrakeIntervention < 1) DynamicBrakeIntervention = Math.Min(DynamicBrakeIntervention + elapsedClockSeconds, 1); diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs index 343592cc63..63d23ae1ef 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/MSTSWagon.cs @@ -598,6 +598,8 @@ public virtual void LoadFromWagFile(string wagFilePath) MaxHandbrakeForceN = InitialMaxHandbrakeForceN; + FrictionBrakeBlendingMaxForceN = InitialMaxBrakeForceN; // set the value of braking when blended with dynamic brakes + if (MaxBrakeShoeForceN != 0 && BrakeShoeType != BrakeShoeTypes.Unknown) { MaxBrakeForceN = MaxBrakeShoeForceN; diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/AirSinglePipe.cs b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/AirSinglePipe.cs index f227e9bf6a..ba7bdcc8a7 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/AirSinglePipe.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/SubSystems/Brakes/MSTS/AirSinglePipe.cs @@ -587,15 +587,15 @@ public override void Update(float elapsedClockSeconds) } } } - if (loco.DynamicBrakePercent > 0 && Car.MaxBrakeForceN > 0) + if (loco.DynamicBrakePercent > 0 && Car.FrictionBrakeBlendingMaxForceN > 0) { if (loco.DynamicBrakePartialBailOff) { - var requiredBrakeForceN = Math.Min(AutoCylPressurePSI / MaxCylPressurePSI, 1) * Car.MaxBrakeForceN; - var localBrakeForceN = loco.DynamicBrakeForceN + Math.Min(CylPressurePSI / MaxCylPressurePSI, 1) * Car.MaxBrakeForceN; - if (localBrakeForceN > requiredBrakeForceN - 0.15f * Car.MaxBrakeForceN) + var requiredBrakeForceN = Math.Min(AutoCylPressurePSI / MaxCylPressurePSI, 1) * Car.FrictionBrakeBlendingMaxForceN; + var localBrakeForceN = loco.DynamicBrakeForceN + Math.Min(CylPressurePSI / MaxCylPressurePSI, 1) * Car.FrictionBrakeBlendingMaxForceN; + if (localBrakeForceN > requiredBrakeForceN - 0.15f * Car.FrictionBrakeBlendingMaxForceN) { - demandedPressurePSI = Math.Min(Math.Max((requiredBrakeForceN - loco.DynamicBrakeForceN)/Car.MaxBrakeForceN*MaxCylPressurePSI, 0), MaxCylPressurePSI); + demandedPressurePSI = Math.Min(Math.Max((requiredBrakeForceN - loco.DynamicBrakeForceN)/Car.FrictionBrakeBlendingMaxForceN * MaxCylPressurePSI, 0), MaxCylPressurePSI); if (demandedPressurePSI > CylPressurePSI && demandedPressurePSI < CylPressurePSI + 4) // Allow some margin for unnecessary air brake application { demandedPressurePSI = CylPressurePSI; diff --git a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs index 44a03f3e42..d503cbcb54 100644 --- a/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs +++ b/Source/Orts.Simulation/Simulation/RollingStocks/TrainCar.cs @@ -578,9 +578,10 @@ public Direction Direction public float TunnelForceN; // Resistive force due to tunnel, in Newtons public float FrictionForceN; // in Newtons ( kg.m/s^2 ) unsigned, includes effects of curvature - public float BrakeForceN; // brake force applied to slow train (Newtons) - will be impacted by wheel/rail friction + public float BrakeForceN; // current braking force applied to slow train (Newtons) - will be impacted by wheel/rail friction public float BrakeRetardForceN; // brake force applied to wheel by brakeshoe (Newtons) independent of friction wheel/rail friction public float BrakeShoeForceN; + public float FrictionBrakeBlendingMaxForceN; // This is the maximum force for the friction barke when it is blended with the dynamic brake // Sum of all the forces acting on a Traincar in the direction of driving. // MotiveForceN and GravityForceN act to accelerate the train. The others act to brake the train.