Exemplo n.º 1
0
        /// <summary>
        /// Main Update method
        /// - computes slip characteristics to get new axle force
        /// - computes axle dynamic model according to its driveType
        /// - computes wheelslip indicators
        /// </summary>
        /// <param name="timeSpan"></param>
        public virtual void Update(float timeSpan)
        {
            //Update axle force ( = k * loadTorqueNm)
            axleForceN = AxleWeightN * SlipCharacteristics(AxleSpeedMpS - TrainSpeedMpS, TrainSpeedMpS, AdhesionK, AdhesionConditions, Adhesion2);

            // The Axle module subtracts brake force from the motive force for calculation purposes. However brake force is already taken into account in the braking module.
            // And thus there is a duplication of the braking effect in OR. To compensate for this, after the slip characteristics have been calculated, the output of the axle module
            // has the brake force "added" back in to give the appropriate motive force output for the locomotive. Braking force is handled separately.
            // Hence CompensatedAxleForce is the actual output force on the axle.
            var compensateAxleForceN = axleForceN;

            switch (driveType)
            {
            case AxleDriveType.NotDriven:
                //Axle revolutions integration
                axleSpeedMpS = AxleRevolutionsInt.Integrate(timeSpan,
                                                            axleDiameterM * axleDiameterM / (4.0f * (totalInertiaKgm2))
                                                            * (2.0f * transmissionRatio / axleDiameterM * (-Math.Abs(brakeRetardForceN)) - AxleForceN));
                break;

            case AxleDriveType.MotorDriven:
                //Axle revolutions integration
                if (TrainSpeedMpS == 0.0f)
                {
                    dampingNs         = 0.0f;
                    brakeRetardForceN = 0.0f;
                }
                axleSpeedMpS = AxleRevolutionsInt.Integrate(timeSpan,
                                                            axleDiameterM * axleDiameterM / (4.0f * (totalInertiaKgm2))
                                                            * (2.0f * transmissionRatio / axleDiameterM * motor.DevelopedTorqueNm * transmissionEfficiency
                                                               - Math.Abs(brakeRetardForceN) - (axleSpeedMpS > 0.0 ? Math.Abs(dampingNs) : 0.0f)) - AxleForceN);

                //update motor values
                motor.RevolutionsRad = axleSpeedMpS * 2.0f * transmissionRatio / (axleDiameterM);
                motor.Update(timeSpan);
                break;

            case AxleDriveType.ForceDriven:
                //Axle revolutions integration
                if (TrainSpeedMpS > 0.01f)
                {
                    axleSpeedMpS = AxleRevolutionsInt.Integrate(timeSpan,
                                                                (
                                                                    driveForceN * transmissionEfficiency
                                                                    - brakeRetardForceN
                                                                    - slipDerivationMpSS * dampingNs
                                                                    - Math.Abs(SlipSpeedMpS) * frictionN
                                                                    - AxleForceN
                                                                )
                                                                / totalInertiaKgm2
                                                                );

                    compensateAxleForceN = axleForceN + brakeRetardForceN;

                    if (Math.Abs(compensateAxleForceN) > Math.Abs(driveForceN))
                    {
                        compensateAxleForceN = driveForceN;
                    }

                    if (brakeRetardForceN > driveForceN && AxleSpeedMpS < 0.1f)
                    {
                        axleSpeedMpS         = 0.0f;
                        axleForceN           = -brakeRetardForceN + driveForceN;
                        compensateAxleForceN = driveForceN;
                    }
                }
                else if (TrainSpeedMpS < -0.01f)
                {
                    axleSpeedMpS = AxleRevolutionsInt.Integrate(timeSpan,
                                                                (
                                                                    driveForceN * transmissionEfficiency
                                                                    + brakeRetardForceN
                                                                    - slipDerivationMpSS * dampingNs
                                                                    + Math.Abs(SlipSpeedMpS) * frictionN
                                                                    - AxleForceN
                                                                )
                                                                / totalInertiaKgm2
                                                                );

                    compensateAxleForceN = axleForceN - brakeRetardForceN;

                    if (Math.Abs(compensateAxleForceN) > Math.Abs(driveForceN))
                    {
                        compensateAxleForceN = driveForceN;
                    }

                    if (brakeRetardForceN > Math.Abs(driveForceN) && AxleSpeedMpS > -0.1f)
                    {
                        axleSpeedMpS         = 0.0f;
                        axleForceN           = brakeRetardForceN - driveForceN;
                        compensateAxleForceN = driveForceN;
                    }
                }
                else
                {
                    if (Math.Abs(driveForceN) < 1f)
                    {
                        Reset();
                        axleSpeedMpS = 0.0f;
                        //axleForceN = 0.0f;
                    }
                    else
                    {
                        axleForceN           = driveForceN - brakeRetardForceN;
                        compensateAxleForceN = driveForceN;
                        if (Math.Abs(axleSpeedMpS) < 0.01f)
                        {
                            Reset();
                        }
                    }

                    //Reset(TrainSpeedMpS);
                    //axleForceN = driveForceN - brakeRetardForceN;
                    //axleSpeedMpS = AxleRevolutionsInt.Value;
                }
                break;

            default:
                totalInertiaKgm2 = inertiaKgm2;
                break;
            }
            if (timeSpan > 0.0f)
            {
                slipDerivationMpSS   = (SlipSpeedMpS - previousSlipSpeedMpS) / timeSpan;
                previousSlipSpeedMpS = SlipSpeedMpS;

                slipDerivationPercentpS = (SlipSpeedPercent - previousSlipPercent) / timeSpan;
                previousSlipPercent     = SlipSpeedPercent;
            }
            //Stability Correction
            if (StabilityCorrection)
            {
                if (slipDerivationPercentpS > 300.0f)
                {
                    adhesionK += 0.0001f * slipDerivationPercentpS;
                }
                else
                {
                    adhesionK = (adhesionK <= 0.7f) ? 0.7f : (adhesionK - 0.005f);
                }
            }

            // Set output MotiveForce to actual value exclusive of brake force.
            compensatedaxleForceN = CompensatedFilterMovingAverage.Update(Math.Abs(compensatedaxleForceN) > Math.Abs(driveForceN) ? driveForceN : compensateAxleForceN);

            axleForceN = FilterMovingAverage.Update(Math.Abs(axleForceN) > Math.Abs(driveForceN) ? driveForceN : axleForceN);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Main Update method
        /// - computes slip characteristics to get new axle force
        /// - computes axle dynamic model according to its driveType
        /// - computes wheelslip indicators
        /// </summary>
        /// <param name="timeSpan"></param>
        public virtual void Update(float timeSpan)
        {
            //Update axle force ( = k * loadTorqueNm)
            axleForceN = AxleWeightN * SlipCharacteristics(AxleSpeedMpS - TrainSpeedMpS, TrainSpeedMpS, AdhesionK, AdhesionConditions, Adhesion2);

            switch (driveType)
            {
            case AxleDriveType.NotDriven:
                //Axle revolutions integration
                axleSpeedMpS = AxleRevolutionsInt.Integrate(timeSpan,
                                                            axleDiameterM * axleDiameterM / (4.0f * (totalInertiaKgm2))
                                                            * (2.0f * transmissionRatio / axleDiameterM * (-Math.Abs(brakeRetardForceN)) - AxleForceN));
                break;

            case AxleDriveType.MotorDriven:
                //Axle revolutions integration
                if (TrainSpeedMpS == 0.0f)
                {
                    dampingNs         = 0.0f;
                    brakeRetardForceN = 0.0f;
                }
                axleSpeedMpS = AxleRevolutionsInt.Integrate(timeSpan,
                                                            axleDiameterM * axleDiameterM / (4.0f * (totalInertiaKgm2))
                                                            * (2.0f * transmissionRatio / axleDiameterM * motor.DevelopedTorqueNm * transmissionEfficiency
                                                               - Math.Abs(brakeRetardForceN) - (axleSpeedMpS > 0.0 ? Math.Abs(dampingNs) : 0.0f)) - AxleForceN);

                //update motor values
                motor.RevolutionsRad = axleSpeedMpS * 2.0f * transmissionRatio / (axleDiameterM);
                motor.Update(timeSpan);
                break;

            case AxleDriveType.ForceDriven:
                //Axle revolutions integration
                if (TrainSpeedMpS > 0.01f)
                {
                    axleSpeedMpS = AxleRevolutionsInt.Integrate(timeSpan,
                                                                (
                                                                    driveForceN * transmissionEfficiency
                                                                    - brakeRetardForceN
                                                                    - slipDerivationMpSS * dampingNs
                                                                    - Math.Abs(SlipSpeedMpS) * frictionN
                                                                    - AxleForceN
                                                                )
                                                                / totalInertiaKgm2
                                                                );

                    if (brakeRetardForceN > driveForceN && AxleSpeedMpS < 0.1f)
                    {
                        axleSpeedMpS = 0.0f;
                        axleForceN   = -brakeRetardForceN + driveForceN;
                    }
                }
                else if (TrainSpeedMpS < -0.01f)
                {
                    axleSpeedMpS = AxleRevolutionsInt.Integrate(timeSpan,
                                                                (
                                                                    driveForceN * transmissionEfficiency
                                                                    + brakeRetardForceN
                                                                    - slipDerivationMpSS * dampingNs
                                                                    + Math.Abs(SlipSpeedMpS) * frictionN
                                                                    - AxleForceN
                                                                )
                                                                / totalInertiaKgm2
                                                                );

                    if (brakeRetardForceN > Math.Abs(driveForceN) && AxleSpeedMpS > -0.1f)
                    {
                        axleSpeedMpS = 0.0f;
                        axleForceN   = brakeRetardForceN - driveForceN;
                    }
                }
                else
                {
                    if (Math.Abs(driveForceN) < 1f)
                    {
                        Reset();
                        axleSpeedMpS = 0.0f;
                        //axleForceN = 0.0f;
                    }
                    else
                    {
                        axleForceN = driveForceN - brakeRetardForceN;
                        if (Math.Abs(axleSpeedMpS) < 0.01f)
                        {
                            Reset();
                        }
                    }

                    //Reset(TrainSpeedMpS);
                    //axleForceN = driveForceN - brakeRetardForceN;
                    //axleSpeedMpS = AxleRevolutionsInt.Value;
                }
                break;

            default:
                totalInertiaKgm2 = inertiaKgm2;
                break;
            }
            if (timeSpan > 0.0f)
            {
                slipDerivationMpSS   = (SlipSpeedMpS - previousSlipSpeedMpS) / timeSpan;
                previousSlipSpeedMpS = SlipSpeedMpS;

                slipDerivationPercentpS = (SlipSpeedPercent - previousSlipPercent) / timeSpan;
                previousSlipPercent     = SlipSpeedPercent;
            }
            //Stability Correction
            if (StabilityCorrection)
            {
                if (slipDerivationPercentpS > 300.0f)
                {
                    adhesionK += 0.0001f * slipDerivationPercentpS;
                }
                else
                {
                    adhesionK = (adhesionK <= 0.7f) ? 0.7f : (adhesionK - 0.005f);
                }
            }

            axleForceN = FilterMovingAverage.Update(Math.Abs(axleForceN) > Math.Abs(driveForceN) ? driveForceN : axleForceN);
        }