コード例 #1
0
    /// <summary>
    /// Add add to v. If v's magnitude > upperlimit, it is set to upperlimit.
    /// </summary>
    public static Vector2 AddWithLimit(Vector2 v, Vector2 add, float upperLimit, LimitMode limitMode = LimitMode.Set)
    {
        v += add;

        if (v.magnitude < upperLimit)
        {
            return(v);
        }
        else
        {
            switch (limitMode)
            {
            case LimitMode.Set:
                return(v.normalized * upperLimit);

            case LimitMode.Smooth:
                if (SubstractMagnitude(v, add.magnitude).magnitude < upperLimit)
                {
                    return(v.normalized * upperLimit);
                }
                else
                {
                    return(SubstractMagnitude(v, add.magnitude));
                }

            default:
                return(v.normalized * upperLimit);
            }
        }
    }
コード例 #2
0
    /// <summary>
    /// Add magnitude to v's magnitude. If v's magnitude > upperlimit, it is set to upperlimit.
    /// </summary>
    public static Vector3 AddWithLimit(Vector3 v, float magnitude, float upperLimit, LimitMode limitMode = LimitMode.Set)
    {
        if (v.magnitude + magnitude < upperLimit)
        {
            return(v.normalized * (v.magnitude + magnitude));
        }
        else
        {
            switch (limitMode)
            {
            case LimitMode.Set:
                return(v.normalized * upperLimit);

            case LimitMode.Smooth:
                if (SubtractMagnitude(v, magnitude).magnitude < upperLimit)
                {
                    return(v.normalized * upperLimit);
                }
                else
                {
                    return(SubtractMagnitude(v, magnitude));
                }

            default:
                return(v.normalized * upperLimit);
            }
        }
    }
 /* This is an API for limits which are not temporary (like the throttle limit set in the GUI)
    The throttleFixedLimit is what consumers like the NodeExecutor should use to compute acceleration and burntime.
    This deliberately sets both values.  The actually applied throttle limit may be lower than thottleFixedLimit
    (i.e. there may be a more limiting temp limit) */
 private void setFixedLimit(float limit, LimitMode mode)
 {
     if (throttleLimit > limit) {
         throttleLimit = limit;
     }
     throttleFixedLimit = limit;
     limiter = mode;
 }
コード例 #4
0
 public AxisLimit(Transform lookTarget, Transform camera, float limitRange, Vector3 axisVector)
 {
     m_LimitMode       = LimitMode.None;
     m_RemoveLimitMode = RemoveLimitMode.None;
     m_LookTarget      = lookTarget;
     m_Camera          = camera;
     m_LimitRange      = limitRange;
     m_AxisVector      = axisVector;
     m_Enable          = true;
 }
コード例 #5
0
ファイル: BTFilter.cs プロジェクト: yasirmx/UmbraFeraMain
        protected override void OnNodeInspectorGUI()
        {
            limitMode = (LimitMode)UnityEditor.EditorGUILayout.EnumPopup("Mode", limitMode);

            if (limitMode == LimitMode.CoolDown)
            {
                coolDownTime = (BBFloat)EditorUtils.BBVariableField("CoolDown Time", coolDownTime);
            }
            else
            if (limitMode == LimitMode.LimitNumberOfTimes)
            {
                maxCount = (BBInt)EditorUtils.BBVariableField("Max Times", maxCount);
            }

            inactiveWhenLimited = UnityEditor.EditorGUILayout.Toggle("Inactive When Limited", inactiveWhenLimited);
        }
コード例 #6
0
        public override void Drive(FlightCtrlState s)
        {
            if (core.GetComputerModule <MechJebModuleThrustWindow>().hidden&& core.GetComputerModule <MechJebModuleAscentGuidance>().hidden)
            {
                return;
            }

            if ((tmode != TMode.OFF) && (vesselState.thrustAvailable > 0))
            {
                double spd = 0;

                switch (tmode)
                {
                case TMode.KEEP_ORBITAL:
                    spd = vesselState.speedOrbital;
                    break;

                case TMode.KEEP_SURFACE:
                    spd = vesselState.speedSurface;
                    break;

                case TMode.KEEP_VERTICAL:
                    spd = vesselState.speedVertical;
                    Vector3d rot = Vector3d.up;
                    if (trans_kill_h)
                    {
                        Vector3 hsdir = Vector3.Exclude(vesselState.up, vessel.srf_velocity);
                        Vector3 dir   = -hsdir + vesselState.up * Math.Max(Math.Abs(spd), 20 * mainBody.GeeASL);
                        if ((Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue) > 5000) && (hsdir.magnitude > Math.Max(Math.Abs(spd), 100 * mainBody.GeeASL) * 2))
                        {
                            tmode         = TMode.DIRECT;
                            trans_spd_act = 100;
                            rot           = -hsdir;
                        }
                        else
                        {
                            rot = dir.normalized;
                        }
                        core.attitude.attitudeTo(rot, AttitudeReference.INERTIAL, null);
                    }
                    break;
                }

                double t_err = (trans_spd_act - spd) / vesselState.maxThrustAccel;
                if ((tmode == TMode.KEEP_ORBITAL && Vector3d.Dot(vesselState.forward, vessel.obt_velocity) < 0) ||
                    (tmode == TMode.KEEP_SURFACE && Vector3d.Dot(vesselState.forward, vessel.srf_velocity) < 0))
                {
                    //allow thrust to declerate
                    t_err *= -1;
                }

                double t_act = pid.Compute(t_err);

                if ((tmode != TMode.KEEP_VERTICAL) ||
                    !trans_kill_h ||
                    (core.attitude.attitudeError < 2) ||
                    ((Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue) < 1000) && (core.attitude.attitudeError < 90)))
                {
                    if (tmode == TMode.DIRECT)
                    {
                        trans_prev_thrust = targetThrottle = trans_spd_act / 100.0F;
                    }
                    else
                    {
                        trans_prev_thrust = targetThrottle = Mathf.Clamp01(trans_prev_thrust + (float)t_act);
                    }
                }
                else
                {
                    if ((core.attitude.attitudeError >= 2) && (vesselState.torqueThrustPYAvailable > Math.Min(vesselState.torqueAvailable.x, vesselState.torqueAvailable.z) * 10))
                    {
                        trans_prev_thrust = targetThrottle = 0.1F;
                    }
                    else
                    {
                        trans_prev_thrust = targetThrottle = 0;
                    }
                }
            }

            // Only set throttle if a module need it. Othewise let the user or other mods set it
            // There is always at least 1 user : the module itself (why ?)
            if (users.Count() > 1)
            {
                s.mainThrottle = targetThrottle;
            }

            float throttleLimit = 1;

            limiter = LimitMode.None;

            if (limitThrottle)
            {
                if (maxThrottle < throttleLimit)
                {
                    limiter = LimitMode.Throttle;
                }
                throttleLimit = Mathf.Min(throttleLimit, (float)maxThrottle);
            }

            if (limitToTerminalVelocity)
            {
                float limit = TerminalVelocityThrottle();
                if (limit < throttleLimit)
                {
                    limiter = LimitMode.TerminalVelocity;
                }
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limitToPreventOverheats)
            {
                float limit = TemperatureSafetyThrottle();
                if (limit < throttleLimit)
                {
                    limiter = LimitMode.Temperature;
                }
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limitAcceleration)
            {
                float limit = AccelerationLimitedThrottle();
                if (limit < throttleLimit)
                {
                    limiter = LimitMode.Acceleration;
                }
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limitToPreventFlameout)
            {
                // This clause benefits being last: if we don't need much air
                // due to prior limits, we can close some intakes.
                float limit = FlameoutSafetyThrottle();
                if (limit < throttleLimit)
                {
                    limiter = LimitMode.Flameout;
                }
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (double.IsNaN(throttleLimit))
            {
                throttleLimit = 0;
            }
            throttleLimit = Mathf.Clamp01(throttleLimit);

            vesselState.throttleLimit = throttleLimit;

            if (s.mainThrottle < throttleLimit)
            {
                limiter = LimitMode.None;
            }

            s.mainThrottle = Mathf.Min(s.mainThrottle, throttleLimit);

            if (smoothThrottle)
            {
                s.mainThrottle = SmoothThrottle(s.mainThrottle);
            }

            if (double.IsNaN(s.mainThrottle))
            {
                s.mainThrottle = 0;
            }
            s.mainThrottle = Mathf.Clamp01(s.mainThrottle);

            if (s.Z == 0 && vesselState.rcsThrust)
            {
                s.Z = -s.mainThrottle;
            }

            lastThrottle = s.mainThrottle;
        }
