Esempio n. 1
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());
                        }
                    }
                }
            }
        }
Esempio n. 2
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"));
            }
        }
Esempio n. 3
0
        public 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 (HighLogic.LoadedSceneIsFlight && (object)part != null && FlightGlobals.ready)
            {
                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 && !vessel.packed)
                    {
                        Vector3d velocity = rb.velocity + Krakensbane.GetFrameVelocity()
                                            - FARWind.GetWind(FlightGlobals.currentMainBody, part, rb.position);

                        double machNumber, v_scalar = velocity.magnitude;

                        rho        = FARAeroUtil.GetCurrentDensity(vessel.mainBody, part.transform.position);
                        machNumber = GetMachNumber(vessel.mainBody, vessel.altitude, velocity);
                        if (rho > 0 && v_scalar > 0.1)
                        {
                            double   failureForceScaling = FARAeroUtil.GetFailureForceScaling(vessel);
                            Vector3d force = RunDragCalculation(velocity, machNumber, rho, failureForceScaling);
                            rb.AddForceAtPosition(force, GetCoD());
                        }
                    }
                }
            }
        }
        public double CalculateEAS()
        {
            double densityRatio = (FARAeroUtil.GetCurrentDensity(_vessel) / 1.225);

            return(_vessel.srfSpeed * Math.Sqrt(densityRatio));
        }
