Ejemplo n.º 1
0
        public override bool Run(bool Holding)
        {
            if (InternalRun())
            {
                return(true);
            }
            if (FDMExec.Holding())
            {
                return(false);                   // if paused don't execute
            }
            vForces  = Vector3D.Zero;
            vMoments = Vector3D.Zero;

            // Only execute gear force code below 300 feet
            if (FDMExec.Propagate.DistanceAGL < 300.0)
            {
                // Sum forces and moments for all gear, here.
                // Some optimizations may be made here - or rather in the gear code itself.
                // The gear ::Run() method is called several times - once for each gear.
                // Perhaps there is some commonality for things which only need to be
                // calculated once.
                foreach (LGear gear in lGear)
                {
                    vForces  += gear.Force();
                    vMoments += gear.Moment();
                }
            }
            else
            {
                // Crash Routine
            }

            return(false);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Runs the Aircraft model; called by the Executive
        /// </summary>
        /// <returns>false if no error</returns>
        public override bool Run()
        {
            if (InternalRun())
            {
                return(true);
            }
            if (FDMExec.Holding())
            {
                return(false);                   // if paused don't execute
            }
            // if false then execute this Run()
            vForces  = Vector3D.Zero;
            vForces  = FDMExec.Aerodynamics.Forces;
            vForces += FDMExec.Propulsion.GetForces();
            vForces += FDMExec.GroundReactions.GetForces();

            vMoments  = Vector3D.Zero;
            vMoments  = FDMExec.Aerodynamics.Moments;
            vMoments += FDMExec.Propulsion.GetMoments();
            vMoments += FDMExec.GroundReactions.GetMoments();

            vBodyAccel = vForces / FDMExec.MassBalance.Mass;

            vNcg = vBodyAccel / FDMExec.Inertial.Gravity;

            vNwcg   = FDMExec.State.GetTb2s() * vNcg;
            vNwcg.Z = -1 * vNwcg.Z + 1;

            return(false);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Runs the Aircraft model; called by the Executive
        /// </summary>
        /// <returns>false if no error</returns>
        public override bool Run(bool Holding)
        {
#if TODO
            if (InternalRun())
            {
                return(true);
            }
            if (FDMExec.Holding())
            {
                return(false);                   // if paused don't execute
            }
            // if false then execute this Run()
            vForces  = Vector3D.Zero;
            vForces  = FDMExec.Aerodynamics.Forces;
            vForces += FDMExec.Propulsion.GetForces();
            vForces += FDMExec.GroundReactions.GetForces();

            vMoments  = Vector3D.Zero;
            vMoments  = FDMExec.Aerodynamics.Moments;
            vMoments += FDMExec.Propulsion.GetMoments();
            vMoments += FDMExec.GroundReactions.GetMoments();

            vBodyAccel = vForces / FDMExec.MassBalance.Mass;

            vNcg = vBodyAccel / FDMExec.Inertial.Gravity;

            vNwcg   = FDMExec.State.GetTb2s() * vNcg;
            vNwcg.Z = -1 * vNwcg.Z + 1;

            return(false);
#endif
            throw new NotImplementedException("Pending upgrade to lastest version of JSBSIM");
        }
Ejemplo n.º 4
0
        public override bool Run()
        {
            double denom, k1, k2, k3, k4, k5, k6;
            double Ixx, Iyy, Izz, Ixy, Ixz, Iyz;

            if (InternalRun())
            {
                return(true);
            }
            if (FDMExec.Holding())
            {
                return(false);                   // if paused don't execute
            }
            weight = emptyWeight + FDMExec.Propulsion.GetTanksWeight() + GetPointMassWeight();

            mass = Constants.lbtoslug * weight;

            // Calculate new CG

            vXYZcg = (FDMExec.Propulsion.GetTanksMoment() + emptyWeight * vbaseXYZcg
                      + GetPointMassMoment()) / weight;

            // Calculate new total moments of inertia

            // At first it is the base configuration inertia matrix ...
            mJ = baseJ;
            // ... with the additional term originating from the parallel axis theorem.
            mJ += GetPointmassInertia(Constants.lbtoslug * emptyWeight, vbaseXYZcg);
            // Then add the contributions from the additional pointmasses.
            mJ += CalculatePMInertias();
            mJ += FDMExec.Propulsion.CalculateTankInertias();

            Ixx = mJ.M11;
            Iyy = mJ.M22;
            Izz = mJ.M33;
            Ixy = -mJ.M12;
            Ixz = -mJ.M13;
            Iyz = -mJ.M23;

            // Calculate inertia matrix inverse (ref. Stevens and Lewis, "Flight Control & Simulation")

            k1 = (Iyy * Izz - Iyz * Iyz);
            k2 = (Iyz * Ixz + Ixy * Izz);
            k3 = (Ixy * Iyz + Iyy * Ixz);

            denom = 1.0 / (Ixx * k1 - Ixy * k2 - Ixz * k3);
            k1    = k1 * denom;
            k2    = k2 * denom;
            k3    = k3 * denom;
            k4    = (Izz * Ixx - Ixz * Ixz) * denom;
            k5    = (Ixy * Ixz + Iyz * Ixx) * denom;
            k6    = (Ixx * Iyy - Ixy * Ixy) * denom;

            mJinv = new Matrix3D(k1, k2, k3, k2, k4, k5, k3, k5, k6);

            return(false);
        }
Ejemplo n.º 5
0
        public override bool Run()
        {
            // Fast return if we have nothing to do ...
            if (InternalRun())
            {
                return(true);
            }
            if (FDMExec.Holding())
            {
                return(false);                   // if paused don't execute
            }
            // Gravitation accel
            double r = FDMExec.Propagate.Radius;

            gAccel = GetGAccel(r);

            return(false);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Runs the Atmosphere model; called by the Executive
        /// </summary>
        /// <returns>false if no error</returns>
        public override bool Run()
        {
            if (InternalRun())
            {
                return(true);
            }
            if (FDMExec.Holding())
            {
                return(false);
            }

            T_dev = 0.0;


            h = FDMExec.Propagate.Altitude;

            if (!useExternal)
            {
                Calculate(h);
                CalculateDerived();
            }
            else
            {
                CalculateDerived();
            }


            // if false then execute this Run()
            //do temp, pressure, and density first
            if (!useExternal)
            {
                h = FDMExec.Propagate.Altitude;
                Calculate(h);
            }

            if (turbType != TurbType.ttNone)
            {
                Turbulence();
                vWindNED += vTurbulence;
            }
            return(false);
        }
Ejemplo n.º 7
0
        public override bool Run()
        {
            if (InternalRun())
            {
                return(true);
            }
            if (FDMExec.Holding())
            {
                return(false);
            }

            T_dev = 0.0;

            // if false then execute this Run()
            //do temp, pressure, and density first
            if (!useExternal)
            {
                h = FDMExec.Propagate.Altitude;
                Calculate(h);
            }

            if (turbType != TurbType.ttNone)
            {
                Turbulence();
                vWindNED += vTurbulence;
            }

            if (vWindNED[0] != 0.0)
            {
                psiw = Math.Atan2(vWindNED[1], vWindNED[0]);
            }

            if (psiw < 0)
            {
                psiw += 2 * Math.PI;
            }

            soundspeed = Math.Sqrt(Constants.SHRatio * Constants.Reng * (useInfo.Temperature));

            return(false);
        }
Ejemplo n.º 8
0
        public override bool Run(bool Holding)
        {
            //if (log.IsInfoEnabled)
            //    log.Info("Entering Run() for model " + name + "rate =" + rate);

            if (InternalRun())
            {
                return(true);
            }
            if (enabled && !FDMExec.State.IsIntegrationSuspended && !FDMExec.Holding())
            {
                if (outputType == OutputType.Socket)
                {
                    // Not done yet
                    //if (log.IsWarnEnabled)
                    //    log.Warn("Socket output is Not Implemented");
                }
                else if (outputType == OutputType.CSV || outputType == OutputType.Tab)
                {
                    DelimitedOutput(filename); //TODO
                }
                else if (outputType == OutputType.Terminal)
                {
                    // Not done yet
                    throw new NotImplementedException("Terminal output");
                }
                else if (outputType == OutputType.Log4Net)
                {
                    Log4NetOutput();
                }
                else if (outputType == OutputType.None)
                {
                    // Do nothing
                }
                else
                {
                    // Not a valid type of output
                }
            }
            return(false);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Executes the propulsion model.
        /// The initial plan for the FGPropulsion class calls for Run() to be executed,
        /// calculating the power available from the engine.
        ///
        /// [Note: Should we be checking the Starved flag here?]
        /// </summary>
        /// <returns></returns>
        public override bool Run(bool Holding)
        {
            if (InternalRun())
            {
                return(true);
            }
            if (FDMExec.Holding())
            {
                return(false);                   // if paused don't execute
            }
            double dt = FDMExec.State.DeltaTime;

            vForces  = Vector3D.Zero;
            vMoments = Vector3D.Zero;

            for (int i = 0; i < engines.Count; i++)
            {
                engines[i].Calculate();
                vForces  += engines[i].GetBodyForces();                  // sum body frame forces
                vMoments += engines[i].GetMoments();                     // sum body frame moments
            }

            totalFuelQuantity = 0.0;
            for (int i = 0; i < tanks.Count; i++)
            {
                tanks[i].Calculate(dt * rate);
                if (tanks[i].TankType == Tank.EnumTankType.Fuel)
                {
                    totalFuelQuantity += tanks[i].Contents;
                }
            }

            if (refuel)
            {
                DoRefuel(dt * rate);
            }

            return(false);
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Runs the Aerodynamics model; called by the Executive
        /// </summary>
        /// <returns>false if no error</returns>
        public override bool Run()
        {
            double alpha, twovel;

            if (InternalRun())
            {
                return(true);
            }
            if (FDMExec.Holding())
            {
                return(false);                   // if paused don't execute
            }
            // calculate some oft-used quantities for speed
            twovel = 2 * FDMExec.Auxiliary.Vt;
            if (twovel != 0)
            {
                bi2vel = FDMExec.Aircraft.WingSpan / twovel;
                ci2vel = FDMExec.Aircraft.WingChord / twovel;
            }

            alphaw = FDMExec.Auxiliary.Getalpha() + FDMExec.Aircraft.WingIncidence;

            alpha     = FDMExec.Auxiliary.Getalpha();
            qbar_area = FDMExec.Aircraft.WingArea * FDMExec.Auxiliary.Qbar;

            if (alphaclmax != 0)
            {
                if (alpha > 0.85 * alphaclmax)
                {
                    impending_stall = 10 * (alpha / alphaclmax - 0.85);
                }
                else
                {
                    impending_stall = 0;
                }
            }

            if (alphahystmax != 0.0 && alphahystmin != 0.0)
            {
                if (alpha > alphahystmax)
                {
                    stall_hyst = 1;
                }
                else if (alpha < alphahystmin)
                {
                    stall_hyst = 0;
                }
            }

            vLastFs = vFs;
            vFs     = Vector3D.Zero;

            // Tell the variable functions to cache their values, so while the aerodynamic
            // functions are being calculated for each axis, these functions do not get
            // calculated each time, but instead use the values that have already
            // been calculated for this frame.
            for (int i = 0; i < variables.Count; i++)
            {
                variables[i].CacheValue(true);
            }

            for (int axis_ctr = 0; axis_ctr < 3; axis_ctr++)
            {
                if (Coeff[axis_ctr] != null)
                {
                    foreach (Function func in Coeff[axis_ctr])
                    {
                        vFs[axis_ctr] += func.GetValue();
                    }
                }
            }

            // calculate lift coefficient squared
            if (FDMExec.Auxiliary.Qbar > 0)
            {
                clsq  = vFs[(int)StabilityAxisForces.eLift] / (FDMExec.Aircraft.WingArea * FDMExec.Auxiliary.Qbar);
                clsq *= clsq;
            }
            if (vFs[(int)StabilityAxisForces.eDrag] > 0)
            {
                lod = vFs[(int)StabilityAxisForces.eLift] / vFs[(int)StabilityAxisForces.eDrag];
            }

            //correct signs of drag and lift to wind axes convention
            //positive forward, right, down
            vFs[(int)StabilityAxisForces.eDrag] *= -1; vFs[(int)StabilityAxisForces.eLift] *= -1;

            vForces = FDMExec.State.GetTs2b() * vFs;

            vDXYZcg = FDMExec.MassBalance.StructuralToBody(FDMExec.Aircraft.AeroRefPointXYZ);

            vMoments = Vector3D.Cross(vDXYZcg, vForces); // M = r X F

            for (int axis_ctr = 0; axis_ctr < 3; axis_ctr++)
            {
                if (Coeff[axis_ctr + 3] != null)
                {
                    foreach (Function func in Coeff[axis_ctr + 3])
                    {
                        vMoments[axis_ctr] += func.GetValue();
                    }
                }
            }

            return(false);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Runs the Auxiliary routines; called by the Executive
        /// </summary>
        /// <returns>false if no error</returns>
        public override bool Run(bool Holding)
        {
#if TODO
            double   A, B, D, hdot_Vt;
            Vector3D vPQR    = FDMExec.Propagate.GetPQR();
            Vector3D vUVW    = FDMExec.Propagate.GetUVW();
            Vector3D vUVWdot = FDMExec.Propagate.GetUVWdot();
            Vector3D vVel    = FDMExec.Propagate.GetVel();

            if (InternalRun())
            {
                return(true);
            }
            if (FDMExec.Holding())
            {
                return(false);                   // if paused don't execute
            }
            p     = FDMExec.Atmosphere.Pressure;
            rhosl = FDMExec.Atmosphere.DensitySeaLevel;
            psl   = FDMExec.Atmosphere.PressureSeaLevel;
            sat   = FDMExec.Atmosphere.Temperature;

            // Rotation

            double cTht = FDMExec.Propagate.GetCosEuler((int)EulerAngleType.eTht);
            double cPhi = FDMExec.Propagate.GetCosEuler((int)EulerAngleType.ePhi);
            double sPhi = FDMExec.Propagate.GetSinEuler((int)EulerAngleType.ePhi);

            vEulerRates.Theta = vPQR.eQ * cPhi - vPQR.eR * sPhi;
            if (cTht != 0.0)
            {
                vEulerRates.Psi = (vPQR.eQ * sPhi + vPQR.eR * cPhi) / cTht;
                vEulerRates.Phi = vPQR.eP + vEulerRates.Psi * sPhi;
            }

            //TODO  vAeroPQR = vPQR + FDMExec.Atmosphere.TurbPQR;

            // Translation

            //vAeroUVW = vUVW + FDMExec.Propagate.GetTl2b() * FDMExec.Atmosphere.GetWindNED();

            vt = vAeroUVW.GetMagnitude();
            if (vt > 0.05)
            {
                if (vAeroUVW.W != 0.0)
                {
                    alpha = vAeroUVW.U * vAeroUVW.U > 0.0 ? Math.Atan2(vAeroUVW.W, vAeroUVW.U) : 0.0;
                }
                if (vAeroUVW.V != 0.0)
                {
                    beta = vAeroUVW.U * vAeroUVW.U + vAeroUVW.W * vAeroUVW.W > 0.0 ? Math.Atan2(vAeroUVW.V,
                                                                                                Math.Sqrt(vAeroUVW.U * vAeroUVW.U + vAeroUVW.W * vAeroUVW.W)) : 0.0;
                }

                double mUW   = (vAeroUVW.U * vAeroUVW.U + vAeroUVW.W * vAeroUVW.W);
                double signU = 1;
                if (vAeroUVW.U != 0.0)
                {
                    signU = vAeroUVW.U / Math.Abs(vAeroUVW.U);
                }

                if ((mUW == 0.0) || (vt == 0.0))
                {
                    adot = 0.0;
                    bdot = 0.0;
                }
                else
                {
                    adot = (vAeroUVW.U * vUVWdot.W - vAeroUVW.W * vUVWdot.U) / mUW;
                    bdot = (signU * mUW * vUVWdot.V - vAeroUVW.V * (vAeroUVW.U * vUVWdot.U
                                                                    + vAeroUVW.W * vUVWdot.W)) / (vt * vt * Math.Sqrt(mUW));
                }
            }
            else
            {
                alpha = beta = adot = bdot = 0;
            }

            qbar       = 0.5 * FDMExec.Atmosphere.Density * vt * vt;
            qbarUW     = 0.5 * FDMExec.Atmosphere.Density * (vAeroUVW.U * vAeroUVW.U + vAeroUVW.W * vAeroUVW.W);
            qbarUV     = 0.5 * FDMExec.Atmosphere.Density * (vAeroUVW.U * vAeroUVW.U + vAeroUVW.V * vAeroUVW.V);
            mach       = vt / FDMExec.Atmosphere.SoundSpeed;
            machU      = vMachUVW.U = vAeroUVW.U / FDMExec.Atmosphere.SoundSpeed;
            vMachUVW.V = vAeroUVW.V / FDMExec.Atmosphere.SoundSpeed;
            vMachUVW.W = vAeroUVW.W / FDMExec.Atmosphere.SoundSpeed;

            // Position

            Vground = Math.Sqrt(vVel.North * vVel.North + vVel.East * vVel.East);

            if (vVel.North == 0)
            {
                psigt = 0;
            }
            else
            {
                psigt = Math.Atan2(vVel.East, vVel.North);
            }

            if (psigt < 0.0)
            {
                psigt += 2 * Math.PI;
            }

            if (vt != 0)
            {
                hdot_Vt = -vVel.Down / vt;
                if (Math.Abs(hdot_Vt) <= 1)
                {
                    gamma = Math.Asin(hdot_Vt);
                }
            }
            else
            {
                gamma = 0.0;
            }

            tat  = sat * (1 + 0.2 * mach * mach); // Total Temperature, isentropic flow
            tatc = Conversion.RankineToCelsius(tat);

            if (machU < 1)
            {   // Calculate total pressure assuming isentropic flow
                pt = p * Math.Pow((1 + 0.2 * machU * machU), 3.5);
            }
            else
            {
                // Use Rayleigh pitot tube formula for normal shock in front of pitot tube
                B  = 5.76 * machU * machU / (5.6 * machU * machU - 0.8);
                D  = (2.8 * machU * machU - 0.4) * 0.4167;
                pt = p * Math.Pow(B, 3.5) * D;
            }

            A = Math.Pow(((pt - p) / psl + 1), 0.28571);
            if (machU > 0.0)
            {
                vcas = Math.Sqrt(7 * psl / rhosl * (A - 1));
                veas = Math.Sqrt(2 * qbar / rhosl);
            }
            else
            {
                vcas = veas = 0.0;
            }

            ///TODO vPilotAccel.InitMatrix();
            if (vt > 1.0)
            {
                vPilotAccel = FDMExec.Aerodynamics.Forces
                              + FDMExec.Propulsion.GetForces()
                              + FDMExec.GroundReactions.GetForces();
                vPilotAccel /= FDMExec.MassBalance.Mass;
                vToEyePt     = FDMExec.MassBalance.StructuralToBody(FDMExec.Aircraft.EyepointXYZ);
                vPilotAccel += Vector3D.Cross(FDMExec.Propagate.GetPQRdot(), vToEyePt);
                vPilotAccel += Vector3D.Cross(vPQR, Vector3D.Cross(vPQR, vToEyePt));
            }
            else
            {
                Vector3D aux = new Vector3D(0.0, 0.0, FDMExec.Inertial.Gravity);
                vPilotAccel = FDMExec.Propagate.GetTl2b() * aux;
            }

            vPilotAccelN = vPilotAccel / FDMExec.Inertial.Gravity;

            earthPosAngle += FDMExec.State.DeltaTime * FDMExec.Inertial.Omega;

            // VRP computation
            Location vLocation     = FDMExec.Propagate.GetLocation();
            Vector3D vrpStructural = FDMExec.Aircraft.VisualRefPointXYZ;
            Vector3D vrpBody       = FDMExec.MassBalance.StructuralToBody(vrpStructural);
            Vector3D vrpLocal      = FDMExec.Propagate.GetTb2l() * vrpBody;
            vLocationVRP = vLocation.LocalToLocation(vrpLocal);

            // Recompute some derived values now that we know the dependent parameters values ...
            hoverbcg = FDMExec.Propagate.DistanceAGL / FDMExec.Aircraft.WingSpan;

            Vector3D vMac = FDMExec.Propagate.GetTb2l() * FDMExec.MassBalance.StructuralToBody(FDMExec.Aircraft.AeroRefPointXYZ);
            hoverbmac = (FDMExec.Propagate.DistanceAGL + vMac.Z) / FDMExec.Aircraft.WingSpan;

            return(false);
#endif
            throw new NotImplementedException("Pending upgrade to lastest version of JSBSIM");
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Runs the Propagate model; called by the Executive
        /// </summary>
        /// <returns>false if no error</returns>
        public override bool Run()
        {
            if (InternalRun())
            {
                return(true);
            }
            if (FDMExec.Holding())
            {
                return(false);                   // if paused don't execute
            }
            RecomputeRunwayRadius();

            double   dt       = FDMExec.State.DeltaTime * rate;                 // The 'stepsize'
            Vector3D omega    = new Vector3D(0.0, 0.0, FDMExec.Inertial.Omega); // earth rotation
            Vector3D vForces  = FDMExec.Aircraft.Forces;                        // current forces
            Vector3D vMoments = FDMExec.Aircraft.Moments;                       // current moments

            double   mass = FDMExec.MassBalance.Mass;                           // mass
            Matrix3D J    = FDMExec.MassBalance.GetJ();                         // inertia matrix
            Matrix3D Jinv = FDMExec.MassBalance.GetJinv();                      // inertia matrix inverse
            double   r    = this.Radius;                                        // radius

            if (r == 0.0)
            {
                if (log.IsErrorEnabled)
                {
                    log.Error("radius = 0 !");
                }
                r = 1e-16;
            }             // radius check
            double   rInv   = 1.0 / r;
            Vector3D gAccel = new Vector3D(0.0, 0.0, FDMExec.Inertial.GetGAccel(r));

            // The rotation matrices:
            Matrix3D Tl2b  = GetTl2b();                   // local to body frame
            Matrix3D Tb2l  = GetTb2l();                   // body to local frame
            Matrix3D Tec2l = VState.vLocation.GetTec2l(); // earth centered to local frame
            Matrix3D Tl2ec = VState.vLocation.GetTl2ec(); // local to earth centered frame

            // Inertial angular velocity measured in the body frame.
            Vector3D pqri = VState.vPQR + Tl2b * (Tec2l * omega);

            // Compute vehicle velocity wrt EC frame, expressed in Local horizontal frame.
            vVel = Tb2l * VState.vUVW;

            // First compute the time derivatives of the vehicle state values:

            // Compute body frame rotational accelerations based on the current body moments
            vPQRdot = Jinv * (vMoments - Vector3D.Cross(pqri, (J * pqri)));

            // Compute body frame accelerations based on the current body forces
            vUVWdot = Vector3D.Cross(VState.vUVW, VState.vPQR) + vForces / mass;

            // Coriolis acceleration.
            Vector3D ecVel = Tl2ec * vVel;
            Vector3D ace   = 2.0 * Vector3D.Cross(omega, ecVel);

            vUVWdot -= Tl2b * (Tec2l * ace);

            // Centrifugal acceleration.
            if (!FDMExec.GroundReactions.GetWOW())
            {
                Vector3D aeec = Vector3D.Cross(omega, Vector3D.Cross(omega, (Vector3D)VState.vLocation));
                vUVWdot -= Tl2b * (Tec2l * aeec);
            }

            // Gravitation accel
            vUVWdot += Tl2b * gAccel;

            // Compute vehicle velocity wrt EC frame, expressed in EC frame
            Vector3D vLocationDot = Tl2ec * vVel;

            Vector3D omegaLocal = new Vector3D(rInv * vVel.East,
                                               -rInv * vVel.North,
                                               -rInv * vVel.East * VState.vLocation.TanLatitude);

            // Compute quaternion orientation derivative on current body rates
            Quaternion vQtrndot = VState.vQtrn.GetQDot(VState.vPQR - Tl2b * omegaLocal);

            // Propagate velocities
            VState.vPQR += dt * vPQRdot;
            VState.vUVW += dt * vUVWdot;

            // Propagate positions
            VState.vQtrn     += dt * vQtrndot;
            VState.vLocation += (Location)(dt * vLocationDot);

            return(false);
        }