コード例 #7
0
        public override void Drive(FlightCtrlState s)
        {
            float threshold = 0.1F;
            bool  _userCommandingRotation = !(Mathfx.Approx(s.pitch, s.pitchTrim, threshold) &&
                                              Mathfx.Approx(s.yaw, s.yawTrim, threshold) &&
                                              Mathfx.Approx(s.roll, s.rollTrim, threshold));
            bool _userCommandingTranslation = !(Math.Abs(s.X) < threshold &&
                                                Math.Abs(s.Y) < threshold &&
                                                Math.Abs(s.Z) < threshold);

            if (_userCommandingRotation && !_userCommandingTranslation)
            {
                userCommandingRotationSmoothed = 2;
            }
            else if (userCommandingRotationSmoothed > 0)
            {
                userCommandingRotationSmoothed--;
            }

            if (core.GetComputerModule <MechJebModuleThrustWindow>().hidden&& core.GetComputerModule <MechJebModuleAscentGuidance>().hidden)
            {
                return;
            }

            if ((tmode != TMode.OFF) && (vesselState.thrustAvailable > 0))
            {
                double spd = 0;

                switch (tmode)
                {
                case TMode.KEEP_ORBITAL:
                    spd = vesselState.speedOrbital;
                    break;

                case TMode.KEEP_SURFACE:
                    spd = vesselState.speedSurface;
                    break;

                case TMode.KEEP_VERTICAL:
                    spd = vesselState.speedVertical;
                    Vector3d rot = Vector3d.up;
                    if (trans_kill_h)
                    {
                        Vector3 hsdir = Vector3.ProjectOnPlane(vesselState.surfaceVelocity, vesselState.up);
                        Vector3 dir   = -hsdir + vesselState.up * Math.Max(Math.Abs(spd), 20 * mainBody.GeeASL);
                        if ((Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue) > 5000) && (hsdir.magnitude > Math.Max(Math.Abs(spd), 100 * mainBody.GeeASL) * 2))
                        {
                            tmode         = TMode.DIRECT;
                            trans_spd_act = 100;
                            rot           = -hsdir;
                        }
                        else
                        {
                            rot = dir.normalized;
                        }
                        core.attitude.attitudeTo(rot, AttitudeReference.INERTIAL, null);
                    }
                    break;
                }

                double t_err = (trans_spd_act - spd) / vesselState.maxThrustAccel;
                if ((tmode == TMode.KEEP_ORBITAL && Vector3d.Dot(vesselState.forward, vesselState.orbitalVelocity) < 0) ||
                    (tmode == TMode.KEEP_SURFACE && Vector3d.Dot(vesselState.forward, vesselState.surfaceVelocity) < 0))
                {
                    //allow thrust to declerate
                    t_err *= -1;
                }

                double t_act = pid.Compute(t_err);

                if ((tmode != TMode.KEEP_VERTICAL) ||
                    !trans_kill_h ||
                    (core.attitude.attitudeError < 2) ||
                    ((Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue) < 1000) && (core.attitude.attitudeError < 90)))
                {
                    if (tmode == TMode.DIRECT)
                    {
                        trans_prev_thrust = targetThrottle = trans_spd_act / 100.0F;
                    }
                    else
                    {
                        trans_prev_thrust = targetThrottle = Mathf.Clamp01(trans_prev_thrust + (float)t_act);
                    }
                }
                else
                {
                    bool useGimbal = (vesselState.torqueFromEngine.x / vessel.ctrlState.mainThrottle > vesselState.torqueAvailable.x * 10) ||
                                     (vesselState.torqueFromEngine.z / vessel.ctrlState.mainThrottle > vesselState.torqueAvailable.z * 10);

                    bool useDiffThrottle = (vesselState.torqueFromDiffThrottle.x > vesselState.torqueAvailable.x * 10) ||
                                           (vesselState.torqueFromDiffThrottle.z > vesselState.torqueAvailable.z * 10);

                    if ((core.attitude.attitudeError >= 2) && (useGimbal || (useDiffThrottle && core.thrust.differentialThrottle)))
                    {
                        trans_prev_thrust = targetThrottle = 0.1F;
                    }
                    else
                    {
                        trans_prev_thrust = targetThrottle = 0;
                    }
                }
            }

            // Only set throttle if a module need it. Othewise let the user or other mods set it
            // There is always at least 1 user : the module itself (why ?)
            if (users.Count() > 1)
            {
                s.mainThrottle = targetThrottle;
            }

            float throttleLimit = 1;

            limiter = LimitMode.None;

            if (limitThrottle)
            {
                if (maxThrottle < throttleLimit)
                {
                    limiter = LimitMode.Throttle;
                }
                throttleLimit = Mathf.Min(throttleLimit, (float)maxThrottle);
            }

            if (limitToTerminalVelocity)
            {
                float limit = TerminalVelocityThrottle();
                if (limit < throttleLimit)
                {
                    limiter = LimitMode.TerminalVelocity;
                }
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limitDynamicPressure)
            {
                float limit = MaximumDynamicPressureThrottle();
                if (limit < throttleLimit)
                {
                    limiter = LimitMode.DynamicPressure;
                }
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limitToPreventOverheats)
            {
                float limit = (float)TemperatureSafetyThrottle();
                if (limit < throttleLimit)
                {
                    limiter = LimitMode.Temperature;
                }
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limitAcceleration)
            {
                float limit = AccelerationLimitedThrottle();
                if (limit < throttleLimit)
                {
                    limiter = LimitMode.Acceleration;
                }
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (electricThrottle && ElectricEngineRunning())
            {
                float limit = ElectricThrottle();
                if (limit < throttleLimit)
                {
                    limiter = LimitMode.Electric;
                }
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limitToPreventFlameout)
            {
                // This clause benefits being last: if we don't need much air
                // due to prior limits, we can close some intakes.
                float limit = FlameoutSafetyThrottle();
                if (limit < throttleLimit)
                {
                    limiter = LimitMode.Flameout;
                }
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limiterMinThrottle && limiter != LimitMode.None && throttleLimit < minThrottle)
            {
                limiter       = LimitMode.MinThrottle;
                throttleLimit = (float)minThrottle;
            }

            if (double.IsNaN(throttleLimit))
            {
                throttleLimit = 0;
            }
            throttleLimit = Mathf.Clamp01(throttleLimit);

            vesselState.throttleLimit = throttleLimit;

            if (s.mainThrottle < throttleLimit)
            {
                limiter = LimitMode.None;
            }

            s.mainThrottle = Mathf.Min(s.mainThrottle, throttleLimit);

            if (smoothThrottle)
            {
                s.mainThrottle = SmoothThrottle(s.mainThrottle);
            }

            if (double.IsNaN(s.mainThrottle))
            {
                s.mainThrottle = 0;
            }
            s.mainThrottle = Mathf.Clamp01(s.mainThrottle);

            if (s.Z == 0 && core.rcs.rcsThrottle && vesselState.rcsThrust)
            {
                s.Z = -s.mainThrottle;
            }

            lastThrottle = s.mainThrottle;

            if (!core.attitude.enabled)
            {
                Vector3d act = new Vector3d(s.pitch, s.yaw, s.roll);
                differentialThrottleDemandedTorque = -Vector3d.Scale(act.xzy, vesselState.torqueFromDiffThrottle * s.mainThrottle * 0.5f);
            }
        }
