Ejemplo n.º 1
0
        public int ExportSweep(CelestialBody body, double pitch, int flapSetting, bool spoilers)
        {
            if (!IsReady())
            {
                return(0);
            }

            FARAeroUtil.UpdateCurrentActiveBody(body);
            FARAeroUtil.ResetEditorParts();

            StaticAnalysisExportFile  exportdata = new StaticAnalysisExportFile();
            InstantConditionSimInput  input      = new InstantConditionSimInput(0, 0, 0, 0, 0, 0, FlightEnv.NewDefaultVal(body), pitch, flapSetting, spoilers);
            InstantConditionSimOutput output;

            Vector3d centerofmass = _instantCondition.GetCoM();

            // Loop through each combination (two dimensions).
            foreach (float mach in exportdata.MachNumberList)
            {
                input.fltenv.MachNumber = mach;
                input.alpha             = 0;                              // zero is used as a neutral value for the reset
                _instantCondition.ResetClCdCmSteady(centerofmass, input); // reset old results (particularly cossweep) that may not reflect the current mach number

                foreach (float aoadeg in exportdata.AoADegreeList)
                {
                    input.alpha = aoadeg;
                    _instantCondition.GetClCdCmSteady(input, out output, true, true);
                    exportdata.AddDatapoint(mach, aoadeg, output.Cl, output.Cd, output.Cm);
                }
            }

            exportdata.Export();
            return(exportdata.DataCount);
        }
Ejemplo n.º 2
0
        public override void FixedUpdate()
        {
            currentDrag = 0;

            // With unity objects, "foo" or "foo != null" calls a method to check if
            // it's destroyed. (object)foo != null just checks if it is actually null.
            if (start != StartState.Editor && (object)part != null)
            {
                if (animatingPart)
                {
                    UpdatePropertiesWithAnimation();
                }

                if (!isShielded)
                {
                    Rigidbody rb     = part.Rigidbody;
                    Vessel    vessel = part.vessel;

                    // Check that rb is not destroyed, but vessel is just not null
                    if (rb && (object)vessel != null && vessel.atmDensity > 0)
                    {
                        Vector3d velocity = rb.velocity + Krakensbane.GetFrameVelocity();
                        double   soundspeed, v_scalar = velocity.magnitude;

                        double rho = FARAeroUtil.GetCurrentDensity(vessel, out soundspeed);
                        if (rho > 0 && v_scalar > 0.1)
                        {
                            Vector3d force = RunDragCalculation(velocity, v_scalar / soundspeed, rho);
                            rb.AddForceAtPosition(force, GetCoD());
                        }
                    }
                }
            }
        }
        public void SimulateAeroProperties(out Vector3 aeroForce, out Vector3 aeroTorque, Vector3 velocityWorldVector, double altitude)
        {
            // Rodhern: It seems that this method, 'SimulateAeroProperties', is only used in FARAPI, which in turn can be used by say KSPTrajectories.
            //          The parameter 'FARCenterQuery dummy' is from a code fix by Benjamin Chung (commit 18fbb9d29431679a4de9dfc22a443f400d2d4f8b).

            FARCenterQuery center = new FARCenterQuery();
            FARCenterQuery dummy  = new FARCenterQuery();

            float pressure;
            float density;
            float temperature;
            float speedOfSound;

            CelestialBody body = vessel.mainBody;      //Calculate main gas properties

            pressure     = (float)body.GetPressure(altitude);
            temperature  = (float)body.GetTemperature(altitude);
            density      = (float)body.GetDensity(pressure, temperature);
            speedOfSound = (float)body.GetSpeedOfSound(pressure, density);

            if (pressure <= 0 || temperature <= 0 || density <= 0 || speedOfSound <= 0)
            {
                aeroForce  = Vector3.zero;
                aeroTorque = Vector3.zero;
                return;
            }

            float     velocityMag         = velocityWorldVector.magnitude;
            float     machNumber          = velocityMag / speedOfSound;
            float     reynoldsNumber      = (float)FARAeroUtil.CalculateReynoldsNumber(density, Length, velocityMag, machNumber, temperature, body.atmosphereAdiabaticIndex);
            float     reynoldsPerLength   = reynoldsNumber / (float)Length;
            float     pseudoKnudsenNumber = machNumber / (reynoldsNumber + machNumber);
            float     skinFriction        = (float)FARAeroUtil.SkinFrictionDrag(reynoldsNumber, machNumber);
            FlightEnv fenv = FlightEnv.NewPredicted(vessel.mainBody, altitude, machNumber);

            if (_currentAeroSections != null)
            {
                for (int i = 0; i < _currentAeroSections.Count; i++)
                {
                    FARAeroSection curSection = _currentAeroSections[i];
                    if (curSection != null)
                    {
                        curSection.PredictionCalculateAeroForces(density, machNumber, reynoldsPerLength, pseudoKnudsenNumber, skinFriction, velocityWorldVector, center);
                    }
                }

                for (int i = 0; i < _legacyWingModels.Count; i++)
                {
                    FARWingAerodynamicModel curWing = _legacyWingModels[i];
                    if ((object)curWing != null)
                    {
                        Vector3d force = curWing.PrecomputeCenterOfLift(velocityWorldVector, fenv, dummy);
                        center.AddForce(curWing.transform.position, force);
                    }
                }
            }

            aeroForce  = center.force;
            aeroTorque = center.TorqueAt(vessel.CoM);
        }
