示例#1
0
 public void AddComputerModuleLater(ComputerModule module)
 {
     //The actual loading is delayed to FixedUpdate because AddComputerModule can get called inside a foreach loop
     //over the modules, and modifying the list during the loop will cause an exception. Maybe there is a better
     //way to deal with this?
     modulesToLoad.Add(module);
 }
示例#2
0
 public T GetComputerModule <T>() where T : ComputerModule
 {
     for (int i = 0; i < unorderedComputerModules.Count; i++)
     {
         ComputerModule pm = unorderedComputerModules[i];
         T module          = pm as T;
         if (module != null)
         {
             return(module);
         }
     }
     return(null);
 }
示例#3
0
 public bool RecursiveUser(object user)
 {
     if (base.Contains(user))
     {
         return(true);
     }
     else
     {
         foreach (object o in this)
         {
             ComputerModule c = o as ComputerModule;
             if (c != null && c != controlledModule)
             {
                 if (c.users.RecursiveUser(user))
                 {
                     return(true);
                 }
             }
         }
         return(false);
     }
 }
示例#4
0
 public void RemoveComputerModule(ComputerModule module)
 {
     unorderedComputerModules.Remove(module);
     ClearModulesCache();
 }
示例#5
0
        public bool landActivate(ComputerModule controller, double touchdownSpeed = 0.5)
        {
            if ((controlModule != null) && (controller != null) && (controlModule != controller))
            {
                return false;
            }

            trans_land_touchdown_speed = touchdownSpeed;

            if (trans_land)
            {
                return true;
            }

            trans_land = true;
            trans_land_gears = false;
            tmode = TMode.KEEP_VERTICAL;

            return true;
        }
示例#6
0
        public bool controlClaim(ComputerModule newController, bool force = false)
        {
            if (controlModule == newController)
            {
                return true;
            }
            if (!controlRelease(newController, force))
            {
                return false;
            }

            _controlModule = newController;

            return true;
        }
示例#7
0
        public bool attitudeTo(Quaternion attitude, AttitudeReference reference, ComputerModule controller)
        {
            if ((controlModule != null) && (controller != null) && (controlModule != controller))
            {
                return false;
            }

            attitudeReference = reference;
            attitudeTarget = attitude;
            _attitudeActive = true;
            _attitudeRollMatters = true;

            return true;
        }