コード例 #8
0
        public override void Drive(FlightCtrlState s)
        {
            if (core.GetComputerModule<MechJebModuleThrustWindow>().hidden && core.GetComputerModule<MechJebModuleAscentGuidance>().hidden) { return; }

            if ((tmode != TMode.OFF) && (vesselState.thrustAvailable > 0))
            {
                double spd = 0;

                switch (tmode)
                {
                    case TMode.KEEP_ORBITAL:
                        spd = vesselState.speedOrbital;
                        break;
                    case TMode.KEEP_SURFACE:
                        spd = vesselState.speedSurface;
                        break;
                    case TMode.KEEP_VERTICAL:
                        spd = vesselState.speedVertical;
                        Vector3d rot = Vector3d.up;
                        if (trans_kill_h)
                        {
                            Vector3 hsdir = Vector3.Exclude(vesselState.up, vessel.srf_velocity);
                            Vector3 dir = -hsdir + vesselState.up * Math.Max(Math.Abs(spd), 20 * mainBody.GeeASL);
                            if ((Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue) > 5000) && (hsdir.magnitude > Math.Max(Math.Abs(spd), 100 * mainBody.GeeASL) * 2))
                            {
                                tmode = TMode.DIRECT;
                                trans_spd_act = 100;
                                rot = -hsdir;
                            }
                            else
                            {
                                rot = dir.normalized;
                            }
                            core.attitude.attitudeTo(rot, AttitudeReference.INERTIAL, null);
                        }
                        break;
                }

                double t_err = (trans_spd_act - spd) / vesselState.maxThrustAccel;
                if ((tmode == TMode.KEEP_ORBITAL && Vector3d.Dot(vesselState.forward, vessel.obt_velocity) < 0) ||
                   (tmode == TMode.KEEP_SURFACE && Vector3d.Dot(vesselState.forward, vessel.srf_velocity) < 0))
                {
                    //allow thrust to declerate
                    t_err *= -1;
                }

                double t_act = pid.Compute(t_err);

                if ((tmode != TMode.KEEP_VERTICAL)
                    || !trans_kill_h
                    || (core.attitude.attitudeError < 2)
                    || ((Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue) < 1000) && (core.attitude.attitudeError < 90)))
                {
                    if (tmode == TMode.DIRECT)
                    {
                        trans_prev_thrust = targetThrottle = trans_spd_act / 100.0F;
                    }
                    else
                    {
                        trans_prev_thrust = targetThrottle = Mathf.Clamp01(trans_prev_thrust + (float)t_act);
                    }
                }
                else
                {
                    if ((core.attitude.attitudeError >= 2) && (vesselState.torqueThrustPYAvailable > Math.Min( vesselState.torqueAvailable.x, vesselState.torqueAvailable.z) * 10))
                    {
                        trans_prev_thrust = targetThrottle = 0.1F;
                    }
                    else
                    {
                        trans_prev_thrust = targetThrottle = 0;
                    }
                }
            }

            // Only set throttle if a module need it. Othewise let the user or other mods set it
            // There is always at least 1 user : the module itself (why ?)
            if (users.Count() > 1)
                s.mainThrottle = targetThrottle;

            float throttleLimit = 1;

            limiter = LimitMode.None;

            if (limitThrottle)
            {
                if (maxThrottle < throttleLimit) limiter = LimitMode.Throttle;
                throttleLimit = Mathf.Min(throttleLimit, (float)maxThrottle);
            }

            if (limitToTerminalVelocity)
            {
                float limit = TerminalVelocityThrottle();
                if (limit < throttleLimit) limiter = LimitMode.TerminalVelocity;
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limitToPreventOverheats)
            {
                float limit = TemperatureSafetyThrottle();
                if(limit < throttleLimit) limiter = LimitMode.Temperature;
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limitAcceleration)
            {
                float limit = AccelerationLimitedThrottle();
                if(limit < throttleLimit) limiter = LimitMode.Acceleration;
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limitToPreventFlameout)
            {
                // This clause benefits being last: if we don't need much air
                // due to prior limits, we can close some intakes.
                float limit = FlameoutSafetyThrottle();
                if (limit < throttleLimit) limiter = LimitMode.Flameout;
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (double.IsNaN(throttleLimit)) throttleLimit = 0;
            throttleLimit = Mathf.Clamp01(throttleLimit);

            vesselState.throttleLimit = throttleLimit;

            if (s.mainThrottle < throttleLimit) limiter = LimitMode.None;

            s.mainThrottle = Mathf.Min(s.mainThrottle, throttleLimit);

            if (smoothThrottle)
            {
                s.mainThrottle = SmoothThrottle(s.mainThrottle);
            }

            if (double.IsNaN(s.mainThrottle)) s.mainThrottle = 0;
            s.mainThrottle = Mathf.Clamp01(s.mainThrottle);

            if (s.Z == 0 && vesselState.rcsThrust) s.Z = -s.mainThrottle;

            lastThrottle = s.mainThrottle;
        }