Ejemplo n.º 4
0
        public void FixedUpdate()
        {
            if (aerodynamicModel_ != null && vessel_ != null)
            {
                CelestialBody body = vessel_.orbit.referenceBody;

                Vector3d bodySpacePosition = vessel_.GetWorldPos3D() - body.position;
                Vector3d bodySpaceVelocity = vessel_.obt_velocity;
                double   altitudeAboveSea  = bodySpacePosition.magnitude - body.Radius;

                Vector3d airVelocity = bodySpaceVelocity - body.getRFrmVel(body.position + bodySpacePosition);

                #if DEBUG_COMPARE_FORCES
                Vector3d FARForce = FARBasicDragModel.debugForceAccumulator + FARWingAerodynamicModel.debugForceAccumulator;
                FARBasicDragModel.debugForceAccumulator       = new Vector3d(0, 0, 0);
                FARWingAerodynamicModel.debugForceAccumulator = new Vector3d(0, 0, 0);

                double rho = FARAeroUtil.GetCurrentDensity(body, altitudeAboveSea);
                //double rho = vessel_.atmDensity;
                //double pressure = FlightGlobals.getStaticPressure(altitudeAboveSea, body);
                //double rho = FlightGlobals.getAtmDensity(pressure);


                double machNumber = FARAeroUtil.GetMachNumber(body, altitudeAboveSea, airVelocity);
                //double machNumber = airVelocity.magnitude / 300.0;

                Transform vesselTransform = vessel_.ReferenceTransform;
                Vector3d  vesselBackward  = (Vector3d)(-vesselTransform.up.normalized);
                Vector3d  vesselForward   = -vesselBackward;
                Vector3d  vesselUp        = (Vector3d)(-vesselTransform.forward.normalized);
                Vector3d  vesselRight     = Vector3d.Cross(vesselUp, vesselBackward).normalized;
                double    AoA             = Math.Acos(Vector3d.Dot(airVelocity.normalized, vesselForward.normalized));
                if (Vector3d.Dot(airVelocity, vesselUp) > 0)
                {
                    AoA = -AoA;
                }

                Vector3d predictedForce = aerodynamicModel_.computeForces_FAR(rho, machNumber, airVelocity, vesselUp, AoA, 0.05);
                aerodynamicModel_.Verbose = true;
                Vector3d predictedForceWithCache = aerodynamicModel_.computeForces(body, bodySpacePosition, airVelocity, AoA, 0.05);
                aerodynamicModel_.Verbose = false;

                Vector3d localFARForce                = new Vector3d(Vector3d.Dot(FARForce, vesselRight), Vector3d.Dot(FARForce, vesselUp), Vector3d.Dot(FARForce, vesselBackward));
                Vector3d localPredictedForce          = new Vector3d(Vector3d.Dot(predictedForce, vesselRight), Vector3d.Dot(predictedForce, vesselUp), Vector3d.Dot(predictedForce, vesselBackward));
                Vector3d localPredictedForceWithCache = new Vector3d(Vector3d.Dot(predictedForceWithCache, vesselRight), Vector3d.Dot(predictedForceWithCache, vesselUp), Vector3d.Dot(predictedForceWithCache, vesselBackward));

                Util.PostSingleScreenMessage("FAR/predict comparison", "air vel=" + Math.Floor(airVelocity.magnitude) + ", AoA=" + (AoA * 180.0 / Math.PI) + ", FAR force=" + localFARForce + ", predicted force=" + localPredictedForce);
                Util.PostSingleScreenMessage("predict with cache", "predicted force with cache=" + localPredictedForceWithCache);
                #endif

                double approximateRho = StockAeroUtil.GetDensity(altitudeAboveSea, body);
                double preciseRho     = StockAeroUtil.GetDensity(vessel_.GetWorldPos3D(), body);
                double actualRho      = vessel_.atmDensity;
                Util.PostSingleScreenMessage("rho info", "preciseRho=" + preciseRho.ToString("0.0000") + " ; approximateRho=" + approximateRho.ToString("0.0000") + " ; actualRho=" + actualRho.ToString("0.0000"));
            }
        }