示例#8
0
        private void drive(FlightCtrlState s)
        {
            stress = 0;

            if (part.State == PartStates.DEAD)
            {
                return;
            }

            if (controlModule != null)
            {
                if (controlModule.enabled)
                {
                    controlModule.drive(s);
                }
                else
                {
                    _controlModule = null;
                }
            }

            if (TimeWarp.CurrentRate > TimeWarp.MaxPhysicsRate)
            {
                return;
            }

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

                if (trans_land)
                {
                    if (part.vessel.Landed || part.vessel.Splashed)
                    {
                        tmode = TMode.OFF;
                        trans_land = false;
                    }
                    else
                    {
                        tmode = TMode.KEEP_VERTICAL;
                        trans_kill_h = true;
                        double minalt = Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue);
                        if (vesselState.maxThrustAccel < vesselState.gravityForce.magnitude)
                        {
                            trans_spd_act = 0;
                        }
                        else
                        {
                            trans_spd_act = (float)-Math.Sqrt((vesselState.maxThrustAccel - vesselState.gravityForce.magnitude) * 2 * minalt) * 0.50F;
                        }
                        if (!trans_land_gears && (minalt < 1000))
                        {
                            foreach (Part p in part.vessel.parts)
                            {
                                if (p is LandingLeg)
                                {
                                    LandingLeg l = (LandingLeg)p;
                                    if (l.legState == LandingLeg.LegStates.RETRACTED)
                                    {
                                        l.DeployOnActivate = true;
                                        l.force_activate();
                                    }
                                }
                            }
                            trans_land_gears = true;
                        }
                        if (minalt < 200)
                        {
                            minalt = Math.Min(vesselState.altitudeBottom, minalt);
                            trans_spd_act = -Mathf.Lerp(0, (float)Math.Sqrt((vesselState.maxThrustAccel - vesselState.gravityForce.magnitude) * 2 * 200) * 0.50F, (float)minalt / 200);
                            trans_spd_act = (float)Math.Min(-trans_land_touchdown_speed, trans_spd_act);
                            //                            if (minalt < 3.0 * trans_land_touchdown_speed) trans_spd_act = -(float)trans_land_touchdown_speed;
                            /*
                            if ((minalt >= 90) && (vesselState.speedHorizontal > 1)) {
                                trans_spd_act = -Mathf.Lerp(0, (float)Math.Sqrt((vesselState.maxThrustAccel - vesselState.gravityForce.magnitude) * 2 * 200) * 0.90F, (float)(minalt - 100) / 300);
                            } else {
                                trans_spd_act = -Mathf.Lerp(0, (float)Math.Sqrt((vesselState.maxThrustAccel - vesselState.gravityForce.magnitude) * 2 * 200) * 0.90F, (float)minalt / 300);
                            }
                            */
                        }
                    }
                }

                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, part.vessel.orbit.GetVel() - part.vessel.mainBody.getRFrmVel(vesselState.CoM));
                            Vector3 dir = -hsdir + vesselState.up * Math.Max(Math.Abs(spd), 20 * part.vessel.mainBody.GeeASL);
                            if ((Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue) > 5000) && (hsdir.magnitude > Math.Max(Math.Abs(spd), 100 * part.vessel.mainBody.GeeASL) * 2))
                            {
                                tmode = TMode.DIRECT;
                                trans_spd_act = 100;
                                rot = -hsdir;
                            }
                            else
                            {
                                if (spd > 0)
                                {
                                    rot = vesselState.up;
                                }
                                else
                                {
                                    rot = dir.normalized;
                                }
                            }
                            attitudeTo(rot, AttitudeReference.INERTIAL, null);
                        }
                        break;
                }

                double t_err = (trans_spd_act - spd) / vesselState.maxThrustAccel;
                t_integral += t_err * TimeWarp.fixedDeltaTime;
                double t_deriv = (t_err - t_prev_err) / TimeWarp.fixedDeltaTime;
                double t_act = (t_Kp * t_err) + (t_Ki * t_integral) + (t_Kd * t_deriv);
                t_prev_err = t_err;

                double int_error = Math.Abs(Vector3d.Angle(attitudeGetReferenceRotation(attitudeReference) * attitudeTarget * Vector3d.forward, vesselState.forward));
                //print("int_error = " + int_error);
                if ((tmode != TMode.KEEP_VERTICAL) || (int_error < 2) || ((Math.Min(vesselState.altitudeASL, vesselState.altitudeTrue) < 1000) && (int_error < 90)))
                {
                    if (tmode == TMode.DIRECT)
                    {
                        trans_prev_thrust = s.mainThrottle = trans_spd_act / 100.0F;
                    }
                    else
                    {
                        trans_prev_thrust = s.mainThrottle = Mathf.Clamp(trans_prev_thrust + (float)t_act, 0, 1.0F);
                    }
                }
                else
                {
                    if ((int_error >= 2) && (vesselState.torqueThrustPYAvailable > vesselState.torquePYAvailable * 10))
                    {
                        trans_prev_thrust = s.mainThrottle = 0.1F;
                    }
                    else
                    {
                        trans_prev_thrust = s.mainThrottle = 0;
                    }
                }
            }

            if (attitudeActive)
            {
                int userCommanding = (Mathfx.Approx(s.pitch, 0, 0.1F) ? 0 : 1) + (Mathfx.Approx(s.yaw, 0, 0.1F) ? 0 : 2) + (Mathfx.Approx(s.roll, 0, 0.1F) ? 0 : 4);

                s.killRot = false;

                Quaternion target = attitudeGetReferenceRotation(attitudeReference) * attitudeTarget;
                Quaternion delta = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(part.vessel.transform.rotation) * target);
                /*
                if (Mathf.Abs(Quaternion.Angle(delta, Quaternion.identity)) > 30) {
                    delta = Quaternion.Slerp(Quaternion.identity, delta, 0.1F);
                }
                */
                Vector3d deltaEuler = delta.eulerAngles;
                Vector3d err = new Vector3d((deltaEuler.x > 180) ? (deltaEuler.x - 360.0F) : deltaEuler.x, -((deltaEuler.y > 180) ? (deltaEuler.y - 360.0F) : deltaEuler.y), (deltaEuler.z > 180) ? (deltaEuler.z - 360.0F) : deltaEuler.z) * Math.PI / 180.0F;
                Vector3d torque = new Vector3d(vesselState.torquePYAvailable + vesselState.torqueThrustPYAvailable * s.mainThrottle, vesselState.torqueRAvailable, vesselState.torquePYAvailable + vesselState.torqueThrustPYAvailable * s.mainThrottle);
                Vector3d inertia = Vector3d.Scale(MuUtils.Sign(vesselState.angularMomentum) * 1.1, Vector3d.Scale(Vector3d.Scale(vesselState.angularMomentum, vesselState.angularMomentum), MuUtils.Invert(Vector3d.Scale(torque, vesselState.MoI))));
                err += MuUtils.Reorder(inertia, 132);
                err.Scale(Vector3d.Scale(vesselState.MoI, MuUtils.Invert(torque)));

                integral += err * TimeWarp.fixedDeltaTime;
                Vector3d deriv = (err - prev_err) / TimeWarp.fixedDeltaTime;
                act = Kp * err + Ki * integral + Kd * deriv;
                prev_err = err;

                if (userCommanding != 0)
                {
                    if (attitudeKILLROT)
                    {
                        attitudeTo(Quaternion.LookRotation(part.vessel.transform.up, -part.vessel.transform.forward), AttitudeReference.INERTIAL, null);
                    }
                }
                if ((userCommanding & 4) > 0)
                {
                    prev_err = new Vector3d(prev_err.x, prev_err.y, 0);
                    integral = new Vector3d(integral.x, integral.y, 0);
                    if (!attitudeRollMatters)
                    {
                        attitudeTo(Quaternion.LookRotation(attitudeTarget * Vector3d.forward, attitudeWorldToReference(-part.vessel.transform.forward, attitudeReference)), attitudeReference, null);
                        _attitudeRollMatters = false;
                    }
                }
                else
                {
                    if (!double.IsNaN(act.z)) s.roll = Mathf.Clamp(s.roll + act.z, -1.0F, 1.0F);
                }
                if ((userCommanding & 3) > 0)
                {
                    prev_err = new Vector3d(0, 0, prev_err.z);
                    integral = new Vector3d(0, 0, integral.z);
                }
                else
                {
                    if (!double.IsNaN(act.x)) s.pitch = Mathf.Clamp(s.pitch + act.x, -1.0F, 1.0F);
                    if (!double.IsNaN(act.y)) s.yaw = Mathf.Clamp(s.yaw + act.y, -1.0F, 1.0F);
                }
                stress = Mathf.Min(Mathf.Abs(act.x), 1.0F) + Mathf.Min(Mathf.Abs(act.y), 1.0F) + Mathf.Min(Mathf.Abs(act.z), 1.0F);
            }

            if (double.IsNaN(s.mainThrottle))
            {
                print("MechJeb: caught throttle = NaN");
                s.mainThrottle = 0;
            }
        }