コード例 #9
0
        public override void Drive(FlightCtrlState s)
        {
            float threshold = 0.1F;
            bool  _userCommandingRotation = !(Mathfx.Approx(s.pitch, s.pitchTrim, threshold) &&
                                              Mathfx.Approx(s.yaw, s.yawTrim, threshold) &&
                                              Mathfx.Approx(s.roll, s.rollTrim, threshold));
            bool _userCommandingTranslation = !(Math.Abs(s.X) < threshold &&
                                                Math.Abs(s.Y) < threshold &&
                                                Math.Abs(s.Z) < threshold);

            if (_userCommandingRotation && !_userCommandingTranslation)
            {
                userCommandingRotationSmoothed = 2;
            }
            else if (userCommandingRotationSmoothed > 0)
            {
                userCommandingRotationSmoothed--;
            }

            if (core.GetComputerModule <MechJebModuleThrustWindow>().hidden&& core.GetComputerModule <MechJebModuleAscentGuidance>().hidden)
            {
                return;
            }

            if ((tmode != TMode.OFF) && (vesselState.thrustAvailable > 0))
            {
                double spd = 0;

                switch (tmode)
                {
                case TMode.KEEP_ORBITAL:
                    spd = vesselState.speedOrbital;
                    break;

                case TMode.KEEP_SURFACE:
                    spd = vesselState.speedSurface;
                    break;

                case TMode.KEEP_VERTICAL:
                    spd = vesselState.speedVertical;
                    Vector3d rot = Vector3d.up;
                    if (trans_kill_h)
                    {
                        Vector3 hsdir = Vector3.ProjectOnPlane(vesselState.surfaceVelocity, vesselState.up);
                        Vector3 dir   = -hsdir + vesselState.up * Math.Max(Math.Abs(spd), 20 * mainBody.GeeASL);
                        if ((Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue) > 5000) && (hsdir.magnitude > Math.Max(Math.Abs(spd), 100 * mainBody.GeeASL) * 2))
                        {
                            tmode         = TMode.DIRECT;
                            trans_spd_act = 100;
                            rot           = -hsdir;
                        }
                        else
                        {
                            rot = dir.normalized;
                        }
                        core.attitude.attitudeTo(rot, AttitudeReference.INERTIAL, null);
                    }
                    break;
                }

                double t_err = (trans_spd_act - spd) / vesselState.maxThrustAccel;
                if ((tmode == TMode.KEEP_ORBITAL && Vector3d.Dot(vesselState.forward, vesselState.orbitalVelocity) < 0) ||
                    (tmode == TMode.KEEP_SURFACE && Vector3d.Dot(vesselState.forward, vesselState.surfaceVelocity) < 0))
                {
                    //allow thrust to declerate
                    t_err *= -1;
                }

                double t_act = pid.Compute(t_err);

                if ((tmode != TMode.KEEP_VERTICAL) ||
                    !trans_kill_h ||
                    (core.attitude.attitudeError < 2) ||
                    ((Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue) < 1000) && (core.attitude.attitudeError < 90)))
                {
                    if (tmode == TMode.DIRECT)
                    {
                        trans_prev_thrust = targetThrottle = trans_spd_act / 100.0F;
                    }
                    else
                    {
                        trans_prev_thrust = targetThrottle = Mathf.Clamp01(trans_prev_thrust + (float)t_act);
                    }
                }
                else
                {
                    bool useGimbal = (vesselState.torqueGimbal.positive.x > vesselState.torqueAvailable.x * 10) ||
                                     (vesselState.torqueGimbal.positive.z > vesselState.torqueAvailable.z * 10);

                    bool useDiffThrottle = (vesselState.torqueDiffThrottle.x > vesselState.torqueAvailable.x * 10) ||
                                           (vesselState.torqueDiffThrottle.z > vesselState.torqueAvailable.z * 10);

                    if ((core.attitude.attitudeError >= 2) && (useGimbal || (useDiffThrottle && core.thrust.differentialThrottle)))
                    {
                        trans_prev_thrust = targetThrottle = 0.1F;
                        print(" targetThrottle = 0.1F");
                    }
                    else
                    {
                        trans_prev_thrust = targetThrottle = 0;
                    }
                }
            }

            // Only set throttle if a module need it. Otherwise let the user or other mods set it
            // There is always at least 1 user : the module itself (why ?)
            if (users.Count > 1)
            {
                s.mainThrottle = targetThrottle;
            }

            throttleLimit      = 1;
            throttleFixedLimit = 1;

            limiter = LimitMode.None;

            if (limitThrottle)
            {
                if (maxThrottle < throttleLimit)
                {
                    setFixedLimit((float)maxThrottle, LimitMode.Throttle);
                }
            }

            if (limitToTerminalVelocity)
            {
                float limit = TerminalVelocityThrottle();
                if (limit < throttleLimit)
                {
                    setFixedLimit(limit, LimitMode.TerminalVelocity);
                }
            }

            if (limitDynamicPressure)
            {
                float limit = MaximumDynamicPressureThrottle();
                if (limit < throttleLimit)
                {
                    setFixedLimit(limit, LimitMode.DynamicPressure);
                }
            }

            if (limitToPreventOverheats)
            {
                float limit = (float)TemperatureSafetyThrottle();
                if (limit < throttleLimit)
                {
                    setFixedLimit(limit, LimitMode.Temperature);
                }
            }

            if (limitAcceleration)
            {
                float limit = AccelerationLimitedThrottle();
                if (limit < throttleLimit)
                {
                    setFixedLimit(limit, LimitMode.Acceleration);
                }
            }

            if (electricThrottle && ElectricEngineRunning())
            {
                float limit = ElectricThrottle();
                if (limit < throttleLimit)
                {
                    setFixedLimit(limit, LimitMode.Electric);
                }
            }

            if (limitToPreventFlameout)
            {
                // This clause benefits being last: if we don't need much air
                // due to prior limits, we can close some intakes.
                float limit = FlameoutSafetyThrottle();
                if (limit < throttleLimit)
                {
                    setFixedLimit(limit, LimitMode.Flameout);
                }
            }

            // Any limiters which can limit to non-zero values must come before this, any
            // limiters (like ullage) which enforce zero throttle should come after.  The
            // minThrottle setting has authority over any other limiter that sets non-zero throttle.
            if (limiterMinThrottle && limiter != LimitMode.None)
            {
                if (minThrottle > throttleFixedLimit)
                {
                    setFixedLimit((float)minThrottle, LimitMode.MinThrottle);
                }
                if (minThrottle > throttleLimit)
                {
                    setTempLimit((float)minThrottle, LimitMode.MinThrottle);
                }
            }

            /* auto-RCS ullaging up to very stable */
            if (autoRCSUllaging && s.mainThrottle > 0.0F && throttleLimit > 0.0F)
            {
                if (vesselState.lowestUllage < VesselState.UllageState.VeryStable)
                {
                    Debug.Log("MechJeb RCS auto-ullaging: found state below very stable: " + vesselState.lowestUllage);
                    if (vessel.hasEnabledRCSModules())
                    {
                        if (!vessel.ActionGroups[KSPActionGroup.RCS])
                        {
                            Debug.Log("MechJeb RCS auto-ullaging: enabling RCS action group for automatic ullaging");
                            vessel.ActionGroups.SetGroup(KSPActionGroup.RCS, true);
                        }
                        Debug.Log("MechJeb RCS auto-ullaging: firing RCS to stabilize ulllage");
                        setTempLimit(0.0F, LimitMode.UnstableIgnition);
                        s.Z = -1.0F;
                    }
                    else
                    {
                        Debug.Log("MechJeb RCS auto-ullaging: vessel has no enabled/staged RCS modules");
                    }
                }
            }

            /* prevent unstable ignitions */
            if (limitToPreventUnstableIgnition && s.mainThrottle > 0.0F && throttleLimit > 0.0F)
            {
                if (vesselState.lowestUllage < VesselState.UllageState.Stable)
                {
                    ScreenMessages.PostScreenMessage(preventingUnstableIgnitionsMessage);
                    Debug.Log("MechJeb Unstable Ignitions: preventing ignition in state: " + vesselState.lowestUllage);
                    setTempLimit(0.0F, LimitMode.UnstableIgnition);
                }
            }

            // we have to force the throttle here so that rssMode can work, otherwise we don't get our last throttle command
            // back on the next tick after disabling.  we save this before applying the throttle limits so that we preserve
            // the requested throttle, and not the limited throttle.
            if (core.rssMode)
            {
                SetFlightGlobals(s.mainThrottle);
            }

            if (double.IsNaN(throttleLimit))
            {
                throttleLimit = 1.0F;
            }
            throttleLimit = Mathf.Clamp01(throttleLimit);

            /* we do not _apply_ the "fixed" limit, the actual throttleLimit should always be the more limited and lower one */
            /* the purpose of the "fixed" limit is for external consumers like the node executor to consume */
            if (double.IsNaN(throttleFixedLimit))
            {
                throttleFixedLimit = 1.0F;
            }
            throttleFixedLimit = Mathf.Clamp01(throttleFixedLimit);

            vesselState.throttleLimit      = throttleLimit;
            vesselState.throttleFixedLimit = throttleFixedLimit;

            if (s.mainThrottle < throttleLimit)
            {
                limiter = LimitMode.None;
            }

            s.mainThrottle = Mathf.Min(s.mainThrottle, throttleLimit);

            if (smoothThrottle)
            {
                s.mainThrottle = SmoothThrottle(s.mainThrottle);
            }

            if (double.IsNaN(s.mainThrottle))
            {
                s.mainThrottle = 0;
            }

            s.mainThrottle = Mathf.Clamp01(s.mainThrottle);


            if (s.Z == 0 && core.rcs.rcsThrottle && vesselState.rcsThrust)
            {
                s.Z = -s.mainThrottle;
            }

            lastThrottle = s.mainThrottle;

            if (!core.attitude.enabled)
            {
                Vector3d act = new Vector3d(s.pitch, s.yaw, s.roll);
                differentialThrottleDemandedTorque = -Vector3d.Scale(act.xzy, vesselState.torqueDiffThrottle * s.mainThrottle * 0.5f);
            }
        }