Ejemplo n.º 5
0
        public void LateUpdate()
        {
            FARAeroUtil.ResetEditorParts();
            FARBaseAerodynamics.GlobalCoLReady = false;

            if (EditorLogic.fetch)
            {
                if (editorGUI == null)
                {
                    editorGUI = new FAREditorGUI();
                    //editorGUI.LoadGUIParameters();
                    editorGUI.RestartCtrlGUI();
                }
                if (EditorLogic.startPod != null)
                {
                    var editorShip = FARAeroUtil.AllEditorParts;


                    if (FARAeroUtil.EditorAboutToAttach() && count++ >= 10)
                    {
                        EditorPartsChanged = true;
                        count = 0;
                    }

                    if (part_count_all != editorShip.Count || part_count_ship != EditorLogic.SortedShipList.Count || EditorPartsChanged)
                    {
                        FindPartsWithoutFARModel(editorShip);
                        foreach (Part p in editorShip)
                        {
                            foreach (PartModule m in p.Modules)
                            {
                                if (m is FARBaseAerodynamics)
                                {
                                    (m as FARBaseAerodynamics).ClearShielding();
                                }
                            }
                        }

                        foreach (Part p in editorShip)
                        {
                            foreach (PartModule m in p.Modules)
                            {
                                if (m is FARPartModule)
                                {
                                    (m as FARPartModule).ForceOnVesselPartsChange();
                                }
                            }
                        }

                        part_count_all     = editorShip.Count;
                        part_count_ship    = EditorLogic.SortedShipList.Count;
                        EditorPartsChanged = false;
                    }
                }
            }
        }
        public void SimulateAeroProperties(out Vector3 aeroForce, out Vector3 aeroTorque, Vector3 velocityWorldVector, double altitude)
        {
            FARCenterQuery center = new FARCenterQuery();

            float pressure;
            float density;
            float temperature;
            float speedOfSound;

            CelestialBody body = vessel.mainBody;      //Calculate main gas properties

            pressure     = (float)body.GetPressure(altitude);
            temperature  = (float)body.GetTemperature(altitude);
            density      = (float)body.GetDensity(pressure, temperature);
            speedOfSound = (float)body.GetSpeedOfSound(pressure, density);

            if (pressure <= 0 || temperature <= 0 || density <= 0 || speedOfSound <= 0)
            {
                aeroForce  = Vector3.zero;
                aeroTorque = Vector3.zero;
                return;
            }

            float velocityMag    = velocityWorldVector.magnitude;
            float machNumber     = velocityMag / speedOfSound;
            float reynoldsNumber = (float)FARAeroUtil.CalculateReynoldsNumber(density, Length, velocityMag, machNumber, temperature, body.atmosphereAdiabaticIndex);

            float reynoldsPerLength = reynoldsNumber / (float)Length;
            float skinFriction      = (float)FARAeroUtil.SkinFrictionDrag(reynoldsNumber, machNumber);

            float pseudoKnudsenNumber = machNumber / (reynoldsNumber + machNumber);

            if (_currentAeroSections != null)
            {
                for (int i = 0; i < _currentAeroSections.Count; i++)
                {
                    FARAeroSection curSection = _currentAeroSections[i];
                    if (curSection != null)
                    {
                        curSection.PredictionCalculateAeroForces(density, machNumber, reynoldsPerLength, pseudoKnudsenNumber, skinFriction, velocityWorldVector, center);
                    }
                }

                for (int i = 0; i < _legacyWingModels.Count; i++)
                {
                    FARWingAerodynamicModel curWing = _legacyWingModels[i];
                    if ((object)curWing != null)
                    {
                        curWing.PrecomputeCenterOfLift(velocityWorldVector, machNumber, density, center);
                    }
                }
            }

            aeroForce  = center.force;
            aeroTorque = center.TorqueAt(vessel.CoM);
        }
Ejemplo n.º 7
0
        private void CalculateAndApplyVesselAeroProperties()
        {
            float atmDensity = (float)_vessel.atmDensity;

            if (atmDensity <= 0)
            {
                machNumber     = 0;
                reynoldsNumber = 0;
                return;
            }

            machNumber     = _vessel.mach;
            reynoldsNumber = FARAeroUtil.CalculateReynoldsNumber(_vessel.atmDensity, Length, _vessel.srfSpeed, machNumber, FlightGlobals.getExternalTemperature((float)_vessel.altitude, _vessel.mainBody), _vessel.mainBody.atmosphereAdiabaticIndex);
            float skinFrictionDragCoefficient = (float)FARAeroUtil.SkinFrictionDrag(reynoldsNumber, machNumber);

            Vector3 frameVel = Krakensbane.GetFrameVelocityV3f();

            if (_updateQueued)                                           //only happens if we have an voxelization scheduled, then we need to check for null
            {
                for (int i = _currentAeroModules.Count - 1; i >= 0; i--) //start from the top and come down to improve performance if it needs to remove anything
                {
                    FARAeroPartModule m = _currentAeroModules[i];
                    if (m != null)
                    {
                        m.UpdateVelocityAndAngVelocity(frameVel);
                    }
                    else
                    {
                        _currentAeroModules.RemoveAt(i);
                        i++;
                    }
                }
            }
            else                                                         //otherwise, we don't need to do Unity's expensive "is this part dead" null-check
            {
                for (int i = _currentAeroModules.Count - 1; i >= 0; i--) //start from the top and come down to improve performance if it needs to remove anything
                {
                    FARAeroPartModule m = _currentAeroModules[i];
                    m.UpdateVelocityAndAngVelocity(frameVel);
                }
            }

            for (int i = 0; i < _currentAeroSections.Count; i++)
            {
                _currentAeroSections[i].FlightCalculateAeroForces(atmDensity, (float)machNumber, (float)(reynoldsNumber / Length), skinFrictionDragCoefficient);
            }

            _vesselIntakeRamDrag.ApplyIntakeRamDrag((float)machNumber, _vessel.srf_velocity.normalized, (float)_vessel.dynamicPressurekPa);

            for (int i = 0; i < _currentAeroModules.Count; i++)
            {
                FARAeroPartModule m = _currentAeroModules[i];
                m.ApplyForces();
            }
        }
