コード例 #1
0
        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);

            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);

            for(int i = 0; i < _currentAeroSections.Count; i++)
                _currentAeroSections[i].PredictionCalculateAeroForces(density, machNumber, reynoldsPerLength, skinFriction, velocityWorldVector, center);

            for (int i = 0; i < _legacyWingModels.Count; i++)
                _legacyWingModels[i].PrecomputeCenterOfLift(velocityWorldVector, machNumber, density, center);

            aeroForce = center.force;
            aeroTorque = center.TorqueAt(_vessel.CoM);
        }
コード例 #2
0
        void UpdateAerodynamicCenter()
        {
            FARCenterQuery aeroSection, dummy;
            aeroSection = new FARCenterQuery();
            dummy = new FARCenterQuery();

            if((object)EditorLogic.RootPart == null)
                return;

            Vector3 vel_base, vel_fuzz;

            Transform rootPartTrans = EditorLogic.RootPart.partTransform;
            if (EditorDriver.editorFacility == EditorFacility.SPH)
            {
                vel_base = Vector3.forward;
                vel_fuzz = 0.02f * Vector3.up;
            }
            else
            {
                vel_base = Vector3.up;
                vel_fuzz = -0.02f * Vector3.forward;
            }

            Vector3 vel = (vel_base - vel_fuzz).normalized;

            for(int i = 0; i < _currentAeroSections.Count; i++)
            {
                FARAeroSection section = _currentAeroSections[i];
                section.PredictionCalculateAeroForces(1, 0.5f, 100000, 0.005f, vel, aeroSection);
            }

            FARBaseAerodynamics.PrecomputeGlobalCenterOfLift(aeroSection, dummy, vel, 1);

            Vector3 pos = Vector3.zero;//rootPartTrans.position;
            float mass = 0;
            for(int i = 0; i < EditorLogic.SortedShipList.Count; i++)
            {
                Part p = EditorLogic.SortedShipList[i];
                float tmpMass = p.mass + p.GetResourceMass();
                mass += tmpMass;
                pos += p.partTransform.position * tmpMass;
            }
            pos /= mass;

            Vector3 avgForcePos = Vector3.zero;

            Vector3 force0, moment0;
            force0 = aeroSection.force;
            moment0 = aeroSection.TorqueAt(pos);
            avgForcePos += aeroSection.GetPos();

            //aeroSection.force = -aeroSection.force;
            //aeroSection.torque = -aeroSection.torque;

            aeroSection.ClearAll();

            vel = (vel_base + vel_fuzz).normalized;

            for (int i = 0; i < _currentAeroSections.Count; i++)
            {
                FARAeroSection section = _currentAeroSections[i];
                section.PredictionCalculateAeroForces(1, 0.5f, 100000, 0.005f, vel, aeroSection);
            }

            FARBaseAerodynamics.PrecomputeGlobalCenterOfLift(aeroSection, dummy, vel, 1);

            Vector3 force1, moment1;
            force1 = aeroSection.force;
            moment1 = aeroSection.TorqueAt(pos);
            avgForcePos += aeroSection.GetPos();

            aeroSection.ClearAll();

            avgForcePos *= 0.5f;

            Vector3 deltaForce = force1 - force0;
            Vector3 deltaMoment = moment1 - moment0;

            Vector3 deltaForcePerp = Vector3.ProjectOnPlane(deltaForce, vel_base);
            float deltaForcePerpMag = deltaForcePerp.magnitude;

            Vector3 deltaForcePerpNorm = deltaForcePerp / deltaForcePerpMag;

            Vector3 deltaMomentPerp = deltaMoment - Vector3.Dot(deltaMoment, deltaForcePerpNorm) * deltaForcePerpNorm - Vector3.Project(deltaMoment, vel_base);

            //float dist = deltaMomentPerp.magnitude / deltaForcePerpMag;
            //vesselRootLocalAeroCenter = vel_base * dist;

            vesselRootLocalAeroCenter = deltaMomentPerp.magnitude / deltaForcePerpMag * vel_base * Math.Sign(Vector3.Dot(Vector3.Cross(deltaForce, deltaMoment), vel_base));

            //Debug.Log(dist + " " + deltaMomentPerp.magnitude + " " + deltaForcePerpMag);
            //vesselRootLocalAeroCenter += avgForcePos;
            //avgForcePos = rootPartTrans.worldToLocalMatrix.MultiplyPoint3x4(avgForcePos);
            //vesselRootLocalAeroCenter += Vector3.ProjectOnPlane(avgForcePos, Vector3.up);
            //vesselRootLocalAeroCenter = aeroSection.GetPos();
            vesselRootLocalAeroCenter += pos;//Vector3.ProjectOnPlane(avgForcePos - pos, vesselRootLocalAeroCenter) + pos;
            vesselRootLocalAeroCenter = rootPartTrans.worldToLocalMatrix.MultiplyPoint3x4(vesselRootLocalAeroCenter);
        }