コード例 #10
0
 /* This is an API for limits which are "temporary" or "conditional" (things like ullage status which will change very soon).
  * This will often be temporarily zero, which means the computed accelleration of the ship will be zero, which would cause
  * consumers (like the NodeExecutor) to compute infinite burntime, so this value should not be used by those consumers */
 private void setTempLimit(float limit, LimitMode mode)
 {
     throttleLimit = limit;
     limiter       = mode;
 }
コード例 #11
0
        public override void Drive(FlightCtrlState s)
        {
            //detect user input:
            if (s.mainThrottle < 1e-4 && lastThrottle > 1e-4)
            {
                targetThrottle = 0; //detect player pressing 'x'
            }
            else if (Mathf.Abs(s.mainThrottle - lastThrottle) > 1e-4)
            {
                targetThrottle = Mathf.Clamp01((s.mainThrottle - lastThrottle) + targetThrottle);
            }

            if ((tmode != TMode.OFF) && (vesselState.thrustAvailable > 0))
            {
                double spd = 0;

                switch (tmode)
                {
                case TMode.KEEP_ORBITAL:
                    spd = vesselState.speedOrbital;
                    break;

                case TMode.KEEP_SURFACE:
                    spd = vesselState.speedSurface;
                    break;

                case TMode.KEEP_VERTICAL:
                    spd = vesselState.speedVertical;
                    Vector3d rot = Vector3d.up;
                    if (trans_kill_h)
                    {
                        Vector3 hsdir = Vector3.Exclude(vesselState.up, vesselState.velocityVesselSurface);
                        Vector3 dir   = -hsdir + vesselState.up * Math.Max(Math.Abs(spd), 20 * mainBody.GeeASL);
                        if ((Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue) > 5000) && (hsdir.magnitude > Math.Max(Math.Abs(spd), 100 * mainBody.GeeASL) * 2))
                        {
                            tmode         = TMode.DIRECT;
                            trans_spd_act = 100;
                            rot           = -hsdir;
                        }
                        else
                        {
                            rot = dir.normalized;
                        }
                        core.attitude.attitudeTo(rot, AttitudeReference.INERTIAL, null);
                    }
                    break;
                }

                double t_err = (trans_spd_act - spd) / vesselState.maxThrustAccel;
                if ((tmode == TMode.KEEP_ORBITAL && Vector3d.Dot(vesselState.forward, vesselState.velocityVesselOrbit) < 0) ||
                    (tmode == TMode.KEEP_SURFACE && Vector3d.Dot(vesselState.forward, vesselState.velocityVesselSurface) < 0))
                {
                    //allow thrust to declerate
                    t_err *= -1;
                }

                double t_act = pid.Compute(t_err);

                if ((tmode != TMode.KEEP_VERTICAL) ||
                    !trans_kill_h ||
                    (core.attitude.attitudeError < 2) ||
                    ((Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue) < 1000) && (core.attitude.attitudeError < 90)))
                {
                    if (tmode == TMode.DIRECT)
                    {
                        trans_prev_thrust = targetThrottle = trans_spd_act / 100.0F;
                    }
                    else
                    {
                        trans_prev_thrust = targetThrottle = Mathf.Clamp01(trans_prev_thrust + (float)t_act);
                    }
                }
                else
                {
                    if ((core.attitude.attitudeError >= 2) && (vesselState.torqueThrustPYAvailable > vesselState.torquePYAvailable * 10))
                    {
                        trans_prev_thrust = targetThrottle = 0.1F;
                    }
                    else
                    {
                        trans_prev_thrust = targetThrottle = 0;
                    }
                }
            }

            s.mainThrottle = targetThrottle;

            float throttleLimit = 1;

            limiter = LimitMode.None;

            if (limitThrottle)
            {
                if (maxThrottle < throttleLimit)
                {
                    limiter = LimitMode.Throttle;
                }
                throttleLimit = Mathf.Min(throttleLimit, (float)maxThrottle);
            }

            if (limitToTerminalVelocity)
            {
                float limit = TerminalVelocityThrottle();
                if (limit < throttleLimit)
                {
                    limiter = LimitMode.TerminalVelocity;
                }
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limitToPreventOverheats)
            {
                float limit = TemperatureSafetyThrottle();
                if (limit < throttleLimit)
                {
                    limiter = LimitMode.Temperature;
                }
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limitAcceleration)
            {
                float limit = AccelerationLimitedThrottle();
                if (limit < throttleLimit)
                {
                    limiter = LimitMode.Acceleration;
                }
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limitToPreventFlameout)
            {
                // This clause benefits being last: if we don't need much air
                // due to prior limits, we can close some intakes.
                float limit = FlameoutSafetyThrottle();
                if (limit < throttleLimit)
                {
                    limiter = LimitMode.Flameout;
                }
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (double.IsNaN(throttleLimit))
            {
                throttleLimit = 0;
            }
            throttleLimit = Mathf.Clamp01(throttleLimit);

            vesselState.throttleLimit = throttleLimit;

            if (s.mainThrottle < throttleLimit)
            {
                limiter = LimitMode.None;
            }

            s.mainThrottle = Mathf.Min(s.mainThrottle, throttleLimit);

            if (smoothThrottle)
            {
                s.mainThrottle = SmoothThrottle(s.mainThrottle);
            }

            if (double.IsNaN(s.mainThrottle))
            {
                s.mainThrottle = 0;
            }
            s.mainThrottle = Mathf.Clamp01(s.mainThrottle);

            lastThrottle = s.mainThrottle;
        }