Esempio n. 5
0
        public void ChangeSurfVelocity()
        {
            active = false;
            //DaMichel: Avoid conflict between multiple vessels in physics range. We only want to show the speed of the active vessel.
            if (FlightGlobals.ActiveVessel != _vessel)
            {
                return;
            }
            //DaMichel: Keep our fingers off of this also if there is no atmosphere (staticPressure <= 0)
            if (FlightGlobals.speedDisplayMode != FlightGlobals.SpeedDisplayModes.Surface || _vessel.atmDensity <= 0)
            {
                return;
            }

            if (SpeedDisplay.Instance == null)
            {
                return;
            }

            double unitConversion = 1;
            string unitString;// = "m/s";
            string caption;

            if (unitMode == SurfaceVelUnit.KNOTS)
            {
                unitConversion = 1.943844492440604768413343347219;
                unitString     = surfUnit_str[1];
            }
            else if (unitMode == SurfaceVelUnit.KM_H)
            {
                unitConversion = 3.6;
                unitString     = surfUnit_str[3];
            }
            else if (unitMode == SurfaceVelUnit.MPH)
            {
                unitConversion = 2.236936;
                unitString     = surfUnit_str[2];
            }
            else
            {
                unitString = surfUnit_str[0];
            }
            if (velMode == SurfaceVelMode.TAS)
            {
                caption   = surfModel_str[0];
                velString = (_vessel.srfSpeed * unitConversion).ToString("F1") + unitString;
            }
            else
            {
                if (velMode == SurfaceVelMode.IAS)
                {
                    caption = surfModel_str[1];
                    //double densityRatio = (FARAeroUtil.GetCurrentDensity(_vessel) / 1.225);
                    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);

                    velString = (velocity * unitConversion).ToString("F1") + unitString;
                }
                else if (velMode == SurfaceVelMode.EAS)
                {
                    caption = surfModel_str[2];
                    double densityRatio = (FARAeroUtil.GetCurrentDensity(_vessel) / 1.225);
                    velString = (_vessel.srfSpeed * Math.Sqrt(densityRatio) * unitConversion).ToString("F1") + unitString;
                }
                else// if (velMode == SurfaceVelMode.MACH)
                {
                    caption   = surfModel_str[3];
                    velString = _vessel.mach.ToString("F3");
                }
            }
            active = true;

            SpeedDisplay UI = SpeedDisplay.Instance;

            if (UI.textSpeed == null || UI.textTitle == null)
            {
                return;
            }

            UI.textTitle.text = caption;
            UI.textSpeed.text = velString;
        }
        public void ChangeSurfVelocity()
        {
            active = false;
            //DaMichel: Avoid conflict between multiple vessels in physics range. We only want to show the speed of the active vessel.
            if (FlightGlobals.ActiveVessel != _vessel)
            {
                return;
            }
            //DaMichel: Keep our fingers off of this also if there is no atmosphere (staticPressure <= 0)
            if (FlightUIController.speedDisplayMode != FlightUIController.SpeedDisplayModes.Surface || _vessel.atmDensity <= 0)
            {
                return;
            }

            double unitConversion = 1;
            string unitString     = "m/s";
            string caption;

            if (unitMode == SurfaceVelUnit.KNOTS)
            {
                unitConversion = 1.943844492440604768413343347219;
                unitString     = "knots";
            }
            else if (unitMode == SurfaceVelUnit.KM_H)
            {
                unitConversion = 3.6;
                unitString     = "km/h";
            }
            else if (unitMode == SurfaceVelUnit.MPH)
            {
                unitConversion = 2.236936;
                unitString     = "mph";
            }
            if (velMode == SurfaceVelMode.TAS)
            {
                caption   = "Surface";
                velString = (_vessel.srfSpeed * unitConversion).ToString("F1") + unitString;
            }
            else
            {
                if (velMode == SurfaceVelMode.IAS)
                {
                    caption = "IAS";
                    double densityRatio  = (FARAeroUtil.GetCurrentDensity(_vessel.mainBody, _vessel.altitude, false) / 1.225);
                    double pressureRatio = FARAeroUtil.StagnationPressureCalc(_vessel.mach);
                    velString = (_vessel.srfSpeed * Math.Sqrt(densityRatio) * pressureRatio * unitConversion).ToString("F1") + unitString;
                }
                else if (velMode == SurfaceVelMode.EAS)
                {
                    caption = "EAS";
                    double densityRatio = (FARAeroUtil.GetCurrentDensity(_vessel.mainBody, _vessel.altitude, false) / 1.225);
                    velString = (_vessel.srfSpeed * Math.Sqrt(densityRatio) * unitConversion).ToString("F1") + unitString;
                }
                else// if (velMode == SurfaceVelMode.MACH)
                {
                    caption   = "Mach";
                    velString = _vessel.mach.ToString("F3");
                }
            }
            active = true;

            FlightUIController UI = FlightUIController.fetch;

            if (UI.spdCaption == null || UI.speed == null)
            {
                return;
            }

            UI.spdCaption.text = caption;
            UI.speed.text      = velString;
        }
        private void FixedUpdate()
        {
            //Flight values
            if (!CompatibilityChecker.IsAllCompatible() || !HighLogic.LoadedSceneIsFlight || FlightGlobals.ActiveVessel == null || this.part.Rigidbody == null)
            {
                return;
            }
            this.pos     = this.part.partTransform.position;
            this.ASL     = FlightGlobals.getAltitudeAtPos(this.pos);
            this.trueAlt = this.ASL;
            if (this.vessel.mainBody.pqsController != null)
            {
                double terrainAlt = this.vessel.pqsAltitude;
                if (!this.vessel.mainBody.ocean || terrainAlt > 0)
                {
                    this.trueAlt -= terrainAlt;
                }
            }
            this.atmPressure = FlightGlobals.getStaticPressure(this.ASL, this.vessel.mainBody) * PhysicsGlobals.KpaToAtmospheres;
            this.atmDensity  = FARAeroUtil.GetCurrentDensity(this.vessel.mainBody, this.ASL, false);
            Vector3 velocity = this.part.Rigidbody.velocity + Krakensbane.GetFrameVelocityV3f();

            this.sqrSpeed   = velocity.sqrMagnitude;
            this.dragVector = -velocity.normalized;
            if (!this.staged && GameSettings.LAUNCH_STAGES.GetKeyDown() && this.vessel.isActiveVessel && (this.part.inverseStage == Staging.CurrentStage - 1 || Staging.CurrentStage == 0))
            {
                ActivateRC();
            }

            if (this.staged)
            {
                //Checks if the parachute must disarm
                if (this.armed)
                {
                    this.part.stackIcon.SetIconColor(XKCDColors.LightCyan);
                    if (this.canDeploy)
                    {
                        this.armed = false;
                    }
                }
                //Parachute deployments
                else
                {
                    //Parachutes
                    if (this.canDeploy)
                    {
                        if (this.isDeployed)
                        {
                            if (!CalculateChuteTemp())
                            {
                                return;
                            }
                            FollowDragDirection();
                        }

                        switch (this.deploymentState)
                        {
                        case DeploymentStates.STOWED:
                        {
                            this.part.stackIcon.SetIconColor(XKCDColors.LightCyan);
                            if (this.pressureCheck && this.randomDeployment)
                            {
                                PreDeploy();
                            }
                            break;
                        }

                        case DeploymentStates.PREDEPLOYED:
                        {
                            this.part.Rigidbody.AddForceAtPosition(DragForce(0, this.preDeployedDiameter, 1f / this.semiDeploymentSpeed), this.forcePosition, ForceMode.Force);
                            if (this.trueAlt <= this.deployAltitude && this.dragTimer.elapsed.TotalSeconds >= 1f / this.semiDeploymentSpeed)
                            {
                                Deploy();
                            }
                            break;
                        }

                        case DeploymentStates.DEPLOYED:
                        {
                            this.part.rigidbody.AddForceAtPosition(DragForce(this.preDeployedDiameter, this.deployedDiameter, 1f / this.deploymentSpeed), this.forcePosition, ForceMode.Force);
                            break;
                        }

                        default:
                            break;
                        }
                    }
                    //Deactivation
                    else
                    {
                        if (this.isDeployed)
                        {
                            Cut();
                        }
                        else
                        {
                            this.failedTimer.Start();
                            StagingReset();
                        }
                    }
                }
            }
        }