示例#9
0
        public bool autoStageActivate(ComputerModule controller, double stagingDelay = 1.0, int stageLimit = 0)
        {
            if ((controlModule != null) && (controller != null) && (controlModule != controller))
            {
                return false;
            }

            autoStage = true;
            autoStageDelay = stagingDelay;
            autoStageLimit = stageLimit;

            return true;
        }
示例#10
0
 public bool attitudeTo(double heading, double pitch, double roll, ComputerModule controller)
 {
     Quaternion attitude = Quaternion.AngleAxis((float)heading, Vector3.up) * Quaternion.AngleAxis(-(float)pitch, Vector3.right) * Quaternion.AngleAxis(-(float)roll, Vector3.forward);
     return attitudeTo(attitude, MechJebCore.AttitudeReference.SURFACE_NORTH, controller);
 }
示例#11
0
        private void drive(FlightCtrlState s)
        {
            stress = 0;

            if (part.State == PartStates.DEAD)
            {
                return;
            }

            if (controlModule != null)
            {
                if (controlModule.enabled)
                {
                    controlModule.drive(s);
                }
                else
                {
                    _controlModule = null;
                }
            }

            if ((TimeWarp.WarpMode == TimeWarp.Modes.HIGH) && (TimeWarp.CurrentRate > TimeWarp.MaxPhysicsRate))
            {
                return;
            }

            driveThrust(s);
            driveAttitude(s);
            driveAutoStaging();

            if (double.IsNaN(s.mainThrottle))
            {
                print("MechJeb: caught throttle = NaN");
                s.mainThrottle = 0;
            }

            lastThrottle = s.mainThrottle;
        }
示例#12
0
        public void warpTo(ComputerModule controller, double timeLeft, double[] lookaheadTimes, double maxRate = 100000.0)
        {
            if ((controlModule != null) && (controller != null) && (controlModule != controller)) return;

            if ((TimeWarp.WarpMode == TimeWarp.Modes.HIGH) && ((timeLeft < lookaheadTimes[TimeWarp.CurrentRateIndex])
                || (timeWarp.warpRates[TimeWarp.CurrentRateIndex] > maxRate)))
            {
                warpDecrease(controller, true);
            }
            else if ((TimeWarp.CurrentRateIndex < timeWarp.warpRates.Length - 1
                && lookaheadTimes[TimeWarp.CurrentRateIndex + 1] < timeLeft
                && timeWarp.warpRates[TimeWarp.CurrentRateIndex + 1] <= maxRate)
                || (TimeWarp.WarpMode == TimeWarp.Modes.LOW))
            {
                warpIncrease(controller, false, maxRate);
            }
        }