コード例 #12
0
        public override void Drive(FlightCtrlState s)
        {
            float threshold = 0.1F;
            bool _userCommandingRotation = !(Mathfx.Approx(s.pitch, s.pitchTrim, threshold)
                    && Mathfx.Approx(s.yaw, s.yawTrim, threshold)
                    && Mathfx.Approx(s.roll, s.rollTrim, threshold));
            bool _userCommandingTranslation = !(Math.Abs(s.X) < threshold
                        && Math.Abs(s.Y) < threshold
                        && Math.Abs(s.Z) < threshold);

            if (_userCommandingRotation && !_userCommandingTranslation)
            {
                userCommandingRotationSmoothed = 2;
            }
            else if (userCommandingRotationSmoothed > 0)
            {
                userCommandingRotationSmoothed--;
            }

            if (core.GetComputerModule<MechJebModuleThrustWindow>().hidden && core.GetComputerModule<MechJebModuleAscentGuidance>().hidden) { return; }

            if ((tmode != TMode.OFF) && (vesselState.thrustAvailable > 0))
            {
                double spd = 0;

                switch (tmode)
                {
                    case TMode.KEEP_ORBITAL:
                        spd = vesselState.speedOrbital;
                        break;
                    case TMode.KEEP_SURFACE:
                        spd = vesselState.speedSurface;
                        break;
                    case TMode.KEEP_VERTICAL:
                        spd = vesselState.speedVertical;
                        Vector3d rot = Vector3d.up;
                        if (trans_kill_h)
                        {
                            Vector3 hsdir = Vector3.ProjectOnPlane(vesselState.surfaceVelocity, vesselState.up);
                            Vector3 dir = -hsdir + vesselState.up * Math.Max(Math.Abs(spd), 20 * mainBody.GeeASL);
                            if ((Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue) > 5000) && (hsdir.magnitude > Math.Max(Math.Abs(spd), 100 * mainBody.GeeASL) * 2))
                            {
                                tmode = TMode.DIRECT;
                                trans_spd_act = 100;
                                rot = -hsdir;
                            }
                            else
                            {
                                rot = dir.normalized;
                            }
                            core.attitude.attitudeTo(rot, AttitudeReference.INERTIAL, null);
                        }
                        break;
                }

                double t_err = (trans_spd_act - spd) / vesselState.maxThrustAccel;
                if ((tmode == TMode.KEEP_ORBITAL && Vector3d.Dot(vesselState.forward, vesselState.orbitalVelocity) < 0) ||
                   (tmode == TMode.KEEP_SURFACE && Vector3d.Dot(vesselState.forward, vesselState.surfaceVelocity) < 0))
                {
                    //allow thrust to declerate 
                    t_err *= -1;
                }

                double t_act = pid.Compute(t_err);

                if ((tmode != TMode.KEEP_VERTICAL)
                    || !trans_kill_h
                    || (core.attitude.attitudeError < 2)
                    || ((Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue) < 1000) && (core.attitude.attitudeError < 90)))
                {
                    if (tmode == TMode.DIRECT)
                    {
                        trans_prev_thrust = targetThrottle = trans_spd_act / 100.0F;
                    }
                    else
                    {
                        trans_prev_thrust = targetThrottle = Mathf.Clamp01(trans_prev_thrust + (float)t_act);
                    }
                }
                else
                {
                    bool useGimbal = (vesselState.torqueFromEngine.x / vessel.ctrlState.mainThrottle > vesselState.torqueAvailable.x * 10) ||
                                     (vesselState.torqueFromEngine.z / vessel.ctrlState.mainThrottle > vesselState.torqueAvailable.z * 10);

                    bool useDiffThrottle = (vesselState.torqueFromDiffThrottle.x > vesselState.torqueAvailable.x * 10) ||
                                           (vesselState.torqueFromDiffThrottle.z > vesselState.torqueAvailable.z * 10);

                    if ((core.attitude.attitudeError >= 2) && (useGimbal || (useDiffThrottle && core.thrust.differentialThrottle)))
                    {
                        trans_prev_thrust = targetThrottle = 0.1F;
                    }
                    else
                    {
                        trans_prev_thrust = targetThrottle = 0;
                    }
                }
            }

            // Only set throttle if a module need it. Othewise let the user or other mods set it
            // There is always at least 1 user : the module itself (why ?)
            if (users.Count() > 1)
                s.mainThrottle = targetThrottle;

            float throttleLimit = 1;

            limiter = LimitMode.None;

            if (limitThrottle)
            {
                if (maxThrottle < throttleLimit) limiter = LimitMode.Throttle;
                throttleLimit = Mathf.Min(throttleLimit, (float)maxThrottle);
            }

            if (limitToTerminalVelocity)
            {
                float limit = TerminalVelocityThrottle();
                if (limit < throttleLimit) limiter = LimitMode.TerminalVelocity;
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limitDynamicPressure)
            {
                float limit = MaximumDynamicPressureThrottle();
                if (limit < throttleLimit) limiter = LimitMode.DynamicPressure;
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }
            
            if (limitToPreventOverheats)
            {
                float limit = (float)TemperatureSafetyThrottle();
                if(limit < throttleLimit) limiter = LimitMode.Temperature;
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limitAcceleration)
            {
                float limit = AccelerationLimitedThrottle();
                if(limit < throttleLimit) limiter = LimitMode.Acceleration;
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limitToPreventFlameout)
            {
                // This clause benefits being last: if we don't need much air
                // due to prior limits, we can close some intakes.
                float limit = FlameoutSafetyThrottle();
                if (limit < throttleLimit) limiter = LimitMode.Flameout;
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limiterMinThrottle  && limiter != LimitMode.None && throttleLimit < minThrottle)
            {
                limiter = LimitMode.MinThrottle;
                throttleLimit = (float) minThrottle;
            }

            if (double.IsNaN(throttleLimit)) throttleLimit = 0;
            throttleLimit = Mathf.Clamp01(throttleLimit);

            vesselState.throttleLimit = throttleLimit;

            if (s.mainThrottle < throttleLimit) limiter = LimitMode.None;

            s.mainThrottle = Mathf.Min(s.mainThrottle, throttleLimit);

            if (smoothThrottle)
            {
                s.mainThrottle = SmoothThrottle(s.mainThrottle);
            }

            if (double.IsNaN(s.mainThrottle)) s.mainThrottle = 0;
            s.mainThrottle = Mathf.Clamp01(s.mainThrottle);
            
            if (s.Z == 0 && core.rcs.rcsThrottle && vesselState.rcsThrust) s.Z = -s.mainThrottle;

            lastThrottle = s.mainThrottle;

            if (!core.attitude.enabled)
            {
                Vector3d act = new Vector3d(s.pitch, s.yaw, s.roll);
                differentialThrottleDemandedTorque = -Vector3d.Scale(act.xzy, vesselState.torqueFromDiffThrottle * s.mainThrottle * 0.5f);
            }
        }