Esempio n. 8
0
        private void partModuleUpdate(PartModule pm)
        {
            if (isFarLoaded && pm is FARControllableSurface)
            {
                FARControllableSurface fcs = (FARControllableSurface)pm;

                if (vessel.atmDensity > 0)
                {
                    Vector3d forcePosition = fcs.AerodynamicCenter - vesselState.CoM;
                    Vector3  velocity      = fcs.GetVelocity();

                    double soundspeed, v_scalar = velocity.magnitude;

                    double rho = FARAeroUtil.GetCurrentDensity(vessel, out soundspeed);
                    if (rho <= 0.0 || v_scalar <= 0.1 || fcs.isShielded)
                    {
                        return;
                    }

                    // First we save the curent state of the part
                    double YmaxForce  = fcs.YmaxForce;
                    double XZmaxForce = fcs.XZmaxForce;

                    double AoAcurrentFlap = (double)(FieldAoAcurrentFlap.GetValue(fcs));

                    double MaxAoAdesiredControl = 0;
                    if (fcs.pitchaxis != 0.0)
                    {
                        MaxAoAdesiredControl += (double)(FieldPitchLocation.GetValue(fcs)) * fcs.pitchaxis * 0.01;
                    }
                    if (fcs.yawaxis != 0.0)
                    {
                        MaxAoAdesiredControl += (double)(FieldYawLocation.GetValue(fcs)) * fcs.yawaxis * 0.01;;
                    }
                    if (fcs.rollaxis != 0.0)
                    {
                        MaxAoAdesiredControl += (double)(FieldRollLocation.GetValue(fcs)) * fcs.rollaxis * 0.01;;
                    }
                    MaxAoAdesiredControl *= fcs.maxdeflect;
                    if (fcs.pitchaxisDueToAoA != 0.0)
                    {
                        double _AoA = (fcs as FARWingAerodynamicModel).CalculateAoA(velocity.normalized);
                        _AoA = FARMathUtil.rad2deg * Math.Asin(_AoA);
                        if (double.IsNaN(_AoA))
                        {
                            _AoA = 0;
                        }
                        MaxAoAdesiredControl += _AoA * fcs.pitchaxisDueToAoA * 0.01;
                    }

                    MaxAoAdesiredControl = FARMathUtil.Clamp(MaxAoAdesiredControl, -Math.Abs(fcs.maxdeflect), Math.Abs(fcs.maxdeflect));

                    double MachNumber = v_scalar / soundspeed;
                    fcs.YmaxForce  = double.MaxValue;
                    fcs.XZmaxForce = double.MaxValue;

                    // Then we turn it one way
                    double AoA = fcs.CalculateAoA(velocity, AoAcurrentFlap + MaxAoAdesiredControl);
                    vesselState.ctrlTorqueAvailable.Add(vessel.GetTransform().InverseTransformDirection(Vector3.Cross(forcePosition, fcs.CalculateForces(velocity, MachNumber, AoA))));

                    // We restore it to the initial state
                    AoA = fcs.CalculateAoA(velocity);
                    fcs.CalculateForces(velocity, MachNumber, AoA);

                    // And we turn it the other way
                    AoA = fcs.CalculateAoA(velocity, AoAcurrentFlap - MaxAoAdesiredControl);
                    vesselState.ctrlTorqueAvailable.Add(vessel.GetTransform().InverseTransformDirection(Vector3.Cross(forcePosition, fcs.CalculateForces(velocity, MachNumber, AoA))));

                    // And in the end we restore its initial state
                    AoA = fcs.CalculateAoA(velocity);
                    fcs.CalculateForces(velocity, MachNumber, AoA);

                    fcs.YmaxForce  = YmaxForce;
                    fcs.XZmaxForce = XZmaxForce;
                }
            }
        }