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);
        }
Exemplo n.º 2
0
        public void ApplyForce(FARAeroSection.PartData pd, Vector3 localVel, Vector3 forceVector, Vector3 torqueVector)
        {
            double tmp = 0.0005 * Vector3.SqrMagnitude(localVel);
            double dynamicPressurekPa = tmp * atmDensity;
            double dragFactor         = dynamicPressurekPa *
                                        Mathf.Max(PhysicsGlobals.DragCurvePseudoReynolds.Evaluate(atmDensity *
                                                                                                  Vector3.Magnitude(localVel)),
                                                  1.0f);
            double liftFactor = dynamicPressurekPa;

            Vector3 localVelNorm   = Vector3.Normalize(localVel);
            Vector3 localForceTemp = Vector3.Dot(localVelNorm, forceVector) * localVelNorm;
            Vector3 partLocalForce =
                localForceTemp * (float)dragFactor + (forceVector - localForceTemp) * (float)liftFactor;

            forceVector  = pd.aeroModule.part.transform.TransformDirection(partLocalForce);
            torqueVector = pd.aeroModule.part.transform.TransformDirection(torqueVector * (float)dynamicPressurekPa);
            if (float.IsNaN(forceVector.x) || float.IsNaN(torqueVector.x))
            {
                return;
            }
            Vector3 centroid =
                pd.aeroModule.part.transform.TransformPoint(pd.centroidPartSpace - pd.aeroModule.part.CoMOffset);

            center.AddForce(centroid, forceVector);
            center.AddTorque(torqueVector);
        }
        private void CalculateTotalAeroForce()
        {
            aeroForces.ClearAll();

            if (_vessel.dynamicPressurekPa <= 0.00001)
            {
                return;
            }

            if (_currentAeroModules != null)
            {
                for (int i = 0; i < _currentAeroModules.Count; i++)
                {
                    FARAeroPartModule m = _currentAeroModules[i];
                    if ((object)m != null)
                    {
                        aeroForces.AddForce(m.transform.position, m.totalWorldSpaceAeroForce);
                        aeroForces.AddTorque(m.worldSpaceTorque);
                    }
                }
            }

            /*
             * for (int i = 0; i < _LEGACY_currentWingAeroModel.Count; i++)
             * {
             *  FARWingAerodynamicModel w = _LEGACY_currentWingAeroModel[i];
             *  if ((object)w == null)
             *      continue;
             *  totalAeroForceVector += w.worldSpaceForce;
             *  aeroForces.AddForce(w.AerodynamicCenter, w.worldSpaceForce);
             *
             *  totalAeroForceVector += w.worldSpaceForce;
             *  totalAeroTorqueVector += Vector3.Cross(w.AerodynamicCenter - _vessel.CoM, w.worldSpaceForce);
             * }
             *
             * for(int i = 0; i < _vessel.parts.Count; i++)
             * {
             *  Part p = _vessel.parts[i];
             *  totalAeroForceVector += -p.dragVectorDir * p.dragScalar; // dragVectorDir is actually the velocity vector direction
             * }
             */
        }
        private void CalculateTotalAeroForce()
        {
            aeroForces.ClearAll();


            if (_vessel.dynamicPressurekPa <= 0.00001)
            {
                return;
            }

            if (_currentAeroModules == null)
            {
                return;
            }
            foreach (FARAeroPartModule m in _currentAeroModules)
            {
                if (m is null)
                {
                    continue;
                }
                aeroForces.AddForce(m.transform.position, m.totalWorldSpaceAeroForce);
                aeroForces.AddTorque(m.worldSpaceTorque);
            }
        }
