@@ -241,10 +241,14 @@ public float CurrentLocomotiveSteamHeatBoilerWaterCapacityL
241
241
// Adhesion parameters
242
242
public enum SlipControlType
243
243
{
244
+ Unknown ,
244
245
None ,
246
+ CutPower ,
247
+ ReduceForce ,
245
248
Full
246
249
}
247
250
public SlipControlType SlipControlSystem ;
251
+ public bool [ ] SlipControlActive ;
248
252
float BaseFrictionCoefficientFactor ; // Factor used to adjust Curtius formula depending upon weather conditions
249
253
float SlipFrictionCoefficientFactor ;
250
254
public float SteamStaticWheelForce ;
@@ -929,10 +933,10 @@ public override void Parse(string lowercasetoken, STFReader stf)
929
933
case "engine(ortsunloadingspeed" : UnloadingSpeedMpS = stf . ReadFloatBlock ( STFReader . UNITS . Speed , null ) ; break ;
930
934
case "engine(ortsslipcontrolsystem" :
931
935
stf . MustMatch ( "(" ) ;
932
- string slipControlType = stf . ReadString ( ) . ToLowerInvariant ( ) ;
936
+ string slipControlType = stf . ReadString ( ) ;
933
937
try
934
938
{
935
- SlipControlSystem = ( SlipControlType ) Enum . Parse ( typeof ( SlipControlType ) , slipControlType . First ( ) . ToString ( ) . ToUpper ( ) + slipControlType . Substring ( 1 ) ) ;
939
+ SlipControlSystem = ( SlipControlType ) Enum . Parse ( typeof ( SlipControlType ) , slipControlType , true ) ;
936
940
}
937
941
catch
938
942
{
@@ -1683,6 +1687,13 @@ public override void Initialize()
1683
1687
}
1684
1688
}
1685
1689
}
1690
+ SlipControlActive = new bool [ LocomotiveAxles . Count ] ;
1691
+ if ( SlipControlSystem == SlipControlType . Unknown )
1692
+ {
1693
+ if ( AntiSlip ) SlipControlSystem = SlipControlType . ReduceForce ;
1694
+ else if ( WheelslipCausesThrottleDown ) SlipControlSystem = SlipControlType . CutPower ;
1695
+ else SlipControlSystem = SlipControlType . None ;
1696
+ }
1686
1697
1687
1698
// Calculate minimum speed to pickup water
1688
1699
const float Aconst = 2 ;
@@ -2719,8 +2730,9 @@ protected virtual void UpdateTractiveForce(float elapsedClockSeconds)
2719
2730
UpdateDynamicBrakeForce ( elapsedClockSeconds ) ;
2720
2731
TractiveForceN -= Math . Sign ( WheelSpeedMpS ) * DynamicBrakeForceN ;
2721
2732
2722
- foreach ( var axle in LocomotiveAxles )
2733
+ for ( int i = 0 ; i < LocomotiveAxles . Count ; i ++ )
2723
2734
{
2735
+ var axle = LocomotiveAxles [ i ] ;
2724
2736
if ( axle . DriveType == AxleDriveType . ForceDriven )
2725
2737
{
2726
2738
float prevForceN = axle . DriveForceN ;
@@ -2736,17 +2748,46 @@ protected virtual void UpdateTractiveForce(float elapsedClockSeconds)
2736
2748
else adhesionLimit = axle . MaximumWheelAdhesion ;
2737
2749
axle . DriveForceN = Math . Sign ( axle . DriveForceN ) * Math . Min ( adhesionLimit * axle . AxleWeightN , Math . Abs ( axle . DriveForceN ) ) ;
2738
2750
}
2739
- else if ( TractionForceN > 0 ) // only for traction (not for dynamic brake)
2751
+ else if ( SlipControlSystem == SlipControlType . CutPower )
2752
+ {
2753
+ if ( TractionForceN > 0 )
2754
+ {
2755
+ if ( axle . HuDIsWheelSlip ) SlipControlActive [ i ] = true ;
2756
+ }
2757
+ else
2758
+ {
2759
+ // Only restore traction when throttle is set to 0
2760
+ SlipControlActive [ i ] = false ;
2761
+ }
2762
+ // Disable traction in the axle if slipping
2763
+ if ( SlipControlActive [ i ] ) axle . DriveForceN = 0 ;
2764
+ }
2765
+ else if ( SlipControlSystem == SlipControlType . ReduceForce )
2740
2766
{
2741
- if ( WheelslipCausesThrottleDown && WheelSlip )
2767
+ if ( TractionForceN > 0 && axle . DriveForceN != 0 && AdvancedAdhesionModel )
2742
2768
{
2743
- // Disable traction in the axle if slipping
2744
- axle . DriveForceN = 0 ;
2769
+ if ( axle . SlipPercent > axle . SlipWarningTresholdPercent ) SlipControlActive [ i ] = true ;
2745
2770
}
2746
- else if ( AntiSlip && AdvancedAdhesionModel && WheelSlipWarning )
2771
+ else
2747
2772
{
2748
- // Reduce tractive force to 0 in 3 seconds until wheel slip warning ends
2749
- float newForceN = Math . Max ( Math . Abs ( prevForceN ) - TractiveForceN * axle . TractiveForceFraction * elapsedClockSeconds / 3 , 0 ) ;
2773
+ SlipControlActive [ i ] = false ;
2774
+ }
2775
+ if ( SlipControlActive [ i ] )
2776
+ {
2777
+ float absForceN = Math . Abs ( axle . DriveForceN ) ;
2778
+ float newForceN ;
2779
+ if ( axle . SlipPercent < axle . SlipWarningTresholdPercent * 0.9f )
2780
+ {
2781
+ // If well below slip threshold, restore full power in 10 seconds
2782
+ newForceN = Math . Min ( Math . Abs ( prevForceN ) + absForceN * elapsedClockSeconds / 10 , absForceN ) ;
2783
+
2784
+ // If full force is restored, disengage slip control
2785
+ if ( newForceN / absForceN > 0.95f ) SlipControlActive [ i ] = false ;
2786
+ }
2787
+ else
2788
+ {
2789
+ newForceN = Math . Max ( Math . Abs ( prevForceN ) - absForceN * elapsedClockSeconds / 3 , 0 ) ;
2790
+ }
2750
2791
if ( axle . DriveForceN > 0 && prevForceN >= 0 ) axle . DriveForceN = newForceN ;
2751
2792
else if ( axle . DriveForceN < 0 && prevForceN <= 0 ) axle . DriveForceN = - newForceN ;
2752
2793
}
0 commit comments