示例#13
0
 public void warpMinimum(ComputerModule controller, bool instant = false)
 {
     if ((controlModule != null) && (controller != null) && (controlModule != controller)) return;
     if (TimeWarp.CurrentRateIndex <= 0) return; //Somehow setting TimeWarp.SetRate to 0 when already at 0 causes unexpected rapid separation (Kracken)
     TimeWarp.SetRate(0, instant);
 }
示例#14
0
        public bool thrustDeactivate(ComputerModule controller)
        {
            /*
            if ((controlModule != null) && (controller != null) && (controlModule != controller))
            {
                return false;
            }
            */

            if (tmode == TMode.OFF)
            {
                return true;
            }

            tmode = TMode.OFF;

            return true;
        }
示例#15
0
        public bool autoStageDeactivate(ComputerModule controller)
        {
            if ((controlModule != null) && (controller != null) && (controlModule != controller))
            {
                return false;
            }

            autoStage = false;

            return true;
        }
示例#16
0
        public bool thrustActivate(ComputerModule controller, float value, TMode mode)
        {
            /*
            if ((controlModule != null) && (controller != null) && (controlModule != controller))
            {
                return false;
            }
            */
            trans_spd_act = value;
            tmode = mode;

            return true;
        }
示例#17
0
        public bool launch(ComputerModule controller)
        {
            if ((controlModule != null) && (controller != null) && (controlModule != controller))
            {
                return false;
            }

            lastStageTime = vesselState.time;
            if (Staging.CurrentStage == Staging.StageCount)
            {
                Staging.ActivateNextStage();
                return true;
            }

            return false;
        }
示例#18
0
        public bool attitudeDeactivate(ComputerModule controller)
        {
            if ((controlModule != null) && (controller != null) && (controlModule != controller))
            {
                return false;
            }

            _attitudeActive = false;
            attitudeChanged = true;

            return true;
        }
示例#19
0
 public void AddComputerModule(ComputerModule module)
 {
     computerModules.Add(module);
     modulesUpdated = true;
 }
示例#20
0
 public bool attitudeTo(Vector3d direction, AttitudeReference reference, ComputerModule controller)
 {
     bool ok = false;
     double ang_diff = Math.Abs(Vector3d.Angle(attitudeGetReferenceRotation(attitudeReference) * attitudeTarget * Vector3d.forward, attitudeGetReferenceRotation(reference) * direction));
     if (!attitudeActive || (ang_diff > 45))
     {
         ok = attitudeTo(Quaternion.LookRotation(direction, attitudeWorldToReference(-part.vessel.transform.forward, reference)), reference, controller);
     }
     else
     {
         ok = attitudeTo(Quaternion.LookRotation(direction, attitudeWorldToReference(attitudeReferenceToWorld(attitudeTarget * Vector3d.up, attitudeReference), reference)), reference, controller);
     }
     if (ok)
     {
         _attitudeRollMatters = false;
         return true;
     }
     else
     {
         return false;
     }
 }
示例#21
0
 public void RemoveComputerModule(ComputerModule module)
 {
     computerModules.Remove(module);
     modulesUpdated = true;
 }
示例#22
0
        public bool controlRelease(ComputerModule controller, bool force = false)
        {
            if (controlModule != null)
            {
                controlModule.onControlLost();
            }

            _controlModule = null;

            attitudeDeactivate(controller);
            landDeactivate(controller);
            tmode = TMode.OFF;

            return true;
        }
示例#23
0
        public void warpDecrease(ComputerModule controller, bool instant = true)
        {
            if ((controlModule != null) && (controller != null) && (controlModule != controller)) return;

            if (TimeWarp.CurrentRateIndex > 0
                /*&& timeWarp.warpRates[TimeWarp.CurrentRateIndex] == TimeWarp.CurrentRate*/)
            {
                TimeWarp.SetRate(TimeWarp.CurrentRateIndex - 1, instant);
            }
        }
示例#24
0
        public bool landDeactivate(ComputerModule controller)
        {
            if ((controlModule != null) && (controller != null) && (controlModule != controller))
            {
                return false;
            }
            if (!trans_land)
            {
                return true;
            }

            trans_land = false;
            tmode = TMode.OFF;

            return true;
        }