Exemplo n.º 5
0
        public void SimulateAeroProperties(
            out Vector3 aeroForce,
            out Vector3 aeroTorque,
            Vector3 velocityWorldVector,
            double altitude
            )
        {
            Vector3d position = vessel.CurrentPosition(altitude);

            if (velocityWorldVector.NearlyEqual(lastSimResults.VelocityVector) &&
                (FARAtmosphere.IsCustom
                 // Custom atmospheres are not guaranteed to be independent of latitude and longitude
                     ? position.NearlyEqual(lastSimResults.Position)
                     : altitude.NearlyEqual(lastSimResults.Position.z)))
            {
                aeroForce  = lastSimResults.Force;
                aeroTorque = lastSimResults.Torque;
                return;
            }

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

            //Calculate main gas properties
            GasProperties properties = FARAtmosphere.GetGasProperties(vessel.mainBody, position, Planetarium.GetUniversalTime());

            if (properties.Pressure <= 0 || properties.Temperature <= 0)
            {
                aeroForce  = Vector3.zero;
                aeroTorque = Vector3.zero;
                return;
            }

            float velocityMag    = velocityWorldVector.magnitude;
            float machNumber     = (float)(velocityMag / properties.SpeedOfSound);
            float reynoldsNumber = (float)FARAeroUtil.CalculateReynoldsNumber(properties.Density,
                                                                              Length,
                                                                              velocityMag,
                                                                              machNumber,
                                                                              properties.Temperature,
                                                                              properties.AdiabaticIndex);

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

            float pseudoKnudsenNumber = machNumber / (reynoldsNumber + machNumber);

            if (_currentAeroSections != null)
            {
                foreach (FARAeroSection curSection in _currentAeroSections)
                {
                    curSection?.PredictionCalculateAeroForces((float)properties.Density,
                                                              machNumber,
                                                              reynoldsPerLength,
                                                              pseudoKnudsenNumber,
                                                              skinFriction,
                                                              velocityWorldVector,
                                                              center);
                }

                foreach (FARWingAerodynamicModel curWing in _legacyWingModels)
                {
                    if (curWing != null)
                    {
                        center.AddForce(curWing.transform.position,
                                        curWing.PrecomputeCenterOfLift(velocityWorldVector,
                                                                       machNumber,
                                                                       properties.Density,
                                                                       dummy));
                    }
                }
            }

            aeroForce  = center.force;
            aeroTorque = center.TorqueAt(vessel.CoM);

            lastSimResults = new CachedSimResults(velocityWorldVector, position, aeroForce, aeroTorque);
        }
        public void SimulateAeroProperties(
            out Vector3 aeroForce,
            out Vector3 aeroTorque,
            Vector3 velocityWorldVector,
            double altitude
            )
        {
            var center = new FARCenterQuery();
            var dummy  = new FARCenterQuery();

            CelestialBody body         = vessel.mainBody; //Calculate main gas properties
            float         pressure     = (float)body.GetPressure(altitude);
            float         temperature  = (float)body.GetTemperature(altitude);
            float         density      = (float)body.GetDensity(pressure, temperature);
            float         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)
            {
                foreach (FARAeroSection curSection in _currentAeroSections)
                {
                    curSection?.PredictionCalculateAeroForces(density,
                                                              machNumber,
                                                              reynoldsPerLength,
                                                              pseudoKnudsenNumber,
                                                              skinFriction,
                                                              velocityWorldVector,
                                                              center);
                }

                foreach (FARWingAerodynamicModel curWing in _legacyWingModels)
                {
                    if (!(curWing is null))
                    {
                        center.AddForce(curWing.transform.position,
                                        curWing.PrecomputeCenterOfLift(velocityWorldVector,
                                                                       machNumber,
                                                                       density,
                                                                       dummy));
                    }
                }
            }

            aeroForce  = center.force;
            aeroTorque = center.TorqueAt(vessel.CoM);
        }
Exemplo n.º 7
0
        public void SimulateAeroProperties(
            out Vector3 aeroForce,
            out Vector3 aeroTorque,
            Vector3 velocityWorldVector,
            double altitude
            )
        {
            var center = new FARCenterQuery();
            var dummy  = new FARCenterQuery();

            //Calculate main gas properties
            GasProperties properties = FARAtmosphere.GetGasProperties(vessel, altitude, Planetarium.GetUniversalTime());

            if (properties.Pressure <= 0 || properties.Temperature <= 0)
            {
                aeroForce  = Vector3.zero;
                aeroTorque = Vector3.zero;
                return;
            }

            float velocityMag    = velocityWorldVector.magnitude;
            float machNumber     = (float)(velocityMag / properties.SpeedOfSound);
            float reynoldsNumber = (float)FARAeroUtil.CalculateReynoldsNumber(properties.Density,
                                                                              Length,
                                                                              velocityMag,
                                                                              machNumber,
                                                                              properties.Temperature,
                                                                              properties.AdiabaticIndex);

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

            float pseudoKnudsenNumber = machNumber / (reynoldsNumber + machNumber);

            if (_currentAeroSections != null)
            {
                foreach (FARAeroSection curSection in _currentAeroSections)
                {
                    curSection?.PredictionCalculateAeroForces((float)properties.Density,
                                                              machNumber,
                                                              reynoldsPerLength,
                                                              pseudoKnudsenNumber,
                                                              skinFriction,
                                                              velocityWorldVector,
                                                              center);
                }

                foreach (FARWingAerodynamicModel curWing in _legacyWingModels)
                {
                    if (curWing != null)
                    {
                        center.AddForce(curWing.transform.position,
                                        curWing.PrecomputeCenterOfLift(velocityWorldVector,
                                                                       machNumber,
                                                                       properties.Density,
                                                                       dummy));
                    }
                }
            }

            aeroForce  = center.force;
            aeroTorque = center.TorqueAt(vessel.CoM);
        }