Exemplo n.º 1
0
 protected override void Overrides()
 {
     Fields["displayChance"].guiName = "Chance of Control Surface Failure";
     Fields["safetyRating"].guiName  = "Control Surface Safety Rating";
     failureType = "Stuck Control Surface";
     //Part is mechanical so can be repaired remotely.
     remoteRepairable = true;
     controlSurface   = part.FindModuleImplementing <ModuleControlSurface>();
 }
Exemplo n.º 2
0
 internal ControlSurface(Part part)
 {
     Part           = part;
     controlSurface = part.InternalPart.Module <ModuleControlSurface> ();
     if (controlSurface == null)
     {
         throw new ArgumentException("Part does not have a ModuleControlSurface PartModule");
     }
 }
Exemplo n.º 3
0
        protected void Init(ModuleControlSurface surface, SimulatedPart part)
        {
            base.Init(surface, part);

            this.deflectionLiftCoeff = surface.deflectionLiftCoeff * surface.ctrlSurfaceArea;
            this.authorityLimiter    = surface.authorityLimiter;
            this.ctrlSurfaceRange    = surface.ctrlSurfaceRange;
            // TODO: Incorporate transformName if required.
            this.rotationAxis = surface.transform.rotation * Vector3.right;
            this.ignorePitch  = surface.ignorePitch;
            this.maxAuthority = 150f; // surface.maxAuthority is private. Hopefully its value never changes.
        }
 public override void OnStart(StartState state)
 {
     try
     {
         base.OnStart(state);
         ControlSurfaceModule = part.FindModuleImplementing <ModuleControlSurface>();
         ctrlSurfaceRange     = ControlSurfaceModule.ctrlSurfaceRange;
         ControlSurfaceModule.ctrlSurfaceRange = ctrlSurfaceRange * vacuumRange;
     }
     catch (Exception ex)
     {
         Debug.LogError("PROBLEM.\n" + ex.Message + "\n" + ex.StackTrace);
     }
 }
        public void FixedUpdate()
        {
            ControlSurfaceModule = part.FindModuleImplementing <ModuleControlSurface>();

            if (null == ControlSurfaceModule)
            {
                return;
            }

            if (plusEnabled)
            {
                ControlSurfaceModule.actuatorSpeed = actuatorSpeed;
            }
        }
        public void FixedUpdate()
        {
            ControlSurfaceModule = part.FindModuleImplementing<ModuleControlSurface>();

            if (null == ControlSurfaceModule)
            {
                return;
            }

            if (plusEnabled)
            {
                ControlSurfaceModule.actuatorSpeed = actuatorSpeed;
            }
        }
        public override void OnStart(StartState state)
        {
            base.OnStart(state);

            _surfaceModule = part.FindModuleImplementing <ModuleControlSurface>();
            if (_surfaceModule == null)
            {
                part.RemoveModule(this);
                Destroy(this);
            }
            else
            {
                _ready = true;
            }
        }
Exemplo n.º 8
0
        public override void OnUpgrade(ConfigNode node, LoadContext loadContext, ConfigNode parentNode)
        {
            ConfigNode[] nodes = node.GetNodes("MODULE");
            int          num   = nodes.Length;

            while (num-- > 0)
            {
                string value = nodes[num].GetValue("name");
                if (value == "ModuleControlSurface")
                {
                    ModuleControlSurface baseModule = GetBaseModule(node, loadContext);
                    ConvertControlAuthority(nodes[num], baseModule);
                    ConvertControlAuthorityAxisGroup(nodes[num]);
                }
            }
        }
Exemplo n.º 9
0
 //control surface will stick and not respond to input
 public override void FailPart()
 {
     controlSurface             = part.FindModuleImplementing <ModuleControlSurface>();
     controlSurface.ignorePitch = true;
     controlSurface.ignoreRoll  = true;
     controlSurface.ignoreYaw   = true;
     if (OhScrap.highlight)
     {
         OhScrap.SetFailedHighlight();
     }
     if (hasFailed)
     {
         return;
     }
     Debug.Log("[OhScrap]: " + SYP.ID + " has suffered a control surface failure");
 }
Exemplo n.º 10
0
        public void setup()
        {
            //Set up atmoshpere change listener

            //Debug.Log("setup called");
            cs = GetComponent <ModuleControlSurface>(); //get the parts control surface module

            if (toggles == null)                        //if necessary, initialize static list
            {
                toggles = new List <ModuleCSToggle>();
            }

            toggles.Add(this);

            removeNullToggles(); // Clean up elements from previous iterations of the list

            csFields = new List <BaseField>();

            if (cs.authorityLimiter != 0)   //We don't want to override authority if the surface is disabled
            {
                authority = cs.authorityLimiter;
            }

            if (!controlActive)   //Needed to disable the appropriate gui event buttons
            {
                disableCS();
            }
            else
            {
                enableCS();
            }

            //bool inAtmo = FlightGlobals.ActiveVessel.atmDensity != 0;
            //if (inAtmo && !wasInAtmo) { //If we changed atmosphere state while vessel was not loaded, enable / disable control surface
            //	enableCS();
            //}
            //if (!inAtmo && wasInAtmo) {
            //	disableCS();
            //}


            GameEvents.onVesselSituationChange.Add(UpdateCurrentAtmosphereState);


            setupCalled = true;             //Setup done
        }
        public override void OnStart(StartState state)
        {
            base.OnStart(state);
            deployModule = part.Modules[DeployModuleIndex] as IScalarModule;
            surfaces     = part.FindModulesImplementing <ModuleLiftingSurface>().ToArray();

            for (int i = 0; i < surfaces.Length; i++)
            {
                lifts.Add(surfaces[i].deflectionLiftCoeff);
                if (surfaces[i].GetType() == typeof(ModuleControlSurface) | surfaces[i].GetType() == typeof(ModuleAeroSurface))
                {
                    ModuleControlSurface srf = surfaces[i] as ModuleControlSurface;
                    ranges.Add(srf.ctrlSurfaceRange);
                }
            }

            deployModule.OnStop.Add(UpdateSurfaces);
            UpdateSurfaces(deployModule.GetScalar);
        }
Exemplo n.º 12
0
 //control surface will stick and not respond to input
 protected override void FailPart()
 {
     controlSurface             = part.FindModuleImplementing <ModuleControlSurface>();
     controlSurface.ignorePitch = true;
     controlSurface.ignoreRoll  = true;
     controlSurface.ignoreYaw   = true;
     if (OhScrap.highlight)
     {
         OhScrap.SetFailedHighlight();
     }
     if (message)
     {
         return;
     }
     if (vessel.vesselType != VesselType.Debris)
     {
         ScreenMessages.PostScreenMessage("Control Surface Failure!");
     }
     Debug.Log("[OhScrap]: " + SYP.ID + " has suffered a control surface failure");
     message = true;
 }
Exemplo n.º 13
0
        private void AnalyzeControlSurfaces()
        {
            torqueControlSurface.Reset();

            foreach (var pair in controlSurfaces)
            {
                Part p = pair.Key;

                List <ModuleControlSurface> mlist = p.Modules.GetModules <ModuleControlSurface>();

                for (int m = 0; m < mlist.Count; m++)
                {
                    Vector3 pos;
                    Vector3 neg;
                    ModuleControlSurface cs = mlist[m];
                    cs.GetPotentialTorque(out pos, out neg);
                    torqueReactionWheel.Add(pos);
                    torqueReactionWheel.Add(-neg);
                }
            }
        }
        public override void OnStart(StartState state)
        {
            Debug.Log(moduleName + ".Start(): v01.07");

            base.OnStart(state);

            ControlSurfaceModule = part.FindModuleImplementing<ModuleControlSurface>();

            if (null == ControlSurfaceModule)
            {
                Debug.LogWarning(moduleName + ".Start(): Did not find Control Surface Module.");
                return;
            }

            ControlSurfaceModule.Fields["deploy"].guiActive = true;
            ControlSurfaceModule.Fields["deploy"].guiActiveEditor = true;

            ControlSurfaceModule.Fields["deployInvert"].guiActive = true;
            ControlSurfaceModule.Fields["deployInvert"].guiActiveEditor = true;

            SetupStockPlus();
        }