コード例 #13
0
        public override void Drive(FlightCtrlState s)
        {
            //detect user input:
            if (s.mainThrottle < 1e-4 && lastThrottle > 1e-4)
            {
                targetThrottle = 0; //detect player pressing 'x'
            }
            else if (Mathf.Abs(s.mainThrottle - lastThrottle) > 1e-4)
            {
                targetThrottle = Mathf.Clamp01((s.mainThrottle - lastThrottle) + targetThrottle);
            }

            if ((tmode != TMode.OFF) && (vesselState.thrustAvailable > 0))
            {
                double spd = 0;

                switch (tmode)
                {
                    case TMode.KEEP_ORBITAL:
                        spd = vesselState.speedOrbital;
                        break;
                    case TMode.KEEP_SURFACE:
                        spd = vesselState.speedSurface;
                        break;
                    case TMode.KEEP_VERTICAL:
                        spd = vesselState.speedVertical;
                        Vector3d rot = Vector3d.up;
                        if (trans_kill_h)
                        {
                            Vector3 hsdir = Vector3.Exclude(vesselState.up, vesselState.velocityVesselSurface);
                            Vector3 dir = -hsdir + vesselState.up * Math.Max(Math.Abs(spd), 20 * mainBody.GeeASL);
                            if ((Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue) > 5000) && (hsdir.magnitude > Math.Max(Math.Abs(spd), 100 * mainBody.GeeASL) * 2))
                            {
                                tmode = TMode.DIRECT;
                                trans_spd_act = 100;
                                rot = -hsdir;
                            }
                            else
                            {
                                rot = dir.normalized;
                            }
                            core.attitude.attitudeTo(rot, AttitudeReference.INERTIAL, null);
                        }
                        break;
                }

                double t_err = (trans_spd_act - spd) / vesselState.maxThrustAccel;
                if ((tmode == TMode.KEEP_ORBITAL && Vector3d.Dot(vesselState.forward, vesselState.velocityVesselOrbit) < 0) ||
                   (tmode == TMode.KEEP_SURFACE && Vector3d.Dot(vesselState.forward, vesselState.velocityVesselSurface) < 0))
                {
                    //allow thrust to declerate
                    t_err *= -1;
                }

                double t_act = pid.Compute(t_err);

                if ((tmode != TMode.KEEP_VERTICAL)
                    || !trans_kill_h
                    || (core.attitude.attitudeError < 2)
                    || ((Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue) < 1000) && (core.attitude.attitudeError < 90)))
                {
                    if (tmode == TMode.DIRECT)
                    {
                        trans_prev_thrust = targetThrottle = trans_spd_act / 100.0F;
                    }
                    else
                    {
                        trans_prev_thrust = targetThrottle = Mathf.Clamp01(trans_prev_thrust + (float)t_act);
                    }
                }
                else
                {
                    if ((core.attitude.attitudeError >= 2) && (vesselState.torqueThrustPYAvailable > Math.Min( vesselState.torqueAvailable.x, vesselState.torqueAvailable.z) * 10))
                    {
                        trans_prev_thrust = targetThrottle = 0.1F;
                    }
                    else
                    {
                        trans_prev_thrust = targetThrottle = 0;
                    }
                }
            }

            s.mainThrottle = targetThrottle;

            float throttleLimit = 1;

            limiter = LimitMode.None;

            if (limitThrottle)
            {
                if (maxThrottle < throttleLimit) limiter = LimitMode.Throttle;
                throttleLimit = Mathf.Min(throttleLimit, (float)maxThrottle);
            }

            if (limitToTerminalVelocity)
            {
                float limit = TerminalVelocityThrottle();
                if (limit < throttleLimit) limiter = LimitMode.TerminalVelocity;
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limitToPreventOverheats)
            {
                float limit = TemperatureSafetyThrottle();
                if(limit < throttleLimit) limiter = LimitMode.Temperature;
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limitAcceleration)
            {
                float limit = AccelerationLimitedThrottle();
                if(limit < throttleLimit) limiter = LimitMode.Acceleration;
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (limitToPreventFlameout)
            {
                // This clause benefits being last: if we don't need much air
                // due to prior limits, we can close some intakes.
                float limit = FlameoutSafetyThrottle();
                if (limit < throttleLimit) limiter = LimitMode.Flameout;
                throttleLimit = Mathf.Min(throttleLimit, limit);
            }

            if (double.IsNaN(throttleLimit)) throttleLimit = 0;
            throttleLimit = Mathf.Clamp01(throttleLimit);

            vesselState.throttleLimit = throttleLimit;

            if (s.mainThrottle < throttleLimit) limiter = LimitMode.None;

            s.mainThrottle = Mathf.Min(s.mainThrottle, throttleLimit);

            if (smoothThrottle)
            {
                s.mainThrottle = SmoothThrottle(s.mainThrottle);
            }

            if (double.IsNaN(s.mainThrottle)) s.mainThrottle = 0;
            s.mainThrottle = Mathf.Clamp01(s.mainThrottle);

            lastThrottle = s.mainThrottle;
        }