Ejemplo n.º 8
0
        private void StabDerivCalcButtonAction(CalcAndExportEnum exportflag)
        {
            CelestialBody body = _bodySettingDropdown.ActiveSelection;

            FARAeroUtil.UpdateCurrentActiveBody(body);
            altitude = Regex.Replace(altitude, @"[^-?[0-9]*(\.[0-9]*)?]", "");
            double altitudeDouble = Convert.ToDouble(altitude) * 1000;

            machNumber = Regex.Replace(machNumber, @"[^-?[0-9]*(\.[0-9]*)?]", "");
            double machDouble           = FARMathUtil.Clamp(Convert.ToSingle(machNumber), 0.001, float.PositiveInfinity);
            int    flapsettingInt       = _flapSettingDropdown.ActiveSelection;
            bool   spoilersDeployedBool = spoilersDeployed;

            if (exportflag == CalcAndExportEnum.LoopExport)
            {
                int n = 0;
                ExportTextFileCache filecache = new ExportTextFileCache();
                foreach (Vector2 altmach in StabilityDerivativeExportFile.LoadConfigList())
                {
                    StabilityDerivExportOutput output = simManager.StabDerivCalculator.CalculateStabilityDerivs(body, (double)altmach.x, (double)altmach.y, flapsettingInt, spoilersDeployedBool);
                    if (AoAOk(output, exportflag) && StabilityDerivativeExportFile.Export(output, filecache))
                    {
                        n++;
                    }
                }
                if (n > 0)
                {
                    filecache.FlushTextFileLines();
                    PopupDialog.SpawnPopupDialog(new Vector2(0, 0), new Vector2(0, 0), "FARStabDerivLoopCount", Localizer.Format("FAREditorStabDerivLoopDone"), Localizer.Format("FAREditorStabDerivLoopDoneExp", n), Localizer.Format("FARGUIOKButton"), true, HighLogic.UISkin);
                }
                else
                {
                    PopupDialog.SpawnPopupDialog(new Vector2(0, 0), new Vector2(0, 0), "FARStabDerivSaveError", Localizer.Format("FAREditorStabDerivSaveError"), Localizer.Format("FAREditorStabDerivSaveErrorExp"), Localizer.Format("FARGUIOKButton"), true, HighLogic.UISkin);
                }
                return; // in the LoopExport case skip the usual calculation
            }

            StabilityDerivExportOutput stabDerivResult = simManager.StabDerivCalculator.CalculateStabilityDerivs(body, altitudeDouble, machDouble, flapsettingInt, spoilersDeployedBool);

            if (!AoAOk(stabDerivResult, exportflag))
            {
                PopupDialog.SpawnPopupDialog(new Vector2(0, 0), new Vector2(0, 0), "FARStabDerivError", Localizer.Format("FAREditorStabDerivError"), Localizer.Format("FAREditorStabDerivErrorExp"), Localizer.Format("FARGUIOKButton"), true, HighLogic.UISkin);
            }
            else
            {
                stabDerivOutput        = stabDerivResult.outputvals;
                simManager.vehicleData = stabDerivResult.outputvals;
                SetAngleVectors(stabDerivResult.outputvals.stableCondition.stableAoA);

                if (exportflag == CalcAndExportEnum.CalculateAndExport && !StabilityDerivativeExportFile.Export(stabDerivResult))
                {
                    PopupDialog.SpawnPopupDialog(new Vector2(0, 0), new Vector2(0, 0), "FARStabDerivSaveError", Localizer.Format("FAREditorStabDerivSaveError"), Localizer.Format("FAREditorStabDerivSaveErrorExp"), Localizer.Format("FARGUIOKButton"), true, HighLogic.UISkin);
                }
            }
        }
        private void CalculateAndApplyVesselAeroProperties()
        {
            float atmDensity = (float)vessel.atmDensity;

            if (atmDensity <= 0)
            {
                MachNumber     = 0;
                ReynoldsNumber = 0;
                return;
            }

            MachNumber     = vessel.mach;
            ReynoldsNumber = FARAeroUtil.CalculateReynoldsNumber(vessel.atmDensity,
                                                                 Length,
                                                                 vessel.srfSpeed,
                                                                 MachNumber,
                                                                 FlightGlobals.getExternalTemperature((float)vessel
                                                                                                      .altitude,
                                                                                                      vessel.mainBody),
                                                                 vessel.mainBody.atmosphereAdiabaticIndex);
            float skinFrictionDragCoefficient = (float)FARAeroUtil.SkinFrictionDrag(ReynoldsNumber, MachNumber);

            float pseudoKnudsenNumber = (float)(MachNumber / (ReynoldsNumber + MachNumber));

            Vector3 frameVel = Krakensbane.GetFrameVelocityV3f();

            //start from the top and come down to improve performance if it needs to remove anything
            for (int i = _currentAeroModules.Count - 1; i >= 0; i--)
            {
                FARAeroPartModule m = _currentAeroModules[i];
                if (m != null && m.part != null && m.part.partTransform != null)
                {
                    m.UpdateVelocityAndAngVelocity(frameVel);
                }
                else
                {
                    _currentAeroModules.RemoveAt(i);
                }
            }

            foreach (FARAeroSection aeroSection in _currentAeroSections)
            {
                aeroSection.FlightCalculateAeroForces((float)MachNumber,
                                                      (float)(ReynoldsNumber / Length),
                                                      pseudoKnudsenNumber,
                                                      skinFrictionDragCoefficient);
            }

            _vesselIntakeRamDrag.ApplyIntakeRamDrag((float)MachNumber, vessel.srf_velocity.normalized);

            foreach (FARAeroPartModule m in _currentAeroModules)
            {
                m.ApplyForces();
            }
        }
        public double CalculateIAS()
        {
            double pressureRatio = FARAeroUtil.RayleighPitotTubeStagPressure(_vessel.mach); //stag pressure at pitot tube face / ambient pressure

            double velocity = pressureRatio - 1;

            velocity *= _vessel.staticPressurekPa * 1000 * 2;
            velocity /= 1.225;
            velocity  = Math.Sqrt(velocity);

            return(velocity);
        }