Exemplo n.º 15
0
 protected override void FailPart()
 {
     if (part.vessel.atmDensity == 0)
     {
         return;
     }
     controlSurface             = part.FindModuleImplementing <ModuleControlSurface>();
     controlSurface.ignorePitch = true;
     controlSurface.ignoreRoll  = true;
     controlSurface.ignoreYaw   = true;
     if (UPFM.highlight)
     {
         UPFM.SetFailedHighlight();
     }
     if (message)
     {
         return;
     }
     ScreenMessages.PostScreenMessage("Control Surface Failure!");
     Debug.Log("[UPFM]: " + SYP.ID + " has suffered a control surface failure");
     message = true;
 }
        public override void OnStart(StartState state)
        {
            Debug.Log(moduleName + ".Start(): v01.04");

            base.OnStart(state);

            ControlSurfaceModule = part.FindModuleImplementing <ModuleControlSurface>();

            if (null == ControlSurfaceModule)
            {
                Debug.LogWarning(moduleName + ".Start(): Did not find Control Surface Module.");
                return;
            }

            ControlSurfaceModule.Fields["deploy"].guiActive       = true;
            ControlSurfaceModule.Fields["deploy"].guiActiveEditor = true;

            ControlSurfaceModule.Fields["deployInvert"].guiActive       = true;
            ControlSurfaceModule.Fields["deployInvert"].guiActiveEditor = true;

            SetupStockPlus();
        }
        public void FixedUpdate()
        {
            ControlSurfaceModule = part.FindModuleImplementing <ModuleControlSurface>();

            if (null == ControlSurfaceModule)
            {
                return;
            }

            if (true == plusEnabled)
            {
                if (FlightGlobals.getStaticPressure(part.transform.position) < 0.001f)
                {
                    if (vacuumRange > 0.01f)
                    {
                        vacuumRange -= 0.05f;
                    }
                    else
                    {
                        vacuumRange = 0.01f;
                    }
                }
                else
                {
                    if (vacuumRange < 1.0f)
                    {
                        vacuumRange += 0.05f;
                    }
                    else
                    {
                        vacuumRange = 1.0f;
                    }
                }
                ControlSurfaceModule.ctrlSurfaceRange = ctrlSurfaceRange * Authority * vacuumRange * Mathf.Sign(ControlSurfaceModule.ctrlSurfaceRange);
            }
        }
        private float vacuumRange = 1.0f; // disables flight controls when in vacuum

        #endregion Fields

        #region Methods

        public void FixedUpdate()
        {
            ControlSurfaceModule = part.FindModuleImplementing<ModuleControlSurface>();

            if (null == ControlSurfaceModule)
            {
                return;
            }

            if (true == plusEnabled)
            {
                if (FlightGlobals.getStaticPressure(part.transform.position) < 0.001f)
                {
                    if (vacuumRange > 0.01f)
                    {
                        vacuumRange -= 0.05f;
                    }
                    else
                    {
                        vacuumRange = 0.01f;
                    }
                }
                else
                {
                    if (vacuumRange < 1.0f)
                    {
                        vacuumRange += 0.05f;
                    }
                    else
                    {
                        vacuumRange = 1.0f;
                    }
                }
                ControlSurfaceModule.ctrlSurfaceRange = ctrlSurfaceRange * Authority * vacuumRange * Mathf.Sign(ControlSurfaceModule.ctrlSurfaceRange);
            }
        }
Exemplo n.º 19
0
        public override void OnFixedUpdate()
        {
            base.OnFixedUpdate();
            if (HighLogic.LoadedSceneIsFlight && FlightGlobals.ready)
            {
                if (boostFlap)
                {
                    if (!bfCheck)
                    {
                        bfCheck            = true;
                        bfPart             = ControlSurface();
                        bfPart.ignorePitch = true;
                        bfPart.ignoreRoll  = true;
                        bfPart.ignoreYaw   = true;
                    }

                    if (!manualDeploy)
                    {
                        if (!this.vessel.Landed)
                        {
                            if (!deployed)
                            {
                                deployed             = true;
                                bfPart.actuatorSpeed = actuatorSpeed;

                                if (toggleDeploy)
                                {
                                    bfPart.deploy = false;
                                }
                                else
                                {
                                    bfPart.deploy = true;
                                }
                            }
                        }
                        else
                        {
                            deployed = false;

                            if (toggleDeploy)
                            {
                                bfPart.deploy = true;
                            }
                            else
                            {
                                bfPart.deploy = false;
                            }
                        }
                    }
                    else
                    {
                        if (!deployed)
                        {
                            deployed = true;

                            if (toggleDeploy)
                            {
                                bfPart.deploy = false;
                            }
                            else
                            {
                                bfPart.deploy = true;
                            }
                        }
                    }
                }
                else
                {
                    if (bfCheck)
                    {
                        bfCheck = false;
                    }
                }
            }
        }
Exemplo n.º 20
0
        private ModuleControlSurface ControlSurface()
        {
            ModuleControlSurface Control = part.FindModuleImplementing <ModuleControlSurface>();

            return(Control);
        }