示例#25
0
        public bool warpIncrease(ComputerModule controller, bool instant = true, double maxRate = 10000.0)
        {
            if ((controlModule != null) && (controller != null) && (controlModule != controller)) return false;

            //need to use instantaneous altitude and not the time-averaged vesselState.altitudeASL,
            //because the game freaks out really hard if you try to violate the altitude limits
            double instantAltitudeASL = (vesselState.CoM - part.vessel.mainBody.position).magnitude - part.vessel.mainBody.Radius;

            //conditions to increase warp:
            //-we are not already at max warp
            //-the most recent non-instant warp change has completed
            //-the next warp rate is not greater than maxRate
            //-we are out of the atmosphere, or the next warp rate is still a physics rate, or we are landed
            //-increasing the rate is allowed by altitude limits, or we are landed
            //-we did not increase the warp within the last 2 seconds
            if (TimeWarp.CurrentRateIndex + 1 < timeWarp.warpRates.Length
                && (TimeWarp.CurrentRate == 0 || timeWarp.warpRates[TimeWarp.CurrentRateIndex] == TimeWarp.CurrentRate)
                && timeWarp.warpRates[TimeWarp.CurrentRateIndex + 1] <= maxRate
                && (instantAltitudeASL > part.vessel.mainBody.maxAtmosphereAltitude
                    || timeWarp.warpRates[TimeWarp.CurrentRateIndex + 1] <= TimeWarp.MaxPhysicsRate
                    || part.vessel.Landed)
                && (instantAltitudeASL > timeWarp.altitudeLimits[TimeWarp.CurrentRateIndex + 1] * part.vessel.mainBody.Radius
                    || part.vessel.Landed)
                && vesselState.time - warpIncreaseAttemptTime > 2)
            {
                warpIncreaseAttemptTime = vesselState.time;
                TimeWarp.SetRate(TimeWarp.CurrentRateIndex + 1, instant);
                return true;
            }
            else
            {
                return false;
            }
        }
示例#26
0
 public UserPool(ComputerModule controlledModule)
     : base()
 {
     this.controlledModule = controlledModule;
 }
示例#27
0
        public void warpMinimum(ComputerModule controller, bool instant = true)
        {
            if ((controlModule != null) && (controller != null) && (controlModule != controller)) return;

            TimeWarp.SetRate(0, instant);
        }
示例#28
0
 public void AddComputerModule(ComputerModule module)
 {
     unorderedComputerModules.Add(module);
     ClearModulesCache();
 }
示例#29
0
        public void warpPhysics(ComputerModule controller, bool instant = true)
        {
            if ((controlModule != null) && (controller != null) && (controlModule != controller)) return;

            if (timeWarp.warpRates[TimeWarp.CurrentRateIndex] <= TimeWarp.MaxPhysicsRate)
            {
                return;
            }
            else
            {
                int newIndex = TimeWarp.CurrentRateIndex;
                while (newIndex > 0 && timeWarp.warpRates[newIndex] > TimeWarp.MaxPhysicsRate) newIndex--;
                TimeWarp.SetRate(newIndex, instant);
            }
        }
示例#30
0
 public void AddComputerModule(ComputerModule module)
 {
     unorderedComputerModules.Add(module);
     sortedModules.Clear();
 }
示例#31
0
 public void warpTo(ComputerModule controller, double timeLeft, double[] lookaheadTimes, double maxRate = 10000.0)
 {
     if (timeLeft < lookaheadTimes[TimeWarp.CurrentRateIndex]
         || timeWarp.warpRates[TimeWarp.CurrentRateIndex] > maxRate)
     {
         warpDecrease(controller, true);
     }
     else if (TimeWarp.CurrentRateIndex < timeWarp.warpRates.Length - 1
         && lookaheadTimes[TimeWarp.CurrentRateIndex + 1] < timeLeft
         && timeWarp.warpRates[TimeWarp.CurrentRateIndex + 1] <= maxRate)
     {
         warpIncrease(controller, false, maxRate);
     }
 }
示例#32
0
 public void RemoveComputerModule(ComputerModule module)
 {
     unorderedComputerModules.Remove(module);
     sortedModules.Clear();
 }
示例#33
0
        public bool stage(ComputerModule controller)
        {
            if ((controlModule != null) && (controller != null) && (controlModule != controller))
            {
                return false;
            }

            lastStageTime = vesselState.time;
            Staging.ActivateNextStage();

            return true;
        }