Ejemplo n.º 11
0
        public void LateUpdate()
        {
            if (!CompatibilityChecker.IsAllCompatible())
            {
                return;
            }

            FARAeroUtil.ResetEditorParts();
            FARBaseAerodynamics.GlobalCoLReady = false;

            if (EditorLogic.fetch)
            {
                if (editorGUI == null)
                {
                    editorGUI = new FAREditorGUI();
                    //editorGUI.LoadGUIParameters();
                    editorGUI.RestartCtrlGUI();
                    GameEvents.onEditorUndo.Add(editorGUI.ResetAll);
                    GameEvents.onEditorRedo.Add(editorGUI.ResetAll);
                }
                if (EditorLogic.RootPart != null)
                {
                    editorShip = FARAeroUtil.AllEditorParts;

                    if (buttonsNeedInitializing)
                    {
                        InitializeButtons();
                    }

                    /*if (EditorLogic.RootPart != lastRootPart)
                     * {
                     *  lastRootPart = EditorLogic.RootPart;
                     *  EditorPartsChanged = true;
                     * }*/

                    if (FARAeroUtil.EditorAboutToAttach() && count++ >= 20)
                    {
                        EditorPartsChanged = true;
                        count = 0;
                    }

                    if (part_count_all != editorShip.Count || part_count_ship != EditorLogic.SortedShipList.Count || EditorPartsChanged)
                    {
                        UpdateEditorShipModules();
                    }
                }
                else if (!buttonsNeedInitializing)
                {
                    DestroyButtons();
                }
            }
        }
        private void UpdateCargoParts()
        {
            if (HighLogic.LoadedSceneIsEditor && FARAeroUtil.EditorAboutToAttach(false) &&
                !FARAeroUtil.CurEditorParts.Contains(part))
            {
                return;
            }

            if (bayAnim == null || !bayOpen || HighLogic.LoadedSceneIsEditor)
            {
                FindShieldedParts();
            }
        }
Ejemplo n.º 13
0
        private void UpdateCargoParts()
        {
            if (start == StartState.Editor && FARAeroUtil.EditorAboutToAttach(false) &&
                !FARAeroUtil.CurEditorParts.Contains(part))
            {
                return;
            }

            if (bayAnim == null || !bayOpen || start == StartState.Editor)
            {
                FindShieldedParts();
            }
        }
        public double CalculateIAS()
        {
            // Rodhern: Presumably _vessel.mach ignores FARWind, which might not be the intended behaviour.
            double pressureRatio = FARAeroUtil.RayleighPitotTubeStagPressure(_vessel.mach); //stag pressure at pitot tube face / ambient pressure

            double velocity = pressureRatio - 1;

            velocity *= _vessel.staticPressurekPa * 1000 * 2;
            velocity /= 1.225;
            velocity  = Math.Sqrt(velocity);

            return(velocity);
        }
Ejemplo n.º 15
0
        public double CalculateIAS()
        {
            //stag pressure at pitot tube face / ambient pressure
            double pressureRatio = FARAeroUtil.RayleighPitotTubeStagPressure(_vessel.mach);

            double velocity = pressureRatio - 1;

            velocity *= FARAtmosphere.GetPressure(_vessel) * 2;
            velocity /= 1.225;
            velocity  = Math.Sqrt(velocity);

            return(velocity);
        }
Ejemplo n.º 16
0
        public GraphData MachNumberSweep(
            double aoAdegrees,
            double pitch,
            double lowerBound,
            double upperBound,
            int numPoints,
            int flapSetting,
            bool spoilers,
            CelestialBody body
            )
        {
            FARAeroUtil.UpdateCurrentActiveBody(body);

            FARAeroUtil.ResetEditorParts();

            var ClValues    = new double[numPoints];
            var CdValues    = new double[numPoints];
            var CmValues    = new double[numPoints];
            var LDValues    = new double[numPoints];
            var AlphaValues = new double[numPoints];

            var input = new InstantConditionSimInput(aoAdegrees, 0, 0, 0, 0, 0, 0, pitch, flapSetting, spoilers);

            for (int i = 0; i < numPoints; i++)
            {
                input.machNumber = i / (double)numPoints * (upperBound - lowerBound) + lowerBound;

                if (input.machNumber.NearlyEqual(0))
                {
                    input.machNumber = 0.001;
                }

                _instantCondition.GetClCdCmSteady(input, out InstantConditionSimOutput output, i == 0);
                AlphaValues[i] = input.machNumber;
                ClValues[i]    = output.Cl;
                CdValues[i]    = output.Cd;
                CmValues[i]    = output.Cm;
                LDValues[i]    = output.Cl * 0.1 / output.Cd;
            }

            var data = new GraphData {
                xValues = AlphaValues
            };

            data.AddData(ClValues, FARConfig.GUIColors.ClColor, Localizer.Format("FARAbbrevCl"), true);
            data.AddData(CdValues, FARConfig.GUIColors.CdColor, Localizer.Format("FARAbbrevCd"), true);
            data.AddData(CmValues, FARConfig.GUIColors.CmColor, Localizer.Format("FARAbbrevCm"), true);
            data.AddData(LDValues, FARConfig.GUIColors.LdColor, Localizer.Format("FARAbbrevL_D"), true);

            return(data);
        }
        public static void SaveConfigs()
        {
            config.SetValue("displayForces", FARDebugValues.displayForces.ToString());
            config.SetValue("displayCoefficients", FARDebugValues.displayCoefficients.ToString());
            config.SetValue("displayShielding", FARDebugValues.displayShielding.ToString());

            config.SetValue("useSplinesForSupersonicMath", FARDebugValues.useSplinesForSupersonicMath.ToString());
            config.SetValue("allowStructuralFailures", FARDebugValues.allowStructuralFailures.ToString());

            FARAeroUtil.SaveCustomAeroDataToConfig();
            FARPartClassification.SaveCustomClassificationTemplates();
            FARAeroStress.SaveCustomStressTemplates();
            config.save();
        }
        public static void LoadConfigs()
        {
            config = KSP.IO.PluginConfiguration.CreateForType <FARDebugOptions>();
            config.load();
            FARDebugValues.displayForces               = Convert.ToBoolean(config.GetValue("displayForces", "false"));
            FARDebugValues.displayCoefficients         = Convert.ToBoolean(config.GetValue("displayCoefficients", "false"));
            FARDebugValues.displayShielding            = Convert.ToBoolean(config.GetValue("displayShielding", "false"));
            FARDebugValues.useSplinesForSupersonicMath = Convert.ToBoolean(config.GetValue("useSplinesForSupersonicMath", "true"));
            FARDebugValues.allowStructuralFailures     = Convert.ToBoolean(config.GetValue("allowStructuralFailures", "true"));

            FARAeroStress.LoadStressTemplates();
            FARPartClassification.LoadClassificationTemplates();
            FARAeroUtil.LoadAeroDataFromConfig();
        }