Exemplo n.º 21
0
    // This method calculates part values such as mass, lift, drag and connection forces, as well as all intermediates.
    public void CalculateAerodynamicValues(bool doInteraction = true)
    {
        // Calculate intemediate values
        //print(part.name + ": Calc Aero values");
        b_2 = (double)tipPosition.z - (double)Root.localPosition.z + 1.0;

        MAC = ((double)tipScale.x + (double)rootScale.x + 2.0) * (double)modelChordLenght / 2.0;

        midChordSweep = (MathD.Rad2Deg * Math.Atan(((double)Root.localPosition.x - (double)tipPosition.x) / b_2));

        taperRatio = ((double)tipScale.x + 1.0) / ((double)rootScale.x + 1.0);

        surfaceArea = MAC * b_2;

        aspectRatio = 2.0 * b_2 / MAC;

        ArSweepScale = Math.Pow(aspectRatio / MathD.Cos(MathD.Deg2Rad * midChordSweep), 2.0) + 4.0;
        ArSweepScale = 2.0 + Math.Sqrt(ArSweepScale);
        ArSweepScale = (2.0 * MathD.PI) / ArSweepScale * aspectRatio;

        wingMass = MathD.Clamp((double)massFudgeNumber * surfaceArea * ((ArSweepScale * 2.0) / (3.0 + ArSweepScale)) * ((1.0 + taperRatio) / 2), 0.01, double.MaxValue);

        Cd = (double)dragBaseValue / ArSweepScale * (double)dragMultiplier;

        Cl = (double)liftFudgeNumber * surfaceArea * ArSweepScale;

        //print("Gather Children");
        GatherChildrenCl();

        connectionForce = MathD.Round(MathD.Clamp(MathD.Sqrt(Cl + ChildrenCl) * (double)connectionFactor, (double)connectionMinimum, double.MaxValue));

        // Values always set
        if (isWing)
        {
            wingCost = (float)wingMass * (1f + (float)ArSweepScale / 4f) * costDensity;
            wingCost = Mathf.Round(wingCost / 5f) * 5f;
        }
        else if (isCtrlSrf)
        {
            wingCost  = (float)wingMass * (1f + (float)ArSweepScale / 4f) * costDensity * (1f - modelControlSurfaceFraction);
            wingCost += (float)wingMass * (1f + (float)ArSweepScale / 4f) * costDensityControl * modelControlSurfaceFraction;
            wingCost  = Mathf.Round(wingCost / 5f) * 5f;
        }

        part.breakingForce  = Mathf.Round((float)connectionForce);
        part.breakingTorque = Mathf.Round((float)connectionForce);

        // Stock-only values
        if (!FARactive)
        {
            // numbers for lift from: http://forum.kerbalspaceprogram.com/threads/118839-Updating-Parts-to-1-0?p=1896409&viewfull=1#post1896409
            float stockLiftCoefficient = (float)(surfaceArea / 3.52);
            // CoL/P matches CoM unless otherwise specified
            part.CoMOffset = new Vector3(Vector3.Dot(Tip.position - Root.position, part.transform.right) / 2, Vector3.Dot(Tip.position - Root.position, part.transform.up) / 2, 0);
            if (isWing && !isCtrlSrf)
            {
                part.Modules.GetModules <ModuleLiftingSurface>().FirstOrDefault().deflectionLiftCoeff = stockLiftCoefficient;
                part.mass = stockLiftCoefficient * 0.1f;
            }
            else
            {
                ModuleControlSurface mCtrlSrf = part.Modules.OfType <ModuleControlSurface>().FirstOrDefault();
                if (mCtrlSrf != null)
                {
                    mCtrlSrf.deflectionLiftCoeff = stockLiftCoefficient;
                    mCtrlSrf.ctrlSurfaceArea     = modelControlSurfaceFraction;
                    part.mass = stockLiftCoefficient * (1 + modelControlSurfaceFraction) * 0.1f;
                }
            }
        }

        // FAR values
        // With reflection stuff from r4m0n
        if (FARactive)
        {
            if (part.Modules.Contains("FARControllableSurface"))
            {
                PartModule FARmodule = part.Modules["FARControllableSurface"];
                Type       FARtype   = FARmodule.GetType();
                FARtype.GetField("b_2").SetValue(FARmodule, b_2);
                FARtype.GetField("b_2_actual").SetValue(FARmodule, b_2);
                FARtype.GetField("MAC").SetValue(FARmodule, MAC);
                FARtype.GetField("MAC_actual").SetValue(FARmodule, MAC);
                FARtype.GetField("S").SetValue(FARmodule, surfaceArea);
                FARtype.GetField("MidChordSweep").SetValue(FARmodule, midChordSweep);
                FARtype.GetField("TaperRatio").SetValue(FARmodule, taperRatio);
                FARtype.GetField("ctrlSurfFrac").SetValue(FARmodule, modelControlSurfaceFraction);
                //print("Set fields");
            }
            else if (part.Modules.Contains("FARWingAerodynamicModel"))
            {
                PartModule FARmodule = part.Modules["FARWingAerodynamicModel"];
                Type       FARtype   = FARmodule.GetType();
                FARtype.GetField("b_2").SetValue(FARmodule, b_2);
                FARtype.GetField("b_2_actual").SetValue(FARmodule, b_2);
                FARtype.GetField("MAC").SetValue(FARmodule, MAC);
                FARtype.GetField("MAC_actual").SetValue(FARmodule, MAC);
                FARtype.GetField("S").SetValue(FARmodule, surfaceArea);
                FARtype.GetField("MidChordSweep").SetValue(FARmodule, midChordSweep);
                FARtype.GetField("TaperRatio").SetValue(FARmodule, taperRatio);
            }
            if (!triggerUpdate && doInteraction)
            {
                TriggerUpdateAllWings();
            }
            if (doInteraction)
            {
                triggerUpdate = false;
            }
        }
        //print("FAR Done");
        // Update GUI values
        if (!FARactive)
        {
            guiCd       = Mathf.Round((float)Cd * 100f) / 100f;
            guiCl       = Mathf.Round((float)Cl * 100f) / 100f;
            guiWingMass = part.mass;
        }

        guiMAC           = (float)MAC;
        guiB_2           = (float)b_2;
        guiMidChordSweep = (float)midChordSweep;
        guiTaperRatio    = (float)taperRatio;
        guiSurfaceArea   = (float)surfaceArea;
        guiAspectRatio   = (float)aspectRatio;

        StartCoroutine(updateAeroDelayed());
    }
