5959using Orts . Simulation . RollingStocks . SubSystems . PowerTransmissions ;
6060using ORTS . Common ;
6161using ORTS . Scripting . Api ;
62+ using SharpDX . Direct3D9 ;
6263using System ;
6364using System . Collections . Generic ;
6465using System . Diagnostics ;
@@ -2499,18 +2500,6 @@ protected virtual void UpdateControllers(float elapsedClockSeconds)
24992500 }
25002501#endif
25012502 }
2502- public void CalculateForcePowerLimit ( ref float targetForceN , ref float maxForceN , float targetPowerW , float maxPowerW )
2503- {
2504- if ( targetForceN * AbsTractionSpeedMpS > targetPowerW )
2505- {
2506- targetForceN = targetPowerW / AbsTractionSpeedMpS ;
2507- }
2508- if ( targetForceN > maxForceN ) targetForceN = maxForceN ;
2509- if ( targetForceN * AbsTractionSpeedMpS > maxPowerW )
2510- {
2511- targetForceN = maxForceN = maxPowerW / AbsTractionSpeedMpS ;
2512- }
2513- }
25142503 public void UpdateForceWithRamp ( ref float forceN , float elapsedClockSeconds , float targetForceN , float maxForceN , float targetPowerW , float maxPowerW , float rampUpNpS = 0 , float rampDownNpS = 0 , float rampZeroNpS = 0 )
25152504 {
25162505 if ( targetForceN > maxForceN ) targetForceN = maxForceN ;
@@ -2528,6 +2517,40 @@ public void UpdateForceWithRamp(ref float forceN, float elapsedClockSeconds, flo
25282517 else forceN = targetForceN ;
25292518 }
25302519 }
2520+ public virtual float GetAvailableTractionForceN ( float t )
2521+ {
2522+ if ( t <= 0 ) return 0 ;
2523+ float powerW = float . MaxValue ;
2524+ float forceN ;
2525+ if ( this is MSTSElectricLocomotive electric && electric . ElectricPowerSupply . MaximumPowerW > 0 )
2526+ powerW = electric . ElectricPowerSupply . MaximumPowerW * t * ( 1 - PowerReduction ) ;
2527+ if ( TractiveForceCurves == null )
2528+ {
2529+ powerW = Math . Min ( powerW , MaxPowerW * t * t * ( 1 - PowerReduction ) ) ;
2530+
2531+ if ( AbsTractionSpeedMpS > MaxSpeedMpS - 0.05f )
2532+ {
2533+ forceN = 20 * ( MaxSpeedMpS - AbsTractionSpeedMpS ) * MaxForceN * ( 1 - PowerReduction ) ;
2534+ }
2535+ else if ( AbsTractionSpeedMpS > MaxSpeedMpS )
2536+ {
2537+ forceN = 0 ;
2538+ }
2539+ else
2540+ {
2541+ forceN = MaxForceN * ( 1 - PowerReduction ) ;
2542+ }
2543+ forceN *= t ;
2544+ }
2545+ else
2546+ {
2547+ forceN = TractiveForceCurves . Get ( t , AbsTractionSpeedMpS ) * ( 1 - PowerReduction ) ;
2548+ if ( forceN < 0 && ! TractiveForceCurves . AcceptsNegativeValues ( ) )
2549+ forceN = 0 ;
2550+ }
2551+ if ( forceN * AbsSpeedMpS > powerW ) forceN = powerW / AbsSpeedMpS ;
2552+ return forceN ;
2553+ }
25312554 protected virtual void UpdateTractionForce ( float elapsedClockSeconds )
25322555 {
25332556 float t = ThrottlePercent / 100 ;
@@ -2536,62 +2559,40 @@ protected virtual void UpdateTractionForce(float elapsedClockSeconds)
25362559 if ( t > maxthrottle ) t = maxthrottle ;
25372560 t = MathHelper . Clamp ( t , 0 , 1 ) ;
25382561
2539- if ( maxthrottle > 0 && Direction != Direction . N )
2562+ if ( maxthrottle > 0 && Direction != Direction . N && LocomotivePowerSupply . MainPowerSupplyOn )
25402563 {
2541- float maxPowerW = float . MaxValue ;
2542- float targetPowerW = float . MaxValue ;
2564+ float targetForceN = GetAvailableTractionForceN ( t ) ;
2565+ float limitForceN = GetAvailableTractionForceN ( maxthrottle ) ;
25432566 float maxForceN = float . MaxValue ;
2544- float targetForceN ;
2567+ if ( limitForceN >= targetForceN )
2568+ maxForceN = limitForceN ;
25452569 if ( this is MSTSElectricLocomotive electric )
25462570 {
2547- maxPowerW = electric . ElectricPowerSupply . AvailableTractionPowerW ;
2548- if ( electric . ElectricPowerSupply . MaximumPowerW > 0 )
2549- {
2550- maxPowerW = Math . Min ( maxPowerW , electric . ElectricPowerSupply . MaximumPowerW * maxthrottle ) ;
2551- targetPowerW = electric . ElectricPowerSupply . MaximumPowerW * t ;
2552- }
2553- }
2554- if ( TractiveForceCurves == null )
2555- {
2556- maxPowerW = Math . Min ( maxPowerW , MaxPowerW * maxthrottle * maxthrottle * ( 1 - PowerReduction ) ) ;
2557- targetPowerW = Math . Min ( targetPowerW , MaxPowerW * t * t * ( 1 - PowerReduction ) ) ;
2558-
2559- if ( AbsTractionSpeedMpS > MaxSpeedMpS - 0.05f )
2560- {
2561- maxForceN = 20 * ( MaxSpeedMpS - AbsTractionSpeedMpS ) * MaxForceN * ( 1 - PowerReduction ) ;
2562- }
2563- else if ( AbsTractionSpeedMpS > MaxSpeedMpS )
2564- {
2565- maxForceN = 0 ;
2566- }
2567- else
2568- {
2569- maxForceN = MaxForceN * ( 1 - PowerReduction ) ;
2570- }
2571- targetForceN = maxForceN * t ;
2572- maxForceN *= maxthrottle ;
2571+ float maxPowerW = electric . ElectricPowerSupply . AvailableTractionPowerW ;
2572+ if ( targetForceN * AbsTractionSpeedMpS > maxPowerW ) maxForceN = maxPowerW / AbsTractionSpeedMpS ;
25732573 }
2574- else
2575- {
2576- targetForceN = TractiveForceCurves . Get ( t , AbsTractionSpeedMpS ) * ( 1 - PowerReduction ) ;
2577- float limitForceN = TractiveForceCurves . Get ( maxthrottle , AbsTractionSpeedMpS ) * ( 1 - PowerReduction ) ;
2578- if ( targetForceN < 0 && ! TractiveForceCurves . AcceptsNegativeValues ( ) )
2579- targetForceN = 0 ;
2580- if ( limitForceN < 0 && ! TractiveForceCurves . AcceptsNegativeValues ( ) )
2581- limitForceN = 0 ;
2582- if ( limitForceN >= targetForceN )
2583- maxForceN = limitForceN ;
2584- }
2585- CalculateForcePowerLimit ( ref targetForceN , ref maxForceN , targetPowerW , maxPowerW ) ;
2586- CurrentMaxTractionForceN = maxForceN ;
25872574 UpdateForceWithRamp ( ref TractionForceN , elapsedClockSeconds , targetForceN , maxForceN , TractionForceRampUpNpS , TractionForceRampDownNpS , TractionForceRampDownToZeroNpS ) ;
25882575 }
25892576 else
25902577 {
2591- CurrentMaxTractionForceN = TractionForceN = 0f ;
2578+ TractionForceN = 0f ;
25922579 }
25932580 TractiveForceN = TractionForceN ;
25942581 }
2582+ public float GetAvailableDynamicBrakeForceN ( float d )
2583+ {
2584+ float forceN = 0 ;
2585+ if ( d > 0 && DynamicBrakeForceCurves != null && AbsSpeedMpS > 0 )
2586+ {
2587+ forceN = DynamicBrakeForceCurves . Get ( d , AbsSpeedMpS ) * ( 1 - PowerReduction ) ;
2588+ if ( LocomotivePowerSupply . MaximumDynamicBrakePowerW > 0 )
2589+ {
2590+ float powerW = LocomotivePowerSupply . MaximumDynamicBrakePowerW * ( 1 - PowerReduction ) ;
2591+ if ( forceN * AbsSpeedMpS > powerW ) forceN = powerW / AbsSpeedMpS ;
2592+ }
2593+ }
2594+ return forceN ;
2595+ }
25952596 protected virtual void UpdateDynamicBrakeForce ( float elapsedClockSeconds )
25962597 {
25972598 if ( ThrottlePercent <= 0 && TractionForceN <= 0 && LocomotivePowerSupply . DynamicBrakeAvailable && Direction != Direction . N )
@@ -2624,26 +2625,16 @@ protected virtual void UpdateDynamicBrakeForce(float elapsedClockSeconds)
26242625 if ( dynamicLimited ) d = maxdynamic ;
26252626 d = MathHelper . Clamp ( d , 0 , 1 ) ;
26262627
2627- if ( maxdynamic > 0 && DynamicBrakeForceCurves != null && AbsSpeedMpS > 0 )
2628+ if ( maxdynamic > 0 && AbsSpeedMpS > 0 )
26282629 {
2629- float maxPowerW = float . MaxValue ;
2630- float targetPowerW = float . MaxValue ;
2631- float targetForceN = DynamicBrakeForceCurves . Get ( d , AbsTractionSpeedMpS ) * ( 1 - PowerReduction ) ;
2632- float limitForceN = DynamicBrakeForceCurves . Get ( maxdynamic , AbsTractionSpeedMpS ) * ( 1 - PowerReduction ) ;
2630+ float limitForceN = GetAvailableDynamicBrakeForceN ( maxdynamic ) ;
2631+ float targetForceN = GetAvailableDynamicBrakeForceN ( d ) ;
26332632 float maxForceN = limitForceN >= targetForceN ? limitForceN : float . MaxValue ;
2634- if ( LocomotivePowerSupply . MaximumDynamicBrakePowerW > 0 )
2635- {
2636- maxPowerW = LocomotivePowerSupply . MaximumDynamicBrakePowerW * ( 1 - PowerReduction ) ;
2637- targetPowerW = maxPowerW * d ;
2638- maxPowerW *= maxdynamic ;
2639- }
2640- CalculateForcePowerLimit ( ref targetForceN , ref maxForceN , targetPowerW , maxPowerW ) ;
2641- CurrentMaxDynamicBrakeForceN = maxForceN ;
26422633 UpdateForceWithRamp ( ref DynamicBrakeForceN , elapsedClockSeconds , targetForceN , maxForceN , DynamicBrakeForceRampUpNpS , DynamicBrakeForceRampDownNpS , DynamicBrakeForceRampDownToZeroNpS ) ;
26432634 }
26442635 else
26452636 {
2646- CurrentMaxDynamicBrakeForceN = DynamicBrakeForceN = 0 ; // Set dynamic brake force to zero if in Notch 0 position
2637+ DynamicBrakeForceN = 0 ; // Set dynamic brake force to zero if in Notch 0 position
26472638 }
26482639 TractiveForceN -= ( SpeedMpS > 0 ? 1 : SpeedMpS < 0 ? - 1 : Direction == Direction . Reverse ? - 1 : 1 ) * DynamicBrakeForceN ;
26492640 }
0 commit comments