Ejemplo n.º 19
0
        private void ResetEditorEvent(ShipConstruct construct)
        {
            FARAeroUtil.ResetEditorParts(); // Rodhern: Partial fix to https://github.com/ferram4/Ferram-Aerospace-Research/issues/177 .

            if (EditorLogic.RootPart != null)
            {
                List <Part> partsList = EditorLogic.SortedShipList;
                for (int i = 0; i < partsList.Count; i++)
                {
                    UpdateGeometryModule(partsList[i]);
                }
            }

            RequestUpdateVoxel();
        }
Ejemplo n.º 20
0
        private double MachDragEffect(double M)
        {
            double multiplier = 1;

            if (M <= 1)
            {
                multiplier = 1 + 0.4 * FARAeroUtil.ExponentialApproximation(10 * M - 10);
            }
            //multiplier = 1f + 0.4f * Mathf.Exp(10 * M - 10f);            //Exponentially increases, mostly from 0.8 to 1;  Models Drag divergence due to locally supersonic flow around object at flight Mach Numbers < 1
            else
            {
                multiplier = 0.15 / M + 1.25;             //Cd drops after Mach 1
            }
            return(multiplier);
        }
Ejemplo n.º 21
0
        private void ResetEditorEvent(ShipConstruct construct)
        {
            FARAeroUtil.ResetEditorParts();

            if (EditorLogic.RootPart != null)
            {
                List <Part> partsList = EditorLogic.SortedShipList;
                for (int i = 0; i < partsList.Count; i++)
                {
                    UpdateGeometryModule(partsList[i]);
                }
            }

            RequestUpdateVoxel();
        }
        public static void LoadConfigs()
        {
            config = KSP.IO.PluginConfiguration.CreateForType <FAREditorGUI>();
            config.load();
            FARControlSys.windowPos           = config.GetValue("FlightWindowPos", new Rect(100, 100, 150, 100));
            FARControlSys.AutopilotWinPos     = config.GetValue("AutopilotWinPos", new Rect());
            FARControlSys.HelpWindowPos       = config.GetValue("HelpWindowPos", new Rect());
            FARControlSys.FlightDataPos       = config.GetValue("FlightDataPos", new Rect());
            FARControlSys.FlightDataHelpPos   = config.GetValue("FlightDataHelpPos", new Rect());
            FARControlSys.AirSpeedPos         = config.GetValue("AirSpeedPos", new Rect());
            FARControlSys.AirSpeedHelpPos     = config.GetValue("AirSpeedHelpPos", new Rect());
            FARControlSys.AeroForceTintingPos = config.GetValue("AeroForceTintingPos", new Rect());
            //FARControlSys.minimize = config.GetValue<bool>("FlightGUIBool", false);
            FARControlSys.k_wingleveler_str  = config.GetValue("k_wingleveler", "0.05");
            FARControlSys.k_wingleveler      = Convert.ToDouble(FARControlSys.k_wingleveler_str);
            FARControlSys.kd_wingleveler_str = config.GetValue("kd_wingleveler", "0.002");
            FARControlSys.kd_wingleveler     = Convert.ToDouble(FARControlSys.kd_wingleveler_str);
            FARControlSys.k_yawdamper_str    = config.GetValue("k_yawdamper", "0.1");
            FARControlSys.k_yawdamper        = Convert.ToDouble(FARControlSys.k_yawdamper_str);
            FARControlSys.k_pitchdamper_str  = config.GetValue("k_pitchdamper", "0.25");
            FARControlSys.k_pitchdamper      = Convert.ToDouble(FARControlSys.k_pitchdamper_str);
            FARControlSys.k2_pitchdamper_str = config.GetValue("k2_pitchdamper", "0.06");
            FARControlSys.k2_pitchdamper     = Convert.ToDouble(FARControlSys.k2_pitchdamper_str);
            FARControlSys.scaleVelocity_str  = config.GetValue("scaleVelocity", "150");
            FARControlSys.scaleVelocity      = Convert.ToDouble(FARControlSys.scaleVelocity_str);
            FARControlSys.alt_str            = config.GetValue("alt", "0");
            FARControlSys.alt           = Convert.ToDouble(FARControlSys.alt_str);
            FARControlSys.upperLim_str  = config.GetValue("upperLim", "25");
            FARControlSys.upperLim      = Convert.ToDouble(FARControlSys.upperLim_str);
            FARControlSys.lowerLim_str  = config.GetValue("lowerLim", "-25");
            FARControlSys.lowerLim      = Convert.ToDouble(FARControlSys.lowerLim_str);
            FARControlSys.k_limiter_str = config.GetValue("k_limiter", "0.25");
            FARControlSys.k_limiter     = Convert.ToDouble(FARControlSys.k_limiter_str);

            FARControlSys.unitMode = (FARControlSys.SurfaceVelUnit)config.GetValue("unitMode", 0);
            FARControlSys.velMode  = (FARControlSys.SurfaceVelMode)config.GetValue("velMode", 0);

            FARDebugValues.displayForces               = Convert.ToBoolean(config.GetValue("displayForces", "false"));
            FARDebugValues.displayCoefficients         = Convert.ToBoolean(config.GetValue("displayCoefficients", "false"));
            FARDebugValues.displayShielding            = Convert.ToBoolean(config.GetValue("displayShielding", "false"));
            FARDebugValues.useSplinesForSupersonicMath = Convert.ToBoolean(config.GetValue("useSplinesForSupersonicMath", "true"));
            FARDebugValues.allowStructuralFailures     = Convert.ToBoolean(config.GetValue("allowStructuralFailures", "true"));

            FARAeroStress.LoadStressTemplates();
            FARPartClassification.LoadClassificationTemplates();
            FARAeroUtil.LoadAeroDataFromConfig();
        }