コード例 #14
0
    /// <summary>
    /// Add add to v. If v's magnitude > upperlimit, it is set to upperlimit.
    /// </summary>
    public static Vector3 AddWithLimit(Vector3 v, Vector3 add, float upperLimit, CalculMode mode = CalculMode.ThreeAxis, LimitMode limitMode = LimitMode.Set, float?smoothLimitSubstract = null)
    {
        switch (mode)
        {
        case CalculMode.ThreeAxis:
            v += add;
            if (v.magnitude < upperLimit)
            {
                return(v);
            }
            else
            {
                switch (limitMode)
                {
                case LimitMode.Set:
                    return(v.normalized * upperLimit);

                case LimitMode.Smooth:
                    if (SubtractMagnitude(v, (smoothLimitSubstract == null ? add.magnitude * 2f : (float)smoothLimitSubstract + add.magnitude)).magnitude < upperLimit)
                    {
                        return(v.normalized * upperLimit);
                    }
                    else
                    {
                        return(SubtractMagnitude(v, (smoothLimitSubstract == null ? add.magnitude * 2f : (float)smoothLimitSubstract + add.magnitude)));
                    }

                default:
                    return(v.normalized * upperLimit);
                }
            }


        case CalculMode.NoYAxis:
            float y = v.y;
            v.y   = 0;
            add.y = 0;
            v    += add;
            if (v.magnitude < upperLimit)
            {
                return(new Vector3(v.x, y, v.z));
            }
            else
            {
                Vector3 temp = v.normalized * upperLimit;

                switch (limitMode)
                {
                case LimitMode.Set:
                    return(new Vector3(temp.x, y, temp.z).normalized *upperLimit);

                case LimitMode.Smooth:
                    if (SubtractMagnitude(v, (smoothLimitSubstract == null ? add.magnitude * 2f : (float)smoothLimitSubstract + add.magnitude)).magnitude < upperLimit)
                    {
                        return(new Vector3(temp.x, y, temp.z));
                    }
                    else
                    {
                        v = SubtractMagnitude(v, (smoothLimitSubstract == null ? add.magnitude * 2f : (float)smoothLimitSubstract + add.magnitude));
                        return(new Vector3(v.x, y, v.z));
                    }

                default:
                    return(new Vector3(v.x, y, v.z).normalized *upperLimit);
                }
            }

        default:
            return(Vector3.zero);
        }
    }
コード例 #15
0
ファイル: TalonSrx.cs プロジェクト: CrossTheRoadElec/HERO-SDK
        /**
         * TODO documentation
         * Configures the soft limit enable (wear leveled persistent memory).
         * Also sets the limit switch overrides.
         */
        public void ConfigLimitMode(LimitMode mode)
        {
            int status = CAN_OK;
            switch (mode)
            {
                case LimitMode.kLimitMode_SwitchInputsOnly: /** Only use switches for limits */
                    /* turn OFF both limits. SRX has individual enables and polarity for each
                     * limit switch.*/
                    status = m_impl.SetForwardSoftEnable(0);
                    HandleStatus(status);
                    status = m_impl.SetReverseSoftEnable(0);
                    HandleStatus(status);
                    {
                        Reporting.SetError(status, Reporting.getHALErrorMessage(status));
                    }
                    /* override enable the limit switches, this circumvents the webdash */
                    status = m_impl.SetOverrideLimitSwitchEn(
                        kLimitSwitchOverride_EnableFwd_EnableRev);
                    HandleStatus(status);
                    break;
                case LimitMode.kLimitMode_SoftPositionLimits: /** Use both switches and soft limits */
                    /* turn on both limits. SRX has individual enables and polarity for each
                     * limit switch.*/
                    status = m_impl.SetForwardSoftEnable(1);
                    HandleStatus(status);
                    status = m_impl.SetReverseSoftEnable(1);
                    HandleStatus(status);
                    /* override enable the limit switches, this circumvents the webdash */
                    status = m_impl.SetOverrideLimitSwitchEn(kLimitSwitchOverride_EnableFwd_EnableRev);
                    HandleStatus(status);
                    break;

                case LimitMode.kLimitMode_SrxDisableSwitchInputs: /** disable both limit switches and
                                               soft limits */
                    /* turn on both limits. SRX has individual enables and polarity for each
                     * limit switch.*/
                    status = m_impl.SetForwardSoftEnable(0);
                    HandleStatus(status);
                    status = m_impl.SetReverseSoftEnable(0);
                    HandleStatus(status);
                    /* override enable the limit switches, this circumvents the webdash */
                    status = m_impl.SetOverrideLimitSwitchEn(kLimitSwitchOverride_DisableFwd_DisableRev);
                    HandleStatus(status);
                    break;
            }
        }