コード例 #3
0
        public void GetClCdCmSteady(InstantConditionSimInput input, out InstantConditionSimOutput output, bool clear, bool reset_stall = false)
        {
            output = new InstantConditionSimOutput();

            double area = 0;
            double MAC = 0;
            double b_2 = 0;

            Vector3d forward = Vector3.forward;
            Vector3d up = Vector3.up;
            Vector3d right = Vector3.right;

            Vector3d CoM = Vector3d.zero;
            double mass = 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;
            }
            CoM /= mass;

            if (EditorDriver.editorFacility == EditorFacility.VAB)
            {
                forward = Vector3.up;
                up = -Vector3.forward;
            }

            double sinAlpha = Math.Sin(input.alpha * Math.PI / 180);
            double cosAlpha = Math.Sqrt(Math.Max(1 - sinAlpha * sinAlpha, 0));

            double sinBeta = Math.Sin(input.beta * Math.PI / 180);
            double cosBeta = Math.Sqrt(Math.Max(1 - sinBeta * sinBeta, 0));

            double sinPhi = Math.Sin(input.phi * Math.PI / 180);
            double cosPhi = Math.Sqrt(Math.Max(1 - sinPhi * sinPhi, 0));

            double alphaDot = input.alphaDot * Math.PI / 180;
            double betaDot = input.betaDot * Math.PI / 180;
            double phiDot = input.phiDot * Math.PI / 180;

            Vector3d AngVel = (phiDot - sinAlpha * betaDot) * forward;
            AngVel += (cosPhi * alphaDot + cosAlpha * sinPhi * betaDot) * right;
            AngVel += (sinPhi * alphaDot - cosAlpha * cosPhi * betaDot) * up;

            Vector3d velocity = forward * cosAlpha * cosBeta;
            velocity += right * (sinPhi * cosAlpha * cosBeta + cosPhi * sinBeta);
            velocity += -up * cosPhi * (sinAlpha * cosBeta + sinBeta);

            velocity.Normalize();

            //this is negative wrt the ground
            Vector3d liftVector = -forward * sinAlpha + right * sinPhi * cosAlpha - up * cosPhi * cosAlpha;

            Vector3d sideways = Vector3.Cross(velocity, liftVector).normalized;


            for (int i = 0; i < _wingAerodynamicModel.Count; i++)
            {
                FARWingAerodynamicModel w = _wingAerodynamicModel[i];
                if (!(w && w.part))
                    continue;

                w.ComputeForceEditor(velocity.normalized, input.machNumber, 2);

                if (clear)
                    w.EditorClClear(reset_stall);

                Vector3d relPos = w.GetAerodynamicCenter() - CoM;

                Vector3d vel = velocity + Vector3d.Cross(AngVel, relPos);

                if (w is FARControllableSurface)
                    (w as FARControllableSurface).SetControlStateEditor(CoM, vel, (float)input.pitchValue, 0, 0, input.flaps, input.spoilers);
                else if (w.isShielded)
                    continue;


                //w.ComputeForceEditor(velocity, input.machNumber);     //do this just to get the AC right

                Vector3d force = w.ComputeForceEditor(vel.normalized, input.machNumber, 2) * 1000;

                output.Cl += -Vector3d.Dot(force, liftVector);
                output.Cy += Vector3d.Dot(force, sideways);
                output.Cd += -Vector3d.Dot(force, velocity);

                Vector3d moment = -Vector3d.Cross(relPos, force);

                output.Cm += Vector3d.Dot(moment, sideways);
                output.Cn += Vector3d.Dot(moment, liftVector);
                output.C_roll += Vector3d.Dot(moment, velocity);

                //w.ComputeClCdEditor(vel.normalized, input.machNumber);

                /*double tmpCl = w.GetCl() * w.S;
                output.Cl += tmpCl * -Vector3d.Dot(w.GetLiftDirection(), liftVector);
                output.Cy += tmpCl * -Vector3d.Dot(w.GetLiftDirection(), sideways);
                double tmpCd = w.GetCd() * w.S;
                output.Cd += tmpCd;
                output.Cm += tmpCl * Vector3d.Dot((relPos), velocity) * -Vector3d.Dot(w.GetLiftDirection(), liftVector) + tmpCd * -Vector3d.Dot((relPos), liftVector);
                output.Cn += tmpCd * Vector3d.Dot((relPos), sideways) + tmpCl * Vector3d.Dot((relPos), velocity) * -Vector3d.Dot(w.GetLiftDirection(), sideways);
                output.C_roll += tmpCl * Vector3d.Dot((relPos), sideways) * -Vector3d.Dot(w.GetLiftDirection(), liftVector);*/
                area += w.S;
                MAC += w.GetMAC() * w.S;
                b_2 += w.Getb_2() * w.S;
            }
            FARCenterQuery center = new FARCenterQuery();
            for (int i = 0; i < _currentAeroSections.Count; i++)
            {
                _currentAeroSections[i].PredictionCalculateAeroForces(2, (float)input.machNumber, 10000, 0.005f, velocity.normalized, center);
            }

            Vector3d centerForce = center.force * 1000;

            output.Cl += -Vector3d.Dot(centerForce, liftVector);
            output.Cy += Vector3d.Dot(centerForce, sideways);
            output.Cd += -Vector3d.Dot(centerForce, velocity);

            Vector3d centerMoment = -center.TorqueAt(CoM) * 1000;

            output.Cm += Vector3d.Dot(centerMoment, sideways);
            output.Cn += Vector3d.Dot(centerMoment, liftVector);
            output.C_roll += Vector3d.Dot(centerMoment, velocity);
            

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

                Vector3 part_pos = p.transform.TransformPoint(p.CoMOffset) - CoM;
                double partMass = p.mass;
                if (p.Resources.Count > 0)
                    partMass += p.GetResourceMass();

                double stock_drag = partMass * p.maximum_drag * FlightGlobals.DragMultiplier * 1000;
                output.Cd += stock_drag;
                output.Cm += stock_drag * -Vector3d.Dot(part_pos, liftVector);
                output.Cn += stock_drag * Vector3d.Dot(part_pos, sideways);
            }*/

            if (area == 0)
            {
                area = _maxCrossSectionFromBody;
                b_2 = 1;
                MAC = _bodyLength;
            }

            double recipArea = 1 / area;

            MAC *= recipArea;
            b_2 *= recipArea;
            output.Cl *= recipArea;
            output.Cd *= recipArea;
            output.Cm *= recipArea / MAC;
            output.Cy *= recipArea;
            output.Cn *= recipArea / b_2;
            output.C_roll *= recipArea / b_2;
        }