Ejemplo n.º 23
0
        public GraphData MachNumberSweep(double aoAdegrees, double pitch, double lowerBound, double upperBound, int numPoints, int flapSetting, bool spoilers, CelestialBody body)
        {
            FARAeroUtil.UpdateCurrentActiveBody(body);

            FARAeroUtil.ResetEditorParts();

            double[] ClValues    = new double[(int)numPoints];
            double[] CdValues    = new double[(int)numPoints];
            double[] CmValues    = new double[(int)numPoints];
            double[] LDValues    = new double[(int)numPoints];
            double[] AlphaValues = new double[(int)numPoints];

            InstantConditionSimInput input = new InstantConditionSimInput(aoAdegrees, 0, 0, 0, 0, 0, FlightEnv.NewDefaultVal(body), pitch, flapSetting, spoilers);

            for (int i = 0; i < numPoints; i++)
            {
                input.fltenv.MachNumber = lowerBound + (upperBound - lowerBound) * (i == 0? 0 : i / (numPoints - 1.0));

                if (input.fltenv.MachNumber < 1E-3)
                {
                    input.fltenv.MachNumber = 1E-3;
                }

                InstantConditionSimOutput output;

                _instantCondition.GetClCdCmSteady(input, out output, i == 0, false);
                AlphaValues[i] = input.fltenv.MachNumber;
                ClValues[i]    = output.Cl;
                CdValues[i]    = output.Cd;
                CmValues[i]    = output.Cm;
                LDValues[i]    = output.Cl * 0.1 / output.Cd;
            }

            GraphData data = new GraphData();

            data.xValues = AlphaValues;
            data.AddData(ClValues, GUIColors.GetColor(0), Localizer.Format("FARAbbrevCl"), true);
            data.AddData(CdValues, GUIColors.GetColor(1), Localizer.Format("FARAbbrevCd"), true);
            data.AddData(CmValues, GUIColors.GetColor(2), Localizer.Format("FARAbbrevCm"), true);
            data.AddData(LDValues, GUIColors.GetColor(3), Localizer.Format("FARAbbrevL_D"), true);

            data.exportdata.AddSizeVariables(_instantCondition, pitch, flapSetting, spoilers);
            data.exportdata.AddMachSweepXVariable(aoAdegrees, AlphaValues);
            data.exportdata.AddYVariables(data);

            return(data);
        }
Ejemplo n.º 24
0
        public void GetCoMAndSize(out Vector3d CoM, out double mass, out double area, out double MAC, out double b)
        {
            CoM  = Vector3d.zero;
            mass = 0; area = 0; MAC = 0; b = 0;

            List <Part> partsList = EditorLogic.SortedShipList;

            for (int i = 0; i < partsList.Count; i++)
            {
                Part p = partsList[i];
                if (FARAeroUtil.IsNonphysical(p))
                {
                    continue;
                }

                double partMass = p.mass;
                if (p.Resources.Count > 0)
                {
                    partMass += p.GetResourceMass();
                }
                //partMass += p.GetModuleMass(p.mass); // If you want to use GetModuleMass, you need to start from p.partInfo.mass, not p.mass

                CoM  += partMass * (Vector3d)p.transform.TransformPoint(p.CoMOffset);
                mass += partMass;

                FARWingAerodynamicModel w = p.GetComponent <FARWingAerodynamicModel>();
                if (w != null && !w.isShielded)
                {
                    area += w.S;
                    MAC  += w.GetMAC() * w.S;
                    b    += w.Getb_2() * w.S;
                }
            }
            if (area > 0)
            {
                MAC /= area;
                b   /= area;
            }
            else
            {
                area = _maxCrossSectionFromBody;
                MAC  = _bodyLength;
                b    = 1;
            }
            CoM  /= mass;
            mass *= 1000;
        }