Exemplo n.º 22
0
        //============================================================================================================================================
        public void EngageAero()
        {
            //FAR Compatibility =)
            //Skip this if FAR isn't being used
            if (assemblyFARUsed == true) {
                foreach (Part EnabledPart in EnabledPartList) {
                    if (EnabledPart.Modules.Contains ("FARControllableSurface")) {
                        AeroFARModuleReference = EnabledPart.Modules ["FARControllableSurface"];
                        if (AeroFARModuleReference.Fields.GetValue ("isSpoiler").ToString() == "True") {
                            RoboBrakes_AeroEnabledCount++;
                            BaseActionList BAL = new BaseActionList (EnabledPart, AeroFARModuleReference);
                            foreach (BaseAction BA in BAL) {
                                if ((RoboBrakes_AUTOMATICBRAKE_ACTIVE == true && RoboBrakes_AEROAUTO == true) | (RoboBrakes_OVERRIDEBRAKE_ACTIVE == true && RoboBrakes_AEROOVERRIDE == true)) {
                                    if (BA.guiName == "Activate Spoiler") {
                                        KSPActionParam AP = new KSPActionParam (KSPActionGroup.None, KSPActionType.Activate);
                                        BA.Invoke (AP);
                                    }
                                } else {
                                    if (BA.guiName == "Activate Spoiler") {
                                        KSPActionParam AP = new KSPActionParam (KSPActionGroup.None, KSPActionType.Deactivate);
                                        BA.Invoke (AP);
                                    }
                                }
                            }
                        }
                    }
                }
            }
            foreach (Part EnabledPart in EnabledPartList) {
                //---------------------------------------------------------------------------------------------------------------------
                //Control Surface Module
                if (EnabledPart.Modules.Contains ("ModuleControlSurface")) {
                    ModuleControlSurface MCS = new ModuleControlSurface ();
                    MCS = EnabledPart.FindModuleImplementing<ModuleControlSurface> ();
                    RoboBrakes_AeroEnabledCount++;
                    BaseActionList BAL = new BaseActionList (EnabledPart, MCS);
                    foreach (BaseAction BA in BAL) {
                        if ((RoboBrakes_AUTOMATICBRAKE_ACTIVE == true && RoboBrakes_AEROAUTO == true) | (RoboBrakes_OVERRIDEBRAKE_ACTIVE == true && RoboBrakes_AEROOVERRIDE == true)) {
                            if (BA.guiName == "Extend") {
                                KSPActionParam AP = new KSPActionParam (KSPActionGroup.None, KSPActionType.Activate);
                                BA.Invoke (AP);
                            }
                        } else {
                            if (BA.guiName == "Retract") {
                                KSPActionParam AP = new KSPActionParam (KSPActionGroup.None, KSPActionType.Activate);
                                BA.Invoke (AP);
                            }
                        }
                    }
                }

                //---------------------------------------------------------------------------------------------------------------------
                //Module Aero Surface
                if (EnabledPart.Modules.Contains ("ModuleAeroSurface")) {
                    ModuleAeroSurface MAS = new ModuleAeroSurface ();
                    MAS = EnabledPart.FindModuleImplementing<ModuleAeroSurface> ();
                    RoboBrakes_AeroEnabledCount++;
                    BaseActionList BAL = new BaseActionList (EnabledPart, MAS);
                    foreach (BaseAction BA in BAL) {
                        if ((RoboBrakes_AUTOMATICBRAKE_ACTIVE == true && RoboBrakes_AEROAUTO == true) | (RoboBrakes_OVERRIDEBRAKE_ACTIVE == true && RoboBrakes_AEROOVERRIDE == true)) {
                            if (BA.guiName == "Extend") {
                                KSPActionParam AP = new KSPActionParam (KSPActionGroup.None, KSPActionType.Activate);
                                BA.Invoke (AP);
                            }
                        } else {
                            if (BA.guiName == "Retract") {
                                KSPActionParam AP = new KSPActionParam (KSPActionGroup.None, KSPActionType.Activate);
                                BA.Invoke (AP);
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 23
0
 public StockModule(ModuleControlSurface module)
 {
     controlSurface = module;
 }
Exemplo n.º 24
0
        /// <summary>
        /// Import from MechJeb2
        /// https://github.com/MuMech/MechJeb2/blob/dev/MechJeb2/VesselState.cs
        /// </summary>
        public static void AnalyzeParts(Vessel vessel)
        {
            torqueAvailable = Vector3d.zero;
            Vector6 torqueReactionSpeed6 = new Vector6();

            torqueReactionWheel.Reset();
            torqueControlSurface.Reset();
            torqueGimbal.Reset();
            torqueOthers.Reset();

            UpdateRCSThrustAndTorque(vessel);

            for (int i = 0; i < vessel.parts.Count; i++)
            {
                Part p = vessel.parts[i];

                for (int m = 0; m < p.Modules.Count; m++)
                {
                    PartModule pm = p.Modules[m];
                    if (!pm.isEnabled)
                    {
                        continue;
                    }

                    ModuleReactionWheel rw = pm as ModuleReactionWheel;
                    if (rw != null)
                    {
                        Vector3 pos;
                        Vector3 neg;
                        rw.GetPotentialTorque(out pos, out neg);

                        // GetPotentialTorque reports the same value for pos & neg on ModuleReactionWheel
                        torqueReactionWheel.Add(pos);
                        torqueReactionWheel.Add(-neg);
                    }
                    else if (pm is ModuleControlSurface) // also does ModuleAeroSurface
                    {
                        ModuleControlSurface cs = (pm as ModuleControlSurface);

                        Vector3 ctrlTorquePos;
                        Vector3 ctrlTorqueNeg;

                        cs.GetPotentialTorque(out ctrlTorquePos, out ctrlTorqueNeg);

                        torqueControlSurface.Add(ctrlTorquePos);
                        torqueControlSurface.Add(ctrlTorqueNeg);

                        torqueReactionSpeed6.Add(Mathf.Abs(cs.ctrlSurfaceRange) / cs.actuatorSpeed * Vector3d.Max(ctrlTorquePos.Abs(), ctrlTorqueNeg.Abs()));
                    }
                    else if (pm is ModuleGimbal)
                    {
                        ModuleGimbal g = (pm as ModuleGimbal);

                        Vector3 pos;
                        Vector3 neg;

                        g.GetPotentialTorque(out pos, out neg);
                        // GetPotentialTorque reports the same value for pos & neg on ModuleGimbal

                        torqueGimbal.Add(pos);
                        torqueGimbal.Add(-neg);

                        if (g.useGimbalResponseSpeed)
                        {
                            torqueReactionSpeed6.Add((Mathf.Abs(g.gimbalRange) / g.gimbalResponseSpeed) * Vector3d.Max(pos.Abs(), neg.Abs()));
                        }
                    }
                    else if (pm is ModuleRCS)
                    {
                        // Handled separately
                    }
                    else if (pm is ITorqueProvider)
                    {
                        ITorqueProvider tp = pm as ITorqueProvider;

                        Vector3 pos;
                        Vector3 neg;
                        tp.GetPotentialTorque(out pos, out neg);

                        torqueOthers.Add(pos);
                        torqueOthers.Add(neg);
                    }
                }
            }

            torqueAvailable += Vector3d.Max(torqueReactionWheel.positive, torqueReactionWheel.negative);
            torqueAvailable += Vector3d.Max(rcsTorqueAvailable.positive, rcsTorqueAvailable.negative);
            torqueAvailable += Vector3d.Max(torqueControlSurface.positive, torqueControlSurface.negative);
            torqueAvailable += Vector3d.Max(torqueGimbal.positive, torqueGimbal.negative);
            torqueAvailable += Vector3d.Max(torqueOthers.positive, torqueOthers.negative);

            if (torqueAvailable.sqrMagnitude > 0)
            {
                torqueReactionSpeed = Vector3d.Max(torqueReactionSpeed6.positive, torqueReactionSpeed6.negative);
                torqueReactionSpeed.Scale(torqueAvailable.InvertNoNaN());
            }
            else
            {
                torqueReactionSpeed = Vector3d.zero;
            }
        }
Exemplo n.º 25
0
    public override void OnStart(PartModule.StartState state)
    {
        debug.debugMode = debugMode;

        FARActive = AssemblyLoader.loadedAssemblies.Any(a => a.assembly.GetName().Name.Equals("FerramAerospaceResearch", StringComparison.InvariantCultureIgnoreCase));
        // This line breaks the plugin :(
        if (FARActive)
        {
            foreach (BaseField f in Fields)
            {
                f.guiActive = false;
            }
            foreach (BaseEvent e in Events)
            {
                e.active          = false;
                e.guiActive       = false;
                e.guiActiveEditor = false;
            }
            foreach (BaseAction a in Actions)
            {
                a.active = false;
            }
            this.enabled = false;
            return;
        }

        //debug.debugMessage("FSwing OnStart: " + part.name);

        #region fligth mode

        if (HighLogic.LoadedSceneIsFlight)
        {
            findTransforms(true);

            // Check if a stock wing module is present, if not, manipulate FSliftSurface stuff instead.
            if (affectStockWingModule)
            {
                //Debug.Log("FSwing: getting stock wing module");
                stockWingModule = part.FindModuleImplementing <ModuleControlSurface>();
                if (stockWingModule != null)
                {
                    //Debug.Log("FSwing: success");
                }
                else
                {
                    debug.debugMessage("FSwing: did not Find stock wing module");
                    affectStockWingModule = false;
                }
            }

            // get the main lift surface for the leading edge to manipulate
            if (affectStockWingModule)
            {
                useCtrlSrf = false;
            }
            else
            {
                FSliftSurface[] surfaces = part.GetComponents <FSliftSurface>();
                foreach (FSliftSurface surface in surfaces)
                {
                    if (surface.liftTransformName == leadingEdgeLiftSurface)
                    {
                        mainLift            = surface;
                        mainLiftAreaDefault = surface.wingArea;
                        //Debug.Log("FSwing: Slat assigned main lift to: " + surface.liftTransformName);
                        break;
                    }
                }
                if (mainLift == null)
                {
                    debug.debugMessage("FSwing: leading edge missing main FSliftSurface: " + leadingEdgeLiftSurface);
                }
            }
        }
        #endregion

        #region help popup

        helpPopup = new Firespitter.info.HelpPopup("Wing setup help", helpTextInternal);

        /*helpSection = new PopupSection();
         * PopupElement helpText = new PopupElement(helpTextnternal, true);
         * helpSection.AddElement(helpText, 300f);
         * if (windowID == 0)
         *  windowID = FSGUIwindowID.getNextID();
         * helpPopup = new FSGUIPopup(part, "FSwing", 0, windowID, windowRect, "Wing setup help");
         * helpPopup.sections.Add(helpSection);
         * helpPopup.useInEditor = true;
         * helpPopup.useInFlight = true;*/

        #endregion

        originalCtrlSurfaceRange = ctrlSurfaceRange;

        if (affectStockWingModule || !showTweakables)
        {
            Fields["pitchResponse"].guiActive       = false;
            Fields["pitchResponse"].guiActiveEditor = false;
            Fields["rollResponse"].guiActive        = false;
            Fields["rollResponse"].guiActiveEditor  = false;
            Fields["yawResponse"].guiActive         = false;
            Fields["yawResponse"].guiActiveEditor   = false;
            Fields["flapResponse"].guiActive        = false;
            Fields["flapResponse"].guiActiveEditor  = false;
        }

        ApplyDamage(partHealth);
    }
Exemplo n.º 26
0
        private void CountSurfaces()
        {
            print("Counting wings for " + vessel.GetName());

            liftingSurfaces = new List <ModuleLiftingSurface>();
            controlSurfaces = new List <ModuleControlSurface>();

            liftingInitLift = new List <float>();
            controlInitLift = new List <float>();

            inRange = true;

            groundPlane = new Plane();

            // This will be calculated later
            wingSpan = 42 / 42;

            foreach (Part part in vessel.Parts)
            {
                ModuleControlSurface thingThatLiftsPartsAndMoves = null;
                ModuleLiftingSurface thingThatLiftsParts         = null;

                // Look through the list of part modules to find anything that inherits ModuleLiftingSurface
                foreach (PartModule module in part.Modules)
                {
                    if (typeof(ModuleLiftingSurface).IsAssignableFrom(module.GetType()))
                    {
                        //thingThatLiftsParts = (ModuleLiftingSurface)(module);
                        //initialLift = thingThatLiftsParts.deflectionLiftCoeff;

                        thingThatLiftsParts = (ModuleLiftingSurface)(module);

                        if (module is ModuleControlSurface)
                        {
                            thingThatLiftsPartsAndMoves = (ModuleControlSurface)(module);
                        }
                    }
                }

                if (thingThatLiftsParts != null)
                {
                    if (thingThatLiftsPartsAndMoves != null)
                    {
                        // It's a control surface, add to control surface arrays
                        controlSurfaces.Add(thingThatLiftsPartsAndMoves);
                        controlInitLift.Add(thingThatLiftsPartsAndMoves.ctrlSurfaceArea);
                    }
                    else
                    {
                        // It's just a lifting surface, add to lifting surface arrays
                        liftingSurfaces.Add(thingThatLiftsParts);
                        liftingInitLift.Add(thingThatLiftsParts.deflectionLiftCoeff);
                    }
                }

                //thingThatLiftsPartsAndMoves.OnCenterOfLiftQuery();
            }

            print("LiftingSurfaces counted for " + vessel.GetName() + ": " + liftingSurfaces.Count);
            print("ControlSurfaces counted for " + vessel.GetName() + ": " + controlSurfaces.Count);
        }
Exemplo n.º 27
0
        public static Vector3 get_part_torque(CenterOfLiftQuery qry, Part p, Vector3 CoM, ref float lift, ref float drag)
        {
            if (p == null || (p.Rigidbody != p.rb) && !PhysicsGlobals.ApplyDragToNonPhysicsParts)
            {
                return(Vector3.zero);
            }

            Vector3 lift_pos = Vector3.zero;
            Vector3 drag_pos = Vector3.zero;

            if (!p.ShieldedFromAirstream)
            {
                var providers = p.FindModulesImplementing <ModuleLiftingSurface>();
                if ((providers != null) && providers.Count > 0)
                {
                    p.hasLiftModule = true;
                }

                Vector3 res = Vector3.zero;

                if (p.hasLiftModule && providers[0] is ModuleControlSurface)
                {
                    p.DragCubes.SetCubeWeight("neutral", 1.5f);
                    p.DragCubes.SetCubeWeight("fullDeflectionPos", 0.0f);
                    p.DragCubes.SetCubeWeight("fullDeflectionNeg", 0.0f);
                }

                // drag from drag-cubes
                if (!p.DragCubes.None)
                {
                    Vector3 drag_force = Vector3.zero;

                    p.dragVector         = qry.refVector;
                    p.dragVectorSqrMag   = p.dragVector.sqrMagnitude;
                    p.dragVectorMag      = Mathf.Sqrt(p.dragVectorSqrMag);
                    p.dragVectorDir      = p.dragVector / p.dragVectorMag;
                    p.dragVectorDirLocal = -p.partTransform.InverseTransformDirection(p.dragVectorDir);

                    p.dynamicPressurekPa = qry.refAirDensity * 0.0005 * p.dragVectorSqrMag;

                    if (p.rb != p.Rigidbody && PhysicsGlobals.ApplyDragToNonPhysicsPartsAtParentCoM)
                    {
                        drag_pos = p.Rigidbody.worldCenterOfMass;
                        lift_pos = drag_pos;
                    }
                    else
                    {
                        lift_pos = p.partTransform.TransformPoint(p.CoLOffset);
                        drag_pos = p.partTransform.TransformPoint(p.CoPOffset);
                    }

                    p.DragCubes.SetDrag(p.dragVectorDirLocal, mach);

                    float pseudoreynolds   = (float)(density * Mathf.Abs(speed));
                    float pseudoredragmult = PhysicsGlobals.DragCurvePseudoReynolds.Evaluate(pseudoreynolds);
                    float drag_k           = p.DragCubes.AreaDrag * PhysicsGlobals.DragCubeMultiplier * pseudoredragmult;
                    p.dragScalar = (float)(p.dynamicPressurekPa * drag_k * PhysicsGlobals.DragMultiplier);

                    drag_force = p.dragScalar * -p.dragVectorDir;

                    res += Vector3.Cross(drag_force, drag_pos - CoM);

                    Vector3 sum_force = drag_force;

                    drag += Vector3.Dot(sum_force, -p.dragVectorDir);
                }

                if (!p.hasLiftModule)
                {
                    // stock aero lift
                    if (!p.DragCubes.None)
                    {
                        p.bodyLiftScalar = (float)(p.dynamicPressurekPa * p.bodyLiftMultiplier * PhysicsGlobals.BodyLiftMultiplier *
                                                   CorrectCoL.CoLMarkerFull.lift_curves.liftMachCurve.Evaluate(mach));

                        Vector3 lift_force = p.partTransform.rotation * (p.bodyLiftScalar * p.DragCubes.LiftForce);
                        lift_force = Vector3.ProjectOnPlane(lift_force, -p.dragVectorDir);

                        res += Vector3.Cross(lift_force, lift_pos - CoM);

                        Vector3 sum_force = lift_force;

                        lift += Vector3.Dot(sum_force, Vector3.Cross(p.dragVectorDir, EditorLogic.RootPart.transform.right).normalized);
                    }
                    return(res);
                }
                else
                {
                    double q = 0.5 * qry.refAirDensity * qry.refVector.sqrMagnitude;

                    for (int i = 0; i < providers.Count; i++)
                    {
                        Vector3 dragvect;
                        Vector3 liftvect;
                        Vector3 lift_force = Vector3.zero;
                        Vector3 drag_force = Vector3.zero;
                        float   abs;
                        ModuleLiftingSurface lsurf = providers[i];
                        ModuleControlSurface csurf = lsurf as ModuleControlSurface;
                        lsurf.SetupCoefficients(qry.refVector, out dragvect, out liftvect, out lsurf.liftDot, out abs);

                        lift_pos = p.partTransform.TransformPoint(p.CoLOffset);
                        drag_pos = p.partTransform.TransformPoint(p.CoPOffset);

                        lift_force = lsurf.GetLiftVector(liftvect, lsurf.liftDot, abs, q, mach);
                        if (lsurf.useInternalDragModel)
                        {
                            drag_force = lsurf.GetDragVector(dragvect, abs, q);
                        }

                        if (csurf != null)
                        {
                            float      deflection = (float)deflection_field.GetValue(csurf);
                            Quaternion incidence  = Quaternion.AngleAxis(csurf.ctrlSurfaceRange * deflection, p.partTransform.rotation * Vector3.right);
                            liftvect      = incidence * liftvect;
                            lsurf.liftDot = Vector3.Dot(dragvect, liftvect);
                            abs           = Mathf.Abs(lsurf.liftDot);
                            lift_force    = lift_force * (1.0f - csurf.ctrlSurfaceArea);
                            lift_force   += lsurf.GetLiftVector(liftvect, lsurf.liftDot, abs, q, mach) * csurf.ctrlSurfaceArea;
                            if (csurf.useInternalDragModel)
                            {
                                drag_force  = drag_force * (1.0f - csurf.ctrlSurfaceArea);
                                drag_force += csurf.GetDragVector(dragvect, abs, q) * csurf.ctrlSurfaceArea;
                            }
                        }

                        res += Vector3.Cross(lift_force, lift_pos - CoM);
                        res += Vector3.Cross(drag_force, drag_pos - CoM);

                        Vector3 result_force = lift_force + drag_force;
                        lift += Vector3.Dot(result_force, Vector3.Cross(qry.refVector, EditorLogic.RootPart.transform.right).normalized);
                        drag += Vector3.Dot(result_force, -qry.refVector.normalized);
                    }
                    return(res);
                }
            }

            return(Vector3.zero);
        }
Exemplo n.º 28
0
        public void Update(Vessel vessel)
        {
            if (vessel.rigidbody == null)
            {
                return;                           //if we try to update before rigidbodies exist we spam the console with NullPointerExceptions.
            }
            //if (vessel.packed) return;

            // To investigate some strange error
            if ((vessel.mainBody == null || (object)(vessel.mainBody) == null) && counter == 0)
            {
                if ((object)(vessel.mainBody) == null)
                {
                    MechJebCore.print("vessel.mainBody is proper null");
                }
                else
                {
                    MechJebCore.print("vessel.mainBody is Unity null");
                }

                counter = counter++ % 100;
            }


            time   = Planetarium.GetUniversalTime();
            deltaT = TimeWarp.fixedDeltaTime;

            CoM = vessel.findWorldCenterOfMass();
            up  = (CoM - vessel.mainBody.position).normalized;

            Rigidbody rigidBody = vessel.rootPart.rigidbody;

            if (rigidBody != null)
            {
                rootPartPos = rigidBody.position;
            }

            north                 = Vector3d.Exclude(up, (vessel.mainBody.position + vessel.mainBody.transform.up * (float)vessel.mainBody.Radius) - CoM).normalized;
            east                  = vessel.mainBody.getRFrmVel(CoM).normalized;
            forward               = vessel.GetTransform().up;
            rotationSurface       = Quaternion.LookRotation(north, up);
            rotationVesselSurface = Quaternion.Inverse(Quaternion.Euler(90, 0, 0) * Quaternion.Inverse(vessel.GetTransform().rotation) * rotationSurface);

//            velocityVesselOrbit = vessel.orbit.GetVel();
//            velocityVesselOrbitUnit = velocityVesselOrbit.normalized;
//            velocityVesselSurface = velocityVesselOrbit - vessel.mainBody.getRFrmVel(CoM);
//            velocityVesselSurfaceUnit = velocityVesselSurface.normalized;
            velocityMainBodySurface = rotationSurface * vessel.srf_velocity;

            horizontalOrbit   = Vector3d.Exclude(up, vessel.obt_velocity).normalized;
            horizontalSurface = Vector3d.Exclude(up, vessel.srf_velocity).normalized;

            angularVelocity = Quaternion.Inverse(vessel.GetTransform().rotation) * vessel.rigidbody.angularVelocity;

            radialPlusSurface = Vector3d.Exclude(vessel.srf_velocity, up).normalized;
            radialPlus        = Vector3d.Exclude(vessel.obt_velocity, up).normalized;
            normalPlusSurface = -Vector3d.Cross(radialPlusSurface, vessel.srf_velocity.normalized);
            normalPlus        = -Vector3d.Cross(radialPlus, vessel.obt_velocity.normalized);

            gravityForce = FlightGlobals.getGeeForceAtPosition(CoM);
            localg       = gravityForce.magnitude;

            speedOrbital.value           = vessel.obt_velocity.magnitude;
            speedSurface.value           = vessel.srf_velocity.magnitude;
            speedVertical.value          = Vector3d.Dot(vessel.srf_velocity, up);
            speedSurfaceHorizontal.value = Vector3d.Exclude(up, vessel.srf_velocity).magnitude; //(velocityVesselSurface - (speedVertical * up)).magnitude;
            speedOrbitHorizontal         = (vessel.obt_velocity - (speedVertical * up)).magnitude;

            vesselHeading.value = rotationVesselSurface.eulerAngles.y;
            vesselPitch.value   = (rotationVesselSurface.eulerAngles.x > 180) ? (360.0 - rotationVesselSurface.eulerAngles.x) : -rotationVesselSurface.eulerAngles.x;
            vesselRoll.value    = (rotationVesselSurface.eulerAngles.z > 180) ? (rotationVesselSurface.eulerAngles.z - 360.0) : rotationVesselSurface.eulerAngles.z;

            altitudeASL.value = vessel.mainBody.GetAltitude(CoM);
            //RaycastHit sfc;
            //if (Physics.Raycast(CoM, -up, out sfc, (float)altitudeASL + 10000.0F, 1 << 15))
            //{
            //    altitudeTrue.value = sfc.distance;
            //}
            //else if (vessel.mainBody.pqsController != null)
            //{
            //    // from here: http://kerbalspaceprogram.com/forum/index.php?topic=10324.msg161923#msg161923
            //    altitudeTrue.value = vessel.mainBody.GetAltitude(CoM) - (vessel.mainBody.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(vessel.mainBody.GetLongitude(CoM), Vector3d.down) * QuaternionD.AngleAxis(vessel.mainBody.GetLatitude(CoM), Vector3d.forward) * Vector3d.right) - vessel.mainBody.pqsController.radius);
            //}
            //else
            //{
            //    altitudeTrue.value = vessel.mainBody.GetAltitude(CoM);
            //}

            //double surfaceAltitudeASL = altitudeASL - altitudeTrue;

            double surfaceAltitudeASL = vessel.mainBody.pqsController != null ? vessel.pqsAltitude : 0d;

            altitudeTrue.value = altitudeASL - surfaceAltitudeASL;

            altitudeBottom = altitudeTrue;
            foreach (Part p in vessel.parts)
            {
                if (p.collider != null)
                {
                    Vector3d bottomPoint   = p.collider.ClosestPointOnBounds(vessel.mainBody.position);
                    double   partBottomAlt = vessel.mainBody.GetAltitude(bottomPoint) - surfaceAltitudeASL;
                    altitudeBottom = Math.Max(0, Math.Min(altitudeBottom, partBottomAlt));
                }
            }

            double atmosphericPressure = FlightGlobals.getStaticPressure(altitudeASL, vessel.mainBody);

            if (atmosphericPressure < vessel.mainBody.atmosphereMultiplier * 1e-6)
            {
                atmosphericPressure = 0;
            }
            atmosphericDensity      = FlightGlobals.getAtmDensity(atmosphericPressure);
            atmosphericDensityGrams = atmosphericDensity * 1000;

            orbitApA.value      = vessel.orbit.ApA;
            orbitPeA.value      = vessel.orbit.PeA;
            orbitPeriod.value   = vessel.orbit.period;
            orbitTimeToAp.value = vessel.orbit.timeToAp;
            if (vessel.orbit.eccentricity < 1)
            {
                orbitTimeToPe.value = vessel.orbit.timeToPe;
            }
            else
            {
                orbitTimeToPe.value = -vessel.orbit.meanAnomaly / (2 * Math.PI / vessel.orbit.period);
            }
            orbitLAN.value = vessel.orbit.LAN;
            orbitArgumentOfPeriapsis.value = vessel.orbit.argumentOfPeriapsis;
            orbitInclination.value         = vessel.orbit.inclination;
            orbitEccentricity.value        = vessel.orbit.eccentricity;
            orbitSemiMajorAxis.value       = vessel.orbit.semiMajorAxis;
            latitude.value  = vessel.mainBody.GetLatitude(CoM);
            longitude.value = MuUtils.ClampDegrees180(vessel.mainBody.GetLongitude(CoM));

            if (vessel.mainBody != Planetarium.fetch.Sun)
            {
                Vector3d delta = vessel.mainBody.getPositionAtUT(Planetarium.GetUniversalTime() + 1) - vessel.mainBody.getPositionAtUT(Planetarium.GetUniversalTime() - 1);
                Vector3d plUp  = Vector3d.Cross(vessel.mainBody.getPositionAtUT(Planetarium.GetUniversalTime()) - vessel.mainBody.referenceBody.getPositionAtUT(Planetarium.GetUniversalTime()), vessel.mainBody.getPositionAtUT(Planetarium.GetUniversalTime() + vessel.mainBody.orbit.period / 4) - vessel.mainBody.referenceBody.getPositionAtUT(Planetarium.GetUniversalTime() + vessel.mainBody.orbit.period / 4)).normalized;
                angleToPrograde = MuUtils.ClampDegrees360((((vessel.orbit.inclination > 90) || (vessel.orbit.inclination < -90)) ? 1 : -1) * ((Vector3)up).AngleInPlane(plUp, delta));
            }
            else
            {
                angleToPrograde = 0;
            }

            mainBody = vessel.mainBody;

            radius = (CoM - vessel.mainBody.position).magnitude;

            mass = massDrag = torqueThrustPYAvailable = 0;
            thrustVectorLastFrame   = new Vector3d();
            thrustVectorMaxThrottle = new Vector3d();
            thrustVectorMinThrottle = new Vector3d();
            torqueAvailable         = new Vector3d();
            rcsThrustAvailable      = new Vector6();
            rcsTorqueAvailable      = new Vector6();
            ctrlTorqueAvailable     = new Vector6();

            EngineInfo einfo = new EngineInfo(CoM);
            IntakeInfo iinfo = new IntakeInfo();

            parachutes = new List <ModuleParachute>();

            var rcsbal = vessel.GetMasterMechJeb().rcsbal;

            if (vessel.ActionGroups[KSPActionGroup.RCS] && rcsbal.enabled)
            {
                Vector3d rot = Vector3d.zero;
                foreach (Vector6.Direction dir6 in Enum.GetValues(typeof(Vector6.Direction)))
                {
                    Vector3d dir = Vector6.directions[dir6];
                    double[] throttles;
                    List <RCSSolver.Thruster> thrusters;
                    rcsbal.GetThrottles(dir, out throttles, out thrusters);
                    if (throttles != null)
                    {
                        for (int i = 0; i < throttles.Length; i++)
                        {
                            if (throttles[i] > 0)
                            {
                                Vector3d force = thrusters[i].GetThrust(dir, rot);
                                rcsThrustAvailable.Add(vessel.GetTransform().InverseTransformDirection(dir * Vector3d.Dot(force * throttles[i], dir)));
                            }
                        }
                    }
                }
            }

            hasMFE = false;

            foreach (Part p in vessel.parts)
            {
                if (p.IsPhysicallySignificant())
                {
                    double partMass = p.TotalMass();
                    mass     += partMass;
                    massDrag += partMass * p.maximum_drag;
                }

                if (vessel.ActionGroups[KSPActionGroup.RCS] && !rcsbal.enabled)
                {
                    foreach (ModuleRCS pm in p.Modules.OfType <ModuleRCS>())
                    {
                        double   maxT         = pm.thrusterPower;
                        Vector3d partPosition = p.Rigidbody.worldCenterOfMass - CoM;

                        if ((pm.isEnabled) && (!pm.isJustForShow))
                        {
                            foreach (Transform t in pm.thrusterTransforms)
                            {
                                Vector3d thrusterThrust = vessel.GetTransform().InverseTransformDirection(-t.up.normalized) * pm.thrusterPower;
                                rcsThrustAvailable.Add(thrusterThrust);
                                Vector3d thrusterTorque = Vector3.Cross(vessel.GetTransform().InverseTransformDirection(partPosition), thrusterThrust);
                                rcsTorqueAvailable.Add(thrusterTorque);
                            }
                        }
                    }
                }

                if (p is ControlSurface)
                {
                    Vector3d       partPosition = p.Rigidbody.worldCenterOfMass - CoM;
                    ControlSurface cs           = (p as ControlSurface);
                    Vector3d       airSpeed     = vessel.srf_velocity + Vector3.Cross(cs.Rigidbody.angularVelocity, cs.transform.position - cs.Rigidbody.position);
                    // Air Speed is velocityVesselSurface
                    // AddForceAtPosition seems to need the airspeed vector rotated with the flap rotation x its surface
                    Quaternion airSpeedRot   = Quaternion.AngleAxis(cs.ctrlSurfaceRange * cs.ctrlSurfaceArea, cs.transform.rotation * cs.pivotAxis);
                    Vector3    ctrlTroquePos = vessel.GetTransform().InverseTransformDirection(Vector3.Cross(partPosition, cs.getLiftVector(airSpeedRot * airSpeed)));
                    Vector3    ctrlTroqueNeg = vessel.GetTransform().InverseTransformDirection(Vector3.Cross(partPosition, cs.getLiftVector(Quaternion.Inverse(airSpeedRot) * airSpeed)));
                    ctrlTorqueAvailable.Add(ctrlTroquePos);
                    ctrlTorqueAvailable.Add(ctrlTroqueNeg);
                }

                if (p is CommandPod)
                {
                    torqueAvailable += Vector3d.one * Math.Abs(((CommandPod)p).rotPower);
                }

                foreach (VesselStatePartExtension vspe in vesselStatePartExtensions)
                {
                    vspe(p);
                }

                foreach (PartModule pm in p.Modules)
                {
                    if (!pm.isEnabled)
                    {
                        continue;
                    }

                    if (pm is ModuleReactionWheel)
                    {
                        ModuleReactionWheel rw = (ModuleReactionWheel)pm;
                        // I had to remove the test for active in .23 since the new ressource system reply to the RW that
                        // there is no energy available when the RW do tiny adjustement.
                        // I replaceed it with a test that check if there is electricity anywhere on the ship.
                        // Let's hope we don't get reaction wheel that use something else
                        //if (rw.wheelState == ModuleReactionWheel.WheelState.Active && !rw.stateString.Contains("Not enough"))
                        if (rw.wheelState == ModuleReactionWheel.WheelState.Active && vessel.HasElectricCharge())
                        {
                            torqueAvailable += new Vector3d(rw.PitchTorque, rw.RollTorque, rw.YawTorque);
                        }
                    }
                    else if (pm is ModuleEngines)
                    {
                        einfo.AddNewEngine(pm as ModuleEngines);
                    }
                    else if (pm is ModuleEnginesFX)
                    {
                        einfo.AddNewEngine(pm as ModuleEnginesFX);
                    }
                    else if (pm is ModuleResourceIntake)
                    {
                        iinfo.addIntake(pm as ModuleResourceIntake);
                    }
                    else if (pm is ModuleParachute)
                    {
                        parachutes.Add(pm as ModuleParachute);
                    }
                    else if (pm is ModuleControlSurface)
                    {
                        // TODO : Tweakable for ignorePitch / ignoreYaw  / ignoreRoll
                        ModuleControlSurface cs           = (pm as ModuleControlSurface);
                        Vector3d             partPosition = p.Rigidbody.worldCenterOfMass - CoM;

                        Vector3d airSpeed = vessel.srf_velocity + Vector3.Cross(cs.part.Rigidbody.angularVelocity, cs.transform.position - cs.part.Rigidbody.position);

                        Quaternion airSpeedRot = Quaternion.AngleAxis(cs.ctrlSurfaceRange * cs.ctrlSurfaceArea, cs.transform.rotation * Vector3.right);

                        Vector3 ctrlTroquePos = vessel.GetTransform().InverseTransformDirection(Vector3.Cross(partPosition, cs.getLiftVector(airSpeedRot * airSpeed)));
                        Vector3 ctrlTroqueNeg = vessel.GetTransform().InverseTransformDirection(Vector3.Cross(partPosition, cs.getLiftVector(Quaternion.Inverse(airSpeedRot) * airSpeed)));
                        ctrlTorqueAvailable.Add(ctrlTroquePos);
                        ctrlTorqueAvailable.Add(ctrlTroqueNeg);
                    }

                    if (pm.ClassName == "ModuleEngineConfigs" || pm.ClassName == "ModuleHybridEngine" || pm.ClassName == "ModuleHybridEngines")
                    {
                        hasMFE = true;
                    }

                    foreach (VesselStatePartModuleExtension vspme in vesselStatePartModuleExtensions)
                    {
                        vspme(pm);
                    }
                }
            }

            // Consider all the parachutes
            {
                bool tempParachuteDeployed = false;
                foreach (ModuleParachute p in parachutes)
                {
                    if (p.deploymentState == ModuleParachute.deploymentStates.DEPLOYED || p.deploymentState == ModuleParachute.deploymentStates.SEMIDEPLOYED)
                    {
                        tempParachuteDeployed = true;
                        break;
                    }
                }
                this.parachuteDeployed = tempParachuteDeployed;
            }

            torqueAvailable += Vector3d.Max(rcsTorqueAvailable.positive, rcsTorqueAvailable.negative);   // Should we use Max or Min ?
            torqueAvailable += Vector3d.Max(ctrlTorqueAvailable.positive, ctrlTorqueAvailable.negative); // Should we use Max or Min ?

            thrustVectorMaxThrottle += einfo.thrustMax;
            thrustVectorMinThrottle += einfo.thrustMin;
            thrustVectorLastFrame   += einfo.thrustCurrent;
            torqueThrustPYAvailable += einfo.torqueThrustPYAvailable;

            if (thrustVectorMaxThrottle.magnitude == 0 && vessel.ActionGroups[KSPActionGroup.RCS])
            {
                rcsThrust = true;
                thrustVectorMaxThrottle += (Vector3d)(vessel.transform.up) * rcsThrustAvailable.down;
            }
            else
            {
                rcsThrust = false;
            }

            // Convert the resource information from the einfo and iinfo format
            // to the more useful ResourceInfo format.
            resources = new Dictionary <int, ResourceInfo>();
            foreach (var info in einfo.resourceRequired)
            {
                int id  = info.Key;
                var req = info.Value;
                resources[id] = new ResourceInfo(
                    PartResourceLibrary.Instance.GetDefinition(id),
                    req.requiredLastFrame,
                    req.requiredAtMaxThrottle,
                    iinfo.getIntakes(id));
            }

            int intakeAirId = PartResourceLibrary.Instance.GetDefinition("IntakeAir").id;

            intakeAir           = 0;
            intakeAirNeeded     = 0;
            intakeAirAtMax      = 0;
            intakeAirAllIntakes = 0;
            if (resources.ContainsKey(intakeAirId))
            {
                intakeAir           = resources[intakeAirId].intakeProvided;
                intakeAirAllIntakes = resources[intakeAirId].intakeAvailable;
                intakeAirNeeded     = resources[intakeAirId].required;
                intakeAirAtMax      = resources[intakeAirId].requiredAtMaxThrottle;
            }

            angularMomentum = new Vector3d(angularVelocity.x * MoI.x, angularVelocity.y * MoI.y, angularVelocity.z * MoI.z);

            inertiaTensor = new Matrix3x3();
            foreach (Part p in vessel.parts)
            {
                if (p.Rigidbody == null)
                {
                    continue;
                }

                //Compute the contributions to the vessel inertia tensor due to the part inertia tensor
                Vector3d   principalMoments = p.Rigidbody.inertiaTensor;
                Quaternion princAxesRot     = Quaternion.Inverse(vessel.GetTransform().rotation) * p.transform.rotation * p.Rigidbody.inertiaTensorRotation;
                Quaternion invPrincAxesRot  = Quaternion.Inverse(princAxesRot);

                for (int i = 0; i < 3; i++)
                {
                    Vector3d iHat = Vector3d.zero;
                    iHat[i] = 1;
                    for (int j = 0; j < 3; j++)
                    {
                        Vector3d jHat = Vector3d.zero;
                        jHat[j]              = 1;
                        inertiaTensor[i, j] += Vector3d.Dot(iHat, princAxesRot * Vector3d.Scale(principalMoments, invPrincAxesRot * jHat));
                    }
                }

                //Compute the contributions to the vessel inertia tensor due to the part mass and position
                double  partMass     = p.TotalMass();
                Vector3 partPosition = vessel.GetTransform().InverseTransformDirection(p.Rigidbody.worldCenterOfMass - CoM);

                for (int i = 0; i < 3; i++)
                {
                    inertiaTensor[i, i] += partMass * partPosition.sqrMagnitude;

                    for (int j = 0; j < 3; j++)
                    {
                        inertiaTensor[i, j] += -partMass * partPosition[i] * partPosition[j];
                    }
                }
            }

            MoI             = new Vector3d(inertiaTensor[0, 0], inertiaTensor[1, 1], inertiaTensor[2, 2]);
            angularMomentum = inertiaTensor * angularVelocity;
        }
Exemplo n.º 29
0
 protected override void DI_Start(StartState state)
 {
     if (HighLogic.LoadedSceneIsFlight)
     {
         this.controlSurface = this.part.Modules.OfType<ModuleControlSurface>().Single();
     }
 }