@@ -703,6 +703,7 @@ public float SlipDerivationPercentpS
703703 }
704704
705705 double integratorError ;
706+ int waitBeforeSpeedingUp ;
706707 int waitBeforeChangingRate ;
707708
708709 /// <summary>
@@ -865,64 +866,87 @@ void Integrate(float elapsedClockSeconds)
865866 {
866867 if ( elapsedClockSeconds <= 0 ) return ;
867868 double prevSpeedMpS = AxleSpeedMpS ;
868-
869- float upperSubStepLimit = 100 ;
870- float lowerSubStepLimit = 1 ;
871-
872- // use straight line graph approximation to increase substeps as slipspeed increases towards the threshold speed point
873- // Points are 1 = (0, upperLimit) and 2 = (threshold, lowerLimit)
874- var AdhesGrad = ( ( upperSubStepLimit - lowerSubStepLimit ) / ( WheelSlipThresholdMpS - 0 ) ) ;
875- var targetNumOfSubstepsPS = Math . Abs ( ( AdhesGrad * SlipSpeedMpS ) + lowerSubStepLimit ) ;
876- if ( float . IsNaN ( ( float ) targetNumOfSubstepsPS ) ) targetNumOfSubstepsPS = 1 ;
877-
878- if ( SlipSpeedMpS > WheelSlipThresholdMpS ) // if in wheel slip then maximise the substeps
879- {
880- targetNumOfSubstepsPS = upperSubStepLimit ;
881- }
882869
883- if ( Math . Abs ( integratorError ) < 0.000277 && ! IsWheelSlip && ! IsWheelSlipWarning && SlipSpeedMpS < 0.25 * WheelSlipThresholdMpS && SlipSpeedMpS < previousSlipSpeedMpS )
870+ if ( UsePolachAdhesion )
884871 {
885- if ( -- waitBeforeChangingRate <= 0 ) //wait for a while before changing the integration rate
872+
873+ float upperSubStepLimit = 100 ;
874+ float lowerSubStepLimit = 1 ;
875+
876+ // use straight line graph approximation to increase substeps as slipspeed increases towards the threshold speed point
877+ // Points are 1 = (0, upperLimit) and 2 = (threshold, lowerLimit)
878+ var AdhesGrad = ( ( upperSubStepLimit - lowerSubStepLimit ) / ( WheelSlipThresholdMpS - 0 ) ) ;
879+ var targetNumOfSubstepsPS = Math . Abs ( ( AdhesGrad * SlipSpeedMpS ) + lowerSubStepLimit ) ;
880+ if ( float . IsNaN ( ( float ) targetNumOfSubstepsPS ) ) targetNumOfSubstepsPS = 1 ;
881+
882+ if ( SlipSpeedMpS > WheelSlipThresholdMpS ) // if in wheel slip then maximise the substeps
886883 {
887- NumOfSubstepsPS -= 2 ; // decrease substeps when under low slip conditions
888- waitBeforeChangingRate = 30 ;
884+ targetNumOfSubstepsPS = upperSubStepLimit ;
889885 }
890- }
891- else if ( targetNumOfSubstepsPS > NumOfSubstepsPS ) // increase substeps
892- {
893- if ( -- waitBeforeChangingRate <= 0 ) //wait for a while before changing the integration rate
894- {
895886
896- if ( IsWheelSlip || IsWheelSlipWarning || SlipSpeedMpS > previousSlipSpeedMpS )
887+ if ( Math . Abs ( integratorError ) < 0.000277 && ! IsWheelSlip && ! IsWheelSlipWarning && SlipSpeedMpS < 0.25 * WheelSlipThresholdMpS && SlipSpeedMpS < previousSlipSpeedMpS )
888+ {
889+ if ( -- waitBeforeChangingRate <= 0 ) //wait for a while before changing the integration rate
897890 {
898- // this speeds up the substep increase if the slip speed approaches the threshold or has exceeded it, ie "critical conditions".
899- NumOfSubstepsPS += 10 ;
900- waitBeforeChangingRate = 5 ;
891+ NumOfSubstepsPS -= 2 ; // decrease substeps when under low slip conditions
892+ waitBeforeChangingRate = 30 ;
901893 }
902- else
894+ }
895+ else if ( targetNumOfSubstepsPS > NumOfSubstepsPS ) // increase substeps
896+ {
897+ if ( -- waitBeforeChangingRate <= 0 ) //wait for a while before changing the integration rate
903898 {
904- // this speeds ups the substeps under "non critical" conditions
905- NumOfSubstepsPS += 3 ;
906- waitBeforeChangingRate = 30 ;
899+
900+ if ( IsWheelSlip || IsWheelSlipWarning || SlipSpeedMpS > previousSlipSpeedMpS )
901+ {
902+ // this speeds up the substep increase if the slip speed approaches the threshold or has exceeded it, ie "critical conditions".
903+ NumOfSubstepsPS += 10 ;
904+ waitBeforeChangingRate = 5 ;
905+ }
906+ else
907+ {
908+ // this speeds ups the substeps under "non critical" conditions
909+ NumOfSubstepsPS += 3 ;
910+ waitBeforeChangingRate = 30 ;
911+ }
912+
907913 }
908-
909914 }
915+ else if ( targetNumOfSubstepsPS < NumOfSubstepsPS ) // decrease sub steps
916+ {
917+ if ( -- waitBeforeChangingRate <= 0 ) //wait for a while before changing the integration rate
918+ {
919+ NumOfSubstepsPS -= 3 ;
920+ waitBeforeChangingRate = 30 ;
921+ }
922+ }
923+
924+ // keeps the substeps to a relevant upper and lower limits
925+ if ( NumOfSubstepsPS < lowerSubStepLimit )
926+ NumOfSubstepsPS = ( int ) lowerSubStepLimit ;
927+
928+ if ( NumOfSubstepsPS > upperSubStepLimit )
929+ NumOfSubstepsPS = ( int ) upperSubStepLimit ;
930+
910931 }
911- else if ( targetNumOfSubstepsPS < NumOfSubstepsPS ) // decrease sub steps
932+ else
912933 {
913- if ( -- waitBeforeChangingRate <= 0 ) //wait for a while before changing the integration rate
934+ if ( Math . Abs ( integratorError ) > Math . Max ( ( Math . Abs ( SlipSpeedMpS ) - 1 ) * 0.01f , 0.001f ) )
914935 {
915- NumOfSubstepsPS -= 3 ;
916- waitBeforeChangingRate = 30 ;
936+ ++ NumOfSubstepsPS ;
937+ waitBeforeSpeedingUp = 100 ;
938+ }
939+ else
940+ {
941+ if ( -- waitBeforeSpeedingUp <= 0 ) //wait for a while before speeding up the integration
942+ {
943+ -- NumOfSubstepsPS ;
944+ waitBeforeSpeedingUp = 10 ; //not so fast ;)
945+ }
917946 }
918- }
919-
920- // keeps the substeps to a relevant upper and lower limits
921- if ( NumOfSubstepsPS < lowerSubStepLimit )
922- NumOfSubstepsPS = ( int ) lowerSubStepLimit ;
923947
924- if ( NumOfSubstepsPS > upperSubStepLimit )
925- NumOfSubstepsPS = ( int ) upperSubStepLimit ;
948+ NumOfSubstepsPS = Math . Max ( Math . Min ( NumOfSubstepsPS , 50 ) , 1 ) ;
949+ }
926950
927951 double dt = elapsedClockSeconds / NumOfSubstepsPS ;
928952 double hdt = dt / 2 ;
@@ -931,6 +955,27 @@ void Integrate(float elapsedClockSeconds)
931955 for ( int i = 0 ; i < NumOfSubstepsPS ; i ++ )
932956 {
933957 var k1 = GetAxleMotionVariation ( AxleSpeedMpS , dt ) ;
958+
959+ if ( i == 0 && ! UsePolachAdhesion )
960+ {
961+ if ( k1 . Item1 * dt > Math . Max ( ( Math . Abs ( SlipSpeedMpS ) - 1 ) * 10 , 1 ) / 100 )
962+ {
963+ NumOfSubstepsPS = Math . Min ( NumOfSubstepsPS + 5 , 50 ) ;
964+ dt = elapsedClockSeconds / NumOfSubstepsPS ;
965+ hdt = dt / 2 ;
966+ }
967+
968+ if ( Math . Sign ( AxleSpeedMpS + k1 . Item1 * dt ) != Math . Sign ( AxleSpeedMpS ) && BrakeRetardForceN + frictionN > Math . Abs ( driveForceN - k1 . Item3 ) )
969+ {
970+ AxlePositionRad += AxleSpeedMpS * hdt ;
971+ AxlePositionRad = MathHelper . WrapAngle ( ( float ) AxlePositionRad ) ;
972+ AxleSpeedMpS = 0 ;
973+ AxleForceN = 0 ;
974+ DriveForceN = ( float ) k1 . Item4 ;
975+ return ;
976+ }
977+ }
978+
934979 var k2 = GetAxleMotionVariation ( AxleSpeedMpS + k1 . Item1 * hdt , hdt ) ;
935980 var k3 = GetAxleMotionVariation ( AxleSpeedMpS + k2 . Item1 * hdt , hdt ) ;
936981 var k4 = GetAxleMotionVariation ( AxleSpeedMpS + k3 . Item1 * dt , dt ) ;
0 commit comments