Ejemplo n.º 25
0
        private void CalculateAndApplyVesselAeroProperties()
        {
            float atmDensity = (float)_vessel.atmDensity;

            if (atmDensity <= 0)
            {
                machNumber     = 0;
                reynoldsNumber = 0;
                return;
            }

            machNumber     = _vessel.mach;
            reynoldsNumber = FARAeroUtil.CalculateReynoldsNumber(_vessel.atmDensity, Length, _vessel.srfSpeed, machNumber, FlightGlobals.getExternalTemperature((float)_vessel.altitude, _vessel.mainBody), _vessel.mainBody.atmosphereAdiabaticIndex);
            float skinFrictionDragCoefficient = (float)FARAeroUtil.SkinFrictionDrag(reynoldsNumber, machNumber);

            Vector3 frameVel = Krakensbane.GetFrameVelocityV3f();

            for (int i = 0; i < _currentAeroModules.Count; i++)
            {
                FARAeroPartModule m = _currentAeroModules[i];
                if (m != null)
                {
                    m.UpdateVelocityAndAngVelocity(frameVel);
                }
                else
                {
                    _currentAeroModules.RemoveAt(i);
                    i--;
                }
            }

            for (int i = 0; i < _currentAeroSections.Count; i++)
            {
                _currentAeroSections[i].FlightCalculateAeroForces(atmDensity, (float)machNumber, (float)(reynoldsNumber / Length), skinFrictionDragCoefficient);
            }

            _vesselIntakeRamDrag.ApplyIntakeRamDrag((float)machNumber, _vessel.srf_velocity.normalized, (float)_vessel.dynamicPressurekPa);

            for (int i = 0; i < _currentAeroModules.Count; i++)
            {
                FARAeroPartModule m = _currentAeroModules[i];
                if ((object)m != null)
                {
                    m.ApplyForces();
                }
            }
        }
Ejemplo n.º 26
0
        private void UpdatePropertiesWithAnimation()
        {
            if (anim)
            {
                if (anim.isPlaying && !currentlyAnimating)
                {
                    currentlyAnimating = true;
                }
                else if (currentlyAnimating && !anim.isPlaying)
                {
                    currentlyAnimating = false;
                    FARAeroUtil.SetBasicDragModuleProperties(this.part);      //By doing this, we update the properties of this object
                    AttachNodeCdAdjust();                                     //In case the node properties somehow update with the node; also to deal with changes in part reference area
                }
//                bayProgress = bayAnim[bayAnimationName].normalizedTime;
            }
        }
 public double GetMachNumber(CelestialBody body, double altitude, Vector3d velocity)
 {
     if (start != StartState.Editor)
     {
         if (FARControl != null)
         {
             return(FARControl.MachNumber);
         }
         else
         {
             return(FARAeroUtil.GetMachNumber(body, altitude, velocity));
         }
     }
     else
     {
         print("GetMachNumber called in editor");
         return(0);
     }
 }
Ejemplo n.º 28
0
        public static void LoadConfigs()
        {
            config = KSP.IO.PluginConfiguration.CreateForType <FAREditorGUI>();
            config.load();
            FARDebugValues.displayForces       = Convert.ToBoolean(config.GetValue("displayForces", "false"));
            FARDebugValues.displayCoefficients = Convert.ToBoolean(config.GetValue("displayCoefficients", "false"));
            FARDebugValues.displayShielding    = Convert.ToBoolean(config.GetValue("displayShielding", "false"));

            FAREditorGUI.windowPos = config.GetValue("windowPos", new Rect());
            //FAREditorGUI.minimize = config.GetValue("EditorGUIBool", true);
            if (FAREditorGUI.windowPos.y < 75)
            {
                FAREditorGUI.windowPos.y = 75;
            }


            FARPartClassification.LoadClassificationTemplates();
            FARAeroUtil.LoadAeroDataFromConfig();
        }
Ejemplo n.º 29
0
        public GraphData MachNumberSweep(double aoAdegrees, double pitch, double lowerBound, double upperBound, int numPoints, int flapSetting, bool spoilers, CelestialBody body)
        {
            FARAeroUtil.UpdateCurrentActiveBody(body);

            FARAeroUtil.ResetEditorParts();

            double[] ClValues    = new double[(int)numPoints];
            double[] CdValues    = new double[(int)numPoints];
            double[] CmValues    = new double[(int)numPoints];
            double[] LDValues    = new double[(int)numPoints];
            double[] AlphaValues = new double[(int)numPoints];

            InstantConditionSimInput input = new InstantConditionSimInput(aoAdegrees, 0, 0, 0, 0, 0, 0, pitch, flapSetting, spoilers);

            for (int i = 0; i < numPoints; i++)
            {
                input.machNumber = i / (double)numPoints * (upperBound - lowerBound) + lowerBound;

                if (input.machNumber == 0)
                {
                    input.machNumber = 0.001;
                }

                InstantConditionSimOutput output;

                _instantCondition.GetClCdCmSteady(input, out output, i == 0);
                AlphaValues[i] = input.machNumber;
                ClValues[i]    = output.Cl;
                CdValues[i]    = output.Cd;
                CmValues[i]    = output.Cm;
                LDValues[i]    = output.Cl * 0.1 / output.Cd;
            }

            GraphData data = new GraphData();

            data.xValues = AlphaValues;
            data.AddData(ClValues, GUIColors.GetColor(0), "Cl", true);
            data.AddData(CdValues, GUIColors.GetColor(1), "Cd", true);
            data.AddData(CmValues, GUIColors.GetColor(2), "Cm", true);
            data.AddData(LDValues, GUIColors.GetColor(3), "L/D", true);

            return(data);
        }
 public double GetMachNumber(CelestialBody body, double altitude, Vector3d velocity)
 {
     if (HighLogic.LoadedSceneIsFlight)
     {
         if (FARControl != null)
         {
             return(FARControl.MachNumber);
         }
         else
         {
             return(FARAeroUtil.GetMachNumber(body, altitude, velocity));
         }
     }
     else
     {
         print("GetMachNumber called in editor");
         return(0);
     }
 }